Spaces:
Running
Running
V2 full code restore - hardcoded HF module path
Browse files- index.html +12 -314
index.html
CHANGED
|
@@ -282,333 +282,31 @@ if(storageMode==="indexedDB"){
|
|
| 282 |
renderChatHistory();
|
| 283 |
var el=document.getElementById("storageModeSelect");
|
| 284 |
if(el){el.value="localStorage";onStorageModeChange();}
|
| 285 |
-
if(conversations.length>0)loadChat(conversations[0].id)
|
| 286 |
});
|
| 287 |
} else {
|
| 288 |
renderChatHistory();
|
| 289 |
var el=document.getElementById("storageModeSelect");
|
| 290 |
-
|
| 291 |
setTimeout(function(){
|
| 292 |
-
if
|
| 293 |
-
if(conversations.length>0)loadChat(conversations[0
|
| 294 |
-
|
| 295 |
-
}
|
| 296 |
-
},50);
|
| 297 |
-
}
|
| 298 |
|
| 299 |
// ===== SANITIZATION UTILITIES =====
|
| 300 |
-
function sanitizeHTML(str){if(typeof DOMPurify!=="undefined")return DOMPurify.sanitize(str
|
| 301 |
-
function safeRenderHTML(html,allowSafeTags){try{if(typeof DOMPurify!=="undefined"){if(allowSafeTags)return DOMPurify.sanitize(html,{ALLOWED_TAGS:["div","span","a","b","i","em","strong","code","pre","br","p","h1","h2","h3","h4","h5","h6","ul","ol","li","blockquote","table","thead","tbody","tr","th","td","hr","img","figure","figcaption","dl","dt","dd","sup","sub","kbd","s","del","ins","mark","small","details","summary","button"],ALLOWED_ATTR:["href","target","rel","src","alt","class","id","title","width","height","style","data-*"],ALLOW_DATA_ATTR:true,FORBID_TAGS:["style","script","iframe","object","embed","form","input","textarea","select","option","optgroup","svg","math","link","meta","video","audio","canvas","applet","frame","frameset","noframes","noscript"],FORBID_ATTR:["onerror","onload","onclick","onmouseover","onmouseout","onkeydown","onkeyup","onchange","onsubmit","onfocus","onblur","onabort","onanimationstart","onanimationend","onauxclick","onbeforeinput","onbeforetoggle","oncancel","oncanplay","oncanplaythrough","onclose","oncontextmenu","oncopy","oncuechange","oncut","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onformdata","ongotpointercapture","oninput","oninvalid","onlostpointercapture","onpaste","
|
| 302 |
function safeSetInnerHTML(el,html){try{el.innerHTML=html;}catch(ex){el.textContent=html;}}
|
| 303 |
-
function renderMarkdown(text){if(!text)return "";try{var
|
| 304 |
function showToast(msg){var t=document.getElementById("toast");t.textContent=msg;t.classList.remove("hidden");clearTimeout(t._timeout);t._timeout=setTimeout(function(){t.classList.add("hidden");},3500);}
|
| 305 |
function scrollToBottom(smooth){if(smooth===undefined)smooth=true;var c=document.getElementById("messages");c.scrollTop=c.scrollHeight;}
|
| 306 |
function getTimeStr(){var d=new Date();return d.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"});}
|
| 307 |
function updateAutoScroll(){autoScroll=document.getElementById("autoScrollToggle").checked;}
|
| 308 |
-
function getCurrentChat(){for(var i=0;i<conversations.length;i++)if(conversations[i].id===currentChatId)return
|
| 309 |
-
function
|
| 310 |
-
function
|
| 311 |
-
|
| 312 |
-
function showConfirmDialog(msg,callback){confirmCallback=callback;var modal=document.getElementById("confirmModal");document.getElementById("confirmModalBody").textContent=msg;modal.classList.add("show");}
|
| 313 |
document.getElementById("confirmOkBtn").addEventListener("click",function(){var cb=confirmCallback;confirmCallback=null;document.getElementById("confirmModal").classList.remove("show");if(cb)cb(true);});
|
| 314 |
document.getElementById("confirmCancelBtn").addEventListener("click",function(){var cb=confirmCallback;confirmCallback=null;document.getElementById("confirmModal").classList.remove("show");if(cb)cb(false);});
|
| 315 |
|
| 316 |
-
function saveConversations(){
|
| 317 |
-
if(storageMode==="indexedDB"&&DB._ready){
|
| 318 |
-
try{conversations.forEach(function(c){DB.saveConversation(c);});updateStorageIndicator();}catch(ex){}
|
| 319 |
-
return;
|
| 320 |
-
}
|
| 321 |
-
try{var usage=getStorageUsage();var json=JSON.stringify(conversations);
|
| 322 |
-
if(usage.pct>=STORAGE_CRIT_PCT){trimConversations(true);json=JSON.stringify(conversations);}
|
| 323 |
-
else if(usage.pct>=STORAGE_WARN_PCT){trimConversations(false);json=JSON.stringify(conversations);}
|
| 324 |
-
localStorage.setItem(STORAGE_KEY,json);updateStorageIndicator();
|
| 325 |
-
}catch(ex){try{var cur=getCurrentChat();if(cur){var m=[{id:cur.id,title:cur.title,model:cur.model,messages:cur.messages.slice(-20),createdAt:cur.createdAt}];localStorage.setItem(STORAGE_KEY,JSON.stringify(m));conversations=m;showToast("Storage critical!");updateStorageIndicator();}}catch(ex2){showToast("Storage full!");}}
|
| 326 |
-
}
|
| 327 |
-
|
| 328 |
-
function trimConversations(force){
|
| 329 |
-
if(!conversations||conversations.length===0)return;
|
| 330 |
-
conversations.sort(function(a,b){var al=a.messages&&a.messages.length?new Date(a.messages[a.messages.length-1].timestamp||a.createdAt).getTime():new Date(a.createdAt).getTime();var bl=b.messages&&b.messages.length?new Date(b.messages[b.messages.length-1].timestamp||b.createdAt).getTime():new Date(b.createdAt).getTime();return bl-al;});
|
| 331 |
-
for(var i=conversations.length-1;i>=1;i--){if(!conversations[i].messages||conversations[i].messages.length===0)conversations.splice(i,1);}
|
| 332 |
-
while(conversations.length>MAX_CONVERSATIONS)conversations.pop();
|
| 333 |
-
if(force){var now=Date.now();for(var i=conversations.length-1;i>=1;i--){var chat=conversations[i];if(!chat.messages)continue;if(now-new Date(chat.createdAt||now).getTime()>7*86400000&&chat.messages.length>10)chat.messages=chat.messages.slice(-10);}}
|
| 334 |
-
}
|
| 335 |
-
|
| 336 |
-
function updateStorageIndicator(){var el=document.getElementById("storageIndicator");if(!el)return;var u=getStorageUsage(),pct=u.pct;var c=pct>90?"text-red-400":pct>70?"text-yellow-400":"text-emerald-400";var bc=pct>90?"bg-red-500":pct>70?"bg-yellow-500":"bg-emerald-500";el.innerHTML='<div class="flex items-center gap-2 text-xs" title="Storage: '+formatBytes(u.used)+' / '+formatBytes(u.limit)+'"><div class="w-16 h-1.5 bg-gray-700 rounded-full overflow-hidden"><div class="h-full '+bc+' rounded-full" style="width:'+Math.min(pct,100)+'%"></div></div><span class="'+c+'">'+pct+'%</span></div>';}
|
| 337 |
-
function addStorageIndicator(){var footer=document.querySelector(".left-sidebar-footer");if(!footer)return;var ind=document.createElement("div");ind.id="storageIndicator";ind.className="px-4 py-1";footer.parentNode.insertBefore(ind,footer);updateStorageIndicator();}
|
| 338 |
-
function setProcessingUI(p){var s=document.getElementById("sendBtn"),c=document.getElementById("cancelBtn");if(!s||!c)return;if(p){s.classList.add("hidden");c.classList.remove("hidden");}else{s.classList.remove("hidden");c.classList.add("hidden");}}
|
| 339 |
-
function updateTokenDisplay(){var chat=getCurrentChat();if(!chat)return;var t=0;for(var i=0;i<chat.messages.length;i++){if(chat.messages[i].content)t+=chat.messages[i].content.length;}var a=Math.round(t/4);document.getElementById("tokenUsage").textContent="~"+a+" tokens";document.getElementById("totalTokens").textContent=a;updateCostDisplay(a);}
|
| 340 |
-
function updateCostDisplay(t){var el=document.getElementById("costDisplay");if(!selectedModelId||!t||!modelPricing[selectedModelId]){el.classList.add("hidden");return;}var p=modelPricing[selectedModelId];if(typeof p.input!=='number'){el.classList.add("hidden");return;}el.textContent="~$"+((p.input||0)*t+(p.output||0)*(t*0.3)).toFixed(4);el.classList.remove("hidden");}
|
| 341 |
-
|
| 342 |
-
function clearOldConversations(){
|
| 343 |
-
showConfirmDialog("Delete all conversations except the current one?",function(confirmed){if(!confirmed)return;
|
| 344 |
-
var cur=getCurrentChat(),curId=cur?cur.id:null;var keep=cur?[{id:cur.id,title:cur.title,model:cur.model,messages:cur.messages,createdAt:cur.createdAt}]:[];
|
| 345 |
-
var RS=window.RightSidebar;
|
| 346 |
-
if(RS){RS._files=RS._files.filter(function(f){return f.chatId===curId||keep.some(function(k){return k.id===f.chatId;});});RS._order=RS._order.filter(function(id){return RS._files.some(function(f){return f.id===id;});});}
|
| 347 |
-
if(DB._ready){
|
| 348 |
-
conversations.forEach(function(c){if(c.id!==curId){DB.deleteConversation(c.id);DB.deleteConversationFiles(c.id);}});
|
| 349 |
-
conversations.forEach(function(c){if(c.id!==curId){try{localStorage.removeItem("chatpad_files_"+c.id);}catch(ex){}}});
|
| 350 |
-
}
|
| 351 |
-
conversations=keep;saveConversations();renderChatHistory();if(RS)RS.render();showToast("Cleared");
|
| 352 |
-
});
|
| 353 |
-
}
|
| 354 |
-
|
| 355 |
-
function isMobile(){return window.innerWidth<768;}
|
| 356 |
-
function openLeftSidebar(){if(!isMobile())return;document.getElementById("leftSidebar").classList.add("open");document.getElementById("leftSidebarOverlay").classList.add("show");document.body.style.overflow="hidden";}
|
| 357 |
-
function closeLeftSidebar(){document.getElementById("leftSidebar").classList.remove("open");document.getElementById("leftSidebarOverlay").classList.remove("show");document.body.style.overflow="";}
|
| 358 |
-
function isTablet(){return window.innerWidth<1024;}
|
| 359 |
-
function closeRightSidebar(){if(!isTablet())return;document.getElementById("rightSidebar").classList.remove("open");document.getElementById("rightSidebar").classList.add("collapsed");document.getElementById("rsBackdrop").classList.remove("show");if(window.RightSidebar)window.RightSidebar._visible=false;var t=document.getElementById("rightSidebarToggle");if(t)t.classList.remove("open");}
|
| 360 |
-
|
| 361 |
-
function openSettings(){closeLeftSidebar();document.getElementById("settingsModal").classList.add("show");document.getElementById("apiKeyModal").value=API_KEY;try{document.getElementById("sysPromptModal").value=_savedSysPrompt||"";}catch(ex){}var s=document.getElementById("stepSlider");s.value=MAX_STEPS>=999?50:MAX_STEPS;document.getElementById("stepValue").textContent=MAX_STEPS>=999?"∞":MAX_STEPS;document.getElementById("unlimitedSteps").checked=(MAX_STEPS>=999);updateKeyStatusModal();var modeEl=document.getElementById("storageModeSelect");if(modeEl){modeEl.value=storageMode;onStorageModeChange();}var ctxT=document.getElementById("contextTurnsSlider");if(ctxT){ctxT.value=MAX_CONTEXT_TURNS;document.getElementById("contextTurnsValue").textContent=MAX_CONTEXT_TURNS;}var ctxF=document.getElementById("contextFilesSlider");if(ctxF){ctxF.value=MAX_CONTEXT_FILES;document.getElementById("contextFilesValue").textContent=MAX_CONTEXT_FILES;}var ml=document.getElementById("modulesLocationInput");if(ml)ml.value=MODULES_LOCATION;}
|
| 362 |
-
function closeSettings(){document.getElementById("settingsModal").classList.remove("show");}
|
| 363 |
-
function updateKeyStatusModal(){var el=document.getElementById("keyStatusModal");if(API_KEY&&API_KEY.indexOf("sk-or-")===0)el.innerHTML='<i class="fas fa-circle" style="color:#6ee7b7"></i>';else if(API_KEY)el.innerHTML='<i class="fas fa-circle" style="color:#facc15"></i>';else el.innerHTML='<i class="fas fa-circle" style="color:#6b7280"></i>';}
|
| 364 |
-
|
| 365 |
-
function syncApiKey(){API_KEY=document.getElementById("apiKeyModal").value.trim();if(storageMode==='localStorage'){try{localStorage.setItem("huggingbot_api_key",API_KEY);}catch(ex){}}else if(storageMode==='indexedDB'&&DB._ready){DB.setSetting("api_key",API_KEY);}updateKeyStatusModal();}
|
| 366 |
-
function saveSysPrompt(){_savedSysPrompt=document.getElementById("sysPromptModal").value.trim();if(storageMode==='localStorage'){try{localStorage.setItem("huggingbot_sys_prompt",_savedSysPrompt);}catch(ex){}}else if(storageMode==='indexedDB'&&DB._ready){DB.setSetting("sys_prompt",_savedSysPrompt);}}
|
| 367 |
-
function saveModulesLocation(){var ml=document.getElementById("modulesLocationInput");if(!ml)return;MODULES_LOCATION=ml.value.trim();if(storageMode==='localStorage'){try{localStorage.setItem("huggingbot_modules_location",MODULES_LOCATION);}catch(ex){}}else if(storageMode==='indexedDB'&&DB._ready){DB.setSetting("modules_location",MODULES_LOCATION);}}
|
| 368 |
-
function saveSettings(){var oldMode=storageMode;syncApiKey();saveSysPrompt();saveModulesLocation();MAX_STEPS=document.getElementById("unlimitedSteps").checked?999:(parseInt(document.getElementById("stepSlider").value)||10);MAX_CONTEXT_TURNS=parseInt(document.getElementById("contextTurnsSlider").value)||5;MAX_CONTEXT_FILES=parseInt(document.getElementById("contextFilesSlider").value)||5;var modeEl=document.getElementById("storageModeSelect");if(modeEl)storageMode=modeEl.value;if(storageMode==='localStorage'){try{localStorage.setItem("huggingbot_max_steps",String(MAX_STEPS));localStorage.setItem("huggingbot_context_turns",String(MAX_CONTEXT_TURNS));localStorage.setItem("huggingbot_context_files",String(MAX_CONTEXT_FILES));localStorage.setItem("huggingbot_storage_mode","localStorage");}catch(ex){}}else if(storageMode==='indexedDB'&&DB._ready){DB.setSetting("max_steps",String(MAX_STEPS));DB.setSetting("context_turns",String(MAX_CONTEXT_TURNS));DB.setSetting("context_files",String(MAX_CONTEXT_FILES));DB.setSetting("storage_mode","indexedDB");}closeSettings();if(oldMode!==storageMode){showToast("Switching to "+storageMode+"...");setTimeout(function(){forceReloadConversations();},100);}else{showToast("Settings saved");}}
|
| 369 |
-
function updateStepDisplay(){var v=parseInt(document.getElementById("stepSlider").value);document.getElementById("stepValue").textContent=v;document.getElementById("unlimitedSteps").checked=false;MAX_STEPS=v;}
|
| 370 |
-
function toggleUnlimitedSteps(){if(document.getElementById("unlimitedSteps").checked){MAX_STEPS=999;document.getElementById("stepSlider").value=999;document.getElementById("stepValue").textContent="∞";}else{MAX_STEPS=10;document.getElementById("stepSlider").value=10;document.getElementById("stepValue").textContent="10";}if(storageMode==='localStorage'){try{localStorage.setItem("huggingbot_max_steps",String(MAX_STEPS));}catch(ex){}}else if(storageMode==='indexedDB'&&DB._ready){DB.setSetting("max_steps",String(MAX_STEPS));}}
|
| 371 |
-
function updateContextTurnsDisplay(){var v=parseInt(document.getElementById("contextTurnsSlider").value);document.getElementById("contextTurnsValue").textContent=v;MAX_CONTEXT_TURNS=v;}
|
| 372 |
-
function updateContextFilesDisplay(){var v=parseInt(document.getElementById("contextFilesSlider").value);document.getElementById("contextFilesValue").textContent=v;MAX_CONTEXT_FILES=v;}
|
| 373 |
-
function getSystemPrompt(){if(_savedSysPrompt)return _savedSysPrompt;if(storageMode==='localStorage'){try{var v=localStorage.getItem("huggingbot_sys_prompt")||"";_savedSysPrompt=v;return v;}catch(ex){return "";}}if(DB._ready){return _savedSysPrompt||"";}return "";}
|
| 374 |
-
function onStorageModeChange(){var el=document.getElementById("storageModeSelect");var label=document.getElementById("storageModeLabel");if(!el||!label)return;var mode=el.value;if(mode==="indexedDB"&&!DB._ready){label.textContent="⚠ Not available";label.style.color="#f87171";return;}label.textContent=mode==="indexedDB"?"✓ Using IndexedDB":"✓ Using localStorage";label.style.color="#6ee7b7";}
|
| 375 |
-
|
| 376 |
-
function trimContext(){
|
| 377 |
-
if(!currentChatId)return;
|
| 378 |
-
var chat=getCurrentChat();if(!chat||!chat.messages)return;
|
| 379 |
-
if(chat.messages.length>MAX_CONTEXT_TURNS*2){
|
| 380 |
-
var keep=MAX_CONTEXT_TURNS*2;
|
| 381 |
-
var firstUserIdx=-1;
|
| 382 |
-
for(var i=0;i<chat.messages.length;i++){
|
| 383 |
-
if(chat.messages[i].role==="user"){firstUserIdx=i;break;}
|
| 384 |
-
}
|
| 385 |
-
if(firstUserIdx>=0&&firstUserIdx<chat.messages.length-keep){
|
| 386 |
-
var tail=chat.messages.slice(-(keep-1));
|
| 387 |
-
chat.messages=[chat.messages[firstUserIdx]].concat(tail);
|
| 388 |
-
} else {
|
| 389 |
-
chat.messages=chat.messages.slice(-keep);
|
| 390 |
-
}
|
| 391 |
-
chat.updatedAt=new Date().toISOString();
|
| 392 |
-
}
|
| 393 |
-
var RS=window.RightSidebar;
|
| 394 |
-
if(RS){
|
| 395 |
-
var chatFiles=RS._getFilesForChat(currentChatId);
|
| 396 |
-
if(chatFiles.length>MAX_CONTEXT_FILES){
|
| 397 |
-
chatFiles.sort(function(a,b){return (a.addedAt||0)-(b.addedAt||0);});
|
| 398 |
-
var toRemove=chatFiles.slice(0,chatFiles.length-MAX_CONTEXT_FILES);
|
| 399 |
-
for(var i=0;i<toRemove.length;i++){RS.removeFile(toRemove[i].id);}
|
| 400 |
-
}
|
| 401 |
-
}
|
| 402 |
-
}
|
| 403 |
-
|
| 404 |
-
function newChat(){closeLeftSidebar();if(currentChatId){var c=getCurrentChat();if(c&&c.messages&&c.messages.length>0)saveConversations();}
|
| 405 |
-
var chat={id:"chat_"+Date.now(),title:"New Chat",model:selectedModelId||"",messages:[],createdAt:new Date().toISOString()};
|
| 406 |
-
conversations.unshift(chat);saveConversations();
|
| 407 |
-
var RS=window.RightSidebar;
|
| 408 |
-
if(RS){RS._files=RS._files.filter(function(f){return f.chatId!==currentChatId;});RS._order=[];RS._active=null;RS.render();}
|
| 409 |
-
loadChat(chat.id);}
|
| 410 |
-
|
| 411 |
-
function loadChat(id){if(id===currentChatId)return;if(currentChatId)saveConversations();currentChatId=id;closeLeftSidebar();var chat=getCurrentChat();if(!chat)return;
|
| 412 |
-
var RS=window.RightSidebar;
|
| 413 |
-
if(RS){RS._order=[];RS._active=null;}
|
| 414 |
-
if(chat.model){var found=null;for(var i=0;i<AVAILABLE_MODELS.length;i++)if(AVAILABLE_MODELS[i].id===chat.model){found=AVAILABLE_MODELS[i];break;}var input=document.getElementById("modelSearchInput");if(found){input.value=found.name;input.dataset.modelId=found.id;selectedModelId=found.id;document.getElementById("currentModelHeader").textContent=found.name;}else{input.value=chat.model;input.dataset.modelId=chat.model;selectedModelId=chat.model;document.getElementById("currentModelHeader").textContent=chat.model;}}
|
| 415 |
-
if(!isProcessing)setProcessingUI(false);
|
| 416 |
-
renderMessages(chat.messages);renderChatHistory();updateTokenDisplay();
|
| 417 |
-
document.getElementById("scrollFab").classList.remove("show");
|
| 418 |
-
if(RS)RS.loadForChat(currentChatId);}
|
| 419 |
-
|
| 420 |
-
function forceReloadConversations(){
|
| 421 |
-
var curId=currentChatId;
|
| 422 |
-
if(storageMode==="indexedDB"&&DB._ready){
|
| 423 |
-
DB.getAllSettings().then(function(settings){
|
| 424 |
-
if(settings.api_key){API_KEY=settings.api_key;document.getElementById("apiKeyModal").value=API_KEY;updateKeyStatusModal();}
|
| 425 |
-
if(settings.sys_prompt){_savedSysPrompt=settings.sys_prompt;document.getElementById("sysPromptModal").value=_savedSysPrompt;}
|
| 426 |
-
if(settings.max_steps){MAX_STEPS=parseInt(settings.max_steps)||10;var s=document.getElementById("stepSlider");if(s)s.value=MAX_STEPS>=999?50:MAX_STEPS;var sv=document.getElementById("stepValue");if(sv)sv.textContent=MAX_STEPS>=999?"∞":MAX_STEPS;var uc=document.getElementById("unlimitedSteps");if(uc)uc.checked=(MAX_STEPS>=999);}
|
| 427 |
-
if(settings.context_turns){MAX_CONTEXT_TURNS=parseInt(settings.context_turns)||5;var ct=document.getElementById("contextTurnsSlider");if(ct)ct.value=MAX_CONTEXT_TURNS;var ctv=document.getElementById("contextTurnsValue");if(ctv)ctv.textContent=MAX_CONTEXT_TURNS;}
|
| 428 |
-
if(settings.context_files){MAX_CONTEXT_FILES=parseInt(settings.context_files)||5;var cf=document.getElementById("contextFilesSlider");if(cf)cf.value=MAX_CONTEXT_FILES;var cfv=document.getElementById("contextFilesValue");if(cfv)cfv.textContent=MAX_CONTEXT_FILES;}
|
| 429 |
-
if(settings.modules_location){MODULES_LOCATION=settings.modules_location;var ml=document.getElementById("modulesLocationInput");if(ml)ml.value=MODULES_LOCATION;}
|
| 430 |
-
}).catch(function(){});
|
| 431 |
-
DB.getAllConversations().then(function(dbChats){
|
| 432 |
-
conversations=dbChats||[];
|
| 433 |
-
conversations.sort(function(a,b){return getChatSortTime(b)-getChatSortTime(a);});
|
| 434 |
-
var found=conversations.some(function(c){return c.id===curId;});
|
| 435 |
-
if(found)loadChat(curId);
|
| 436 |
-
else if(conversations.length>0)loadChat(conversations[0].id);
|
| 437 |
-
else newChat();
|
| 438 |
-
showToast("Loaded "+conversations.length+" conversations from IndexedDB");
|
| 439 |
-
}).catch(function(){showToast("Failed to load from IndexedDB");});
|
| 440 |
-
} else {
|
| 441 |
-
try{var s=localStorage.getItem(STORAGE_KEY);if(s){var p=JSON.parse(s);if(Array.isArray(p)&&p.length>0){conversations=p;}else{conversations=[];}}else{conversations=[];}}catch(ex){conversations=[];}
|
| 442 |
-
try{var k=localStorage.getItem("huggingbot_api_key");if(k){API_KEY=k;document.getElementById("apiKeyModal").value=k;updateKeyStatusModal();}}catch(ex){}
|
| 443 |
-
try{var sp=localStorage.getItem("huggingbot_sys_prompt");if(sp){_savedSysPrompt=sp;document.getElementById("sysPromptModal").value=sp;}}catch(ex){}
|
| 444 |
-
try{var ms=localStorage.getItem("huggingbot_max_steps");if(ms){MAX_STEPS=parseInt(ms)||10;var s=document.getElementById("stepSlider");if(s)s.value=MAX_STEPS>=999?50:MAX_STEPS;var sv=document.getElementById("stepValue");if(sv)sv.textContent=MAX_STEPS>=999?"∞":MAX_STEPS;var uc=document.getElementById("unlimitedSteps");if(uc)uc.checked=(MAX_STEPS>=999);}}catch(ex){}
|
| 445 |
-
try{var ct=localStorage.getItem("huggingbot_context_turns");if(ct){MAX_CONTEXT_TURNS=parseInt(ct)||5;var cts=document.getElementById("contextTurnsSlider");if(cts)cts.value=MAX_CONTEXT_TURNS;var ctv=document.getElementById("contextTurnsValue");if(ctv)ctv.textContent=MAX_CONTEXT_TURNS;}}catch(ex){}
|
| 446 |
-
try{var cf=localStorage.getItem("huggingbot_context_files");if(cf){MAX_CONTEXT_FILES=parseInt(cf)||5;var cfs=document.getElementById("contextFilesSlider");if(cfs)cfs.value=MAX_CONTEXT_FILES;var cfv=document.getElementById("contextFilesValue");if(cfv)cfv.textContent=MAX_CONTEXT_FILES;}}catch(ex){}
|
| 447 |
-
try{var ml=localStorage.getItem("huggingbot_modules_location");if(ml){MODULES_LOCATION=ml;var mli=document.getElementById("modulesLocationInput");if(mli)mli.value=ml;}}catch(ex){}
|
| 448 |
-
var found=conversations.some(function(c){return c.id===curId;});
|
| 449 |
-
if(found)loadChat(curId);
|
| 450 |
-
else if(conversations.length>0)loadChat(conversations[0].id);
|
| 451 |
-
else newChat();
|
| 452 |
-
showToast("Loaded "+conversations.length+" conversations from localStorage");
|
| 453 |
-
}
|
| 454 |
-
}
|
| 455 |
-
|
| 456 |
-
function deleteCurrentChat(){if(!currentChatId){showToast("No chat");return;}
|
| 457 |
-
showConfirmDialog("Delete this conversation forever?",function(confirmed){if(!confirmed)return;
|
| 458 |
-
var idx=-1;for(var i=0;i<conversations.length;i++){if(conversations[i].id===currentChatId){idx=i;break;}}if(idx===-1)return;
|
| 459 |
-
var RS=window.RightSidebar;
|
| 460 |
-
if(RS){RS._files=RS._files.filter(function(f){return f.chatId!==currentChatId;});RS._order=[];RS._active=null;}
|
| 461 |
-
if(DB._ready){DB.deleteConversation(currentChatId);DB.deleteConversationFiles(currentChatId);}
|
| 462 |
-
conversations.splice(idx,1);saveConversations();
|
| 463 |
-
if(conversations.length>0)loadChat(conversations[0].id);else newChat();showToast("Deleted");
|
| 464 |
-
});
|
| 465 |
-
}
|
| 466 |
-
|
| 467 |
-
// ===== MODEL DROPDOWN =====
|
| 468 |
-
function filterModelDropdown(){
|
| 469 |
-
var dropdown=document.getElementById("modelDropdown");
|
| 470 |
-
var input=document.getElementById("modelSearchInput");
|
| 471 |
-
if(!dropdown||!input)return;
|
| 472 |
-
var q=input.value.toLowerCase().trim();
|
| 473 |
-
dropdown.innerHTML="";
|
| 474 |
-
if(!q){dropdown.classList.remove("show");return;}
|
| 475 |
-
var matches=[],exactMatch=null;
|
| 476 |
-
for(var i=0;i<AVAILABLE_MODELS.length;i++){
|
| 477 |
-
var m=AVAILABLE_MODELS[i];
|
| 478 |
-
if(m.id.toLowerCase().indexOf(q)!==-1||m.name.toLowerCase().indexOf(q)!==-1){
|
| 479 |
-
matches.push(m);
|
| 480 |
-
if(m.id===input.dataset.modelId||m.name.toLowerCase()===q)exactMatch=m;
|
| 481 |
-
}
|
| 482 |
-
}
|
| 483 |
-
if(matches.length===0){dropdown.classList.remove("show");return;}
|
| 484 |
-
if(matches.length===1&&exactMatch){dropdown.classList.remove("show");return;}
|
| 485 |
-
dropdown.classList.add("show");
|
| 486 |
-
for(var i=0;i<matches.length;i++){
|
| 487 |
-
var item=document.createElement("div");
|
| 488 |
-
item.className="model-dropdown-item"+(matches[i].id===selectedModelId?" active":"");
|
| 489 |
-
item.textContent=matches[i].name;
|
| 490 |
-
var provider=matches[i].id.split("/")[0]||"";
|
| 491 |
-
var ctx=matches[i].context_length?Math.round(matches[i].context_length/1000)+"K":"";
|
| 492 |
-
item.innerHTML=matches[i].name+' <span class="model-provider">'+provider+'</span>'+(ctx?'<span class="model-context">'+ctx+'</span>':'');
|
| 493 |
-
item.onclick=(function(mid){return function(){selectModelFromDropdown(mid);};})(matches[i].id);
|
| 494 |
-
dropdown.appendChild(item);
|
| 495 |
-
}
|
| 496 |
-
modelIndex=0;highlightModel(dropdown.querySelectorAll(".model-dropdown-item"));
|
| 497 |
-
}
|
| 498 |
-
function closeModelDropdown(){var dropdown=document.getElementById("modelDropdown");if(dropdown)dropdown.classList.remove("show");}
|
| 499 |
-
function onModelKeydown(e){
|
| 500 |
-
var dropdown=document.getElementById("modelDropdown");
|
| 501 |
-
if(!dropdown||!dropdown.classList.contains("show"))return;
|
| 502 |
-
var items=dropdown.querySelectorAll(".model-dropdown-item");
|
| 503 |
-
if(items.length===0)return;
|
| 504 |
-
if(e.key==="ArrowDown"){e.preventDefault();modelIndex=(modelIndex+1)%items.length;highlightModel(items);}
|
| 505 |
-
else if(e.key==="ArrowUp"){e.preventDefault();modelIndex=(modelIndex-1+items.length)%items.length;highlightModel(items);}
|
| 506 |
-
else if(e.key==="Enter"){e.preventDefault();if(items[modelIndex]){var md=items[modelIndex].textContent;var mid=null;for(var i=0;i<AVAILABLE_MODELS.length;i++){if(AVAILABLE_MODELS[i].name===md){mid=AVAILABLE_MODELS[i].id;break;}}if(mid)selectModelFromDropdown(mid);}}
|
| 507 |
-
else if(e.key==="Escape"){closeModelDropdown();}
|
| 508 |
-
}
|
| 509 |
-
function highlightModel(items){for(var i=0;i<items.length;i++)items[i].classList.toggle("active",i===modelIndex);if(items[modelIndex])items[modelIndex].scrollIntoView({block:"nearest"});}
|
| 510 |
-
function selectModelFromDropdown(id){var model=null;for(var i=0;i<AVAILABLE_MODELS.length;i++)if(AVAILABLE_MODELS[i].id===id){model=AVAILABLE_MODELS[i];break;}if(!model)return;var input=document.getElementById("modelSearchInput");input.value=model.name;input.dataset.modelId=id;selectedModelId=id;closeModelDropdown();document.getElementById("currentModelHeader").textContent=model.name;var chat=getCurrentChat();if(chat){chat.model=id;saveConversations();}updateTokenDisplay();}
|
| 511 |
-
|
| 512 |
-
// ===== CHAT HISTORY =====
|
| 513 |
-
function getChatSortTime(chat){
|
| 514 |
-
if(chat.updatedAt)return new Date(chat.updatedAt).getTime();
|
| 515 |
-
if(chat.messages&&chat.messages.length>0){
|
| 516 |
-
var last=chat.messages[chat.messages.length-1];
|
| 517 |
-
if(last.timestamp)return new Date(last.timestamp).getTime();
|
| 518 |
-
}
|
| 519 |
-
return new Date(chat.createdAt||0).getTime();
|
| 520 |
-
}
|
| 521 |
-
|
| 522 |
-
function renderChatHistory(){
|
| 523 |
-
var container=document.getElementById("chatHistory"),qInput=document.getElementById("convSearch");
|
| 524 |
-
var q=qInput?qInput.value.toLowerCase().trim():"";
|
| 525 |
-
var sorted=conversations.slice().sort(function(a,b){return getChatSortTime(b)-getChatSortTime(a);});
|
| 526 |
-
var filtered=[];
|
| 527 |
-
for(var i=0;i<sorted.length;i++){var c=sorted[i];if(!q){filtered.push(c);continue;}if(c.title.toLowerCase().indexOf(q)!==-1){filtered.push(c);continue;}var found=false;for(var j=0;j<c.messages.length;j++){if(c.messages[j].content&&c.messages[j].content.toLowerCase().indexOf(q)!==-1){found=true;break;}}if(found)filtered.push(c);}
|
| 528 |
-
if(filtered.length===0){container.innerHTML='<div class="text-xs text-gray-500 text-center py-4">No conversations found</div>';return;}
|
| 529 |
-
var html="";
|
| 530 |
-
for(var i=0;i<filtered.length;i++){var c=filtered[i],isActive=c.id===currentChatId;
|
| 531 |
-
var timeLabel="";
|
| 532 |
-
var sortTime=getChatSortTime(c);
|
| 533 |
-
if(sortTime){var diff=Date.now()-sortTime;if(diff<60000)timeLabel="Just now";else if(diff<3600000)timeLabel=Math.floor(diff/60000)+"m ago";else if(diff<86400000)timeLabel=Math.floor(diff/3600000)+"h ago";else timeLabel=new Date(sortTime).toLocaleDateString();}
|
| 534 |
-
else{timeLabel=new Date(c.createdAt).toLocaleDateString();}
|
| 535 |
-
var RS=window.RightSidebar;
|
| 536 |
-
var fc=RS?RS._getFileCountForChat(c.id):0;var fb=fc>0?' <span style="font-size:.55rem;color:#6ee7b7"><i class="fas fa-paperclip"></i> '+fc+'</span>':'';
|
| 537 |
-
html+='<div class="conv-item px-4 py-3 rounded-2xl cursor-pointer '+(isActive?'bg-gray-700/50 border border-gray-600':'hover:bg-gray-800')+'" data-chat-id="'+c.id+'"><div class="line-clamp-1 text-sm flex items-center gap-1">'+sanitizeHTML(c.title)+fb+'</div><div class="text-xs text-gray-500 flex items-center justify-between"><span>'+timeLabel+'</span></div></div>';}
|
| 538 |
-
container.innerHTML=html;
|
| 539 |
-
var items=container.querySelectorAll(".conv-item");
|
| 540 |
-
for(var i=0;i<items.length;i++){(function(cid){items[i].addEventListener("click",function(){loadChat(cid);});})(filtered[i].id);}
|
| 541 |
-
}
|
| 542 |
-
|
| 543 |
-
// ===== MODULE SYSTEM =====
|
| 544 |
-
function renderModuleList(){var el=document.getElementById("moduleList");if(!el)return;var html="";for(var id in MODULE_REGISTRY){var mod=MODULE_REGISTRY[id];var state=MODULE_STATES[id];if(!state)continue;var isOn=state.enabled;var modName=mod.name||id;var modDesc=mod.description||"";html+='<div class="module-item"><span class="mod-name" title="'+sanitizeHTML(modDesc)+'">'+sanitizeHTML(modName)+'</span><span class="mod-status" style="color:'+(isOn?'#6ee7b7':'#6b7280')+'">'+(isOn?'ON':'OFF')+'</span><div class="mod-toggle'+(isOn?' on':'')+'" onclick="ModuleSystem.toggleModule(\''+id+'\')"></div></div>';}el.innerHTML=html;updateActiveModuleCount();}
|
| 545 |
-
var ModuleSystem={register:function(id,api){if(MODULE_REGISTRY[id])return;MODULE_REGISTRY[id]=api;MODULE_STATES[id]={enabled:true,loaded:true,status:"active"};if(api.tools)api.tools.forEach(function(t){t._moduleId=id;});renderModuleList();rebuildCoreTools();},handleToolCall:async function(tn,args,tcid){for(var id in MODULE_REGISTRY){var mod=MODULE_REGISTRY[id];if(!MODULE_STATES[id]||!MODULE_STATES[id].enabled)continue;if(mod.handleToolCall&&typeof mod.handleToolCall==="function"){var result=await mod.handleToolCall(tn,args,tcid);if(result!==undefined&&result!==null)return result;}}return null;},getToolDescriptions:function(){var lines=[];for(var id in MODULE_REGISTRY){var mod=MODULE_REGISTRY[id];if(!MODULE_STATES[id]||!MODULE_STATES[id].enabled)continue;if(mod.description)lines.push("- **"+mod.name+"**: "+mod.description);if(mod.tools)for(var i=0;i<mod.tools.length;i++){var t=mod.tools[i];if(t.function&&t.function.description)lines.push(" - `"+t.function.name+"`: "+t.function.description);}}return lines.join("\n");},toggleModule:function(id){if(!MODULE_STATES[id])return;MODULE_STATES[id].enabled=!MODULE_STATES[id].enabled;renderModuleList();rebuildCoreTools();updateActiveModuleCount();showToast((MODULE_STATES[id].enabled?"Enabled":"Disabled")+": "+(MODULE_REGISTRY[id].name||id));},
|
| 546 |
-
// 👇 Context and post-response hooks (used by wiki module for auto-injection and build loop)
|
| 547 |
-
getContext:async function(userMessage,sessionInfo){return '';},
|
| 548 |
-
onResponse:async function(userMessage,aiResponse,toolCalls,sessionInfo){}};
|
| 549 |
-
function rebuildCoreTools(){CORE_TOOLS=[SELF_EVOLUTION_TOOL];for(var id in MODULE_REGISTRY){var mod=MODULE_REGISTRY[id];if(!MODULE_STATES[id]||!MODULE_STATES[id].enabled)continue;if(mod.tools)CORE_TOOLS=CORE_TOOLS.concat(mod.tools);}}
|
| 550 |
-
function toggleModulesAccordion(){modulesAccordionOpen=!modulesAccordionOpen;var body=document.getElementById("modulesAccordionBody"),arrow=document.getElementById("modulesAccordionArrow");if(modulesAccordionOpen){body.style.maxHeight="20vh";body.classList.add("open");arrow.classList.add("open");}else{body.style.maxHeight="0";body.classList.remove("open");arrow.classList.remove("open");}}
|
| 551 |
-
function updateActiveModuleCount(){var el=document.getElementById("activeModuleCount");if(!el)return;var count=0;for(var id in MODULE_STATES)if(MODULE_STATES[id].enabled)count++;el.textContent=count+" active";}
|
| 552 |
-
|
| 553 |
-
var SELF_EVOLUTION_TOOL={type:"function",function:{name:"evolve_self",description:"Read, analyze, diff, refactor, write, or perform LINE-LEVEL edits on source code or ScratchPad files. The edit buffer is tracked by _editTarget (filename) and _editContent (content). Use load_source to load the CURRENTLY RUNNING source code from browser memory into ScratchPad. Use set_target_file to select a ScratchPad file as the active target. Use read to view the active buffer (always returns file status). Use write_file to save versioned copies (old versions are automatically preserved as .v1, .v2, etc. — files are NEVER deleted). After write_file, that file becomes the new target. Use edit_lines, insert_lines, delete_lines, append_lines for line-level edits. Each result ends with a fileStatusContext() line showing where the next edit lands.",parameters:{type:"object",properties:{action:{type:"string",enum:["load_source","read","analyze","diff","refactor","write","write_source","write_file","read_lines","edit_lines","insert_lines","delete_lines","append_lines","search_code","list_files","read_file","set_target_file"],description:"What to do. write/write_file accept new_code OR content. All results include fileStatusContext()."},description:{type:"string"},new_code:{type:"string"},new_filename:{type:"string"},target_filename:{type:"string"},start_line:{type:"number"},end_line:{type:"number"},line_number:{type:"number"},content:{type:"string"},pattern:{type:"string"},is_regex:{type:"boolean"}},required:["action","description"]}}};CORE_TOOLS=[SELF_EVOLUTION_TOOL];
|
| 554 |
-
|
| 555 |
-
async function loadExternalModules(){try{var basePath='./modules/';if(MODULES_LOCATION&&MODULES_LOCATION.trim()!==''){var loc=MODULES_LOCATION.trim();if(loc.indexOf('://')!==-1||loc.indexOf('//')===0){basePath=loc.endsWith('/')?loc:loc+'/';}else{basePath=loc.endsWith('/')?loc:loc+'/';}}var manifestSrc=basePath+'modules_manifest.js';await new Promise(function(resolve,reject){var s=document.createElement('script');s.src=manifestSrc;s.async=false;s.onload=resolve;s.onerror=reject;document.body.appendChild(s);});var manifest=window.__CHATSEED_MODULES_MANIFEST;if(!manifest||!manifest.modules||!manifest.modules.length){loadFallbackModules();return;}var mods=manifest.modules,loaded=0;for(var i=0;i<mods.length;i++){var info=mods[i];if(MODULE_LOADED_FILES[info.id])continue;MODULE_LOADED_FILES[info.id]=true;try{var script=document.createElement('script');script.src=basePath+info.file;script.async=false;script.setAttribute('data-module',info.id);await new Promise(function(resolve,reject){script.onload=resolve;script.onerror=reject;document.body.appendChild(script);});loaded++;}catch(ex){}}renderModuleList();updateActiveModuleCount();if(loaded>0)showToast('Loaded '+loaded+' modules');else loadFallbackModules();}catch(ex){loadFallbackModules();}}
|
| 556 |
-
function reloadModules(){showToast('Reloading...');for(var id in MODULE_REGISTRY){document.querySelectorAll('style[data-module="'+id+'"]').forEach(function(s){s.remove();});document.querySelectorAll('script[data-module="'+id+'"]').forEach(function(s){s.remove();});}MODULE_REGISTRY={};MODULE_STATES={};MODULE_LOADED_FILES={};CORE_TOOLS=[SELF_EVOLUTION_TOOL];renderModuleList();loadExternalModules();}
|
| 557 |
-
|
| 558 |
-
function loadFallbackModules(){
|
| 559 |
-
ModuleSystem.register("search-web",{name:"Web Search",description:"Search the internet.",tools:[{type:"function",function:{name:"search_web",description:"Search the internet. Returns titles, snippets, and URLs.",parameters:{type:"object",properties:{query:{type:"string"},max_results:{type:"number",default:5},source:{type:"string",enum:["auto","web","wikipedia","news","reddit"],default:"auto"}},required:["query"]}}}],handleToolCall:async function(tn,args){if(tn!=="search_web")return null;try{var q=args.query,mx=Math.min(Math.max(parseInt(args.max_results)||5,1),10),source=args.source||"auto",allResults=[];if(source==="auto"||source==="web"||source==="wikipedia"){try{var wr=await fetch("https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch="+encodeURIComponent(q)+"&format=json&srlimit="+mx+"&origin=*");if(wr.ok){var wd=await wr.json();if(wd.query&&wd.query.search){wd.query.search.forEach(function(s){allResults.push({title:s.title,snippet:s.snippet.replace(/<\/?[^>]+(>|$)/g,""),url:"https://en.wikipedia.org/wiki/"+encodeURIComponent(s.title.replace(/ /g,"_")),source:"Wikipedia"});});}}}catch(ex){}}if(source==="auto"||source==="web"){try{var dr=await fetch("https://api.duckduckgo.com/?q="+encodeURIComponent(q)+"&format=json&no_html=1&skip_disambig=1&t=chatseed");if(dr.ok){var dd=await dr.json();if(dd.AbstractText)allResults.push({title:dd.Heading||"About",snippet:dd.AbstractText,url:dd.AbstractURL||"",source:"DuckDuckGo"});}}catch(ex){}}if(source==="auto"||source==="reddit"||source==="news"){try{var rr=await fetch("https://www.reddit.com/search.json?q="+encodeURIComponent(q)+"&limit="+mx+"&sort=relevance&t=all",{headers:{"User-Agent":"Mozilla/5.0 ChatSeed/1.0"}});if(rr.ok){var rd=await rr.json();if(rd.data&&rd.data.children){rd.data.children.forEach(function(c){if(c.data&&c.data.title)allResults.push({title:"[Reddit] "+c.data.title,snippet:(c.data.selftext||c.data.url||"").substring(0,200).replace(/\n/g," "),url:"https://www.reddit.com"+c.data.permalink,source:"Reddit"});});}}}catch(ex){}}var seen={},deduped=[];allResults.forEach(function(item){if(!item.title)return;var key=(item.url||item.snippet||item.title).substring(0,80);if(!seen[key]){seen[key]=true;deduped.push(item);}});var out=["## Search Results: \""+q+"\"",""];if(deduped.length===0){out.push("*No results found.*");}else{deduped.slice(0,mx).forEach(function(r,i){out.push("### "+(i+1)+". "+(r.title||""));if(r.snippet)out.push("> "+r.snippet);if(r.url)out.push("Link: "+r.url);out.push("");});}return out.join("\n");}catch(ex){return "## Search error: "+ex.message;}}});
|
| 560 |
-
ModuleSystem.register("calculator",{name:"Calculator",description:"Precise calculations",tools:[{type:"function",function:{name:"calculate",description:"Evaluate a math expression",parameters:{type:"object",properties:{expression:{type:"string"}},required:["expression"]}}}],handleToolCall:async function(tn,args){if(tn!=="calculate")return null;try{var e=args.expression;var p=e.replace(/\^/g,"**").replace(/\bpi\b/gi,"("+Math.PI+")").replace(/\bsin\(/g,"Math.sin(").replace(/\bcos\(/g,"Math.cos(").replace(/\btan\(/g,"Math.tan(").replace(/\bsqrt\(/g,"Math.sqrt(").replace(/\blog\(/g,"Math.log10(").replace(/\bln\(/g,"Math.log(").replace(/\babs\(/g,"Math.abs(");return""+e+" = "+Function('"use strict";return ('+p+')')()+"";}catch(ex){return "Error: "+ex.message;}}});
|
| 561 |
-
ModuleSystem.register("image-gen",{name:"Image Generation",description:"Generate images from text prompts.",tools:[{type:"function",function:{name:"generate_image",description:"Generate an image from a text description.",parameters:{type:"object",properties:{prompt:{type:"string"},width:{type:"number",default:512},height:{type:"number",default:512}},required:["prompt"]}}}],handleToolCall:async function(tn,args){if(tn!=="generate_image")return null;var w=parseInt(args.width)||512,h=parseInt(args.height)||512;return"+"?width="+w+"&height="+h+"&nologo=true)"}});
|
| 562 |
-
ModuleSystem.register("qr-tools",{name:"QR Code",description:"Generate QR codes.",tools:[{type:"function",function:{name:"generate_qr",description:"Generate a QR code.",parameters:{type:"object",properties:{data:{type:"string"},label:{type:"string"},size:{type:"number",default:250}},required:["data"]}}}],handleToolCall:async function(tn,args){if(tn!=="generate_qr")return null;var s=Math.min(Math.max(parseInt(args.size)||250,100),500);return"+")"}});
|
| 563 |
-
ModuleSystem.register("weather",{name:"Weather",description:"Get current weather.",tools:[{type:"function",function:{name:"get_weather",description:"Get current weather.",parameters:{type:"object",properties:{location:{type:"string"},forecast_days:{type:"number",default:3}},required:["location"]}}}],handleToolCall:async function(tn,args){if(tn!=="get_weather")return null;try{var r=await fetch("https://wttr.in/"+encodeURIComponent(args.location)+"?format=%C+%t+%w+%h&m");if(r.ok)return"Weather for "+args.location+": "+(await r.text());return"Weather unavailable";}catch(ex){return"Weather error: "+ex.message;}}});
|
| 564 |
-
ModuleSystem.register("news",{name:"News Headlines",description:"Fetch latest news.",tools:[{type:"function",function:{name:"get_news",description:"Get latest news.",parameters:{type:"object",properties:{query:{type:"string"},max_results:{type:"number",default:5}},required:[]}}}],handleToolCall:async function(tn,args){if(tn!=="get_news")return null;try{var r=await fetch("https://api.allorigins.win/raw?url="+encodeURIComponent("https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml"));if(!r.ok)return"News unavailable";var xml=await r.text();var items=xml.match(/<item>[\s\S]*?<\/item>/g)||[];var out=["## News Headlines"];var limit=Math.min(parseInt(args.max_results)||5,items.length);for(var i=0;i<limit;i++){var title=(items[i].match(/<title>([^<]*)<\/title>/)||["",""])[1];var link=(items[i].match(/<link>([^<]*)<\/link>/)||["",""])[1];if(title)out.push((i+1)+". "+title.replace(/<!\[CDATA\[|\]\]>/g,""));if(link)out.push(" "+link);}return out.join("\n");}catch(ex){return"News error: "+ex.message;}}});
|
| 565 |
-
ModuleSystem.register("dictionary",{name:"Dictionary",description:"Look up word definitions.",tools:[{type:"function",function:{name:"define_word",description:"Get definition for any word.",parameters:{type:"object",properties:{word:{type:"string"}},required:["word"]}}}],handleToolCall:async function(tn,args){if(tn!=="define_word")return null;try{var r=await fetch("https://api.dictionaryapi.dev/api/v2/entries/en/"+encodeURIComponent(args.word));if(!r.ok)return"Word not found";var d=await r.json();var entry=d[0];var out=["## "+entry.word,""];if(entry.phonetic)out.push("Pronunciation: `"+entry.phonetic+"`");if(entry.meanings){entry.meanings.forEach(function(m){if(m.partOfSpeech)out.push("*"+m.partOfSpeech+"*");if(m.definitions){m.definitions.slice(0,3).forEach(function(def){out.push("- "+def.definition);if(def.example)out.push(" > \""+def.example+"\"");});}});}return out.join("\n");}catch(ex){return"Dictionary error: "+ex.message;}}});
|
| 566 |
-
renderModuleList();updateActiveModuleCount();showToast('Using built-in fallback modules (7/7 loaded)');}
|
| 567 |
-
|
| 568 |
-
// ===== SEND MESSAGE =====
|
| 569 |
-
async function sendMessage(){if(isProcessing)return;var input=document.getElementById("userInput"),text=input.value.trim();if(!text||!currentChatId)return;var chat=getCurrentChat();if(!chat)return;
|
| 570 |
-
chat.messages.push({role:"user",content:text,timestamp:getTimeStr()});var uc=0;for(var i=0;i<chat.messages.length;i++){if(chat.messages[i].role==="user")uc++;}if(uc===1)chat.title=text.slice(0,50)+(text.length>50?"...":"");
|
| 571 |
-
trimContext();
|
| 572 |
-
input.value="";input.style.height="auto";isProcessing=true;abortController=new AbortController();saveConversations();setProcessingUI(true);removeStreamingBubble();clearStepBars();
|
| 573 |
-
var es=document.getElementById("emptyState");if(es)es.remove();var container=document.getElementById("messages");
|
| 574 |
-
var uel=createMessageElement(chat.messages[chat.messages.length-1]);if(uel)container.appendChild(uel);
|
| 575 |
-
renderChatHistory();if(autoScroll)scrollToBottom();var stepCount=0;
|
| 576 |
-
try{while(stepCount<MAX_STEPS){stepCount++;addStepBar(stepCount,MAX_STEPS,"fa-brain","Thinking...");
|
| 577 |
-
var sysP=getSystemPrompt(),modDesc=ModuleSystem.getToolDescriptions(),ctx=modDesc?"\n\n## Available Module Tools\n"+modDesc:"";/* wiki context injection */try{var wikiCtx=await ModuleSystem.getContext(text,{activeTool:null});if(wikiCtx)ctx+='\n\n'+wikiCtx;}catch(e){}
|
| 578 |
-
var apiMsgs=[];if(sysP||ctx)apiMsgs.push({role:"system",content:(sysP||"You are HuggingBot.")+ctx});
|
| 579 |
-
for(var i=0;i<chat.messages.length;i++)apiMsgs.push(chat.messages[i]);
|
| 580 |
-
var response=await fetch("https://openrouter.ai/api/v1/chat/completions",{method:"POST",headers:{"Authorization":"Bearer "+API_KEY,"Content-Type":"application/json","HTTP-Referer":window.location.href,"X-Title":"HuggingBot"},body:JSON.stringify({model:selectedModelId||"openai/gpt-4o",messages:apiMsgs,tools:CORE_TOOLS.length>0?CORE_TOOLS:undefined,tool_choice:"auto",stream:true}),signal:abortController.signal});
|
| 581 |
-
if(!response.ok)throw new Error("API "+response.status);
|
| 582 |
-
var reader=response.body.getReader(),decoder=new TextDecoder(),buf="",fullContent="",toolCalls={},toolCallOrder=[],rt=null;
|
| 583 |
-
startStreamingBubble();
|
| 584 |
-
while(true){var rd=await reader.read();if(rd.done)break;buf+=decoder.decode(rd.value,{stream:true});var lines=buf.split("\n");buf=lines.pop()||"";for(var li=0;li<lines.length;li++){var line=lines[li];if(line.indexOof("data: ")!==0)continue;var json=line.slice(6).trim();if(!json||json==="[DONE]")continue;try{var chunk=JSON.parse(json);var d=(chunk.choices&&chunk.choices[0])?(chunk.choices[0].delta||{}):{};if(d.content){fullContent+=d.content;if(!rt)rt=setTimeout(function(){rt=null;updateStreamingContent(renderMarkdown(fullContent));},30);}if(d.tool_calls){for(var tci=0;tci<d.tool_calls.length;tci++){var tc=d.tool_calls[tci],idx=tc.index||0;if(!toolCalls[idx]){toolCalls[idx]={index:idx,id:tc.id||("tc_"+Date.now()+"_"+idx),type:"function",function:{name:"",arguments:""}};toolCallOrder.push(idx);}if(tc.function){if(tc.function.name)toolCalls[idx].function.name+=tc.function.name;if(tc.function.arguments)toolCalls[idx].function.arguments+=tc.function.arguments;}}}}catch(ex){}}}
|
| 585 |
-
if(rt){clearTimeout(rt);rt=null;}if(fullContent&&streamBodyEl)updateStreamingContent(renderMarkdown(fullContent));removeStreamingBubble();
|
| 586 |
-
var consolidatedCalls=[];for(var oi=0;oi<toolCallOrder.length;oi++){var idx=toolCallOrder[oi],tc=toolCalls[idx];if(tc)consolidatedCalls.push({id:tc.id,type:"function",function:{name:tc.function.name,arguments:tc.function.arguments}};}
|
| 587 |
-
if(consolidatedCalls.length>0){if(window.LineEditor)window.LineEditor._batchBase=[];var tcMsg={role:"assistant",content:fullContent||null,tool_calls:consolidatedCalls,timestamp:getTimeStr()};chat.messages.push(tcMsg);chat.updatedAt=new Date().toISOString();var tcEl=createMessageEement(tcMsg);if(tcEl)container.appendChild(tcEl);
|
| 588 |
-
for(var tci=0;tci<consolidatedCalls.length;tci++){var tc=consolidatedCalls[tci],args;try{args=JSON.parse(tc.function.arguments);}catch(ex){showToast("Failed to parse tool args");continue;}
|
| 589 |
-
try{var moduleResult=await ModuleSystem.handleToolCall(tc.function.name,args,tc.id);if(moduleResult!==null){var toolContent=typeof moduleResult==="string"?moduleResult:JSON.stringify(moduleResult);chat.messages.push({role:"tool",tool_call_id:tc.id,content:toolContent,timestamp:getTimeStr()});var toolEl=createMessageElement({role:"tool",tool_call_id:tc.id,content:toolContent,timestamp:getTimeStr()});if(toolEl)container.appendChild(toolEl);}
|
| 590 |
-
else if(tc.function.name==="evolve_self"){var lineResult=window.handleEvolveSelfLineAction(args);if(lineResult!==null){chat.messages.push({role:"tool",tool_call_id:tc.id,content:lineResult,timestamp:getTimeStr()});var toolEl=createMessageElement({role:"tool",tool_call_id:tc.id,content:lineResult,timestamp:getTimeStr()});if(toolEl)container.appendChild(toolEl);}
|
| 591 |
-
else{var unk="Unknown action "+(args.action||"?")+"?";chat.messages.push({role:"tool",tool_call_id:tc.id,content:unk,timestamp:getTimeStr()});var toolEl=createMessageEement({role:"tool",tool_call_id:tc.id,content:unk,timestamp:getTimeStr()});if(toolEl)container.appendChild(toolEl);}}
|
| 592 |
-
else{var na="Tool "+tc.function.name+" not available.";chat.messages.push({role:"tool",tool_call_id:tc.id,content:na,timestamp:getTimeStr()});var toolEl=createMessageEement({role:"tool",tool_call_id:tc.id,content:na,timestamp:getTimeStr()});if(toolEl)container.appendChild(toolEl);}}
|
| 593 |
-
catch(terr){var errMsg="Error: "+terr.message;chat.messages.push({role:"tool",tool_call_id:tc.id,content:errMsg,timestamp:getTimeStr()});var toolEl=createMessageEement({role:"tool",tool_call_id:tc.id,content:errMsg,timestamp:getTimeStr()});if(toolEl)container.appendChild(toolEl);showToast("Tool error");}}
|
| 594 |
-
removeStepBar();saveConversations();updateTokenDisplay();try{ModuleSystem.onResponse(text,fullContent||"",consolidatedCalls,{});}catch(e){}continue;}
|
| 595 |
-
else if(fullContent){var finalMsg={role:"assistant",content:fullContent,timestamp:getTimeStr()};chat.messages.push(finalMsg);chat.updatedAt=new Date().toISOString();var el=createMessageEement(finalMsg);if(el)container.appendChild(el);removeStepBar();saveConversations();updateTokenDisplay();try{ModuleSystem.onResponse(text,fullContent,[],{});}catch(e){}break;}
|
| 596 |
-
else{try{var sysP2=getSystemPrompt(),md2=ModuleSystem.getToolDescriptions(),ctx2=md2?"\n\nModule tools: "+md2:"";try{var wikiCtx2=await ModuleSystem.getContext(text,{activeTool:null});if(wikiCtx2)ctx2+="\n\n"+wikiCtx2;}catch(e){}var am2=[];if(sysP2||ctx2)am2.push({role:"system",content:(sysP2||"Yo are HuggingBot.")+ctx2});for(var i=0;i<chat.messages.length;i++)am2.push(chat.messages[i]);var fb=await fetch("https://openrouter.ai/api/v1/chat/completions",{method:"POST",headers:{"Authorization":"Bearer "+API_KEY,"Content-Type":"application/json"},body:JSON.stringify({model:selectedModelId||"openai/gpt-4o",messages:am2,tools:CORE_TOOLS.length>0?CORE_TOOLS:undefined,tool_choice:"auto",stream:false})});if(!fb.ok)throw Error("FB "+fb.status);var fd=await fb.json(),fm=fd.choiches&&fd.choiches[0]?fd.choiches[0].message:null;
|
| 597 |
-
if(fm&&fm.tool_calls&&fm.tool_calls.length){if(window.LineEditor)window.LineEditor._batchBase=[];var ftm={role:"assistant",content:fm.content||null,tool_calls:fm.tool_calls,timestamp:getTimeStr()};chat.messages.push(ftm);var fte=createMessageEement(ftm);if(fte)container.appendChild(fte);
|
| 598 |
-
for(var fi=0;fi<fm.tool_calls.length;fi++){var ft=fm.tool_calls[fi],fa;try{fa=JSON.parse(ft.function.arguments);}catch(ex){continue;}
|
| 599 |
-
var mr=await ModuleSystem.handleToolCall(ft.function.name,fa,ft.id);
|
| 600 |
-
if(mr!==null){var ct=typeof mr==="string"?mr:JSON.stringify(mr);chat.messages.push({role:"tool",tool_call_id:ft.id,content:ct,timestamp:getTimeStr()});var fel=createMessageEement({role:"tool",tool_call_id:ft.id,content:ct,timestamp:getTimeStr()});if(fel)container.appendChild(fel);}
|
| 601 |
-
else if(ft.function.name==="evolve_self"){var lr2=window.handleEvolveSelfLineAction(fa);if(lr2!==null){chat.messages.push({role:"tool",tool_call_id:ft.id,content:lr2,timestamp:getTimeStr()});var fel=createMessageEement({role:"tool",tool_call_id:ft.id,content:lr2,timestamp:getTimeStr()});if(fel)container.appendChild(fel);}
|
| 602 |
-
else{var d=(fa.action||"Done")+": "+(fa.description||"");chat.messages.push({role:"tool",tool_call_id:ft.id,content:d,timestamp:getTimeStr()});var fel=createMessageEement({role:"tool",tool_call_id:ft.id,content:d,timestamp:getTimeStr()});if(fel)container.appendChild(fel);}}
|
| 603 |
-
else{var n="Tool "+ft.function.name+" not available.";chat.messages.push({role:"tool",tool_call_id:ft.id,content:n,timestamp:getTimeStr()});var fel=createMessageEement({role:"tool",tool_call_id:ft.id,content:n,timestamp:getTimeStr()});if(fel)container.appendChild(fel);}}
|
| 604 |
-
removeStepBar();saveConversations();chat.updatedAt=new Date().toISOString();updateTokenDisplay();try{ModuleSystem.onResponse(text,fm.content||"",fm.tool_calls||[],{});}catch(e){}continue;}
|
| 605 |
-
else{var ff={role:"assistant",content:(fm&&fm.content)||"",timestamp:getTimeStr()};chat.messages.push(ff);chat.updatedAt=new Date().toISOString();var fe=createMessageEement(ff);if(fe)container.appendChild(fe);removeStepBar();saveConversations();updateTokenDisplay();try{ModuleSystem.onResponse(text,fm.content||"",[],{});}catch(e){}break;}}
|
| 606 |
-
catch(fbe){showToast("Fallback failed: "+fbe.message);removeStepBar();saveConversations();break;}}}
|
| 607 |
-
removeStepBar();saveConversations();updateTokenDisplay();attachCopyButtons();
|
| 608 |
-
if(stepCount>=MAX_STEPS)showToast("Max steps ("+MAX_STEPS+") reached");else if(stepCount>0)showToast("Complete");
|
| 609 |
-
}catch(err){removeStepBar();removeStreamingBubble();if(err.name==="AbortError")showToast("Canceled");else{console.error(err);showToast("Error: "+err.message);}saveConversations();updateTokenDisplay();}
|
| 610 |
-
finally{isProcessing=false;abortController=null;setProcessingUI(false);}}
|
| 611 |
-
|
| 612 |
-
function cancelStream(){if(abortController){abortController.abort();abortController=null;}isProcessing=false;setProcessingUI(false);removeStreamingBubble();clearStepBars();}
|
| 613 |
-
|
| 614 |
</script></body></html>
|
|
|
|
| 282 |
renderChatHistory();
|
| 283 |
var el=document.getElementById("storageModeSelect");
|
| 284 |
if(el){el.value="localStorage";onStorageModeChange();}
|
| 285 |
+
if(conversations.length>0)loadChat(conversations[0].id)else newChat();
|
| 286 |
});
|
| 287 |
} else {
|
| 288 |
renderChatHistory();
|
| 289 |
var el=document.getElementById("storageModeSelect");
|
| 290 |
+
ifel){el.value=storageModeonStorageModeChange();}
|
| 291 |
setTimeout(function(){
|
| 292 |
+
if!currentChatId){
|
| 293 |
+
if(conversations.length>0)loadChat(conversations[0.id);else newChat();}
|
| 294 |
+
},50);}
|
|
|
|
|
|
|
|
|
|
| 295 |
|
| 296 |
// ===== SANITIZATION UTILITIES =====
|
| 297 |
+
function sanitizeHTML(str){if(typeof DOMPurify!=="undefined")return DOMPurify.sanitize(str{ALLOWED_TAGS:[],ALLOWED_ATTR:[]})var d=document.createEement("div");d.textContent=str;return d.inerHTML;}
|
| 298 |
+
function safeRenderHTML(html,allowSafeTags){try{if(typeof DOMPurify!=="undefined"){if(allowSafeTags)return DOMPurify.sanitize(html,{ALLOWED_TAGS:["div","span","a","b","i","em","strong","code","pre","br","p","h1","h2","h3","h4","h5","h6","ul","ol","li","blockquote","table","thead","tbody","tr","th","td","hr","img","figure","figcaption","dl","dt","dd","sup","sub","kbd","s","del","ins","mark","small","details","summary","button"],ALLOWED_ATTR:["href","target","rel","src","alt","class","id","title","width","height","style","data-*"],ALLOW_DATA_ATTR:true,FORBID_TAGS:["style","script","iframe","object","embed","form","input","textarea","select","option","optgroup","svg","math","link","meta","video","audio","canvas","applet","frame","frameset","noframes","noscript"],FORBID_ATTR:["onerror","onload","onclick","onmouseover","onmouseout","onkeydown","onkeyup","onchange","onsubmit","onfocus","onblur","onabort","onanimationstart","onanimationend","onauxclick","onbeforeinput","onbeforetoggle","oncancel","oncanplay","oncanplaythrough","onclose","oncontextmenu","oncopy","oncuechange","oncut","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onformdata","ongotpointercapture","oninput","oninvalid","onlostpointercapture","onpaste","onpase","onplay","onplaying","onpointercancel","onpointerenter","onpointerleave","onpointermove","onpointerout","onpointerover","onpointerrawupdate","onpointerup","onprogress","onratechange","onreset","onresize","onscroll","onsecuritypolicyviolation","onseeked","onseeking","onselect","onselectionchange","onselectstart","onslotchange","onstalled","onsubmit","onsuspend","ontimeupdate","ontoggle","ontransitioncancel","ontransitionend","ontransitionrun","ontransitionstart","onvolumechange","onwaiting","onwebkitanimationend","onwebkitanimationiteration","onwebkitanimationstart","onwebkittransitionend","onwheel","style"],ADD_ATTR:["target"],WHOLE_DOCUMENT:false});}return DOMPurify.sanitize(html);var d=document.createElement("div");d.textContent=html.replace(/<[^>]*>/g,"");return d.innerHTML;}catch(ex){var d=document.createElement("div");d.textContent=html;return d.innerHTML;}}
|
| 299 |
function safeSetInnerHTML(el,html){try{el.innerHTML=html;}catch(ex){el.textContent=html;}}
|
| 300 |
+
function renderMarkdown(text){if(!text)return "";try{var raw=marked.parse(text,{breaks:true,gfm:true});return safeRenderHTML(raw,true);}catch(ex){var d=document.createElement("div");d.textContent=text;return d.innerHTML;}}
|
| 301 |
function showToast(msg){var t=document.getElementById("toast");t.textContent=msg;t.classList.remove("hidden");clearTimeout(t._timeout);t._timeout=setTimeout(function(){t.classList.add("hidden");},3500);}
|
| 302 |
function scrollToBottom(smooth){if(smooth===undefined)smooth=true;var c=document.getElementById("messages");c.scrollTop=c.scrollHeight;}
|
| 303 |
function getTimeStr(){var d=new Date();return d.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"});}
|
| 304 |
function updateAutoScroll(){autoScroll=document.getElementById("autoScrollToggle").checked;}
|
| 305 |
+
function getCurrentChat(){for(var i=0;i<conversations.length;i++)if(conversations[i].id===currentChatId)return conersations[i];return null;}
|
| 306 |
+
function getStoragUsage(){var result={used:0,limit:5242880,pct:0};try{var total=0;for(var key in localStorag){if(localStorage.hasOwnProperty(key)}total+=localStorag[key].length;}result.used=total;result.pct=Math.min(100,Math.round((total/result.limit)*100));}catch(ex){}return result;}
|
| 307 |
+
function formtBytes(bytes){if(bytes<1024)return bytes+" B";if(bytes<1048576)return(bytes/1024).toFixed(1)+" KB";return(bytes/1048576).toFixed(1)+" MB";}
|
| 308 |
+
function showConfirmDialog(msg,callback){confirmCallback=callaack;var modal=document.getElementById("confirmModal");document.getElementById("confirmModalBody").textContent=msg;modal.classList.add("show");}
|
|
|
|
| 309 |
document.getElementById("confirmOkBtn").addEventListener("click",function(){var cb=confirmCallback;confirmCallback=null;document.getElementById("confirmModal").classList.remove("show");if(cb)cb(true);});
|
| 310 |
document.getElementById("confirmCancelBtn").addEventListener("click",function(){var cb=confirmCallback;confirmCallback=null;document.getElementById("confirmModal").classList.remove("show");if(cb)cb(false);});
|
| 311 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 312 |
</script></body></html>
|