var N={gemini:{apiKey:"",model:"gemini-3.1-flash-lite-preview"},chatgpt:{apiKey:"",model:"gpt-4.1-mini"},deepseek:{apiKey:"",model:"deepseek-chat"},qwen:{apiKey:"",model:"qwen3.5-flash"},kimi:{apiKey:"",model:"kimi-k2.5"}},z={llm:{activeProvider:"gemini",providers:{...N}},sensitivity:3,scanThreshold:"medium",chunkGranularity:"fine",chunkIntensity:5,disabledSites:[]},J={gemini:{format:"gemini",baseUrl:"",label:"Gemini"},chatgpt:{format:"openai-compatible",baseUrl:"https://api.openai.com",label:"ChatGPT"},deepseek:{format:"openai-compatible",baseUrl:"https://api.deepseek.com",label:"DeepSeek"},qwen:{format:"openai-compatible",baseUrl:"https://dashscope.aliyuncs.com/compatible-mode",label:"Qwen"},kimi:{format:"openai-compatible",baseUrl:"https://api.moonshot.cn",label:"Kimi"}};function R(e){let t=e.activeProvider,n=e.providers[t],r=J[t];return{format:r.format,apiKey:n.apiKey,baseUrl:r.baseUrl,model:n.model}}function Q(e){if(e&&typeof e=="object"&&"activeProvider"in e)return e;let t=e,n={...N};if(t?.apiKey){let r=t.format==="gemini"?"gemini":"chatgpt";return n[r]={apiKey:t.apiKey,model:t.model||N[r].model},{activeProvider:r,providers:n}}return{activeProvider:"gemini",providers:n}}var Y=10080*60*1e3;var ve="openen-cache",Re=1,f="chunks";function X(){return new Promise((e,t)=>{let n=indexedDB.open(ve,Re);n.onupgradeneeded=()=>{let r=n.result;r.objectStoreNames.contains(f)||r.createObjectStore(f,{keyPath:"hash"})},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)})}function Z(e){let t=2166136261;for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t=t*16777619>>>0;return t.toString(36)}async function ee(e){let t=new Map;try{let a=(await X()).transaction(f,"readonly").objectStore(f);await Promise.all(e.map(s=>new Promise(o=>{let c=Z(s),i=a.get(c);i.onsuccess=()=>{let l=i.result;l&&Date.now()-l.timestamp<=Y&&t.set(s,l.result),o()},i.onerror=()=>o()})))}catch{}return t}async function te(e){try{let r=(await X()).transaction(f,"readwrite").objectStore(f);for(let{sentence:a,result:s}of e){let o=Z(a);r.put({hash:o,result:s,timestamp:Date.now()})}}catch{}}var Pe=15e3;async function P(e,t,n=Pe){let r=new AbortController,a=setTimeout(()=>r.abort(),n);try{return await fetch(e,{...t,signal:r.signal})}finally{clearTimeout(a)}}function ke(e,t=[]){return`You are an English reading assistant. Your job is to restructure complex English sentences into indented chunks that reveal their grammatical structure, making them easier to parse visually.

## Rules

1. **Skeleton first**: The main clause (subject-verb-object) stays at the top level (no indentation).
2. **Indent subordinate elements**: Each level of nesting gets 2 more spaces of indentation:
   - Subordinate clauses (that, which, who, if, because, although, etc.)
   - Relative clauses
   - Conditional clauses
   - Temporal clauses
   - Participial phrases, prepositional phrases, and appositive phrases
3. **Simple sentences**: If a sentence has no subordinate clauses and is straightforward, return it unchanged with is_simple=true.
4. **Preserve original text**: Do not change any words. Only add line breaks and indentation. Do NOT add brackets, parentheses, or any other symbols that are not in the original text.

## New Words

${t.length>0?`The user already knows these words (do NOT mark them as new): ${t.join(", ")}`:"The user is at an advanced English level (IELTS 7+). Be very selective \u2014 only mark words that a proficient non-native reader would genuinely not know."}

For each sentence, identify words that the user likely doesn't know. Provide a brief Chinese definition for each.

Important constraints for new_words:
- Do NOT mark proper nouns, brand names, or product names (e.g. ChatGPT, Google, Tesla, iPhone)
- Do NOT mark common tech/internet terms (e.g. AI, API, app, blog, email, online)
- Do NOT mark words that appear in any standard 6000-word English vocabulary list
- Only mark words that would genuinely challenge an advanced reader \u2014 rare, literary, domain-specific, or highly idiomatic expressions
- When in doubt, do NOT mark it. Fewer is better.

## Input

${e.map((r,a)=>`[${a}] ${r}`).join(`
`)}

## Output Format

Return a JSON array with one object per input sentence, in the same order:

\`\`\`json
[
  {
    "index": 0,
    "original": "the original sentence",
    "chunked": "the chunked version with\\n  indentation\\n    and nested clauses",
    "is_simple": false,
    "new_words": [
      {"word": "example", "definition": "\u4F8B\u5B50\uFF0C\u5B9E\u4F8B"}
    ]
  }
]
\`\`\`

Important:
- Use \\n for line breaks in the chunked field
- Use spaces (not tabs) for indentation, 2 spaces per level
- Return valid JSON only, no markdown fences
- The array must have exactly ${e.length} elements`}var Se="https://generativelanguage.googleapis.com/v1beta/models";function re(e,t){let n=t.model||"gemini-2.0-flash";return{url:`${Se}/${n}:generateContent?key=${t.apiKey}`,body:{contents:[{parts:[{text:e}]}],generationConfig:{temperature:.1,responseMimeType:"application/json",thinkingConfig:{thinkingBudget:0}}}}}function ae(e,t){let r=`${t.baseUrl.replace(/\/+$/,"")}/v1/chat/completions`,a={model:t.model,messages:[{role:"system",content:"You are a helpful English reading assistant. Always respond with valid JSON."},{role:"user",content:e}]},s={"Content-Type":"application/json",Authorization:`Bearer ${t.apiKey}`};return{url:r,body:a,headers:s}}function Be(e){let n=e?.candidates?.[0]?.content?.parts?.[0]?.text;if(!n)throw new Error("Gemini \u8FD4\u56DE\u4E86\u7A7A\u54CD\u5E94");return se(n)}function Te(e){let n=e?.choices?.[0]?.message?.content;if(!n)throw new Error("OpenAI \u8FD4\u56DE\u4E86\u7A7A\u54CD\u5E94");return se(n)}function se(e){let t=e.trim(),n=t.match(/```(?:json)?\s*([\s\S]*?)```/);n&&(t=n[1].trim());let r;try{r=JSON.parse(t)}catch{throw new Error(`LLM \u8FD4\u56DE\u7684 JSON \u683C\u5F0F\u65E0\u6548: ${t.slice(0,100)}...`)}if(r&&typeof r=="object"&&!Array.isArray(r)){let a=r,s=Object.keys(a).find(o=>Array.isArray(a[o]));s&&(r=a[s])}if(!Array.isArray(r))throw new Error("LLM \u8FD4\u56DE\u7684\u4E0D\u662F\u6570\u7EC4\u683C\u5F0F");return r.map(a=>({index:a.index??0,original:a.original??"",chunked:a.chunked??a.original??"",is_simple:a.is_simple??!0,new_words:Array.isArray(a.new_words)?a.new_words:[]}))}function ne(e,t){return e.map((n,r)=>{let a=t.find(s=>s.index===r);return a?{original:a.original||n,chunked:a.chunked,isSimple:a.is_simple,newWords:a.new_words??[]}:{original:n,chunked:n,isSimple:!0,newWords:[]}})}async function oe(e,t,n=[]){let r=ke(e,n),a;if(t.format==="gemini"){let{url:s,body:o}=re(r,t),c=await P(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)});if(!c.ok){let l=await c.text();throw new Error(`Gemini API \u9519\u8BEF (${c.status}): ${l.slice(0,200)}`)}a=await c.json();let i=Be(a);return ne(e,i)}else{let{url:s,body:o,headers:c}=ae(r,t),i=await P(s,{method:"POST",headers:c,body:JSON.stringify(o)});if(!i.ok){let g=await i.text();throw new Error(`OpenAI API \u9519\u8BEF (${i.status}): ${g.slice(0,200)}`)}a=await i.json();let l=Te(a);return ne(e,l)}}var ie=["insertion","background_first","nested","long_list","inverted","long_subject","omission","contrast","condition","long_modifier","other"];function Ae(e){return`You are an English reading assistant for Chinese learners. Analyze the following English sentence in depth.

## Input sentence

${e}

## Output format

Return a single JSON object (NOT an array) with these fields:

\`\`\`json
{
  "chunked": "the chunked version with\\n  indentation",
  "pattern_key": "one of the allowed keys",
  "sentence_analysis": "\u7528\u4E2D\u6587\u89E3\u91CA\u8FD9\u53E5\u8BDD\u4E3A\u4EC0\u4E48\u96BE\u8BFB\uFF0C\u6307\u51FA\u54EA\u4E9B\u7ED3\u6784\u9020\u6210\u4E86\u9605\u8BFB\u969C\u788D",
  "expression_tips": "\u7528\u4E2D\u6587\u8BB2\u89E3\u8FD9\u53E5\u8BDD\u4E2D\u503C\u5F97\u5B66\u4E60\u7684\u8868\u8FBE\u65B9\u5F0F\u548C\u53E5\u5F0F\uFF0C\u7528 **\u52A0\u7C97** \u6807\u6CE8\u5173\u952E\u8868\u8FBE",
  "new_words": [{"word": "example", "definition": "\u4F8B\u5B50\uFF0C\u5B9E\u4F8B"}],
  "is_worth_practicing": true
}
\`\`\`

## Rules

### chunked
- Main clause (subject-verb-object) at top level (no indentation)
- Indent subordinate elements with 2 spaces per level
- Preserve original text exactly, only add \\n and spaces

### pattern_key
Must be one of: ${ie.join(", ")}

### sentence_analysis & expression_tips
- Write in Chinese (\u4E2D\u6587)
- Be concise but insightful

### new_words
- Only words that a IELTS 7+ Chinese reader might not know
- Do NOT mark proper nouns, brand names, common tech terms
- Provide brief Chinese definitions

### is_worth_practicing
- true if the sentence has interesting structure worth studying
- false if it's straightforward despite being long

Return valid JSON only, no markdown fences.`}function Ce(e){let t=e.trim(),n=t.match(/```(?:json)?\s*([\s\S]*?)```/);n&&(t=n[1].trim());let r;try{r=JSON.parse(t)}catch{throw new Error(`LLM \u8FD4\u56DE\u7684 JSON \u683C\u5F0F\u65E0\u6548: ${t.slice(0,100)}...`)}let a=r,s=String(a.pattern_key||"other");return ie.includes(s)||(s="other"),{chunked:String(a.chunked||""),pattern_key:s,sentence_analysis:String(a.sentence_analysis||""),expression_tips:String(a.expression_tips||""),new_words:Array.isArray(a.new_words)?a.new_words.map(o=>({word:String(o.word||""),definition:String(o.definition||"")})):[],is_worth_practicing:!!a.is_worth_practicing}}function Ee(e,t){if(t==="gemini"){let r=e?.candidates?.[0]?.content?.parts?.[0]?.text;if(!r)throw new Error("Gemini \u8FD4\u56DE\u4E86\u7A7A\u54CD\u5E94");return r}else{let r=e?.choices?.[0]?.message?.content;if(!r)throw new Error("OpenAI \u8FD4\u56DE\u4E86\u7A7A\u54CD\u5E94");return r}}async function ce(e,t){let n=Ae(e),r;if(t.format==="gemini"){let{url:s,body:o}=re(n,t),c=await P(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)});if(!c.ok){let i=await c.text();throw new Error(`Gemini API \u9519\u8BEF (${c.status}): ${i.slice(0,200)}`)}r=await c.json()}else{let{url:s,body:o,headers:c}=ae(n,t),i=await P(s,{method:"POST",headers:c,body:JSON.stringify(o)});if(!i.ok){let l=await i.text();throw new Error(`OpenAI API \u9519\u8BEF (${i.status}): ${l.slice(0,200)}`)}r=await i.json()}let a=Ee(r,t.format);return Ce(a)}var Oe="openen-data";var d={vocab:"vocab",vocab_contexts:"vocab_contexts",patterns:"patterns",pattern_examples:"pattern_examples",learning_records:"learning_records",settings:"settings",weekly_reports:"weekly_reports",review_items:"review_items",wallpaper_records:"wallpaper_records",pending_sentences:"pending_sentences"};function S(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}var w=null;function de(e=indexedDB){return w?Promise.resolve(w):new Promise((t,n)=>{let r=e.open(Oe,2);r.onupgradeneeded=a=>{let s=r.result,o=a.oldVersion,c=r.transaction;Le(s,o,c)},r.onsuccess=()=>{w=r.result,w.onclose=()=>{w=null},t(w)},r.onerror=()=>n(r.error)})}function Le(e,t,n){t<1&&Me(e),t<2&&Ne(e,n)}function Me(e){let t=e.createObjectStore(d.vocab,{keyPath:"id"});t.createIndex("by_word","word",{unique:!0}),t.createIndex("by_status","status"),t.createIndex("by_updated_at","updated_at");let n=e.createObjectStore(d.vocab_contexts,{keyPath:"id"});n.createIndex("by_vocab_id","vocab_id"),n.createIndex("by_updated_at","updated_at");let r=e.createObjectStore(d.patterns,{keyPath:"id"});r.createIndex("by_key","key",{unique:!0}),r.createIndex("by_updated_at","updated_at");let a=e.createObjectStore(d.pattern_examples,{keyPath:"id"});a.createIndex("by_pattern_id","pattern_id"),a.createIndex("by_updated_at","updated_at");let s=e.createObjectStore(d.learning_records,{keyPath:"id"});s.createIndex("by_created_at","created_at"),s.createIndex("by_pattern_key","pattern_key"),s.createIndex("by_source_url","source_url"),s.createIndex("by_updated_at","updated_at"),e.createObjectStore(d.settings,{keyPath:"key"}).createIndex("by_updated_at","updated_at");let c=e.createObjectStore(d.weekly_reports,{keyPath:"id"});c.createIndex("by_week_start","week_start",{unique:!0}),c.createIndex("by_updated_at","updated_at");let i=e.createObjectStore(d.review_items,{keyPath:"id"});i.createIndex("by_type","type"),i.createIndex("by_reference_id","reference_id"),i.createIndex("by_next_review_at","next_review_at"),i.createIndex("by_updated_at","updated_at");let l=e.createObjectStore(d.wallpaper_records,{keyPath:"id"});l.createIndex("by_created_at","created_at"),l.createIndex("by_updated_at","updated_at")}function Ne(e,t){let n=e.createObjectStore(d.pending_sentences,{keyPath:"id"});n.createIndex("by_text","text",{unique:!0}),n.createIndex("by_analyzed","analyzed"),n.createIndex("by_created_at","created_at"),n.createIndex("by_source_hostname","source_hostname"),n.createIndex("by_manual","manual"),n.createIndex("by_updated_at","updated_at"),t.objectStore(d.learning_records).createIndex("by_sentence","sentence")}function I(e,t,n){return e.transaction(t,n).objectStore(t)}function D(e){return new Promise((t,n)=>{e.onsuccess=()=>t(e.result),e.onerror=()=>n(e.error)})}function le(e){return new Promise((t,n)=>{e.oncomplete=()=>t(),e.onerror=()=>n(e.error),e.onabort=()=>n(e.error)})}async function j(e,t,n){return D(I(e,t,"readonly").get(n))}async function k(e,t,n,r){let s=I(e,t,"readonly").index(n);return D(s.getAll(r))}async function B(e,t){return D(I(e,t,"readonly").getAll())}async function b(e,t,n){let r=e.transaction(t,"readwrite");r.objectStore(t).put(n),await le(r)}async function T(e,t,n){let r=e.transaction(t,"readwrite");r.objectStore(t).delete(n),await le(r)}async function K(e,t,n,r){let s=I(e,t,"readonly").index(n);return D(s.get(r))}var _={async add(e,t){let n=Date.now(),r={id:S(),encounter_count:1,first_seen_at:n,updated_at:n,is_dirty:!0,...t};return await b(e,d.vocab,r),r},async getById(e,t){return j(e,d.vocab,t)},async getByWord(e,t){return K(e,d.vocab,"by_word",t)},async getByStatus(e,t){return k(e,d.vocab,"by_status",t)},async getAll(e){return B(e,d.vocab)},async update(e,t,n){let r=await this.getById(e,t);if(!r)return;let a={...r,...n,id:t,updated_at:Date.now(),is_dirty:!0};return await b(e,d.vocab,a),a},async delete(e,t){await T(e,d.vocab,t)},async recordEncounter(e,t){let n=await this.getById(e,t);if(n)return this.update(e,t,{encounter_count:n.encounter_count+1})},async markMastered(e,t){return this.update(e,t,{status:"mastered",mastered_at:Date.now()})},async getMasteredWords(e){let t=await this.getByStatus(e,"mastered");return new Set(t.map(n=>n.word))}},ue={async add(e,t){let n=Date.now(),r={id:S(),created_at:n,updated_at:n,is_dirty:!0,...t};return await b(e,d.vocab_contexts,r),r},async getByVocabId(e,t){return k(e,d.vocab_contexts,"by_vocab_id",t)},async getAll(e){return B(e,d.vocab_contexts)},async delete(e,t){await T(e,d.vocab_contexts,t)}};var V={async add(e,t){let n=Date.now(),r={id:S(),created_at:n,updated_at:n,is_dirty:!0,...t};return await b(e,d.learning_records,r),r},async getById(e,t){return j(e,d.learning_records,t)},async getAll(e){return B(e,d.learning_records)},async getByPatternKey(e,t){return k(e,d.learning_records,"by_pattern_key",t)},async getBySourceUrl(e,t){return k(e,d.learning_records,"by_source_url",t)},async update(e,t,n){let r=await this.getById(e,t);if(!r)return;let a={...r,...n,id:t,updated_at:Date.now(),is_dirty:!0};return await b(e,d.learning_records,a),a},async delete(e,t){await T(e,d.learning_records,t)},async getBySentence(e,t){return K(e,d.learning_records,"by_sentence",t)},async getByDateRange(e,t,n){let a=I(e,d.learning_records,"readonly").index("by_created_at"),s=IDBKeyRange.bound(t,n);return D(a.getAll(s))}};var v={async add(e,t){if(await this.getByText(e,t.text))return null;let r=Date.now(),a={id:S(),analyzed:!1,created_at:r,updated_at:r,is_dirty:!0,...t};return await b(e,d.pending_sentences,a),a},async getById(e,t){return j(e,d.pending_sentences,t)},async getByText(e,t){return K(e,d.pending_sentences,"by_text",t)},async getAll(e){return B(e,d.pending_sentences)},async getUnanalyzed(e){return(await this.getAll(e)).filter(n=>!n.analyzed).sort((n,r)=>n.manual!==r.manual?n.manual?-1:1:r.created_at-n.created_at)},async getPage(e,t,n){let r=await this.getAll(e);r.sort((s,o)=>s.manual!==o.manual?s.manual?-1:1:o.created_at-s.created_at);let a=(t-1)*n;return{records:r.slice(a,a+n),total:r.length}},async markAnalyzed(e,t){let n=await this.getById(e,t);n&&await b(e,d.pending_sentences,{...n,analyzed:!0,updated_at:Date.now(),is_dirty:!0})},async delete(e,t){await T(e,d.pending_sentences,t)}};var U=new Map;async function ge(e){if(U.has(e))return U.get(e);let t=chrome.runtime.getURL(e),n=await fetch(t);if(!n.ok)throw new Error(`Failed to load ${e}: ${n.status}`);let r=await n.json();return U.set(e,r),r}var C=null,A=null;async function je(){C||(A||(A=ge("data/core-imagery.json").then(e=>{C=e}).catch(e=>{console.warn("[\u63B0it] \u6838\u5FC3\u610F\u8C61\u6570\u636E\u52A0\u8F7D\u5931\u8D25:",e),A=null})),await A)}async function pe(e){return await je(),C?C[e.toLowerCase()]??null:null}var me="phc_USA7kkQsvO2IHXCQiwsgy4Z58W7IP4eEKMxTpNFbBBD",ye="https://us.i.posthog.com",Ke={analyticsOptIn:null,installTimestamp:0};async function Ve(){return await chrome.storage.sync.get(Ke)}async function q(){return(await Ve()).analyticsOptIn===!0}async function be(){let t=(await chrome.storage.local.get("analyticsClientId")).analyticsClientId;return t||(t=crypto.randomUUID(),await chrome.storage.local.set({analyticsClientId:t})),t}var p=[];var Ue=20;function he(){chrome.alarms.create("analytics-flush",{periodInMinutes:.5}),chrome.alarms.onAlarm.addListener(e=>{e.name==="analytics-flush"&&W().catch(()=>{})}),qe().then(()=>{W().catch(()=>{})})}function fe(){chrome.storage.sync.get("installTimestamp",e=>{e.installTimestamp||chrome.storage.sync.set({installTimestamp:Date.now()})})}async function we(e,t){await q()&&(p.push({event:e,properties:t,timestamp:new Date().toISOString()}),await $(),p.length>=Ue&&await W())}async function W(){if(p.length===0)return;if(!await q()){p=[],await $();return}let t=await be(),n=p.splice(0);try{(await fetch(`${ye}/batch/`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({api_key:me,batch:n.map(a=>({event:a.event,properties:{...a.properties,distinct_id:t,$lib:"bait-chrome-extension"},timestamp:a.timestamp}))})})).ok||p.unshift(...n)}catch{p.unshift(...n)}await $()}async function $(){let e=p.slice(0,100);await chrome.storage.local.set({analyticsQueue:e})}async function qe(){let t=(await chrome.storage.local.get({analyticsQueue:[]})).analyticsQueue;t.length>0&&p.push(...t)}async function h(){let e=Object.keys(z),n=await chrome.storage.sync.get(e);return Array.isArray(n.disabledSites)||(n.disabledSites=[]),n.chunkGranularity||(n.chunkGranularity="fine"),n.llm=Q(n.llm),n}async function We(e){let t=await h(),n={...t,...e};return e.llm&&(n.llm={...t.llm,...e.llm}),await chrome.storage.sync.set(n),n}function O(e){try{return new URL(e).hostname}catch{return""}}async function L(e){return!(await h()).disabledSites.includes(e)}async function G(){return(await chrome.storage.sync.get({globalEnabled:!0})).globalEnabled}async function $e(){let t=!await G();return await chrome.storage.sync.set({globalEnabled:t}),t}async function Ge(e){let t=await h(),n=t.disabledSites.indexOf(e),r;return n>=0?(t.disabledSites.splice(n,1),r=!0):(t.disabledSites.push(e),r=!1),await chrome.storage.sync.set({disabledSites:t.disabledSites}),{enabled:r,disabledSites:t.disabledSites}}async function m(e,t){let n=t?"-on":"";try{await chrome.action.setIcon({path:{16:`icons/icon16${n}.png`,48:`icons/icon48${n}.png`,128:`icons/icon128${n}.png`},tabId:e})}catch{}}async function M(e){return(await chrome.storage.session.get({pausedTabs:[]})).pausedTabs.includes(e)}async function xe(e){let n=(await chrome.storage.session.get({pausedTabs:[]})).pausedTabs;n.includes(e)||(n.push(e),await chrome.storage.session.set({pausedTabs:n}))}async function F(e){let n=(await chrome.storage.session.get({pausedTabs:[]})).pausedTabs.filter(r=>r!==e);await chrome.storage.session.set({pausedTabs:n})}chrome.tabs.onRemoved.addListener(async e=>{await F(e)});async function Ie(e,t){let n=t?O(t):"";if(!n)return!1;let[r,a,s]=await Promise.all([G(),L(n),M(e)]);return r&&a&&!s}async function De(e,t){await m(e,await Ie(e,t))}var u=null,Fe=50,He=5;function ze(e,t){return new Promise(n=>{u||(u={sentences:[],source_url:t,resolvers:new Map,timer:null}),u.sentences.push(e),u.resolvers.set(e,n),u.timer&&clearTimeout(u.timer),u.sentences.length>=He?_e():u.timer=setTimeout(_e,Fe)})}async function _e(){if(!u||u.sentences.length===0)return;let e=u;u=null,e.timer&&clearTimeout(e.timer);try{let t=await h(),n=R(t.llm);if(!n.apiKey)throw new Error("API key \u672A\u914D\u7F6E");let r=await oe(e.sentences,n),a=r.map((s,o)=>({sentence:e.sentences[o],result:s}));te(a).catch(()=>{});for(let s=0;s<r.length;s++){let o=e.resolvers.get(e.sentences[s]);o&&o(r[s])}Je(r.filter(s=>!s.isSimple).length)}catch{for(let[t,n]of e.resolvers)n({original:t,chunked:t,isSimple:!0,newWords:[]})}}async function Je(e){let t=new Date().toISOString().slice(0,10),n=await chrome.storage.local.get({statsDate:"",todayChunked:0});n.statsDate!==t?await chrome.storage.local.set({statsDate:t,todayChunked:e}):await chrome.storage.local.set({todayChunked:n.todayChunked+e})}var x=null;async function E(){return x||(x=await de(),x.onclose=()=>{x=null},x)}async function Qe(e){let t=await E(),n=await h(),r=R(n.llm);if(r.apiKey)for(let a=0;a<e.length;a++){let s=e[a];try{let o=await v.getById(t,s);if(!o||o.analyzed)continue;let c=await V.getBySentence(t,o.text);if(c){await v.markAnalyzed(t,s),chrome.runtime.sendMessage({type:"sentenceAnalyzed",pendingId:s,learningRecord:c}).catch(()=>{});continue}let i=await ce(o.text,r),l=await V.add(t,{sentence:o.text,chunked:i.chunked,sentence_analysis:i.sentence_analysis,expression_tips:i.expression_tips,pattern_key:i.pattern_key,new_words:i.new_words,source_url:o.source_url,llm_provider:n.llm.activeProvider});await v.markAnalyzed(t,s),chrome.runtime.sendMessage({type:"sentenceAnalyzed",pendingId:s,learningRecord:l}).catch(()=>{})}catch(o){chrome.runtime.sendMessage({type:"sentenceAnalysisFailed",pendingId:s,error:o instanceof Error?o.message:"Unknown error"}).catch(()=>{})}a<e.length-1&&await new Promise(o=>setTimeout(o,500))}}chrome.runtime.onMessage.addListener((e,t,n)=>(Ye(e,t).then(r=>{try{n(r)}catch{}}),!0));async function Ye(e,t){switch(e.type){case"chunk":{let{sentences:n,source_url:r}=e,a=await ee(n),s=n.filter(i=>!a.has(i));if(s.length===0)return{results:n.map(i=>a.get(i))};let o=await Promise.all(s.map(i=>ze(i,r))),c=new Map;return s.forEach((i,l)=>c.set(i,o[l])),{results:n.map(i=>a.get(i)??c.get(i))}}case"checkActive":{let n=t.tab?.id;if(n===void 0)return{active:!1};let r=await Ie(n,t.tab?.url);return m(n,r),{active:r}}case"toggleSite":{let{hostname:n}=e,r=await Ge(n),a=await chrome.tabs.query({});for(let s of a)s.id&&s.url&&O(s.url)===n&&(m(s.id,r.enabled),chrome.tabs.sendMessage(s.id,{type:r.enabled?"activate":"deactivate"}).catch(()=>{}));return{enabled:r.enabled,disabledSites:r.disabledSites}}case"toggleGlobal":{let n=await $e(),r=await chrome.tabs.query({});for(let a of r){if(!a.id||!a.url)continue;let s=O(a.url);if(s)if(n){let o=await L(s),c=await M(a.id),i=o&&!c;m(a.id,i),i&&chrome.tabs.sendMessage(a.id,{type:"activate"}).catch(()=>{})}else m(a.id,!1),chrome.tabs.sendMessage(a.id,{type:"deactivate"}).catch(()=>{})}return{globalEnabled:n}}case"pauseTab":{let{tabId:n}=e;return await xe(n),m(n,!1),chrome.tabs.sendMessage(n,{type:"pause"}).catch(()=>{}),{ok:!0}}case"resumeTab":{let{tabId:n}=e;return await F(n),m(n,!0),chrome.tabs.sendMessage(n,{type:"resume"}).catch(()=>{}),{ok:!0}}case"getTabState":{let{tabId:n,hostname:r}=e;return await M(n)?{state:"paused"}:(r?await L(r):!1)?{state:"active"}:{state:"disabled"}}case"hasApiKey":{let n=await h();return{hasKey:!!R(n.llm).apiKey}}case"getConfig":return h();case"updateConfig":return We(e.config);case"saveSentence":try{let n=await E();return{ok:!0,saved:await v.add(n,{text:e.text,source_url:e.source_url,source_hostname:e.source_hostname,manual:e.manual,new_words:e.new_words})!==null}}catch{return{ok:!0,saved:!1}}case"analyzeSentences":{let{sentenceIds:n}=e;return Qe(n).catch(()=>{}),{ok:!0}}case"getImagery":return{imagery:await pe(e.word)};case"markMastered":try{let n=await E(),r=await _.getByWord(n,e.word);return r&&await _.markMastered(n,r.id),{ok:!0}}catch{return{ok:!1}}case"ANALYTICS":return await we(e.event,e.properties),{ok:!0};case"addToVocab":try{let n=await E(),{word:r,definition:a,sentence:s,sourceUrl:o}=e,c=await _.getByWord(n,r),i;return c?(await _.recordEncounter(n,c.id),i=c.id):i=(await _.add(n,{word:r,status:"new",definition:a})).id,s&&await ue.add(n,{vocab_id:i,sentence:s,context_definition:a,source_url:o}),{ok:!0}}catch{return{ok:!1}}case"injectDebugScript":return{error:"Debug not available"};default:return{error:"Unknown message type"}}}chrome.tabs.onActivated.addListener(async e=>{try{let t=await chrome.tabs.get(e.tabId);t.url&&await De(e.tabId,t.url)}catch{}});chrome.tabs.onUpdated.addListener(async(e,t,n)=>{t.status==="complete"&&n.url&&await De(e,n.url)});chrome.runtime.onInstalled.addListener(async()=>{fe();let e=await chrome.tabs.query({url:["http://*/*","https://*/*"]});for(let t of e)if(t.id)try{await chrome.scripting.executeScript({target:{tabId:t.id},files:["content.js"]})}catch{}});he();chrome.commands.onCommand.addListener(async e=>{if(e!=="toggle-page")return;let[t]=await chrome.tabs.query({active:!0,currentWindow:!0});if(!t?.id||!t.url||!await G())return;let n=O(t.url);if(!(n?await L(n):!1))return;await M(t.id)?(await F(t.id),m(t.id,!0),chrome.tabs.sendMessage(t.id,{type:"resume"}).catch(()=>{})):(await xe(t.id),m(t.id,!1),chrome.tabs.sendMessage(t.id,{type:"pause"}).catch(()=>{}))});
