// ==UserScript== // @name dichtruyen.ai.vn // @namespace https://github.com/sourman-dev/dichtruyen-ai-userscript // @version 0.0.9 // @author suppaman101@gmail.com // @description Userscript hỗ trợ đọc dịch online các loại truyện convert, truyện tiếng nước ngoài bằng AI // @license MIT // @icon https://vitejs.dev/logo.svg // @supportURL https://github.com/sourman-dev/dichtruyen-ai-userscript/issues // @downloadURL https://raw.githubusercontent.com/sourman-dev/dichtruyen-ai-userscript/main/dist/dichtruyen.ai.vn.user.js // @updateURL https://raw.githubusercontent.com/sourman-dev/dichtruyen-ai-userscript/main/dist/dichtruyen.ai.vn.user.js // @match *://*/* // @grant GM.deleteValue // @grant GM.getValue // @grant GM.setValue // @grant GM.xmlHttpRequest // @inject-into content // ==/UserScript== (async function () { 'use strict'; let t,n,r,i,a,s,o=Object.getPrototypeOf,l={isConnected:1},c={},d=o(l),u=o(o),addAndScheduleOnFirst=(t,n,r,i)=>(t??(setTimeout(r,i),new Set)).add(n),runAndCaptureDeps=(t,n,i)=>{let a=r;r=n;try{return t(i)}catch(e){return i}finally{r=a;}},keepConnected=t=>t.filter((t=>t._dom?.isConnected)),addStatesToGc=t=>a=addAndScheduleOnFirst(a,t,(()=>{for(let t of a)t._bindings=keepConnected(t._bindings),t._listeners=keepConnected(t._listeners);a=s;}),1e3),h={get val(){return r?._getters?.add(this),this.rawVal},get oldVal(){return r?._getters?.add(this),this._oldVal},set val(i){r?._setters?.add(this),i!==this.rawVal&&(this.rawVal=i,this._bindings.length+this._listeners.length?(n?.add(this),t=addAndScheduleOnFirst(t,this,updateDoms)):this._oldVal=i);}},state$1=t=>({__proto__:h,rawVal:t,_oldVal:t,_bindings:[],_listeners:[]}),bind=(t,n)=>{let r={_getters:new Set,_setters:new Set},a={f:t},s=i;i=[];let o=runAndCaptureDeps(t,r,n);o=(o??document).nodeType?o:new Text(o);for(let i of r._getters)r._setters.has(i)||(addStatesToGc(i),i._bindings.push(a));for(let l of i)l._dom=o;return i=s,a._dom=o},derive$1=(t,n=state$1(),r)=>{let a={_getters:new Set,_setters:new Set},s={f:t,s:n};s._dom=r??i?.push(s)??l,n.val=runAndCaptureDeps(t,a,n.rawVal);for(let i of a._getters)a._setters.has(i)||(addStatesToGc(i),i._listeners.push(s));return n},add$1=(t,...n)=>{for(let r of n.flat(1/0)){let n=o(r??0),i=n===h?bind((()=>r.val)):n===u?bind(r):r;i!=s&&t.append(i);}return t},tag=(t,n,...r)=>{let[{is:i,...a},...l]=o(r[0]??0)===d?r:[{},...r],p=t?document.createElementNS(t,n,{is:i}):document.createElement(n,{is:i});for(let[d,g]of Object.entries(a)){let getPropDescriptor=t=>t?Object.getOwnPropertyDescriptor(t,d)??getPropDescriptor(o(t)):s,t=n+","+d,r=c[t]??=getPropDescriptor(o(p))?.set??0,i=d.startsWith("on")?(t,n)=>{let r=d.slice(2);p.removeEventListener(r,n),p.addEventListener(r,t);}:r?r.bind(p):p.setAttribute.bind(p,d),a=o(g??0);d.startsWith("on")||a===u&&(g=derive$1(g),a=h),a===h?bind((()=>(i(g.val,g._oldVal),p))):i(g);}return add$1(p,l)},handler=t=>({get:(n,r)=>tag.bind(s,t,r)}),update=(t,n)=>n?n!==t&&t.replaceWith(n):t.remove(),updateDoms=()=>{let r=0,i=[...t].filter((t=>t.rawVal!==t._oldVal));do{n=new Set;for(let t of new Set(i.flatMap((t=>t._listeners=keepConnected(t._listeners)))))derive$1(t.f,t.s,t._dom),t._dom=s;}while(++r<100&&(i=[...n]).length);let a=[...t].filter((t=>t.rawVal!==t._oldVal));t=s;for(let t of new Set(a.flatMap((t=>t._bindings=keepConnected(t._bindings)))))update(t._dom,bind(t.f,t._dom)),t._dom=s;for(let t of a)t._oldVal=t.rawVal;};const p={tags:new Proxy((t=>new Proxy(tag,handler(t))),handler()),hydrate:(t,n)=>update(t,bind(n,t)),add:add$1,state:state$1,derive:derive$1};function e(t,n,r={mode:"open"}){window.customElements.define(t,class extends HTMLElement{constructor(){super(),this.a=[];}setAttribute(t,n){super.setAttribute(t,n),this.a[t]&&(this.a[t].val=n);}connectedCallback(){let t;p.add(r?this.attachShadow(r):this,n({attr:(t,n)=>this.a[t]??=p.state(this.getAttribute(t)??n),mount:n=>{let r=t;t=()=>{let t=r?.(),i=n();return ()=>{t?.(),i?.();}};},$this:this})),this.d=t?.();}disconnectedCallback(){this.d?.();}});}const{button:g,div:b,header:v,input:w,label:E,span:T,style:A}=p.tags,toStyleStr=t=>Object.entries(t).map((([t,n])=>`${t}: ${n};`)).join(""),Await=({value:t,container:n=b,Loading:r,Error:i},a)=>{const s=p.state({status:"pending"});return t.then((t=>s.val={status:"fulfilled",value:t})).catch((t=>s.val={status:"rejected",value:t})),n((()=>"pending"===s.val.status?r?.()??"":"rejected"===s.val.status?i?.(s.val.value):a(s.val.value)))};let S=0;const Tabs=({activeTab:t,resultClass:n="",style:r="",tabButtonRowColor:i="#f1f1f1",tabButtonBorderStyle:a="1px solid #000",tabButtonHoverColor:s="#ddd",tabButtonActiveColor:o="#ccc",transitionSec:l=.3,tabButtonRowClass:c="",tabButtonRowStyleOverrides:d={},tabButtonClass:u="",tabButtonStyleOverrides:h={},tabContentClass:v="",tabContentStyleOverrides:w={}},E)=>{const T=t??p.state(Object.keys(E)[0]),A=toStyleStr({overflow:"hidden","background-color":i,...d}),x=toStyleStr({float:"left",border:"none","border-right":a,outline:"none",cursor:"pointer",padding:"8px 16px",transition:`background-color ${l}s`,...h}),C=toStyleStr({padding:"6px 12px","border-top":"none",...w}),P="vanui-tabs-"+ ++S;return document.head.appendChild(p.tags.style(`#${P} .vanui-tab-button { background-color: inherit }\n#${P} .vanui-tab-button:hover { background-color: ${s} }\n#${P} .vanui-tab-button.active { background-color: ${o} }`)),b({id:P,class:n,style:r},b({class:c,style:A},Object.keys(E).map((t=>g({class:()=>["vanui-tab-button"].concat(u||[],t===T.val?"active":[]).join(" "),style:x,onclick:()=>T.val=t},t)))),Object.entries(E).map((([t,n])=>b({class:v,style:()=>`display: ${t===T.val?"block":"none"}; ${C}`},n))))};let x,C,{fromEntries:P,entries:L,keys:k,hasOwn:R,getPrototypeOf:I}=Object,{get:D,set:O,deleteProperty:M,ownKeys:B}=Reflect,{state:V,derive:$,add:G}=p,F=Symbol(),j=Symbol(),z=Symbol(),W=Symbol(),q=Symbol(),K=Symbol(),isObject=t=>t instanceof Object&&!(t instanceof Function)&&!t[K],toState=t=>{if(t?.[j]){let n=V();return $((()=>{let r=t();isObject(n.rawVal)&&isObject(r)?replace(n.rawVal,r):n.val=reactive(r);})),n}return V(reactive(t))},X={get:(t,n,r)=>n===F?t:R(t,n)?Array.isArray(t)&&"length"===n?(t[W].val,t.length):t[n].val:D(t,n,r),set:(t,n,r,i)=>R(t,n)?Array.isArray(t)&&"length"===n?(r!==t.length&&++t[W].val,t.length=r,1):(t[n].val=reactive(r),1):n in t?O(t,n,r,i):O(t,n,toState(r))&&(++t[W].val,filterBindings(t).forEach(addToContainer.bind(x,i,n,t[n],C)),1),deleteProperty:(t,n)=>(M(t,n)&&onDelete(t,n),++t[W].val),ownKeys:t=>(t[W].val,B(t))},reactive=t=>!isObject(t)||t[F]?t:new Proxy((t=>{let n=Array.isArray(t)?[]:{__proto__:I(t)};for(let[r,i]of L(t))n[r]=toState(i);return n[z]=[],n[W]=V(1),n})(t),X),filterBindings=t=>t[z]=t[z].filter((t=>t._containerDom.isConnected)),addToContainer=(t,n,r,i,{_containerDom:a,f:s})=>{let o=Array.isArray(t),l=o?Number(n):n;G(a,(()=>a[q][n]=s(r,(()=>delete t[n]),l))),o&&!i&&l!==t.length-1&&a.insertBefore(a.lastChild,a[q][k(t).find((t=>Number(t)>l))]);},onDelete=(t,n)=>{for(let r of filterBindings(t)){let t=r._containerDom[q];t[n]?.remove(),delete t[n];}},replaceInternal=(t,n)=>{for(let[a,s]of L(n)){let n=t[a];isObject(n)&&isObject(s)?replaceInternal(n,s):t[a]=s;}for(let a in t)R(n,a)||delete t[a];let r=k(n),i=Array.isArray(t);if(i||k(t).some(((t,n)=>t!==r[n]))){let a=t[F];if(i)t.length=n.length;else {++a[W].val;let t={...a};for(let n of r)delete a[n];for(let n of r)a[n]=t[n];}for(let{_containerDom:t}of filterBindings(a)){let{firstChild:n,[q]:i}=t;for(let a of r)n===i[a]?n=n.nextSibling:t.insertBefore(i[a],n);}}return t},replace=(t,n)=>{C=1;try{return replaceInternal(t,n instanceof Function?Array.isArray(t)?n(t.filter((t=>1))):P(n(L(t))):n)}finally{C=x;}},compact=t=>Array.isArray(t)?t.filter((t=>1)).map(compact):isObject(t)?P(L(t).map((([t,n])=>[t,compact(n)]))):t;var J=function(){function defineProperties(t,n){for(var r=0;r1?r-1:0),a=1;a0&&Array.isArray(r[0])&&(r=r[0]),this.transformers=r.map((function(t){return "function"==typeof t?t():t})),this.tag}return J(TemplateTag,[{key:"interimTag",value:function interimTag(t,n){for(var r=arguments.length,i=Array(r>2?r-2:0),a=2;a0&&void 0!==arguments[0]?arguments[0]:"";return {onEndResult:function onEndResult(n){if(""===t)return n.trim();if("start"===(t=t.toLowerCase())||"left"===t)return n.replace(/^\s*/,"");if("end"===t||"right"===t)return n.replace(/\s*$/,"");throw new Error("Side not supported: "+t)}}};var ee=function stripIndentTransformer(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"initial";return {onEndResult:function onEndResult(n){if("initial"===t){var r=n.match(/^[^\S\n]*(?=\S)/gm),i=r&&Math.min.apply(Math,function _toConsumableArray(t){if(Array.isArray(t)){for(var n=0,r=Array(t.length);n0&&void 0!==arguments[0]?arguments[0]:re;return {onSubstitution:function onSubstitution(n,r){if(Array.isArray(n)){var i=n.length,a=t.separator,s=t.conjunction,o=t.serial,l=r.match(/(\n?[^\S\n]+)$/);if(n=l?n.join(a+l[1]):n.join(a+" "),s&&i>1){var c=n.lastIndexOf(a);n=n.slice(0,c)+(o?a:"")+" "+s+n.slice(c+1);}}return n}}},ae=function splitStringTransformer(t){return {onSubstitution:function onSubstitution(n,r){return "string"==typeof n&&n.includes(t)&&(n=n.split(t)),n}}},se=function isValidValue(t){return null!=t&&!Number.isNaN(t)&&"boolean"!=typeof t};new Q(ie({separator:","}),ee,Z),new Q(ie({separator:",",conjunction:"and"}),ee,Z),new Q(ie({separator:",",conjunction:"or"}),ee,Z),new Q(ae("\n"),(function removeNonPrintingValuesTransformer(){return {onSubstitution:function onSubstitution(t){return Array.isArray(t)?t.filter(se):se(t)?t:""}}}),ie,ee,Z),new Q(ae("\n"),ie,ee,Z,ne(/&/g,"&"),ne(//g,">"),ne(/"/g,"""),ne(/'/g,"'"),ne(/`/g,"`"));var oe=new Q(te(/(?:\n(?:\s*))+/g," "),Z);new Q(te(/(?:\n\s*)/g,""),Z),new Q(ie({separator:","}),te(/(?:\s+)/g," "),Z),new Q(ie({separator:",",conjunction:"or"}),te(/(?:\s+)/g," "),Z),new Q(ie({separator:",",conjunction:"and"}),te(/(?:\s+)/g," "),Z),new Q(ie,ee,Z),new Q(ie,te(/(?:\s+)/g," "),Z);var le=new Q(ee,Z);function promisifyRequest(t){return new Promise(((n,r)=>{t.oncomplete=t.onsuccess=()=>n(t.result),t.onabort=t.onerror=()=>r(t.error);}))}let ce;function defaultGetStore(){return ce||(ce=function createStore(t,n){const r=indexedDB.open(t);r.onupgradeneeded=()=>r.result.createObjectStore(n);const i=promisifyRequest(r);return (t,r)=>i.then((i=>r(i.transaction(n,t).objectStore(n))))}("keyval-store","keyval")),ce}new Q(ee("all"),Z);const db_get=async t=>await function get(t,n=defaultGetStore()){return n("readonly",(n=>promisifyRequest(n.get(t))))}(t),db_set=async(t,n)=>await function set(t,n,r=defaultGetStore()){return r("readwrite",(r=>(r.put(n,t),promisifyRequest(r.transaction))))}(t,n),db_del=async t=>await function del(t,n=defaultGetStore()){return n("readwrite",(n=>(n.delete(t),promisifyRequest(n.transaction))))}(t);var de=(()=>"undefined"!=typeof GM?GM:void 0)();async function fetchApi(t,n="json"){try{const r=await fetch(t);return "json"===n?await r.json():await r.text()}catch(r){throw new Error(`Fetch error: ${r}`)}}async function fetchAndCached(t,n=false){const{apiURL:r,apiType:i,nameOfCache:a}=t,s=await de.getValue(`${a}-check`),o=await de.getValue(a);if(n||!s||!o||Date.now()-s>432e5)try{let n=await fetchApi(r,i);return t.parseJSON&&(n=n?JSON.parse(n):null),n&&(await de.setValue(a,t.parseJSON?JSON.stringify(n):n),await de.setValue(`${a}-check`,Date.now())),n}catch(l){return o?JSON.parse(o):null}return t.parseJSON?JSON.parse(o):o}async function getSystemPrompt(t=false){return await fetchAndCached({apiURL:"https://gist.githubusercontent.com/sourman-dev/1f8bc4876a5a300105ec657231fbfb30/raw",apiType:"text",nameOfCache:"dichtruyen:ai-systemPrompt"},t)}async function vietPhraseTrans(t,n=0){const r=0===n?"TranslateHanViet":"TranslateVietPhraseS";return new Promise(((n,i)=>{de.xmlHttpRequest({method:"POST",url:`https://vietphrase.info/Vietphrase/${r}`,data:JSON.stringify({chineseContent:t}),headers:{"Content-Type":"application/json"},onload:function(t){n(t.responseText);},onerror:function(t){i(t);}});}))}const translateFunc=async(t,n)=>{try{const r=function currentAiProvider(){const t={name:null,baseURL:null,model:null,apiKey:null,isVietPharseFirst:me.isVietPharseFirst??!1},n=me.providers.find((t=>!0===t.selected));if(n){t.name=n.name,t.baseURL=n.baseUrl,t.apiKey=n.apiKey;let r=n.models.find((t=>!0===t.selected));!r&&n.models.length>0&&(n.models[0].selected=!0,r=n.models[0]),r&&(t.model=r.name);}if(null!==t.apiKey&&null!==t.model)return t}();if(!t||t.length<=5)return;const i=currentPrompt();if(!r||!i.isValid)return;if(!r?.baseURL||!r?.apiKey)throw new Error("AI provider configuration is incomplete.");let a="";replaceAppState({isTranslating:!0,currentView:"reader"});const s=await async function combinePrompt(t){const n=currentPrompt();if(!n.isValid)return "";const r=await vietPhraseTrans(t),i=await vietPhraseTrans(t,1);let a=`${n.basePrompt}\nDựa trên:\n`;return a+=`**Bản dịch Hán Việt** (Lấy danh từ riêng): ${r}`,a+=`**Bản dịch máy**(tham khảo từ khó): ${i}\n`,a+=`**Bản cần dịch:** ${t}`,a}(t),o={baseURL:r.baseURL,apiKey:r.apiKey,data:{model:r?.model,messages:[{role:"user",content:s}],stream:!0,temperature:.8,top_p:.95}};await async function openAICompletion(t,n){try{const r=function ensureApiPath(t){const n=t.trim().replace(/\/+$/,"");return /\/(v1|v1beta|openai)$/i.test(n)?`${n}/chat/completions`:`${n}/v1/chat/completions`}(t.baseURL),i=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t.apiKey}`},body:JSON.stringify(t.data)});if(!i.ok)throw new Error(`HTTP error! status: ${i.status}`);if(i.body?.getReader){const t=i.body.getReader(),r=new TextDecoder;let a="";for(;;){const{done:i,value:s}=await t.read();if(i)break;a+=r.decode(s,{stream:!0});const o=a.split("\n");a=o.pop()||"";for(const t of o){const r=t.trim();if(r&&r.startsWith("data: "))try{const t=r.slice(5).trim();if("[DONE]"===t)return;const i=JSON.parse(t),a=i?.choices?.[0]?.delta?.content;if(a&&n(a),"stop"===i?.choices?.[0]?.finish_reason)return}catch(e){continue}}}}else {const t=await i.text();try{const r=t.split("\n");for(const t of r)if(t.startsWith("data: ")){const r=t.slice(5).trim();if("[DONE]"===r)continue;const i=JSON.parse(r),a=i?.choices?.[0]?.delta?.content;a&&n(a);}}catch(e){throw e}}}catch(r){throw r}}(o,(t=>{a+=t,n(a);})),n(a+"\n[Translation completed]");const l={url:window.location.href,title:document.title,cachedAt:Date.now(),...findPrevNextChapterLinks()};replaceAppState({isTranslating:!1,currentView:"reader"}),await(async(t,n)=>{try{if(!t?.url)return;let r=JSON.parse(localStorage.getItem("dichtruyen-ai:history")||"[]");r=r.filter((t=>t&&t.url));const i=r.findIndex((n=>n.url===t.url));-1!==i?r[i]=t:(r.length>=20&&r.shift(),r.push(t)),localStorage.setItem("dichtruyen-ai:history",JSON.stringify(r)),await db_set(`history:${t.url}`,t),await db_set(`translated:${t.url}`,n);}catch(r){}})(l,a);}catch(r){}finally{replaceAppState({isTranslating:false});}};function currentPrompt(){const t=me.prompt.systemPrompts.find((t=>t.selected))?.content,n=me.prompt.userPrompts.find((t=>t.selected))?.content;return {isValid:null!=t&&t.length>10,basePrompt:le`${oe`${t}\n${n}`}\n`}}function findElementByIndicators(t){const n=document.querySelectorAll("a");let r=null,i=null;for(const a of n){const n=`${a.textContent?.trim()||""} ${a.getAttribute("aria-label")||""} ${a.getAttribute("title")||""}`,s=t.find((t=>n.toLowerCase().includes(t.toLowerCase())));if(s){r=a,i=s;break}}return {element:r,indicator:i}}function findPrevNextChapterLinks(){const t=findElementByIndicators(["trước","previous","prev","<","←","«","上一章","上一節","back","Previous Chapter","Prev Chapter","上章","Chương trước"]),n=findElementByIndicators(["sau","next",">","→","»","tiếp","下一章","下一節","Next Chapter","下章","Chương sau","tiếp theo"]);let r=t.element?.href||null,i=n.element?.href||null;if(!isValidUrl(r)||!isValidUrl(i)){const t=window.location.href,n=t.match(/\d+/)?.[0];if(n){const t=parseInt(n);document.querySelectorAll("a").forEach((n=>{const a=n.href,s=a.match(/\d+/)?.[0];if(s){const n=parseInt(s);n===t-1?r=a:n===t+1&&(i=a);}}));}}return {previous:isValidUrl(r)?r:t.indicator,next:isValidUrl(i)?i:n.indicator}}const isValidUrl=t=>{if(!t)return false;try{return "javascript:"!==new URL(t).protocol}catch{return false}},fetchResource=async t=>await fetchApi(t,"text"),getRelease=async(t=false)=>{try{const n={apiURL:"https://api.github.com/repos/sourman-dev/dichtruyen-ai-userscript/releases/latest",apiType:"text",nameOfCache:"dichtruyen-ai:release",parseJSON:!0},r=await fetchAndCached(n,t),i={version:r.tag_name,description:r.body,fileUrl:r.assets[0]?.browser_download_url||null};return await de.setValue("dichtruyen-ai:release",JSON.stringify(i)),i}catch(e){return {version:"0.0.9",description:null,fileUrl:null}}},ue=[{id:"openai",name:"OpenAI",baseUrl:"https://api.openai.com/v1",defaultModels:["gpt-4o","gpt-4o-mini","gpt-3.5-turbo"],supportsModelsEndpoint:true,note:"Industry standard. Requires paid API key."},{id:"gemini",name:"Google Gemini",baseUrl:"https://generativelanguage.googleapis.com/v1beta/openai",defaultModels:["gemini-2.0-flash-exp","gemini-1.5-pro","gemini-1.5-flash"],supportsModelsEndpoint:false,note:"Free tier available. Get key from AI Studio."},{id:"deepseek",name:"DeepSeek",baseUrl:"https://api.deepseek.com/v1",defaultModels:["deepseek-chat","deepseek-coder"],supportsModelsEndpoint:true,note:"Best for Chinese/Vietnamese. Very cost-effective."},{id:"groq",name:"Groq",baseUrl:"https://api.groq.com/openai/v1",defaultModels:["llama-3.3-70b-versatile","llama-3.1-70b-versatile","mixtral-8x7b-32768"],supportsModelsEndpoint:true,note:"Fastest inference (LPU). Generous free tier."},{id:"together",name:"Together AI",baseUrl:"https://api.together.xyz/v1",defaultModels:["meta-llama/Llama-3-70b-chat-hf","mistralai/Mixtral-8x7B-Instruct-v0.1"],supportsModelsEndpoint:true,note:"$25 free credit. Open-source models."},{id:"fireworks",name:"Fireworks AI",baseUrl:"https://api.fireworks.ai/inference/v1",defaultModels:["accounts/fireworks/models/llama-v3p1-70b-instruct","accounts/fireworks/models/qwen2p5-72b-instruct"],supportsModelsEndpoint:true,note:"Fast inference. $1 free credit."},{id:"openrouter",name:"OpenRouter",baseUrl:"https://openrouter.ai/api/v1",defaultModels:["anthropic/claude-3.5-sonnet","google/gemini-pro-1.5","openai/gpt-4o"],supportsModelsEndpoint:true,note:"Aggregator: 70+ models. Access Claude, GPT-4, Gemini with one key."},{id:"mistral",name:"Mistral AI",baseUrl:"https://api.mistral.ai/v1",defaultModels:["mistral-large-latest","mistral-small-latest","codestral-latest"],supportsModelsEndpoint:true,note:"European provider. GDPR compliant."},{id:"novita",name:"Novita.ai",baseUrl:"https://api.novita.ai/v3/openai",defaultModels:["gpt-4o","llama-3.1-70b-instruct","qwen2.5-72b-instruct"],supportsModelsEndpoint:true,note:"Aggregator. $0.50 free credit."},{id:"custom",name:"Custom...",baseUrl:"",defaultModels:[],supportsModelsEndpoint:true,note:"Add any OpenAI-compatible API."}];function presetToProvider(t,n=""){const r=t.defaultModels.map(((t,n)=>({name:t,selected:0===n})));return {name:t.name,baseUrl:t.baseUrl,apiKey:n||null,selected:false,models:r,isCustom:"custom"===t.id,supportsModelsEndpoint:t.supportsModelsEndpoint,note:t.note}}function getPresetByName(t){return ue.find((n=>n.name===t))}const he={version:"0.0.9",prompt:{systemPrompts:[],userPrompts:[{id:"default-0",name:"Default",content:"",selected:true}]},providers:[],readerView:{backgroundColor:"#F4F4F4",fontFamily:"system-ui",lineHeight:"1.2",fontSize:18,bionicReading:false,includeTitle:false},isVietPharseFirst:false};let pe;const me=reactive(he),ge=reactive({currentView:"empty",isTranslating:false,openReaderConfig:false}),mergeProviders=async t=>{const n=ue.filter((t=>"custom"!==t.id)).map((n=>{const r=t.providers.find((t=>t.name===n.name));return r?.apiKey||r?.selected?{...presetToProvider(n),apiKey:r.apiKey,selected:r.selected,baseUrl:r.baseUrl||n.baseUrl,models:r.models.length>0?r.models:presetToProvider(n).models}:presetToProvider(n)})),r=t.providers.filter((t=>t.isCustom));return t.providers=[...n,...r],t},mergeSystemPrompt=async t=>{const n=await getSystemPrompt(true),r=t.prompt.systemPrompts.find((t=>"default-0"===t.id));return r?r.content=n:t.prompt.systemPrompts.push({id:"default-0",name:"Default",content:n,selected:true}),t},replaceAppState=t=>{replace(ge,Object.assign(ge,t));},replaceReaderState=t=>{replace(me.readerView,Object.assign({},me.readerView,t));};const{span:fe,button:be,div:ve}=p.tags,createIconButton=(t,n,r)=>be({class:"icon-button",id:r||void 0,onclick:n},t);function changeView(t){const n=ge.currentView===t?"empty":t;replaceAppState({currentView:n});}const iconEl=t=>fe({class:"icon",style:`background-image: url('data:image/svg+xml;utf8,${t}');`}),ye=iconEl(''),_e=iconEl(''),we=iconEl(''),Ee=iconEl(''),changeIcon=t=>{Array.from(document.querySelectorAll("*")).map((t=>t.shadowRoot)).filter((t=>null!==t)).forEach((n=>{const r=n.querySelector("#transButton");if(r){for(;r.firstChild;)r.removeChild(r.firstChild);r.appendChild(t);}}));},{p:Ne,div:Te,button:Ae,select:Se,option:xe,label:Ce,input:Pe}=p.tags,Le=[{name:"System ui",value:'"system-ui", sans-serif'},{name:"Times New Roman",value:'"Times New Roman", serif'},{name:"Arial",value:'"Arial", sans-serif'},{name:"Verdana",value:'"Verdana", sans-serif'},{name:"Tahoma",value:"Tahoma"},{name:"Roboto",value:'"Roboto", sans-serif'},{name:"Be Vietnam Pro",value:'"Be Vietnam Pro", sans-serif'},{name:"Noto Sans",value:'"Noto Sans", sans-serif'},{name:"Merriweather",value:'"Merriweather", serif'},{name:"Lora",value:'"Lora", serif'},{name:"Source Sans 3",value:'"Source Sans 3", sans-serif'},{name:"Open Sans",value:'"Open Sans", sans-serif'},{name:"Playfair Display",value:'"Playfair Display", serif'}],ke=[{name:"Light Gray",value:"#F4F4F4"},{name:"Light Blue",value:"#E8EBEE"},{name:"Deep Blue",value:"#E1E4F2"},{name:"Light Yellow",value:"#F4F4E3"},{name:"Sepia",value:"#EAE4D3"},{name:"Deep Yellow",value:"#FAFAC8"},{name:"Dark",value:"black"}],Re=["1.6","1","1.2","1.4","1.8","2"],openCloseModal=(t="none")=>{Array.from(document.querySelectorAll("*")).map((t=>t.shadowRoot)).filter((t=>null!==t)).forEach((n=>{const r=n.getElementById("mdlReaderContainer");r&&(r.style.display=t);}));},Ie=p.derive((()=>me.readerView));function ModalReaderConfig(){const t=p.state(false);return Te({id:"mdlReaderContainer",style:"display: none"},(({closed:t,backgroundColor:n="rgba(0,0,0,.5)",blurBackground:r=false,clickBackgroundToClose:i=false,backgroundClass:a="",backgroundStyleOverrides:s={},modalClass:o="",modalStyleOverrides:l={}},...c)=>{const d={display:"flex","align-items":"center","justify-content":"center",left:0,right:0,top:0,bottom:0,position:"fixed","z-index":1e4,"background-color":n,"backdrop-filter":r?"blur(0.25rem)":"none",...s},u={"border-radius":"0.5rem",padding:"1rem",display:"block","background-color":"white",...l};return document.activeElement instanceof HTMLElement&&document.activeElement.blur(),()=>{if(t.val)return null;const n=b({class:a,style:toStyleStr(d)},b({class:o,style:toStyleStr(u)},c));return i&&n.addEventListener("click",(r=>r.target===n&&(t.val=true))),n}})({closed:t},Te({class:"pure-g"},Te({class:"pure-u-1 pure-u-md-1-2 p-1"},Ne("Font Family"),Se({class:"pure-input-1",onchange:t=>{replaceReaderState({fontFamily:t.target.value});}},Le.map((t=>xe({value:t.value,selected:()=>Ie.val.fontFamily===t.value},t.name))))),Te({class:"pure-u-1 pure-u-md-1-2 p-1"},Ne("Font Size"),Se({class:"pure-input-1",onchange:t=>{replaceReaderState({fontSize:t.target.value});}},Array.from({length:15},((t,n)=>n+20)).map((t=>xe({value:t,selected:()=>Number(Ie.val.fontSize)===t},`${t}px`))))),Te({class:"pure-u-1 pure-u-md-1-2 p-1"},Ne("Background Color"),Se({class:"pure-input-1",onchange:t=>{replaceReaderState({backgroundColor:t.target.value});}},ke.map((t=>xe({value:t.value,selected:()=>Ie.val.backgroundColor===t.value},t.name))))),Te({class:"pure-u-1 pure-u-md-1-2 p-1"},Ne("Line Height"),Se({class:"pure-input-1",onchange:t=>{replaceReaderState({lineHeight:t.target.value});}},Re.map((t=>xe({value:t,selected:()=>Ie.val.lineHeight===t},t))))),Te({class:"pure-u-1 p-1",style:"margin: 5px 0px;"},Ce({class:"pure-checkbox"},Pe({type:"checkbox",checked:Ie.val.bionicReading,onchange:t=>{replaceReaderState({bionicReading:t.target.checked});}})," Fast Reader"))),Te({style:"display: flex; justify-content: center;"},Ae({onclick:()=>replaceAppState({openReaderConfig:false})},"Ok"))))}p.derive((()=>{ true===ge.openReaderConfig?openCloseModal("flex"):openCloseModal("none");}));const{div:De,style:Oe,button:Me,a:Be}=p.tags,currentHistory=async()=>await db_get(`history:${window.location.href}`),createHistoryItem=(t,n)=>De({class:"history-item"},Be({href:t,class:"history-link",onclick:n=>{n.preventDefault(),window.location.href=t;}},n),Me({onclick:async function(){await(async t=>{try{await db_del(`history:${t}`),await db_del(`translated:${t}`);let n=JSON.parse(localStorage.getItem("dichtruyen-ai:history")||"[]");return n=n.filter((n=>n.url!==t)),localStorage.setItem("dichtruyen-ai:history",JSON.stringify(n)),!0}catch(n){throw n}})(t),window.location.reload();},class:"delete-button"},"❌"));e("history-view",(({})=>{let t=JSON.parse(localStorage.getItem("dichtruyen-ai:history")||"[]");return t=t.filter((t=>t.url!==window.location.href)),[Oe("\n .history-item {\n padding: 0.5em;\n margin: 0.5em 0;\n border-bottom: 1px solid #eee;\n }\n .history-link {\n text-decoration: none;\n color: #333;\n margin-right: 1em;\n }\n .delete-button {\n float: right;\n border: none;\n background: none;\n cursor: pointer;\n }\n .empty-label {\n text-align: center;\n padding: 2em;\n color: #666;\n }\n .history-list {\n max-height: 700px;\n overflow-y: auto;\n border-bottom: 3px solid #333;\n }\n "),De({class:"pure-g"},De({class:"pure-u-1 history-list"},0===t.length?De({class:"empty-label"},"Lịch sử trống"):t.map((t=>createHistoryItem(t.url,t.title)))),Await({value:currentHistory(),container:De},(t=>t&&createHistoryItem(t.url,t.title))))]}),false);var Ue,Ve={exports:{}};function requireReadability$1(){return Ue||(Ue=1,function(t){function Readability(t,n){if(n&&n.documentElement)t=n,n=arguments[2];else if(!t||!t.documentElement)throw new Error("First argument to Readability constructor should be a document object.");if(n=n||{},this._doc=t,this._docJSDOMParser=this._doc.firstChild.__JSDOMParser__,this._articleTitle=null,this._articleByline=null,this._articleDir=null,this._articleSiteName=null,this._attempts=[],this._metadata={},this._debug=!!n.debug,this._maxElemsToParse=n.maxElemsToParse||this.DEFAULT_MAX_ELEMS_TO_PARSE,this._nbTopCandidates=n.nbTopCandidates||this.DEFAULT_N_TOP_CANDIDATES,this._charThreshold=n.charThreshold||this.DEFAULT_CHAR_THRESHOLD,this._classesToPreserve=this.CLASSES_TO_PRESERVE.concat(n.classesToPreserve||[]),this._keepClasses=!!n.keepClasses,this._serializer=n.serializer||function(t){return t.innerHTML},this._disableJSONLD=!!n.disableJSONLD,this._allowedVideoRegex=n.allowedVideoRegex||this.REGEXPS.videos,this._linkDensityModifier=n.linkDensityModifier||0,this._flags=this.FLAG_STRIP_UNLIKELYS|this.FLAG_WEIGHT_CLASSES|this.FLAG_CLEAN_CONDITIONALLY,this._debug){let logNode=function(t){if(t.nodeType==t.TEXT_NODE)return `${t.nodeName} ("${t.textContent}")`;let n=Array.from(t.attributes||[],(function(t){return `${t.name}="${t.value}"`})).join(" ");return `<${t.localName} ${n}>`};this.log=function(){if("undefined"!=typeof console){Array.from(arguments,(t=>t&&t.nodeType==this.ELEMENT_NODE?logNode(t):t)).unshift("Reader: (Readability)");}else if("undefined"!=typeof dump){var t=Array.prototype.map.call(arguments,(function(t){return t&&t.nodeName?logNode(t):t})).join(" ");dump("Reader: (Readability) "+t+"\n");}};}else this.log=function(){};}Readability.prototype={FLAG_STRIP_UNLIKELYS:1,FLAG_WEIGHT_CLASSES:2,FLAG_CLEAN_CONDITIONALLY:4,ELEMENT_NODE:1,TEXT_NODE:3,DEFAULT_MAX_ELEMS_TO_PARSE:0,DEFAULT_N_TOP_CANDIDATES:5,DEFAULT_TAGS_TO_SCORE:"section,h2,h3,h4,h5,h6,p,td,pre".toUpperCase().split(","),DEFAULT_CHAR_THRESHOLD:500,REGEXPS:{unlikelyCandidates:/-ad-|ai2html|banner|breadcrumbs|combx|comment|community|cover-wrap|disqus|extra|footer|gdpr|header|legends|menu|related|remark|replies|rss|shoutbox|sidebar|skyscraper|social|sponsor|supplemental|ad-break|agegate|pagination|pager|popup|yom-remote/i,okMaybeItsACandidate:/and|article|body|column|content|main|shadow/i,positive:/article|body|content|entry|hentry|h-entry|main|page|pagination|post|text|blog|story/i,negative:/-ad-|hidden|^hid$| hid$| hid |^hid |banner|combx|comment|com-|contact|footer|gdpr|masthead|media|meta|outbrain|promo|related|scroll|share|shoutbox|sidebar|skyscraper|sponsor|shopping|tags|widget/i,extraneous:/print|archive|comment|discuss|e[\-]?mail|share|reply|all|login|sign|single|utility/i,byline:/byline|author|dateline|writtenby|p-author/i,replaceFonts:/<(\/?)font[^>]*>/gi,normalize:/\s{2,}/g,videos:/\/\/(www\.)?((dailymotion|youtube|youtube-nocookie|player\.vimeo|v\.qq)\.com|(archive|upload\.wikimedia)\.org|player\.twitch\.tv)/i,shareElements:/(\b|_)(share|sharedaddy)(\b|_)/i,nextLink:/(next|weiter|continue|>([^\|]|$)|»([^\|]|$))/i,prevLink:/(prev|earl|old|new|<|«)/i,tokenize:/\W+/g,whitespace:/^\s*$/,hasContent:/\S$/,hashUrl:/^#.+/,srcsetUrl:/(\S+)(\s+[\d.]+[xw])?(\s*(?:,|$))/g,b64DataUrl:/^data:\s*([^\s;,]+)\s*;\s*base64\s*,/i,commas:/\u002C|\u060C|\uFE50|\uFE10|\uFE11|\u2E41|\u2E34|\u2E32|\uFF0C/g,jsonLdArticleTypes:/^Article|AdvertiserContentArticle|NewsArticle|AnalysisNewsArticle|AskPublicNewsArticle|BackgroundNewsArticle|OpinionNewsArticle|ReportageNewsArticle|ReviewNewsArticle|Report|SatiricalArticle|ScholarlyArticle|MedicalScholarlyArticle|SocialMediaPosting|BlogPosting|LiveBlogPosting|DiscussionForumPosting|TechArticle|APIReference$/,adWords:/^(ad(vertising|vertisement)?|pub(licité)?|werb(ung)?|广告|Реклама|Anuncio)$/iu,loadingWords:/^((loading|正在加载|Загрузка|chargement|cargando)(…|\.\.\.)?)$/iu},UNLIKELY_ROLES:["menu","menubar","complementary","navigation","alert","alertdialog","dialog"],DIV_TO_P_ELEMS:new Set(["BLOCKQUOTE","DL","DIV","IMG","OL","P","PRE","TABLE","UL"]),ALTER_TO_DIV_EXCEPTIONS:["DIV","ARTICLE","SECTION","P","OL","UL"],PRESENTATIONAL_ATTRIBUTES:["align","background","bgcolor","border","cellpadding","cellspacing","frame","hspace","rules","style","valign","vspace"],DEPRECATED_SIZE_ATTRIBUTE_ELEMS:["TABLE","TH","TD","HR","PRE"],PHRASING_ELEMS:["ABBR","AUDIO","B","BDO","BR","BUTTON","CITE","CODE","DATA","DATALIST","DFN","EM","EMBED","I","IMG","INPUT","KBD","LABEL","MARK","MATH","METER","NOSCRIPT","OBJECT","OUTPUT","PROGRESS","Q","RUBY","SAMP","SCRIPT","SELECT","SMALL","SPAN","STRONG","SUB","SUP","TEXTAREA","TIME","VAR","WBR"],CLASSES_TO_PRESERVE:["page"],HTML_ESCAPE_MAP:{lt:"<",gt:">",amp:"&",quot:'"',apos:"'"},_postProcessContent(t){this._fixRelativeUris(t),this._simplifyNestedElements(t),this._keepClasses||this._cleanClasses(t);},_removeNodes(t,n){if(this._docJSDOMParser&&t._isLiveNodeList)throw new Error("Do not pass live node lists to _removeNodes");for(var r=t.length-1;r>=0;r--){var i=t[r],a=i.parentNode;a&&(n&&!n.call(this,i,r,t)||a.removeChild(i));}},_replaceNodeTags(t,n){if(this._docJSDOMParser&&t._isLiveNodeList)throw new Error("Do not pass live node lists to _replaceNodeTags");for(const r of t)this._setNodeTag(r,n);},_forEachNode(t,n){Array.prototype.forEach.call(t,n,this);},_findNode(t,n){return Array.prototype.find.call(t,n,this)},_someNode(t,n){return Array.prototype.some.call(t,n,this)},_everyNode(t,n){return Array.prototype.every.call(t,n,this)},_getAllNodesWithTag:(t,n)=>t.querySelectorAll?t.querySelectorAll(n.join(",")):[].concat.apply([],n.map((function(n){var r=t.getElementsByTagName(n);return Array.isArray(r)?r:Array.from(r)}))),_cleanClasses(t){var n=this._classesToPreserve,r=(t.getAttribute("class")||"").split(/\s+/).filter((t=>n.includes(t))).join(" ");for(r?t.setAttribute("class",r):t.removeAttribute("class"),t=t.firstElementChild;t;t=t.nextElementSibling)this._cleanClasses(t);},_isUrl(t){try{return new URL(t),!0}catch{return false}},_fixRelativeUris(t){var n=this._doc.baseURI,r=this._doc.documentURI;function toAbsoluteURI(t){if(n==r&&"#"==t.charAt(0))return t;try{return new URL(t,n).href}catch(i){}return t}var i=this._getAllNodesWithTag(t,["a"]);this._forEachNode(i,(function(t){var n=t.getAttribute("href");if(n)if(0===n.indexOf("javascript:"))if(1===t.childNodes.length&&t.childNodes[0].nodeType===this.TEXT_NODE){var r=this._doc.createTextNode(t.textContent);t.parentNode.replaceChild(r,t);}else {for(var i=this._doc.createElement("span");t.firstChild;)i.appendChild(t.firstChild);t.parentNode.replaceChild(i,t);}else t.setAttribute("href",toAbsoluteURI(n));}));var a=this._getAllNodesWithTag(t,["img","picture","figure","video","audio","source"]);this._forEachNode(a,(function(t){var n=t.getAttribute("src"),r=t.getAttribute("poster"),i=t.getAttribute("srcset");if(n&&t.setAttribute("src",toAbsoluteURI(n)),r&&t.setAttribute("poster",toAbsoluteURI(r)),i){var a=i.replace(this.REGEXPS.srcsetUrl,(function(t,n,r,i){return toAbsoluteURI(n)+(r||"")+i}));t.setAttribute("srcset",a);}}));},_simplifyNestedElements(t){for(var n=t;n;){if(n.parentNode&&["DIV","SECTION"].includes(n.tagName)&&(!n.id||!n.id.startsWith("readability"))){if(this._isElementWithoutContent(n)){n=this._removeAndGetNext(n);continue}if(this._hasSingleTagInsideElement(n,"DIV")||this._hasSingleTagInsideElement(n,"SECTION")){for(var r=n.children[0],i=0;i»] /.test(n)){i=/ [\\\/>»] /.test(n);let t=Array.from(r.matchAll(/ [\|\-\\\/>»] /gi));wordCount(n=r.substring(0,t.pop().index))<3&&(n=r.replace(/^[^\|\-\\\/>»]*[\|\-\\\/>»]/gi,""));}else if(n.includes(": ")){var a=this._getAllNodesWithTag(t,["h1","h2"]),s=n.trim();this._someNode(a,(function(t){return t.textContent.trim()===s}))||(wordCount(n=r.substring(r.lastIndexOf(":")+1))<3?n=r.substring(r.indexOf(":")+1):wordCount(r.substr(0,r.indexOf(":")))>5&&(n=r));}else if(n.length>150||n.length<15){var o=t.getElementsByTagName("h1");1===o.length&&(n=this._getInnerText(o[0]));}var l=wordCount(n=n.trim().replace(this.REGEXPS.normalize," "));return l<=4&&(!i||l!=wordCount(r.replace(/[\|\-\\\/>»]+/g,""))-1)&&(n=r),n},_prepDocument(){var t=this._doc;this._removeNodes(this._getAllNodesWithTag(t,["style"])),t.body&&this._replaceBrs(t.body),this._replaceNodeTags(this._getAllNodesWithTag(t,["font"]),"SPAN");},_nextNode(t){for(var n=t;n&&n.nodeType!=this.ELEMENT_NODE&&this.REGEXPS.whitespace.test(n.textContent);)n=n.nextSibling;return n},_replaceBrs(t){this._forEachNode(this._getAllNodesWithTag(t,["br"]),(function(t){for(var n=t.nextSibling,r=false;(n=this._nextNode(n))&&"BR"==n.tagName;){r=true;var i=n.nextSibling;n.remove(),n=i;}if(r){var a=this._doc.createElement("p");for(t.parentNode.replaceChild(a,t),n=a.nextSibling;n;){if("BR"==n.tagName){var s=this._nextNode(n.nextSibling);if(s&&"BR"==s.tagName)break}if(!this._isPhrasingContent(n))break;var o=n.nextSibling;a.appendChild(n),n=o;}for(;a.lastChild&&this._isWhitespace(a.lastChild);)a.lastChild.remove();"P"===a.parentNode.tagName&&this._setNodeTag(a.parentNode,"DIV");}}));},_setNodeTag(t,n){if(this.log("_setNodeTag",t,n),this._docJSDOMParser)return t.localName=n.toLowerCase(),t.tagName=n.toUpperCase(),t;for(var r=t.ownerDocument.createElement(n);t.firstChild;)r.appendChild(t.firstChild);t.parentNode.replaceChild(r,t),t.readability&&(r.readability=t.readability);for(var i=0;i!r.includes(t))).join(" ").length/i.join(" ").length:0},_isValidByline(t,n){var r=t.getAttribute("rel"),i=t.getAttribute("itemprop"),a=t.textContent.trim().length;return ("author"===r||i&&i.includes("author")||this.REGEXPS.byline.test(n))&&!!a&&a<100},_getNodeAncestors(t,n){n=n||0;for(var r=0,i=[];t.parentNode&&(i.push(t.parentNode),!n||++r!==n);)t=t.parentNode;return i},_grabArticle(t){this.log("**** grabArticle ****");var n=this._doc,r=null!==t;if(!(t=t||this._doc.body))return this.log("No body found in document. Abort."),null;for(var i=t.innerHTML;;){this.log("Starting grabArticle loop");var a=this._flagIsActive(this.FLAG_STRIP_UNLIKELYS),s=[],o=this._doc.documentElement;let re=true;for(;o;){"HTML"===o.tagName&&(this._articleLang=o.getAttribute("lang"));var l=o.className+" "+o.id;if(this._isProbablyVisible(o))if("true"!=o.getAttribute("aria-modal")||"dialog"!=o.getAttribute("role"))if(this._articleByline||this._metadata.byline||!this._isValidByline(o,l))if(re&&this._headerDuplicatesTitle(o))this.log("Removing header: ",o.textContent.trim(),this._articleTitle.trim()),re=false,o=this._removeAndGetNext(o);else {if(a){if(this.REGEXPS.unlikelyCandidates.test(l)&&!this.REGEXPS.okMaybeItsACandidate.test(l)&&!this._hasAncestorTag(o,"table")&&!this._hasAncestorTag(o,"code")&&"BODY"!==o.tagName&&"A"!==o.tagName){this.log("Removing unlikely candidate - "+l),o=this._removeAndGetNext(o);continue}if(this.UNLIKELY_ROLES.includes(o.getAttribute("role"))){this.log("Removing content with role "+o.getAttribute("role")+" - "+l),o=this._removeAndGetNext(o);continue}}if("DIV"!==o.tagName&&"SECTION"!==o.tagName&&"HEADER"!==o.tagName&&"H1"!==o.tagName&&"H2"!==o.tagName&&"H3"!==o.tagName&&"H4"!==o.tagName&&"H5"!==o.tagName&&"H6"!==o.tagName||!this._isElementWithoutContent(o)){if(this.DEFAULT_TAGS_TO_SCORE.includes(o.tagName)&&s.push(o),"DIV"===o.tagName){for(var c=null,d=o.firstChild;d;){var u=d.nextSibling;if(this._isPhrasingContent(d))null!==c?c.appendChild(d):this._isWhitespace(d)||(c=n.createElement("p"),o.replaceChild(c,d),c.appendChild(d));else if(null!==c){for(;c.lastChild&&this._isWhitespace(c.lastChild);)c.lastChild.remove();c=null;}d=u;}if(this._hasSingleTagInsideElement(o,"P")&&this._getLinkDensity(o)<.25){var h=o.children[0];o.parentNode.replaceChild(h,o),o=h,s.push(o);}else this._hasChildBlockElement(o)||(o=this._setNodeTag(o,"P"),s.push(o));}o=this._getNextNode(o);}else o=this._removeAndGetNext(o);}else {for(var p=this._getNextNode(o,true),g=this._getNextNode(o),b=null;g&&g!=p;){var v=g.getAttribute("itemprop");if(v&&v.includes("name")){b=g;break}g=this._getNextNode(g);}this._articleByline=(b??o).textContent.trim(),o=this._removeAndGetNext(o);}else o=this._removeAndGetNext(o);else this.log("Removing hidden node - "+l),o=this._removeAndGetNext(o);}var w=[];this._forEachNode(s,(function(t){if(t.parentNode&&void 0!==t.parentNode.tagName){var n=this._getInnerText(t);if(!(n.length<25)){var r=this._getNodeAncestors(t,5);if(0!==r.length){var i=0;i+=1,i+=n.split(this.REGEXPS.commas).length,i+=Math.min(Math.floor(n.length/100),3),this._forEachNode(r,(function(t,n){if(t.tagName&&t.parentNode&&void 0!==t.parentNode.tagName){if(void 0===t.readability&&(this._initializeNode(t),w.push(t)),0===n)var r=1;else r=1===n?2:3*n;t.readability.contentScore+=i/r;}}));}}}}));for(var E=[],T=0,A=w.length;TP.readability.contentScore){E.splice(C,0,S),E.length>this._nbTopCandidates&&E.pop();break}}}var L,k=E[0]||null,R=false;if(null===k||"BODY"===k.tagName){for(k=n.createElement("DIV"),R=true;t.firstChild;)this.log("Moving child out:",t.firstChild),k.appendChild(t.firstChild);t.appendChild(k),this._initializeNode(k);}else if(k){for(var I=[],D=1;D=.75&&I.push(this._getNodeAncestors(E[D]));if(I.length>=3)for(L=k.parentNode;"BODY"!==L.tagName;){for(var O=0,M=0;M=3){k=L;break}L=L.parentNode;}k.readability||this._initializeNode(k),L=k.parentNode;for(var B=k.readability.contentScore,V=B/3;"BODY"!==L.tagName;)if(L.readability){var $=L.readability.contentScore;if($B){k=L;break}B=L.readability.contentScore,L=L.parentNode;}else L=L.parentNode;for(L=k.parentNode;"BODY"!=L.tagName&&1==L.children.length;)L=(k=L).parentNode;k.readability||this._initializeNode(k);}var G=n.createElement("DIV");r&&(G.id="readability-content");for(var F=Math.max(10,.2*k.readability.contentScore),j=(L=k.parentNode).children,z=0,W=j.length;z=F)K=true;else if("P"===q.nodeName){var J=this._getLinkDensity(q),Y=this._getInnerText(q),Q=Y.length;(Q>80&&J<.25||Q<80&&Q>0&&0===J&&-1!==Y.search(/\.( |$)/))&&(K=true);}}K&&(this.log("Appending node:",q),this.ALTER_TO_DIV_EXCEPTIONS.includes(q.nodeName)||(this.log("Altering sibling:",q,"to div."),q=this._setNodeTag(q,"DIV")),G.appendChild(q),j=L.children,z-=1,W-=1);}if(this._debug&&this.log("Article content pre-prep: "+G.innerHTML),this._prepArticle(G),this._debug&&this.log("Article content post-prep: "+G.innerHTML),R)k.id="readability-page-1",k.className="page";else {var Z=n.createElement("DIV");for(Z.id="readability-page-1",Z.className="page";G.firstChild;)Z.appendChild(G.firstChild);G.appendChild(Z);}this._debug&&this.log("Article content after paging: "+G.innerHTML);var ee=true,te=this._getInnerText(G,true).length;if(te1114111||i>=55296&&i<=57343)&&(i=65533),String.fromCodePoint(i)}))},_getJSONLD(t){var n,r=this._getAllNodesWithTag(t,["script"]);return this._forEachNode(r,(function(t){if(!n&&"application/ld+json"===t.getAttribute("type"))try{var r=t.textContent.replace(/^\s*\s*$/g,""),i=JSON.parse(r);if(Array.isArray(i)&&!(i=i.find((t=>t["@type"]&&t["@type"].match(this.REGEXPS.jsonLdArticleTypes)))))return;var a=/^https?\:\/\/schema\.org\/?$/;if(!("string"==typeof i["@context"]&&i["@context"].match(a)||"object"==typeof i["@context"]&&"string"==typeof i["@context"]["@vocab"]&&i["@context"]["@vocab"].match(a)))return;if(!i["@type"]&&Array.isArray(i["@graph"])&&(i=i["@graph"].find((t=>(t["@type"]||"").match(this.REGEXPS.jsonLdArticleTypes)))),!i||!i["@type"]||!i["@type"].match(this.REGEXPS.jsonLdArticleTypes))return;if(n={},"string"==typeof i.name&&"string"==typeof i.headline&&i.name!==i.headline){var s=this._getArticleTitle(),o=this._textSimilarity(i.name,s)>.75,l=this._textSimilarity(i.headline,s)>.75;n.title=l&&!o?i.headline:i.name;}else "string"==typeof i.name?n.title=i.name.trim():"string"==typeof i.headline&&(n.title=i.headline.trim());i.author&&("string"==typeof i.author.name?n.byline=i.author.name.trim():Array.isArray(i.author)&&i.author[0]&&"string"==typeof i.author[0].name&&(n.byline=i.author.filter((function(t){return t&&"string"==typeof t.name})).map((function(t){return t.name.trim()})).join(", "))),"string"==typeof i.description&&(n.excerpt=i.description.trim()),i.publisher&&"string"==typeof i.publisher.name&&(n.siteName=i.publisher.name.trim()),"string"==typeof i.datePublished&&(n.datePublished=i.datePublished.trim());}catch(c){this.log(c.message);}})),n||{}},_getArticleMetadata(t){var n={},r={},i=this._doc.getElementsByTagName("meta"),a=/\s*(article|dc|dcterm|og|twitter)\s*:\s*(author|creator|description|published_time|title|site_name)\s*/gi,s=/^\s*(?:(dc|dcterm|og|twitter|parsely|weibo:(article|webpage))\s*[-\.:]\s*)?(author|creator|pub-date|description|title|site_name)\s*$/i;this._forEachNode(i,(function(t){var n=t.getAttribute("name"),i=t.getAttribute("property"),o=t.getAttribute("content");if(o){var l=null,c=null;i&&(l=i.match(a))&&(c=l[0].toLowerCase().replace(/\s/g,""),r[c]=o.trim()),!l&&n&&s.test(n)&&(c=n,o&&(c=c.toLowerCase().replace(/\s/g,"").replace(/\./g,":"),r[c]=o.trim()));}})),n.title=t.title||r["dc:title"]||r["dcterm:title"]||r["og:title"]||r["weibo:article:title"]||r["weibo:webpage:title"]||r.title||r["twitter:title"]||r["parsely-title"],n.title||(n.title=this._getArticleTitle());const o="string"!=typeof r["article:author"]||this._isUrl(r["article:author"])?void 0:r["article:author"];return n.byline=t.byline||r["dc:creator"]||r["dcterm:creator"]||r.author||r["parsely-author"]||o,n.excerpt=t.excerpt||r["dc:description"]||r["dcterm:description"]||r["og:description"]||r["weibo:article:description"]||r["weibo:webpage:description"]||r.description||r["twitter:description"],n.siteName=t.siteName||r["og:site_name"],n.publishedTime=t.datePublished||r["article:published_time"]||r["parsely-pub-date"]||null,n.title=this._unescapeHtmlEntities(n.title),n.byline=this._unescapeHtmlEntities(n.byline),n.excerpt=this._unescapeHtmlEntities(n.excerpt),n.siteName=this._unescapeHtmlEntities(n.siteName),n.publishedTime=this._unescapeHtmlEntities(n.publishedTime),n},_isSingleImage(t){for(;t;){if("IMG"===t.tagName)return true;if(1!==t.children.length||""!==t.textContent.trim())return false;t=t.children[0];}return false},_unwrapNoscriptImages(t){var n=Array.from(t.getElementsByTagName("img"));this._forEachNode(n,(function(t){for(var n=0;n0&&a>r)return false;if(t.parentNode.tagName===n&&(!i||i(t.parentNode)))return true;t=t.parentNode,a++;}return false},_getRowAndColumnCount(t){for(var n=0,r=0,i=t.getElementsByTagName("tr"),a=0;a=10||s.columns>4?i._readabilityDataTable=true:i._readabilityDataTable=s.rows*s.columns>10:i._readabilityDataTable=false;}}}else i._readabilityDataTable=false;else i._readabilityDataTable=false;}},_fixLazyImages(t){this._forEachNode(this._getAllNodesWithTag(t,["img","picture","figure"]),(function(t){if(t.src&&this.REGEXPS.b64DataUrl.test(t.src)){var n=this.REGEXPS.b64DataUrl.exec(t.src);if("image/svg+xml"===n[1])return;for(var r=false,i=0;ii+=this._getInnerText(t,true).length)),i/r},_cleanConditionally(t,n){this._flagIsActive(this.FLAG_CLEAN_CONDITIONALLY)&&this._removeNodes(this._getAllNodesWithTag(t,[n]),(function(t){var isDataTable=function(t){return t._readabilityDataTable},r="ul"===n||"ol"===n;if(!r){var i=0,a=this._getAllNodesWithTag(t,["ul","ol"]);this._forEachNode(a,(t=>i+=this._getInnerText(t).length)),r=i/this._getInnerText(t).length>.9;}if("table"===n&&isDataTable(t))return false;if(this._hasAncestorTag(t,"table",-1,isDataTable))return false;if(this._hasAncestorTag(t,"code"))return false;if([...t.getElementsByTagName("table")].some((t=>t._readabilityDataTable)))return false;var s=this._getClassWeight(t);this.log("Cleaning Conditionally",t);if(s+0<0)return true;if(this._getCharCount(t,",")<10){for(var o=t.getElementsByTagName("p").length,l=t.getElementsByTagName("img").length,c=t.getElementsByTagName("li").length-100,d=t.getElementsByTagName("input").length,u=this._getTextDensity(t,["h1","h2","h3","h4","h5","h6"]),h=0,p=this._getAllNodesWithTag(t,["object","embed","iframe"]),g=0;g{const t=[];return !S&&l>1&&o/l<.5&&t.push(`Bad p to img ratio (img=${l}, p=${o})`),!r&&c>o&&t.push(`Too many li's outside of a list. (li=${c} > p=${o})`),d>Math.floor(o/3)&&t.push(`Too many inputs per p. (input=${d}, p=${o})`),!r&&!S&&u<.9&&w<25&&(0===l||l>2)&&E>0&&t.push(`Suspiciously short. (headingDensity=${u}, img=${l}, linkDensity=${E})`),!r&&s<25&&E>.2+this._linkDensityModifier&&t.push(`Low weight and a little linky. (linkDensity=${E})`),s>=25&&E>.5+this._linkDensityModifier&&t.push(`High weight and mostly links. (linkDensity=${E})`),(1===h&&w<75||h>1)&&t.push(`Suspicious embed. (embedCount=${h}, contentLength=${w})`),0===l&&0===A&&t.push(`No useful content. (img=${l}, textDensity=${A})`),!!t.length&&(this.log("Checks failed",t),true)})();if(r&&x){for(var C=0;C1)return x}let n=t.getElementsByTagName("li").length;if(l==n)return false}return x}return false}));},_cleanMatchedNodes(t,n){for(var r=this._getNextNode(t,true),i=this._getNextNode(t);i&&i!=r;)i=n.call(this,i,i.className+" "+i.id)?this._removeAndGetNext(i):this._getNextNode(i);},_cleanHeaders(t){let n=this._getAllNodesWithTag(t,["h1","h2"]);this._removeNodes(n,(function(t){let n=this._getClassWeight(t)<0;return n&&this.log("Removing header with low class weight:",t),n}));},_headerDuplicatesTitle(t){if("H1"!=t.tagName&&"H2"!=t.tagName)return false;var n=this._getInnerText(t,false);return this.log("Evaluating similarity of header:",n,this._articleTitle),this._textSimilarity(this._articleTitle,n)>.75},_flagIsActive(t){return (this._flags&t)>0},_removeFlag(t){this._flags=this._flags&~t;},_isProbablyVisible:t=>(!t.style||"none"!=t.style.display)&&(!t.style||"hidden"!=t.style.visibility)&&!t.hasAttribute("hidden")&&(!t.hasAttribute("aria-hidden")||"true"!=t.getAttribute("aria-hidden")||t.className&&t.className.includes&&t.className.includes("fallback-image")),parse(){if(this._maxElemsToParse>0){var t=this._doc.getElementsByTagName("*").length;if(t>this._maxElemsToParse)throw new Error("Aborting parsing document; "+t+" elements found")}this._unwrapNoscriptImages(this._doc);var n=this._disableJSONLD?{}:this._getJSONLD(this._doc);this._removeScripts(this._doc),this._prepDocument();var r=this._getArticleMetadata(n);this._metadata=r,this._articleTitle=r.title;var i=this._grabArticle();if(!i)return null;if(this.log("Grabbed: "+i.innerHTML),this._postProcessContent(i),!r.excerpt){var a=i.getElementsByTagName("p");a.length&&(r.excerpt=a[0].textContent.trim());}var s=i.textContent;return {title:this._articleTitle,byline:r.byline||this._articleByline,dir:this._articleDir,lang:this._articleLang,content:this._serializer(i),textContent:s,length:s.length,excerpt:r.excerpt,siteName:r.siteName||this._articleSiteName,publishedTime:r.publishedTime}}},t.exports=Readability;}(Ve)),Ve.exports}var $e,Ge,He,Fe={exports:{}};var je=function requireReadability(){if(He)return Ge;He=1;var t=requireReadability$1(),n=function requireReadabilityReaderable(){return $e||($e=1,function(){var t={unlikelyCandidates:/-ad-|ai2html|banner|breadcrumbs|combx|comment|community|cover-wrap|disqus|extra|footer|gdpr|header|legends|menu|related|remark|replies|rss|shoutbox|sidebar|skyscraper|social|sponsor|supplemental|ad-break|agegate|pagination|pager|popup|yom-remote/i,okMaybeItsACandidate:/and|article|body|column|content|main|shadow/i};function isNodeVisible(t){return (!t.style||"none"!=t.style.display)&&!t.hasAttribute("hidden")&&(!t.hasAttribute("aria-hidden")||"true"!=t.getAttribute("aria-hidden")||t.className&&t.className.includes&&t.className.includes("fallback-image"))}Fe.exports=function isProbablyReaderable(n,r={}){"function"==typeof r&&(r={visibilityChecker:r});var i={minScore:20,minContentLength:140,visibilityChecker:isNodeVisible};r=Object.assign(i,r);var a=n.querySelectorAll("p, pre, article"),s=n.querySelectorAll("div > br");if(s.length){var o=new Set(a);[].forEach.call(s,(function(t){o.add(t.parentNode);})),a=Array.from(o);}var l=0;return [].some.call(a,(function(n){if(!r.visibilityChecker(n))return false;var i=n.className+" "+n.id;if(t.unlikelyCandidates.test(i)&&!t.okMaybeItsACandidate.test(i))return false;if(n.matches("li p"))return false;var a=n.textContent.trim().length;return !(ar.minScore}))};}()),Fe.exports}();return Ge={Readability:t,isProbablyReaderable:n}}();const f=t=>null==t||""===t,_=(t,n)=>Object.keys(t).reduce(((t,r)=>(n(t[r])&&delete t[r],t)),t),ze=["",""],y=t=>((t,n)=>({...n,..._(t,f)}))(t,{sep:ze,fixationPoint:1,ignoreHtmlTag:true,ignoreHtmlEntity:true}),We=[[0,4,12,17,24,29,35,42,48],[1,2,7,10,13,14,19,22,25,28,31,34,37,40,43,46,49],[1,2,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49],[0,2,4,5,6,8,9,11,14,15,17,18,20,0,21,23,24,26,27,29,30,32,33,35,36,38,39,41,42,44,45,47,48],[0,2,3,5,6,7,8,10,11,12,14,15,17,19,20,21,23,24,25,26,28,29,30,32,33,34,35,37,38,39,41,42,43,44,46,47,48]],H=(t,n)=>{const{length:r}=t,i=We[n-1]??We[0],a=i.findIndex((t=>r<=t));let s=r-a;return -1===a&&(s=r-i.length),Math.max(s,0)},N=(t,n)=>"string"==typeof n?`${n}${t}${n}`:`${n[0]}${t}${n[1]}`,m=t=>Array.from(t).map((t=>{const n=t.index,[r]=t,{length:i}=r;return [n,n+i-1]})),qe=/()|(<[^>]*>)/g,Ke=/(&[\w#]+;)/g,Xe=/(\p{L}|\p{Nd})*\p{L}(\p{L}|\p{Nd})*/gu,U=(t,n={})=>{if(null==t||!t.length)return "";const{fixationPoint:r,sep:i,ignoreHtmlTag:a,ignoreHtmlEntity:s}=y(n),o=Array.from(t.matchAll(Xe));let l,c,d="",u=0;a&&(l=(t=>{const n=t.matchAll(qe),r=m(n).reverse();return t=>{const n=t.index,i=r.find((([t])=>n>t));if(!i)return false;const[,a]=i;return n{const n=t.matchAll(Ke),r=m(n).reverse();return t=>{const n=t.index,i=r.find((([t])=>n>t));if(!i)return false;const[,a]=i;return n{const t=findPrevNextChapterLinks(),n=Je({class:"config-chapter-link",style:"display: none; justify-content: center; align-items: center; margin: 5px 0; gap: 10px;"});return t.previous||t.next?(n.appendChild(chapterButton("<",t.previous)),n.appendChild(configButton()),n.appendChild(chapterButton(">",t.next))):n.appendChild(configButton()),n},visbile=()=>{Array.from(document.querySelectorAll("*")).map((t=>t.shadowRoot)).filter((t=>null!==t)).forEach((t=>{t?.querySelectorAll(".config-chapter-link").forEach((t=>{t.style.display="flex";}));}));},configButton=()=>{const t=Qe({class:"icon",style:'background-image: url(\'data:image/svg+xml;utf8,\'); width: 20px; height: 20px; display: block; background-size: contain;'});return Ye({onclick:()=>replaceAppState({openReaderConfig:true}),style:"height: 30px; min-width: 30px; display: flex; align-items: center; justify-content: center;"},t)},chapterButton=(t,n)=>Ye({disable:!n,onclick:()=>{if(n)if(isValidUrl(n))window.location.href=n;else {const t=findElementByIndicators([n]);t&&t.element&&t.element.click();}},style:"height: 30px; min-width: 30px; display: flex; align-items: center; justify-content: center;"},t),{div:Ze}=p.tags;e("reader-view",(({mount:t})=>{const n=Ze({class:"content-container"}),r=p.state(false);return t((()=>((async()=>{const t=await(async t=>{try{return await db_get(`translated:${t}`)}catch(n){return null}})(window.location.href);if(p.derive((()=>{r.val=me.readerView.bionicReading,t&&(n.innerHTML=true===r.val?U(t):t,visbile());})),!t){n.innerText="[Xin đợi...]";const t=document.cloneNode(true),i=new je.Readability(t).parse();await translateFunc(i?.textContent,(t=>{n.innerHTML=!0===r.val?U(t):t;})),visbile();}})(),()=>{p.derive((async()=>{ true===ge.isTranslating&&(ge.isTranslating=false,window.location.reload());}));}))),[render,n,render]}),false);const{div:et,select:tt,option:nt,textarea:rt,label:it,button:at}=p.tags,st=p.state("");function showSavedFeedback(){st.val="Saved",setTimeout((()=>{st.val="";}),2e3);}function PromptSelector({lbl:t,prompts:n,onSelect:r,onContentChange:i}){const a=n.find((t=>t.selected))||n[0],s=p.state(a?.content||"");return et({class:"pure-g",style:"padding: 0 0.5em; margin-bottom: 0.5em;"},et({class:"pure-u-1"},it({class:""},t),et({class:"pure-form pure-form-stacked"},et({class:"pure-g",style:"padding-right: 1em"},et({class:"pure-u-20-24"},tt({class:"pure-input-1",value:a?.name,onchange:t=>{const i=t.target.value;r(i);const a=n.find((t=>t.name===i));s.val=a?.content||"",showSavedFeedback();}},...n.map((t=>nt({value:t.name},t.name))))),et({class:"pure-u-4-24"},at({class:"pure-button",style:"margin-left: 0.5em; width: 40px; height: 30.5px; margin-top: 4px; padding: 0; line-height: 2.3em;"},"+"))))),et({class:"pure-u-1",style:"padding-right: 1em"},rt({class:"pure-input-1",style:"height: 150px; margin-top: 1em; resize: vertical; display: block; box-sizing: border-box; width: 100%;",value:s,onblur:t=>{const n=t.target.value;s.val=n,a&&i(a.name,n),showSavedFeedback();}})))}function getCacheKey(t){return t.isCustom?`models_cache_custom_${btoa(t.baseUrl).slice(0,16)}`:`models_cache_${t.name.toLowerCase().replace(/\s+/g,"_")}`}function normalizeBaseUrl(t){return t.trim().replace(/\/+$/,"")}async function fetchModelsFromApi(t){const n=function ensureV1Path(t){const n=normalizeBaseUrl(t);return /\/(v1|v1beta|openai)$/i.test(n)?n:`${n}/v1`}(t.baseUrl),r=await function gmFetch(t){return new Promise(((n,r)=>{de.xmlHttpRequest({method:t.method,url:t.url,headers:t.headers,timeout:t.timeout||1e4,onload:t=>n({status:t.status,responseText:t.responseText}),onerror:()=>r(new Error("Network error")),ontimeout:()=>r(new Error("Request timeout"))});}))}({method:"GET",url:`${n}/models`,headers:{Authorization:`Bearer ${t.apiKey}`,"Content-Type":"application/json"},timeout:1e4});if(401===r.status)throw new Error("Invalid API key");if(403===r.status)throw new Error("Quota exceeded or access forbidden");if(404===r.status)throw new Error("Models endpoint not supported");if(200!==r.status)throw new Error(`HTTP ${r.status}`);return JSON.parse(r.responseText).data.map((t=>t.id)).filter((t=>!t.includes("embed")&&!t.includes("tts")&&!t.includes("whisper"))).slice(0,50)}async function fetchModels(t,n=false){const r=function getDefaultModels(t){const n=getPresetByName(t);return n?.defaultModels||[]}(t.name);if(!(false!==t.supportsModelsEndpoint))return {models:r,fromCache:false};if(!t.apiKey)return {models:r,fromCache:false,error:"API key required"};if(!n){const n=await async function getCachedModels(t){const n=getCacheKey(t),r=await de.getValue(n);if(!r)return null;try{const t=JSON.parse(r);return Date.now()>t.expiresAt?(await de.deleteValue(n),null):t.models}catch{return await de.deleteValue(n),null}}(t);if(n&&n.length>0)return {models:n,fromCache:true}}try{const n=await fetchModelsFromApi(t);return await async function cacheModels(t,n){const r=getCacheKey(t),i={providerId:r,models:n,expiresAt:Date.now()+864e5};await de.setValue(r,JSON.stringify(i));}(t,n),{models:n,fromCache:!1}}catch(i){return {models:r,fromCache:false,error:i instanceof Error?i.message:"Unknown error"}}}function toProviderModels(t,n){return t.map(((t,r)=>({name:t,selected:n?t===n:0===r})))}const{div:ot,select:lt,option:ct,textarea:dt,label:ut,input:ht,style:pt,button:mt,span:gt,h4:ft}=p.tags;function AiProviderTab(){const t=p.state(""),n=p.state(false),r=p.state(""),i=p.state("list"),a=p.state(""),s=p.state(""),o=p.state(""),l=p.state(""),c=p.state([]),showSavedMessage=()=>{t.val="Saved",setTimeout((()=>t.val=""),2e3);},handleProviderChange=t=>{const n=t.target.value;"__add_new__"===n?(i.val="add",a.val="",s.val="",o.val="",l.val="",c.val=[],r.val=""):(i.val="list",me.providers.forEach((t=>{t.selected=t.name===n;})),showSavedMessage());},handleModelChange=t=>{const n=me.providers.find((t=>t.selected));if(n){const r=t.target.value;n.models.forEach((t=>{t.selected=t.name===r;})),showSavedMessage();}},handleApiKeyChange=t=>{const n=me.providers.find((t=>t.selected));n&&(n.apiKey=t.target.value,showSavedMessage());},handleBaseUrlChange=t=>{const n=me.providers.find((t=>t.selected));n&&(n.baseUrl=normalizeBaseUrl(t.target.value),showSavedMessage());},handleFetchModels=async()=>{const t=me.providers.find((t=>t.selected));if(!t)return;n.val=true,r.val="";const i=await fetchModels(t,true);n.val=false,i.error&&(r.val=i.error),i.models.length>0&&(t.models=toProviderModels(i.models,t.models.find((t=>t.selected))?.name),showSavedMessage());},handleFetchCustomModels=async()=>{if(!s.val||!o.val)return void(r.val="Please enter Base URL and API Key first");n.val=true,r.val="";const t={name:"temp",baseUrl:normalizeBaseUrl(s.val),apiKey:o.val,models:[],selected:false,isCustom:true,supportsModelsEndpoint:true},i=await fetchModels(t,true);n.val=false,i.error?(r.val=i.error,c.val=i.models):(c.val=i.models,r.val="");},handleSaveCustomProvider=()=>{const t=normalizeBaseUrl(s.val);let n=l.val.trim();if(c.val.length>0&&!n){const t=document.getElementById("custom-model-select");n=t?.value||c.val[0];}if(!t||!o.val||!n)return void(r.val="Please fill in Base URL, API Key, and Model");let d=a.val.trim();if(!d)try{d=`${new URL(t).hostname.replace(/^api\./,"").split(".")[0]}/${n}`.slice(0,30);}catch{d=`custom/${n}`.slice(0,30);}const u={name:d,baseUrl:t,apiKey:o.val,models:c.val.length>0?toProviderModels(c.val,n):[{name:n,selected:true}],selected:true,isCustom:true,supportsModelsEndpoint:true};me.providers.forEach((t=>t.selected=false)),me.providers.push(u),i.val="list",a.val="",s.val="",o.val="",c.val=[],l.val="",r.val="",showSavedMessage();},handleDeleteProvider=()=>{const t=me.providers.find((t=>t.selected));if(!t||!t.isCustom)return;const n=me.providers.indexOf(t);n>-1&&(me.providers.splice(n,1),me.providers.length>0&&(me.providers[0].selected=true),showSavedMessage());},handleCancelAdd=()=>{i.val="list",r.val="";const t=me.providers.some((t=>t.selected));!t&&me.providers.length>0&&(me.providers[0].selected=true);};return ot(ot({class:"pure-g",style:"padding: 0 0.5em;"},ot({class:"pure-u-1"},ot({class:"pure-form pure-form-stacked"},(()=>"add"===i.val?ot({class:"custom-provider-form"},ft({style:"margin-top: 0;"},"Add Custom Provider"),ot({class:"pure-control-group"},ut({class:"form-label"},"Name (optional)"),ht({type:"text",class:"pure-input-1",placeholder:"My Custom API",id:"custom-name-input",oninput:t=>{a.val=t.target.value;}})),ot({class:"pure-control-group"},ut({class:"form-label"},"Base URL *"),ht({type:"text",class:"pure-input-1",placeholder:"https://api.example.com/v1",id:"custom-baseurl-input",oninput:t=>{s.val=t.target.value;}})),ot({class:"pure-control-group"},ut({class:"form-label"},"API Key *"),dt({class:"pure-input-1",placeholder:"sk-...",id:"custom-apikey-input",rows:3,oninput:t=>{o.val=t.target.value;}})),ot({class:"pure-control-group"},mt({class:"pure-button pure-button-primary",onclick:handleFetchCustomModels},(()=>n.val?"Loading...":"Fetch Models"))),(()=>r.val?ot({class:"error-message"},r.val):null),(()=>c.val.length>0?ot({class:"pure-control-group"},ut({class:"form-label"},"Model"),lt({class:"pure-input-1",id:"custom-model-select",onchange:t=>{const n=t.target;l.val=n.value;}},...c.val.map(((t,n)=>ct({value:t,selected:0===n},t))))):null),(()=>r.val&&0===c.val.length?ot({class:"pure-control-group"},ut({class:"form-label"},"Model (manual) *"),ht({type:"text",class:"pure-input-1",placeholder:"gpt-4o",id:"custom-model-input",oninput:t=>{l.val=t.target.value;}})):null),ot({class:"pure-control-group",style:"display: flex; gap: 10px;"},mt({class:"pure-button button-success",onclick:handleSaveCustomProvider},"Save Provider"),mt({class:"pure-button",onclick:handleCancelAdd},"Cancel"))):(()=>{const t=me.providers.find((t=>t.selected)),i=true===t?.isCustom,a=t?getPresetByName(t.name):null;return ot(ot({class:"pure-control-group"},ut({class:"form-label"},"Provider"),lt({class:"pure-input-1",onchange:handleProviderChange},...me.providers.map((t=>ct({selected:t.selected,value:t.name},t.name+(t.isCustom?" ★":"")))),ct({value:"__add_new__"},"+ Add Custom Provider..."))),ot({class:"pure-control-group"},ut({class:"form-label"},"Base URL"),ot({class:"pure-g"},ot({class:"pure-u-19-24"},ht({type:"text",class:"pure-input-1",value:t?.baseUrl||"",onblur:handleBaseUrlChange})),ot({class:"pure-u-5-24",style:"padding-left: 5px;"},a?mt({class:"pure-button",title:"Reset to default",onclick:()=>{t&&a&&(t.baseUrl=a.baseUrl,showSavedMessage());}},"Reset"):null))),ot({class:"pure-control-group"},ut({class:"form-label"},"Model"),ot({class:"pure-g"},ot({class:"pure-u-19-24"},lt({class:"pure-input-1",onchange:handleModelChange},...(t?.models||[]).map((t=>ct({selected:t.selected,value:t.name},t.name))))),ot({class:"pure-u-5-24",style:"padding-left: 5px;"},mt({class:"pure-button",disabled:n.val,title:"Fetch latest models from API",onclick:handleFetchModels},(()=>n.val?"...":"Fetch")))),(()=>r.val?gt({class:"error-message"},r.val):null)),ot({class:"pure-control-group"},ut({class:"form-label"},"API Key"),dt({rows:4,class:"pure-input-1",placeholder:"Enter your API key",value:t?.apiKey||"",onblur:handleApiKeyChange})),i?ot({class:"pure-control-group"},mt({class:"pure-button button-danger",onclick:handleDeleteProvider},"Delete This Provider")):null,t?.note?ot({class:"pure-control-group"},ot({innerHTML:t.note})):null)})()),ot({class:"pure-control-group",style:"margin: 5px 0px;"},ut({class:"pure-checkbox"},ht({type:"checkbox",checked:me.isVietPharseFirst&&true===me.isVietPharseFirst,onchange:t=>{me.isVietPharseFirst=t.target.checked;}})," Use VietPhrase to translate first?")),ut({class:"saved-message"},(()=>t.val))))),pt("\n .ai-provider-container {\n max-width: 600px;\n margin: 0 auto;\n }\n .form-label {\n display: block;\n margin-bottom: 0.5rem;\n font-weight: 500;\n color: #333;\n }\n .saved-message {\n color: #00aa00;\n margin: 0.5rem 0;\n font-size: 0.9rem;\n font-weight: bold;\n text-align: center;\n display: block;\n }\n textarea.pure-input-1 {\n resize: none;\n min-height: 100px;\n }\n .custom-provider-form {\n padding: 1rem;\n background: #f9f9f9;\n border-radius: 4px;\n margin: 0.5rem 0;\n border: 1px solid #ddd;\n }\n .error-message {\n color: #cc0000;\n padding: 0.5rem 0;\n font-size: 0.9rem;\n }\n button:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n .button-success {\n background: #1cb841 !important;\n color: white !important;\n }\n .button-danger {\n background: #ca3c3c !important;\n color: white !important;\n }\n "))}const{div:bt,label:vt,button:yt}=p.tags;function VersionTab(){const t=p.state("");return [bt({class:"pure-form pure-form-stacked"},[bt({class:"pure-g",style:"padding: 0px 0.5em;"},[bt({class:"pure-u-1 pure-u-md-1-2 pure-u-lg-1-3"},[vt({class:"pure-u-1"},`Current version: ${me.version}`),bt({innerHTML:t,class:"pure-u-1",style:"margin-bottom:20px;border: 1px solid #ccc; min-height: 150px; background: #fff;"}),yt({onclick:async()=>{t.val=await async function displayVersion(t=false){const n=await getRelease(t);return `Latest version: ${n.version}
Link download: dichtruyen.ai.vn.user.js
${n.description}`}(true);},class:"pure-button pure-button-primary pure-u-1",style:"margin-bottom: 10px"},"Check Update"),yt({onclick:async()=>await mergeSystemPrompt(me),class:"pure-button button-success pure-u-1",style:"margin-bottom: 10px"},"Update System Prompt"),yt({onclick:async()=>await mergeProviders(me),class:"pure-button button-success pure-u-1",style:"margin-bottom: 10px"},"Update AI Providers")])])])]}const{div:_t,style:wt}=p.tags;e("settings-view",(()=>[wt("\n .tbbt.active{\n background-color:rgba(58, 119, 224, 0.88) !important;\n }\n "),_t({id:"settings-container"},Tabs({style:"max-width: 500px;",tabButtonBorderStyle:"none",tabButtonClass:"tbbt",tabButtonRowColor:"none",tabButtonRowStyleOverrides:{"padding-left":"12px"}},{Prompt:[et({class:"pure-g"},et({class:"pure-u-1"},PromptSelector({lbl:"System Prompts",prompts:me.prompt.systemPrompts.map((t=>({name:t.name,content:t.content||"",selected:t.selected}))),onSelect:t=>{me.prompt.systemPrompts.forEach((n=>n.selected=n.name===t));},onContentChange:(t,n)=>{const r=me.prompt.systemPrompts.find((n=>n.name===t));r&&(r.content=n);}}),PromptSelector({lbl:"User Prompts",prompts:me.prompt.userPrompts.map((t=>({name:t.name,content:t.content||"",selected:t.selected}))),onSelect:t=>{me.prompt.userPrompts.forEach((n=>n.selected=n.name===t));},onContentChange:(t,n)=>{const r=me.prompt.userPrompts.find((n=>n.name===t));r&&(r.content=n);}}))),it({id:"lblRs1",class:"pure-form-message-inline",style:"color: green; text-align: center; display: block; width: 100%"},st)],AI:AiProviderTab,Update:VersionTab()}))]),false);const{div:Et}=p.tags,CurrentView=()=>{const t=Et();return p.derive((()=>{if("empty"!==ge.currentView){if(t.id="view",t.childElementCount>0)for(const r of t.childNodes)r.remove();const n=document.createElement(`${ge.currentView}-view`);t.appendChild(n);}else if(t.id="",t.childElementCount>0)for(const n of t.childNodes)n.remove();})),t},{style:Nt}=p.tags;await( async function initStore(){const t=await de.getValue("dichtruyen-ai"),n=await getRelease(true);if(t){let i=JSON.parse(t);const a=0==i.prompt.systemPrompts.length||0===i.providers.length;if(i.version!==n.version||a)try{i.version=n.version,i=await mergeSystemPrompt(i),i=await mergeProviders(i),pe=i;}catch(r){}else pe=i;}else {const t=await getSystemPrompt(),n=he;n.prompt.systemPrompts.push({id:"default-0",name:"Default",content:t,selected:true}),n.providers=ue.filter((t=>"custom"!==t.id)).map(((t,n)=>({...presetToProvider(t),selected:0===n}))),pe=n;}replace(me,pe),p.derive((async()=>{await de.setValue("dichtruyen-ai",JSON.stringify(compact(me)));}));}()),e("dichtruyen-ai",(()=>{const t=p.derive((()=>{const t="black"===me.readerView.backgroundColor?"white":"black";return `\n reader-view {\n background-color: ${me.readerView.backgroundColor} !important;\n }\n .content-container {\n font-family: ${me.readerView.fontFamily} !important;\n line-height: ${me.readerView.lineHeight};\n font-size: ${me.readerView.fontSize}px;\n color: ${t};\n margin: 5px auto;\n padding: 10px;\n box-sizing: border-box;\n width: 100%;\n max-width: 800px;\n white-space: pre-wrap;\n }\n .article-title {\n font-size: 1.5em;\n font-weight: bold;\n margin-bottom: 1em;\n text-align: center;\n }\n `}));return [Nt("\n :host {\n display: block;\n height: 100%;\n width: 100%;\n pointer-events: all;\n }\n #bottom-bar {\n position: fixed;\n bottom: 0;\n left: 0;\n right: 0;\n background-color: white;\n box-shadow: 0 -2px 5px rgba(0,0,0,0.1);\n padding: 10px;\n display: flex;\n justify-content: center;\n gap: 20px;\n width: 100%;\n height: auto;\n min-height: 60px;\n box-sizing: border-box;\n -webkit-overflow-scrolling: touch;\n pointer-events: auto;\n isolation: isolate;\n z-index: 9999;\n }\n .icon-button {\n background: none;\n border: none;\n cursor: pointer;\n padding: 8px;\n border-radius: 50%;\n background-color: white;\n box-shadow: 0 2px 5px rgba(0,0,0,0.2);\n touch-action: manipulation;\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n z-index: 1;\n }\n .icon {\n display: inline-block;\n width: 24px;\n height: 24px;\n background-size: contain;\n background-repeat: no-repeat;\n vertical-align: middle;\n }\n #mdlReaderContainer p{\n margin: 5px 0px;\n }\n "),Nt("\n #view {\n width: 100%;\n height: 100%;\n background-color: white;\n }\n history-view, settings-view, reader-view {\n display: block;\n width: 100%;\n\n overflow-y: auto;\n -webkit-overflow-scrolling: touch;\n z-index: 9999;\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 60px;\n overflow-y: auto;\n -webkit-overflow-scrolling: touch;\n background-color: white;\n }\n "),Nt(t),Await({value:fetchResource("https://cdn.jsdelivr.net/npm/purecss@3.0.0/build/pure-min.css"),container:Nt,Loading:()=>""},(t=>t)),Nt("\n .button-success,\n .button-error,\n .button-warning,\n .button-secondary {\n color: white;\n border-radius: 4px;\n text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);\n }\n\n .button-success {\n background: rgb(28, 184, 65);\n /* this is a green */\n }\n\n .button-error {\n background: rgb(202, 60, 60);\n /* this is a maroon */\n }\n\n .button-warning {\n background: rgb(223, 117, 20);\n /* this is an orange */\n }\n\n .button-secondary {\n background: rgb(66, 184, 221);\n /* this is a light blue */\n } \n "),CurrentView(),ModalReaderConfig(),(p.derive((()=>{"reader"===ge.currentView&&(true===ge.isTranslating?changeIcon(Ee):changeIcon(_e));})),ve({id:"bottom-bar"},createIconButton(ye,(()=>changeView("history"))),createIconButton(_e,(()=>changeView("reader")),"transButton"),createIconButton(we,(()=>changeView("settings")))))]})),function addGoogleFonts(){let t=document.createElement("link");t.rel="stylesheet",t.href="https://fonts.googleapis.com/css2?family=Be+Vietnam+Pro:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Lora:ital,wght@0,400..700;1,400..700&family=Merriweather:ital,opsz,wght@0,18..144,300..900;1,18..144,300..900&family=Noto+Sans:ital,wght@0,100..900;1,100..900&family=Open+Sans:ital,wght@0,300..800;1,300..800&family=Playfair+Display:ital,wght@0,400..900;1,400..900&family=Roboto:ital,wght@0,100..900;1,100..900&family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap",window.parent.document.head.appendChild(t);}();const Tt=document.createElement("dichtruyen-ai");window.parent.document.body.appendChild(Tt); })();