diff --git "a/assets/main-DUB1sqLl.js" "b/assets/main-DUB1sqLl.js"
deleted file mode 100644--- "a/assets/main-DUB1sqLl.js"
+++ /dev/null
@@ -1,166 +0,0 @@
-import"./modulepreload-polyfill-B5Qt9EMX.js";import{i as so,l as ao,e as co,c as lo,f as uo,p as ho,g as fo,d as mo,A as po,K as pr,h as go,j as bo,D as vn,b as Hn,S as on,m as vo,k as zn,t as yo,a as So,n as wo,o as Eo,r as ko}from"./autotune-ZCGTapUs.js";import{m as yn,D as Sn,P as Wn,d as Mo,b as Co,M as xo,p as Ao,a as Po}from"./models-QsPq0tJ5.js";const To="/assets/hero-DgsFBh_e.webp",Kn="'Songti SC','SimSun','Noto Serif CJK SC','Noto Serif TC',serif",$e=e=>``,ue={paste:$e(''),trash:$e(''),copy:$e(''),download:$e(''),cancel:$e(''),retry:$e(''),cpu:$e(''),translate:$e(''),upload:$e(''),board:$e(''),flag:$e('')},Ro=`
-
-
-
-
-
-
-
-
Mặc Hi
-
Dịch truyện Trung – Việt · chạy trọn trong trình duyệt
-
-
-
-
-
-
-
-
Cần WebGPU để vận công
-
-
-
- Khắc phục nâng cao
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Chuẩn bị…
-
-
-
-
Lần đầu tải ~74 MB trọng số —
- các lần sau mở nhanh nhờ bộ nhớ đệm của trình duyệt.
-
-
-
-
-
-
中文0 ký tự
-
-
-
-
-
-
-
-
Tiếng Việt
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Kéo thả file .txt vào đây, hoặc
-
-
Tự nhận diện mã hóa GBK / Big5 / UTF-8 · tối đa 20 MB
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
`;function Bo(e){e.innerHTML=Ro;const t={};for(const n of e.querySelectorAll("[data-ref]"))t[n.dataset.ref]=n;return t}const sn=e=>typeof e=="string"?e:"";function No({userAgent:e="",platform:t="",mobile:n,maxTouchPoints:r=0}={}){const o=sn(e),i=sn(t),s=Number.isFinite(Number(r))?Number(r):0,c=/\b(?:iPad|iPhone|iPod)\b/i.test(o)||/Mac/i.test(i)&&s>1,u=c||/Android/i.test(o)||(typeof n=="boolean"?n:/\b(?:Mobile|Mobi)\b/i.test(o));let l="unknown";return c&&/\b(?:CriOS|FxiOS|EdgiOS|OPiOS)\//i.test(o)?l="ios-other":/\bEdg(?:A|iOS)?\//i.test(o)?l="edge":/\b(?:Chrome|Chromium|CriOS)\//i.test(o)?l="chrome":/\b(?:Firefox|FxiOS)\//i.test(o)?l="firefox":/\bSafari\//i.test(o)&&/\bVersion\//i.test(o)&&(l="safari"),{browser:l,mobile:u,ios:c}}function Io(e){const t=sn(e?.message??e);return/no adapter/i.test(t)?"no-adapter":/WebGPU unavailable/i.test(t)?"missing-api":"unknown"}const fe=(e,t=null)=>({text:e,address:t});function $o(e,t){const n=e==="chrome",r=n?"Chrome":"Edge",o=n?"chrome":"edge",i=`${o}://settings/system`,s=`${o}://gpu`,c=`${o}://flags/#enable-unsafe-webgpu`;return{steps:[fe(`Cập nhật ${r} lên bản mới nhất rồi mở lại trang này.`),fe(`Mở địa chỉ dưới đây, bật “Dùng tính năng tăng tốc đồ họa khi có thể”, rồi khởi động lại ${r}.`,i),fe("Sau khi khởi động lại, mở trang chẩn đoán dưới đây và kiểm tra WebGPU hiển thị “Hardware accelerated”.",s)],advanced:t==="no-adapter"?{text:`Chỉ khi ${s} báo WebGPU bị blocklist hoặc không được hỗ trợ, bạn có thể thử cờ dưới đây rồi khởi động lại ${r}. Đây là cờ thử nghiệm; hãy trả về Default nếu trình duyệt thiếu ổn định.`,address:c}:null}}function Fo(e){const t=e==="edge"?"Edge":"Chrome";return{steps:[fe(`Cập nhật ${t} và Android lên phiên bản mới nhất.`),fe("Với Chrome, cấu hình phổ biến cần Chrome 121+ và Android 12+; WebGPU vẫn phụ thuộc GPU và driver được thiết bị hỗ trợ."),fe(`Đóng hẳn ${t}, mở lại trang này rồi bấm “Kiểm tra lại”.`),fe("Nếu vẫn không kết nối được GPU, hãy thử Chrome mới nhất hoặc một thiết bị WebGPU khác.")],advanced:null}}function Oo(e){return{steps:[fe(`Cập nhật hệ điều hành trên ${e?"iPhone/iPad":"máy Mac"} để có Safari 26+.`),fe("Đóng hẳn Safari, mở lại trang này rồi bấm “Kiểm tra lại”."),fe("Nếu vẫn không kết nối được GPU, thiết bị hoặc phiên bản hệ điều hành hiện tại có thể chưa cung cấp adapter WebGPU phù hợp.")],advanced:null}}function _o(){return{steps:[fe("Cập nhật iOS/iPadOS và Safari lên phiên bản mới nhất."),fe("Sao chép địa chỉ trang này và mở lại bằng Safari 26+."),fe("Trong Safari, bấm “Kiểm tra lại” để thử kết nối GPU.")],advanced:null}}function Lo(e){return{steps:[fe("Cập nhật trình duyệt và hệ điều hành lên phiên bản mới nhất."),fe("Mở trang này bằng Chrome hoặc Edge mới nhất trên máy tính/Android, hoặc Safari 26+ trên thiết bị Apple."),fe(e==="firefox"?"Firefox chưa nằm trong cấu hình được ứng dụng kiểm thử; hãy thử một trình duyệt được liệt kê ở trên.":"Nếu trình duyệt hiện tại vẫn không có WebGPU, hãy thử một thiết bị hoặc trình duyệt được liệt kê ở trên.")],advanced:null}}function Go({userAgent:e="",platform:t="",mobile:n,maxTouchPoints:r=0,message:o=""}={}){const i=No({userAgent:e,platform:t,mobile:n,maxTouchPoints:r}),s=Io(o),c=s==="no-adapter"?"Trình duyệt có WebGPU nhưng chưa kết nối được với GPU phù hợp.":s==="missing-api"?"Trình duyệt chưa cung cấp WebGPU cho trang này.":"Trình duyệt chưa khởi tạo được WebGPU.";let u;return(i.browser==="chrome"||i.browser==="edge")&&i.mobile?u=Fo(i.browser):i.browser==="chrome"||i.browser==="edge"?u=$o(i.browser,s):i.browser==="safari"?u=Oo(i.mobile):i.browser==="ios-other"?u=_o():u=Lo(i.browser),{...i,failureKind:s,summary:c,...u}}const Vn=200,qn=/[。。.!!??;;…]/,Do=/[”’』」)〉》"')\]]/,Uo=/[,、,]/;function jo(e){const t=[];let n=0;for(let o=0;o=0?n+1:Vn,o=e.slice(0,r).trim(),i=e.slice(r).trim();return[...o?an(o):[],...i?an(i):[]]}function Ho(e){const t=[],n=[];for(const r of e.split(`
-`)){let o=0;for(const i of jo(r))for(const s of an(i))t.push(s),o++;n.push(o)}return{sentences:t,paras:n}}function zo(e,t,n=200){const r=[],o=[];let i=0;for(const s of t){let c="",u=0;for(let l=0;ln&&(r.push(c),u++,c=""),c+=h}c&&(r.push(c),u++),i+=s,o.push(u)}return{rows:r,rowParas:o}}function Wo(e,t){const n=[];let r=0;for(const o of e)n.push(t.slice(r,r+o).join(" ").trim()),r+=o;return n.join(`
-`)}const Ko={㑯:"㑔",㑳:"㑇",㑶:"㐹",㓨:"刾",㗲:"𠵾",㘚:"㘎",㜄:"㚯",㜏:"㛣",㜢:"𡞱",㠏:"㟆",㠣:"𫵷",㥮:"㤘",㩜:"㨫",㩳:"㧐",㩵:"擜",㺏:"𤠋",䁪:"𥇢",䁻:"䀥",䃮:"鿎",䊷:"䌶",䋙:"䌺",䋚:"䌻",䋹:"䌿",䋻:"䌾",䍦:"䍠",䎱:"䎬",䓣:"𬜯",䙡:"䙌",䜀:"䜧",䝼:"䞍",䡵:"𫟦",䥇:"䦂",䥑:"鿏",䥕:"𬭯",䥱:"䥾",䦛:"䦶",䦟:"䦷",䧢:"𨸟",䮄:"𫠊",䯀:"䯅",䰾:"鲃",䱷:"䲣",䱽:"䲝",䲁:"鳚",䲘:"鳤",䴉:"鹮",丟:"丢",並:"并",乾:"干",亂:"乱",亙:"亘",亞:"亚",佇:"伫",佈:"布",佔:"占",併:"并",來:"来",侖:"仑",侶:"侣",侷:"局",俁:"俣",係:"系",俔:"伣",俠:"侠",俥:"伡",俬:"私",倀:"伥",倆:"俩",倈:"俫",倉:"仓",個:"个",們:"们",倖:"幸",倫:"伦",倲:"㑈",偉:"伟",偑:"㐽",側:"侧",偵:"侦",偽:"伪",傌:"㐷",傑:"杰",傖:"伧",傘:"伞",備:"备",傢:"家",傭:"佣",傯:"偬",傳:"传",傴:"伛",債:"债",傷:"伤",傾:"倾",僂:"偻",僅:"仅",僉:"佥",僑:"侨",僕:"仆",僞:"伪",僤:"𫢸",僥:"侥",僨:"偾",僱:"雇",價:"价",儀:"仪",儁:"俊",儂:"侬",億:"亿",儈:"侩",儉:"俭",儎:"傤",儐:"傧",儔:"俦",儕:"侪",儘:"尽",償:"偿",優:"优",儲:"储",儷:"俪",儸:"㑩",儺:"傩",儻:"傥",儼:"俨",兇:"凶",兌:"兑",兒:"儿",兗:"兖",內:"内",兩:"两",冊:"册",冑:"胄",冪:"幂",凈:"净",凍:"冻",凜:"凛",凱:"凯",別:"别",刪:"删",剄:"刭",則:"则",剋:"克",剎:"刹",剗:"刬",剛:"刚",剝:"剥",剮:"剐",剴:"剀",創:"创",剷:"铲",劃:"划",劄:"札",劇:"剧",劉:"刘",劊:"刽",劌:"刿",劍:"剑",劏:"㓥",劑:"剂",劚:"㔉",勁:"劲",動:"动",務:"务",勛:"勋",勝:"胜",勞:"劳",勢:"势",勣:"𪟝",勩:"勚",勱:"劢",勳:"勋",勵:"励",勸:"劝",勻:"匀",匭:"匦",匯:"汇",匱:"匮",區:"区",協:"协",卹:"恤",卻:"却",卽:"即",厙:"厍",厠:"厕",厤:"历",厭:"厌",厲:"厉",厴:"厣",參:"参",叄:"叁",叢:"丛",吒:"咤",吳:"吴",吶:"呐",呂:"吕",咼:"呙",員:"员",唄:"呗",唸:"念",問:"问",啓:"启",啞:"哑",啟:"启",啢:"唡",喎:"㖞",喚:"唤",喪:"丧",喫:"吃",喬:"乔",單:"单",喲:"哟",嗆:"呛",嗇:"啬",嗊:"唝",嗎:"吗",嗚:"呜",嗩:"唢",嗰:"𠮶",嗶:"哔",嘆:"叹",嘍:"喽",嘓:"啯",嘔:"呕",嘖:"啧",嘗:"尝",嘜:"唛",嘩:"哗",嘮:"唠",嘯:"啸",嘰:"叽",嘵:"哓",嘸:"呒",嘽:"啴",噁:"恶",噓:"嘘",噚:"㖊",噝:"咝",噠:"哒",噥:"哝",噦:"哕",噯:"嗳",噲:"哙",噴:"喷",噸:"吨",噹:"当",嚀:"咛",嚇:"吓",嚌:"哜",嚐:"尝",嚕:"噜",嚙:"啮",嚥:"咽",嚦:"呖",嚧:"𠰷",嚨:"咙",嚮:"向",嚲:"亸",嚳:"喾",嚴:"严",嚶:"嘤",囀:"啭",囁:"嗫",囂:"嚣",囅:"冁",囈:"呓",囉:"啰",囌:"苏",囑:"嘱",囪:"囱",圇:"囵",國:"国",圍:"围",園:"园",圓:"圆",圖:"图",團:"团",垻:"坝",埡:"垭",埨:"𫭢",埰:"采",執:"执",堅:"坚",堊:"垩",堖:"垴",堝:"埚",堯:"尧",報:"报",場:"场",塊:"块",塋:"茔",塏:"垲",塒:"埘",塗:"涂",塚:"冢",塢:"坞",塤:"埙",塵:"尘",塸:"𫭟",塹:"堑",塿:"𪣻",墊:"垫",墜:"坠",墠:"𫮃",墮:"堕",墰:"坛",墳:"坟",墶:"垯",墻:"墙",墾:"垦",壇:"坛",壋:"垱",壎:"埙",壓:"压",壗:"𡋤",壘:"垒",壙:"圹",壚:"垆",壜:"坛",壞:"坏",壟:"垄",壠:"垅",壢:"坜",壩:"坝",壪:"塆",壯:"壮",壺:"壶",壼:"壸",壽:"寿",夠:"够",夢:"梦",夥:"伙",夾:"夹",奐:"奂",奧:"奥",奩:"奁",奪:"夺",奬:"奖",奮:"奋",奼:"姹",妝:"妆",姍:"姗",姦:"奸",娙:"𫰛",娛:"娱",婁:"娄",婦:"妇",婭:"娅",媧:"娲",媯:"妫",媰:"㛀",媼:"媪",媽:"妈",嫋:"袅",嫗:"妪",嫵:"妩",嫺:"娴",嫻:"娴",嫿:"婳",嬀:"妫",嬃:"媭",嬈:"娆",嬋:"婵",嬌:"娇",嬙:"嫱",嬡:"嫒",嬤:"嬷",嬪:"嫔",嬰:"婴",嬸:"婶",孃:"娘",孋:"㛤",孌:"娈",孫:"孙",學:"学",孻:"𡥧",孿:"孪",宮:"宫",寀:"采",寢:"寝",實:"实",寧:"宁",審:"审",寫:"写",寬:"宽",寵:"宠",寶:"宝",將:"将",專:"专",尋:"寻",對:"对",導:"导",尷:"尴",屆:"届",屍:"尸",屓:"屃",屜:"屉",屢:"屡",層:"层",屨:"屦",屬:"属",岡:"冈",峯:"峰",峴:"岘",島:"岛",峽:"峡",崍:"崃",崑:"昆",崗:"岗",崙:"仑",崢:"峥",崬:"岽",嵐:"岚",嵗:"岁",嵽:"𫶇",嵾:"㟥",嶁:"嵝",嶄:"崭",嶇:"岖",嶔:"嵚",嶗:"崂",嶠:"峤",嶢:"峣",嶧:"峄",嶨:"峃",嶮:"崄",嶸:"嵘",嶺:"岭",嶼:"屿",嶽:"岳",巋:"岿",巒:"峦",巔:"巅",巖:"岩",巘:"𪩘",巰:"巯",巹:"卺",帥:"帅",師:"师",帳:"帐",帶:"带",幀:"帧",幃:"帏",幓:"㡎",幗:"帼",幘:"帻",幟:"帜",幣:"币",幫:"帮",幬:"帱",幷:"并",幹:"干",幾:"几",庫:"库",廁:"厕",廂:"厢",廄:"厩",廈:"厦",廎:"庼",廕:"荫",廚:"厨",廝:"厮",廞:"𫷷",廟:"庙",廠:"厂",廡:"庑",廢:"废",廣:"广",廩:"廪",廬:"庐",廳:"厅",弒:"弑",弔:"吊",弳:"弪",張:"张",強:"强",彄:"𫸩",彆:"别",彈:"弹",彌:"弥",彎:"弯",彔:"录",彙:"汇",彠:"彟",彥:"彦",彫:"雕",彲:"彨",彿:"佛",後:"后",徑:"径",從:"从",徠:"徕",復:"复",徵:"征",徹:"彻",恆:"恒",恥:"耻",悅:"悦",悞:"悮",悵:"怅",悶:"闷",悽:"凄",惡:"恶",惱:"恼",惲:"恽",惻:"恻",愛:"爱",愜:"惬",愨:"悫",愴:"怆",愷:"恺",愾:"忾",慄:"栗",態:"态",慍:"愠",慘:"惨",慚:"惭",慟:"恸",慣:"惯",慤:"悫",慪:"怄",慫:"怂",慮:"虑",慳:"悭",慶:"庆",慺:"㥪",慼:"戚",慾:"欲",憂:"忧",憊:"惫",憐:"怜",憑:"凭",憒:"愦",憖:"慭",憚:"惮",憤:"愤",憫:"悯",憮:"怃",憲:"宪",憶:"忆",懇:"恳",應:"应",懌:"怿",懍:"懔",懞:"蒙",懟:"怼",懣:"懑",懤:"㤽",懨:"恹",懲:"惩",懶:"懒",懷:"怀",懸:"悬",懺:"忏",懼:"惧",懾:"慑",戀:"恋",戇:"戆",戔:"戋",戧:"戗",戩:"戬",戰:"战",戱:"戯",戲:"戏",戶:"户",扞:"捍",拋:"抛",拚:"拼",挩:"捝",挱:"挲",挾:"挟",捨:"舍",捫:"扪",捱:"挨",捲:"卷",掃:"扫",掄:"抡",掆:"㧏",掗:"挜",掙:"挣",掛:"挂",採:"采",揀:"拣",揚:"扬",換:"换",揮:"挥",揯:"搄",損:"损",搖:"摇",搗:"捣",搧:"扇",搵:"揾",搶:"抢",摑:"掴",摜:"掼",摟:"搂",摯:"挚",摳:"抠",摶:"抟",摺:"折",摻:"掺",撈:"捞",撏:"挦",撐:"撑",撓:"挠",撝:"㧑",撟:"挢",撣:"掸",撥:"拨",撫:"抚",撲:"扑",撳:"揿",撻:"挞",撾:"挝",撿:"捡",擁:"拥",擄:"掳",擇:"择",擊:"击",擋:"挡",擓:"㧟",擔:"担",據:"据",擠:"挤",擡:"抬",擣:"捣",擬:"拟",擯:"摈",擰:"拧",擱:"搁",擲:"掷",擴:"扩",擷:"撷",擺:"摆",擻:"擞",擼:"撸",擽:"㧰",擾:"扰",攄:"摅",攆:"撵",攏:"拢",攔:"拦",攖:"撄",攙:"搀",攛:"撺",攜:"携",攝:"摄",攢:"攒",攣:"挛",攤:"摊",攪:"搅",攬:"揽",敎:"教",敓:"敚",敗:"败",敘:"叙",敵:"敌",數:"数",斂:"敛",斃:"毙",斆:"敩",斕:"斓",斬:"斩",斷:"断",於:"于",旂:"旗",旣:"既",昇:"升",時:"时",晉:"晋",晛:"𬀪",晝:"昼",暈:"晕",暉:"晖",暐:"𬀩",暘:"旸",暢:"畅",暫:"暂",曄:"晔",曆:"历",曇:"昙",曉:"晓",曏:"向",曖:"暧",曠:"旷",曥:"𣆐",曨:"昽",曬:"晒",書:"书",會:"会",朥:"𦛨",朧:"胧",朮:"术",東:"东",枴:"拐",柵:"栅",柺:"拐",査:"查",桱:"𣐕",桿:"杆",梔:"栀",梘:"枧",梜:"𬂩",條:"条",梟:"枭",梲:"棁",棄:"弃",棊:"棋",棖:"枨",棗:"枣",棟:"栋",棡:"㭎",棧:"栈",棲:"栖",棶:"梾",椏:"桠",椲:"㭏",楊:"杨",楓:"枫",楨:"桢",業:"业",極:"极",榘:"矩",榦:"干",榪:"杩",榮:"荣",榲:"榅",榿:"桤",構:"构",槍:"枪",槓:"杠",槤:"梿",槧:"椠",槨:"椁",槮:"椮",槳:"桨",槶:"椢",槼:"椝",樁:"桩",樂:"乐",樅:"枞",樑:"梁",樓:"楼",標:"标",樞:"枢",樢:"㭤",樣:"样",樧:"榝",樫:"㭴",樳:"桪",樸:"朴",樹:"树",樺:"桦",樿:"椫",橈:"桡",橋:"桥",機:"机",橢:"椭",橫:"横",橯:"𣓿",檁:"檩",檉:"柽",檔:"档",檜:"桧",檟:"槚",檢:"检",檣:"樯",檮:"梼",檯:"台",檳:"槟",檸:"柠",檻:"槛",櫃:"柜",櫍:"𬃊",櫓:"橹",櫚:"榈",櫛:"栉",櫝:"椟",櫞:"橼",櫟:"栎",櫥:"橱",櫧:"槠",櫨:"栌",櫪:"枥",櫫:"橥",櫬:"榇",櫱:"蘖",櫳:"栊",櫸:"榉",櫻:"樱",欄:"栏",欅:"榉",權:"权",欏:"椤",欒:"栾",欓:"𣗋",欖:"榄",欞:"棂",欽:"钦",歎:"叹",歐:"欧",歟:"欤",歡:"欢",歲:"岁",歷:"历",歸:"归",歿:"殁",殘:"残",殞:"殒",殤:"殇",殨:"㱮",殫:"殚",殭:"僵",殮:"殓",殯:"殡",殰:"㱩",殲:"歼",殺:"杀",殻:"壳",殼:"壳",毀:"毁",毆:"殴",毿:"毵",氂:"牦",氈:"毡",氌:"氇",氣:"气",氫:"氢",氬:"氩",氳:"氲",氾:"泛",汎:"泛",汙:"污",決:"决",沒:"没",沖:"冲",況:"况",泝:"溯",洩:"泄",洶:"汹",浹:"浃",浿:"𬇙",涇:"泾",涗:"涚",涼:"凉",淒:"凄",淚:"泪",淥:"渌",淨:"净",淩:"凌",淪:"沦",淵:"渊",淶:"涞",淺:"浅",渙:"涣",減:"减",渢:"沨",渦:"涡",測:"测",渾:"浑",湊:"凑",湋:"𣲗",湞:"浈",湧:"涌",湯:"汤",溈:"沩",準:"准",溝:"沟",溫:"温",溮:"浉",溳:"涢",溼:"湿",滄:"沧",滅:"灭",滌:"涤",滎:"荥",滙:"汇",滬:"沪",滯:"滞",滲:"渗",滷:"卤",滸:"浒",滻:"浐",滾:"滚",滿:"满",漁:"渔",漊:"溇",漍:"𬇹",漚:"沤",漢:"汉",漣:"涟",漬:"渍",漲:"涨",漵:"溆",漸:"渐",漿:"浆",潁:"颍",潑:"泼",潔:"洁",潕:"𣲘",潙:"沩",潚:"㴋",潛:"潜",潤:"润",潯:"浔",潰:"溃",潷:"滗",潿:"涠",澀:"涩",澆:"浇",澇:"涝",澐:"沄",澗:"涧",澠:"渑",澤:"泽",澦:"滪",澩:"泶",澫:"𬇕",澮:"浍",澱:"淀",澾:"㳠",濁:"浊",濃:"浓",濄:"㳡",濆:"𣸣",濕:"湿",濘:"泞",濚:"溁",濛:"蒙",濜:"浕",濟:"济",濤:"涛",濧:"㳔",濫:"滥",濰:"潍",濱:"滨",濺:"溅",濼:"泺",濾:"滤",瀂:"澛",瀅:"滢",瀆:"渎",瀇:"㲿",瀉:"泻",瀋:"沈",瀏:"浏",瀕:"濒",瀘:"泸",瀝:"沥",瀟:"潇",瀠:"潆",瀦:"潴",瀧:"泷",瀨:"濑",瀰:"弥",瀲:"��",瀾:"澜",灃:"沣",灄:"滠",灑:"洒",灒:"𪷽",灕:"漓",灘:"滩",灙:"𣺼",灝:"灏",灡:"㳕",灣:"湾",灤:"滦",灧:"滟",灩:"滟",災:"灾",為:"为",烏:"乌",烴:"烃",無:"无",煉:"炼",煒:"炜",煙:"烟",煢:"茕",煥:"焕",煩:"烦",煬:"炀",煱:"㶽",熅:"煴",熒:"荧",熗:"炝",熰:"𬉼",熱:"热",熲:"颎",熾:"炽",燀:"𬊤",燁:"烨",燈:"灯",燉:"炖",燒:"烧",燖:"𬊈",燙:"烫",燜:"焖",營:"营",燦:"灿",燬:"毁",燭:"烛",燴:"烩",燶:"㶶",燻:"熏",燼:"烬",燾:"焘",爍:"烁",爐:"炉",爛:"烂",爭:"争",爲:"为",爺:"爷",爾:"尔",牀:"床",牆:"墙",牘:"牍",牴:"抵",牽:"牵",犖:"荦",犛:"牦",犢:"犊",犧:"牺",狀:"状",狹:"狭",狽:"狈",猙:"狰",猶:"犹",猻:"狲",獁:"犸",獃:"呆",獄:"狱",獅:"狮",獎:"奖",獨:"独",獪:"狯",獫:"猃",獮:"狝",獰:"狞",獱:"㺍",獲:"获",獵:"猎",獷:"犷",獸:"兽",獺:"獭",獻:"献",獼:"猕",玀:"猡",現:"现",琱:"雕",琺:"珐",琿:"珲",瑋:"玮",瑒:"玚",瑣:"琐",瑤:"瑶",瑩:"莹",瑪:"玛",瑲:"玱",璉:"琏",璊:"𫞩",璕:"𬍤",璗:"𬍡",璡:"琎",璣:"玑",璦:"瑷",璫:"珰",璯:"㻅",環:"环",璵:"玙",璸:"瑸",璽:"玺",璿:"璇",瓅:"𬍛",瓊:"琼",瓏:"珑",瓔:"璎",瓚:"瓒",瓛:"𤩽",甌:"瓯",甕:"瓮",產:"产",産:"产",畝:"亩",畢:"毕",畫:"画",異:"异",畵:"画",當:"当",疇:"畴",疊:"叠",痙:"痉",痠:"酸",痾:"疴",瘂:"痖",瘋:"疯",瘍:"疡",瘓:"痪",瘞:"瘗",瘡:"疮",瘧:"疟",瘮:"瘆",瘲:"疭",瘺:"瘘",瘻:"瘘",療:"疗",癆:"痨",癇:"痫",癉:"瘅",癒:"愈",癘:"疠",癟:"瘪",癡:"痴",癢:"痒",癤:"疖",癥:"症",癧:"疬",癩:"癞",癬:"癣",癭:"瘿",癮:"瘾",癰:"痈",癱:"瘫",癲:"癫",發:"发",皁:"皂",皚:"皑",皰:"疱",皸:"皲",皺:"皱",盃:"杯",盜:"盗",盞:"盏",盡:"尽",監:"监",盤:"盘",盧:"卢",盪:"荡",眞:"真",眥:"眦",眾:"众",睍:"𪾢",睏:"困",睜:"睁",睞:"睐",瞘:"眍",瞜:"䁖",瞞:"瞒",瞶:"瞆",瞼:"睑",矇:"蒙",矓:"眬",矚:"瞩",矯:"矫",硃:"朱",硜:"硁",硤:"硖",硨:"砗",硯:"砚",碕:"埼",碩:"硕",碭:"砀",碸:"砜",確:"确",碼:"码",碽:"䂵",磑:"硙",磚:"砖",磠:"硵",磣:"碜",磧:"碛",磯:"矶",磽:"硗",磾:"䃅",礄:"硚",礎:"础",礐:"𬒈",礙:"碍",礦:"矿",礪:"砺",礫:"砾",礬:"矾",礱:"砻",祕:"秘",祿:"禄",禍:"祸",禎:"祯",禕:"祎",禡:"祃",禦:"御",禪:"禅",禮:"礼",禰:"祢",禱:"祷",禿:"秃",秈:"籼",稅:"税",稈:"秆",稏:"䅉",稜:"棱",稟:"禀",種:"种",稱:"称",穀:"谷",穇:"䅟",穌:"稣",積:"积",穎:"颖",穠:"秾",穡:"穑",穢:"秽",穩:"稳",穫:"获",穭:"穞",窩:"窝",窪:"洼",窮:"穷",窯:"窑",窵:"窎",窶:"窭",窺:"窥",竄:"窜",竅:"窍",竇:"窦",竈:"灶",竊:"窃",竪:"竖",競:"竞",筆:"笔",筍:"笋",筧:"笕",筴:"䇲",箇:"个",箋:"笺",箏:"筝",箚:"札",節:"节",範:"范",築:"筑",篋:"箧",篔:"筼",篠:"筿",篢:"𬕂",篤:"笃",篩:"筛",篳:"筚",篸:"𥮾",簀:"箦",簍:"篓",簑:"蓑",簞:"箪",簡:"简",簣:"篑",簫:"箫",簹:"筜",簽:"签",簾:"帘",籃:"篮",籅:"𥫣",籌:"筹",籔:"䉤",籙:"箓",籛:"篯",籜:"箨",籟:"籁",籠:"笼",籤:"签",籩:"笾",籪:"簖",籬:"篱",籮:"箩",籲:"吁",粵:"粤",糉:"粽",糝:"糁",糞:"粪",糧:"粮",糰:"团",糲:"粝",糴:"籴",糶:"粜",糹:"纟",糾:"纠",紀:"纪",紂:"纣",紃:"𬘓",約:"约",紅:"红",紆:"纡",紇:"纥",紈:"纨",紉:"纫",紋:"纹",納:"纳",紐:"纽",紓:"纾",純:"纯",紕:"纰",紖:"纼",紗:"纱",紘:"纮",紙:"纸",級:"级",紛:"纷",紜:"纭",紝:"纴",紞:"𬘘",紡:"纺",紬:"䌷",紮:"扎",細:"细",紱:"绂",紲:"绁",紳:"绅",紵:"纻",紹:"绍",紺:"绀",紼:"绋",紿:"绐",絀:"绌",終:"终",絃:"弦",組:"组",絅:"䌹",絆:"绊",絎:"绗",結:"结",絕:"绝",絛:"绦",絝:"绔",絞:"绞",絡:"络",絢:"绚",給:"给",絨:"绒",絪:"𬘡",絰:"绖",統:"统",絲:"丝",絳:"绛",絶:"绝",絹:"绢",絺:"𫄨",綁:"绑",綃:"绡",綄:"𬘫",綆:"绠",綈:"绨",綉:"绣",綌:"绤",綎:"𬘩",綏:"绥",綐:"䌼",綑:"捆",經:"经",綖:"𫄧",綜:"综",綝:"𬘭",綞:"缍",綠:"绿",綡:"𫟅",綢:"绸",綣:"绻",綧:"𬘯",綪:"𬘬",綫:"线",綬:"绶",維:"维",綯:"绹",綰:"绾",綱:"纲",網:"网",綳:"绷",綴:"缀",綵:"彩",綸:"纶",綹:"绺",綺:"绮",綻:"绽",綽:"绰",綾:"绫",綿:"绵",緄:"绲",緇:"缁",緊:"紧",緋:"绯",緑:"绿",緒:"绪",緓:"绬",緔:"绱",緗:"缃",緘:"缄",緙:"缂",線:"线",緝:"缉",緞:"缎",締:"缔",緡:"缗",緣:"缘",緦:"缌",編:"编",緩:"缓",緬:"缅",緯:"纬",緱:"缑",緲:"缈",練:"练",緶:"缏",緹:"缇",緻:"致",緼:"缊",縈:"萦",縉:"缙",縊:"缢",縋:"缒",縐:"绉",縑:"缣",縕:"缊",縗:"缞",縛:"缚",縝:"缜",縞:"缟",縟:"缛",縣:"县",縧:"绦",縫:"缝",縭:"缡",縮:"缩",縯:"𬙂",縱:"纵",縲:"缧",縳:"䌸",縴:"纤",縵:"缦",縶:"絷",縷:"缕",縹:"缥",總:"总",績:"绩",繃:"绷",繅:"缫",繆:"缪",繒:"缯",織:"织",繕:"缮",繚:"缭",繞:"绕",繡:"绣",繢:"缋",繩:"绳",繪:"绘",繫:"系",繭:"茧",繮:"缰",繯:"缳",繰:"缲",繳:"缴",繶:"𫄷",繸:"䍁",繹:"绎",繻:"𦈡",繼:"继",繽:"缤",繾:"缱",繿:"䍀",纁:"𫄸",纆:"𬙊",纇:"颣",纈:"缬",纊:"纩",續:"续",纍:"累",纏:"缠",纓:"缨",纔:"才",纕:"𬙋",纖:"纤",纘:"缵",纜:"缆",缽:"钵",罃:"䓨",罈:"坛",罌:"罂",罎:"坛",罰:"罚",罵:"骂",罷:"罢",羅:"罗",羆:"罴",羈:"羁",羋:"芈",羣:"群",羥:"羟",羨:"羡",義:"义",羶:"膻",習:"习",翫:"玩",翬:"翚",翹:"翘",翽:"翙",耬:"耧",耮:"耢",聖:"圣",聞:"闻",聯:"联",聰:"聪",聲:"声",聳:"耸",聵:"聩",聶:"聂",職:"职",聹:"聍",聽:"听",聾:"聋",肅:"肃",脅:"胁",脈:"脉",脛:"胫",脣:"唇",脩:"修",脫:"脱",脹:"胀",腎:"肾",腖:"胨",腡:"脶",腦:"脑",腫:"肿",腳:"脚",腸:"肠",膃:"腽",膕:"腘",膚:"肤",膞:"䏝",膠:"胶",膢:"𦝼",膩:"腻",膽:"胆",膾:"脍",膿:"脓",臉:"脸",臍:"脐",臏:"膑",臘:"腊",臚:"胪",臟:"脏",臠:"脔",臢:"臜",臥:"卧",臨:"临",臺:"台",與:"与",興:"兴",舉:"举",舊:"旧",舖:"铺",舘:"馆",艙:"舱",艤:"舣",艦:"舰",艫:"舻",艱:"艰",艷:"艳",芻:"刍",苧:"苎",茲:"兹",荊:"荆",莊:"庄",莖:"茎",莢:"荚",莧:"苋",華:"华",菴:"庵",菸:"烟",萇:"苌",萊:"莱",萬:"万",萴:"荝",萵:"莴",葉:"叶",葒:"荭",葤:"荮",葦:"苇",葯:"药",葷:"荤",蒍:"𫇭",蒐:"搜",蒓:"莼",蒔:"莳",蒕:"蒀",蒞:"莅",蒼:"苍",蓀:"荪",蓆:"席",蓋:"盖",蓮:"莲",蓯:"苁",蓴:"莼",蓽:"荜",蔄:"𬜬",蔔:"卜",蔘:"参",蔞:"蒌",蔣:"蒋",蔥:"葱",蔦:"茑",蔭:"荫",蔯:"𫈟",蔿:"𫇭",蕁:"荨",蕆:"蒇",蕎:"荞",蕒:"荬",蕓:"芸",蕕:"莸",蕘:"荛",蕢:"蒉",蕩:"荡",蕪:"芜",蕭:"萧",蕷:"蓣",薀:"蕰",薈:"荟",薊:"蓟",薌:"芗",薑:"姜",薔:"蔷",薘:"荙",薟:"莶",薦:"荐",薩:"萨",薳:"䓕",薴:"苧",薵:"䓓",薹:"苔",薺:"荠",藍:"蓝",藎:"荩",藝:"艺",藥:"药",藪:"薮",藭:"䓖",藴:"蕴",藶:"苈",藹:"蔼",藺:"蔺",蘀:"萚",蘄:"蕲",蘆:"芦",蘇:"苏",蘊:"蕴",蘋:"苹",蘚:"藓",蘞:"蔹",蘟:"𦻕",蘢:"茏",蘭:"兰",蘺:"蓠",蘿:"萝",虆:"蔂",虉:"𬟁",處:"处",虛:"虚",虜:"虏",號:"号",虧:"亏",虯:"虬",蛺:"蛱",蛻:"蜕",蜆:"蚬",蝀:"𬟽",蝕:"蚀",蝟:"猬",蝦:"虾",蝨:"虱",蝸:"蜗",螄:"蛳",螞:"蚂",螢:"萤",螮:"䗖",螻:"蝼",螿:"螀",蟄:"蛰",蟈:"蝈",蟎:"螨",蟣:"虮",蟬:"蝉",蟯:"蛲",蟲:"虫",蟳:"𫊻",蟶:"蛏",蟻:"蚁",蠁:"蚃",蠅:"蝇",蠆:"虿",蠍:"蝎",蠐:"蛴",蠑:"蝾",蠔:"蚝",蠟:"蜡",蠣:"蛎",蠨:"蟏",蠱:"蛊",蠶:"蚕",蠻:"蛮",衆:"众",衊:"蔑",術:"术",衕:"同",衚:"胡",衛:"卫",衝:"冲",袞:"衮",袷:"夹",裊:"袅",裏:"里",補:"补",裝:"装",裡:"里",製:"制",複:"复",褌:"裈",褘:"袆",褲:"裤",褳:"裢",褸:"褛",褻:"亵",襀:"𫌀",襇:"裥",襉:"裥",襏:"袯",襖:"袄",襝:"裣",襠:"裆",襤:"褴",襪:"袜",襬:"摆",襯:"衬",襲:"袭",襴:"襕",覈:"核",見:"见",覎:"觃",規:"规",覓:"觅",視:"视",覘:"觇",覡:"觋",覥:"觍",覦:"觎",親:"亲",覬:"觊",覯:"觏",覲:"觐",覷:"觑",覺:"觉",覽:"览",覿:"觌",觀:"观",觴:"觞",觶:"觯",觸:"触",訁:"讠",訂:"订",訃:"讣",計:"计",訊:"讯",訌:"讧",討:"讨",訏:"𬣙",訐:"讦",訒:"讱",訓:"训",訕:"讪",訖:"讫",託:"托",記:"记",訛:"讹",訝:"讶",訟:"讼",訢:"䜣",訣:"诀",訥:"讷",訩:"讻",訪:"访",設:"设",許:"许",訴:"诉",訶:"诃",診:"诊",註:"注",証:"证",詀:"𧮪",詁:"诂",詆:"诋",詎:"讵",詐:"诈",詒:"诒",詔:"诏",評:"评",詖:"诐",詗:"诇",詘:"诎",詛:"诅",詝:"𬣞",詞:"词",詠:"咏",詡:"诩",詢:"询",詣:"诣",試:"试",詩:"诗",詪:"𬣳",詫:"诧",詬:"诟",詭:"诡",詮:"诠",詰:"诘",話:"话",該:"该",詳:"详",詵:"诜",詷:"𫍣",詼:"诙",詿:"诖",誄:"诔",誅:"诛",誆:"诓",誇:"夸",誌:"志",認:"认",誑:"诳",誒:"诶",誕:"诞",誘:"诱",誚:"诮",語:"语",誠:"诚",誡:"诫",誣:"诬",誤:"误",誥:"诰",誦:"诵",誨:"诲",說:"说",説:"说",誰:"谁",課:"课",誶:"谇",誹:"诽",誼:"谊",誾:"訚",調:"调",諂:"谄",諄:"谆",談:"谈",諉:"诿",請:"请",諍:"诤",諏:"诹",諑:"诼",諒:"谅",諓:"𬣡",論:"论",諗:"谂",諛:"谀",諜:"谍",諝:"谞",諞:"谝",諟:"𬤊",諡:"谥",諢:"诨",諤:"谔",諦:"谛",諧:"谐",諫:"谏",諭:"谕",諮:"咨",諱:"讳",諲:"𬤇",諳:"谙",諴:"𫍯",諶:"谌",諷:"讽",諸:"诸",諺:"谚",諼:"谖",諾:"诺",謀:"谋",謁:"谒",謂:"谓",謄:"誊",謅:"诌",謊:"谎",謎:"谜",謏:"𫍲",謐:"谧",謔:"谑",謖:"谡",謗:"谤",謙:"谦",謚:"谥",講:"讲",謝:"谢",謠:"谣",謡:"谣",謨:"谟",謫:"谪",謬:"谬",謭:"谫",謳:"讴",謹:"谨",謾:"谩",譁:"哗",證:"证",譎:"谲",譏:"讥",譓:"𬤝",譖:"谮",識:"识",譙:"谯",譚:"谭",譜:"谱",譞:"𫍽",譟:"噪",譫:"谵",譭:"毁",譯:"译",議:"议",譴:"谴",護:"护",譸:"诪",譽:"誉",譾:"谫",讀:"读",讅:"谉",變:"变",讋:"詟",讌:"䜩",讎:"雠",讒:"谗",讓:"让",讕:"谰",讖:"谶",讚:"赞",讜:"谠",讞:"谳",谿:"溪",豈:"岂",豎:"竖",豐:"丰",豔:"艳",豬:"猪",豶:"豮",貍:"狸",貓:"猫",貙:"䝙",貝:"贝",貞:"贞",貟:"贠",負:"负",財:"财",貢:"贡",貧:"贫",貨:"货",販:"贩",貪:"贪",貫:"贯",責:"责",貯:"贮",貰:"贳",貲:"赀",貳:"贰",貴:"贵",貶:"贬",買:"买",貸:"贷",貺:"贶",費:"费",貼:"贴",貽:"贻",貿:"贸",賀:"贺",賁:"贲",賂:"赂",賃:"赁",賄:"贿",賅:"赅",資:"资",賈:"贾",賊:"贼",賑:"赈",賒:"赊",賓:"宾",賕:"赇",賙:"赒",賚:"赉",賜:"赐",賞:"赏",賠:"赔",賡:"赓",賢:"贤",賣:"卖",賤:"贱",賦:"赋",賧:"赕",質:"质",賫:"赍",賬:"账",賭:"赌",賰:"䞐",賴:"赖",賵:"赗",賺:"赚",賻:"赙",購:"购",賽:"赛",賾:"赜",贄:"贽",贅:"赘",贇:"赟",贈:"赠",贊:"赞",贋:"赝",贍:"赡",贏:"赢",贐:"赆",贓:"赃",贔:"赑",贖:"赎",贗:"赝",贛:"赣",贜:"赃",赬:"赪",趕:"赶",趙:"赵",趨:"趋",趲:"趱",跡:"迹",踐:"践",踰:"逾",踴:"踊",蹌:"跄",蹕:"跸",蹟:"迹",蹠:"跖",蹣:"蹒",蹤:"踪",蹺:"跷",躂:"跶",躉:"趸",躊:"踌",躋:"跻",躍:"跃",躎:"䟢",躑:"踯",躒:"跞",躓:"踬",躕:"蹰",躚:"跹",躡:"蹑",躥:"蹿",躦:"躜",躪:"躏",軀:"躯",車:"车",軋:"轧",軌:"轨",軍:"军",軏:"𫐄",軑:"轪",軒:"轩",軔:"轫",軛:"轭",軝:"𬨂",軟:"软",軤:"轷",軫:"轸",軲:"轱",軸:"轴",軹:"轵",軺:"轺",軻:"轲",軼:"轶",軾:"轼",較:"较",輄:"𨐈",輅:"辂",輇:"辁",輈:"辀",載:"载",輊:"轾",輋:"𪨶",輒:"辄",輓:"挽",輔:"辅",輕:"轻",輗:"𫐐",輛:"辆",輜:"辎",輝:"辉",輞:"辋",輟:"辍",輥:"辊",輦:"辇",輩:"辈",輪:"轮",輬:"辌",輮:"𫐓",輯:"辑",輳:"辏",輶:"𬨎",輸:"输",輻:"辐",輼:"辒",輾:"辗",輿:"舆",轀:"辒",轂:"毂",轄:"辖",轅:"辕",轆:"辘",轉:"转",轍:"辙",轎:"轿",轔:"辚",轟:"轰",轡:"辔",轢:"轹",轤:"轳",辦:"办",辭:"辞",辮:"辫",辯:"辩",農:"农",迴:"回",逕:"径",這:"这",連:"连",週:"周",進:"进",遊:"游",運:"运",過:"过",達:"达",違:"违",遙:"遥",遜:"逊",遞:"递",遠:"远",遡:"溯",適:"适",遲:"迟",遶:"绕",遷:"迁",選:"选",遺:"遗",遼:"辽",邁:"迈",還:"还",邇:"迩",邊:"边",邏:"逻",邐:"逦",郟:"郏",郵:"邮",鄆:"郓",鄉:"乡",鄒:"邹",鄔:"邬",鄖:"郧",鄧:"邓",鄩:"𬩽",鄭:"郑",鄰:"邻",鄲:"郸",鄳:"𫑡",鄴:"邺",鄶:"郐",鄺:"邝",酇:"酂",酈:"郦",醃:"腌",醖:"酝",醜:"丑",醞:"酝",醟:"蒏",醣:"糖",醫:"医",醬:"酱",醱:"酦",醲:"𬪩",釀:"酿",釁:"衅",釃:"酾",釅:"酽",釋:"释",釐:"厘",釒:"钅",釓:"钆",釔:"钇",釕:"钌",釗:"钊",釘:"钉",釙:"钋",針:"针",釣:"钓",釤:"钐",釦:"扣",釧:"钏",釩:"钒",釴:"𬬩",釵:"钗",釷:"钍",釹:"钕",釺:"钎",釾:"䥺",釿:"𬬱",鈀:"钯",鈁:"钫",鈃:"钘",鈄:"钭",鈅:"钥",鈇:"𫓧",鈈:"钚",鈉:"钠",鈍:"钝",鈎:"钩",鈐:"钤",鈑:"钣",鈒:"钑",鈔:"钞",鈕:"钮",鈞:"钧",鈡:"钟",鈣:"钙",鈥:"钬",鈦:"钛",鈧:"钪",鈮:"铌",鈰:"铈",鈳:"钶",鈴:"铃",鈷:"钴",鈸:"钹",鈹:"铍",鈺:"钰",鈽:"钸",鈾:"铀",鈿:"钿",鉀:"钾",鉅:"巨",鉆:"钻",鉈:"铊",鉉:"铉",鉊:"𬬿",鉋:"铇",鉍:"铋",鉑:"铂",鉕:"钷",鉗:"钳",鉚:"铆",鉛:"铅",鉝:"𫟷",鉞:"钺",鉢:"钵",鉤:"钩",鉥:"𬬸",鉦:"钲",鉧:"𬭁",鉬:"钼",鉭:"钽",鉮:"𬬹",鉳:"锫",鉶:"铏",鉷:"𫟹",鉸:"铰",鉺:"铒",鉻:"铬",鉿:"铪",銀:"银",銃:"铳",銅:"铜",銈:"𫓯",銍:"铚",銑:"铣",銓:"铨",銖:"铢",銘:"铭",銚:"铫",銛:"铦",銜:"衔",銠:"铑",銣:"铷",銥:"铱",銦:"铟",銨:"铵",銩:"铥",銪:"铕",銫:"铯",銬:"铐",銱:"铞",銳:"锐",銶:"𨱇",銷:"销",銹:"锈",銻:"锑",銼:"锉",鋁:"铝",鋃:"锒",鋅:"锌",鋇:"钡",鋌:"铤",鋏:"铗",鋐:"𬭎",鋒:"锋",鋗:"𫓶",鋙:"铻",鋝:"锊",鋟:"锓",鋣:"铘",鋤:"锄",鋥:"锃",鋦:"锔",鋨:"锇",鋩:"铓",鋪:"铺",鋭:"锐",鋮:"铖",鋯:"锆",鋰:"锂",鋱:"铽",鋶:"锍",鋸:"锯",鋹:"𬬮",鋼:"钢",錀:"𬬭",錁:"锞",錄:"录",錆:"锖",錇:"锫",錈:"锩",錏:"铔",錐:"锥",錒:"锕",錕:"锟",錘:"锤",錙:"锱",錚:"铮",錛:"锛",錞:"𬭚",錟:"锬",錠:"锭",錡:"锜",錢:"钱",錤:"𫓹",錦:"锦",錨:"锚",錩:"锠",錫:"锡",錮:"锢",錯:"错",録:"录",錳:"锰",錶:"表",錸:"铼",錼:"镎",鍀:"锝",鍁:"锨",鍃:"锪",鍅:"钫",鍆:"钔",鍇:"锴",鍈:"锳",鍊:"炼",鍋:"锅",鍍:"镀",鍔:"锷",鍘:"铡",鍚:"钖",鍛:"锻",鍠:"锽",鍤:"锸",鍥:"锲",鍩:"锘",鍬:"锹",鍭:"𬭤",鍰:"锾",鍵:"键",鍶:"锶",鍺:"锗",鍼:"针",鍾:"钟",鎂:"镁",鎄:"锿",鎇:"镅",鎊:"镑",鎌:"镰",鎓:"𬭩",鎔:"镕",鎖:"锁",鎘:"镉",鎚:"锤",鎛:"镈",鎝:"𨱏",鎡:"镃",鎢:"钨",鎣:"蓥",鎦:"镏",鎧:"铠",鎩:"铩",鎪:"锼",鎬:"镐",鎭:"镇",鎮:"镇",鎰:"镒",鎲:"镋",鎳:"镍",鎵:"镓",鎶:"鿔",鎸:"镌",鎿:"镎",鏃:"镞",鏇:"旋",鏈:"链",鏌:"镆",鏍:"镙",鏏:"𬭬",鏐:"镠",鏑:"镝",鏗:"铿",鏘:"锵",鏜:"镗",鏝:"镘",鏞:"镛",鏟:"铲",鏡:"镜",鏢:"镖",鏤:"镂",鏨:"錾",鏰:"镚",鏵:"铧",鏷:"镤",鏹:"镪",鏺:"䥽",鏻:"𬭸",鏽:"锈",鐃:"铙",鐄:"𨱑",鐇:"𫔍",鐋:"铴",鐍:"𫔎",鐏:"𨱔",鐐:"镣",鐒:"铹",鐓:"镦",鐔:"镡",鐘:"钟",鐙:"镫",鐝:"镢",鐠:"镨",鐥:"䦅",鐦:"锎",鐧:"锏",鐨:"镄",鐩:"𬭼",鐫:"镌",鐮:"镰",鐯:"䦃",鐲:"镯",鐳:"镭",鐵:"铁",鐶:"镮",鐸:"铎",鐺:"铛",鐽:"𫟼",鐿:"镱",鑄:"铸",鑊:"镬",鑌:"镔",鑑:"鉴",鑒:"鉴",鑔:"镲",鑕:"锧",鑞:"镴",鑠:"铄",鑣:"镳",鑥:"镥",鑪:"𬬻",鑭:"镧",鑰:"钥",鑱:"镵",鑲:"镶",鑷:"镊",鑹:"镩",鑼:"锣",鑽:"钻",鑾:"銮",鑿:"凿",钁:"镢",钂:"镋",長:"长",門:"门",閂:"闩",閃:"闪",閆:"闫",閈:"闬",閉:"闭",開:"开",閌:"闶",閎:"闳",閏:"闰",閑:"闲",閒:"闲",間:"间",閔:"闵",閘:"闸",閡:"阂",閣:"阁",閤:"合",閥:"阀",閨:"闺",閩:"闽",閫:"阃",閬:"阆",閭:"闾",閱:"阅",閲:"阅",閶:"阊",閹:"阉",閻:"阎",閼:"阏",閽:"阍",閾:"阈",閿:"阌",闃:"阒",闆:"板",闇:"暗",闈:"闱",闉:"𬮱",闊:"阔",闋:"阕",闌:"阑",闍:"阇",闐:"阗",闑:"𫔶",闒:"阘",闓:"闿",闔:"阖",闕:"阙",闖:"闯",關:"关",闞:"阚",闠:"阓",闡:"阐",闢:"辟",闤:"阛",闥:"闼",陘:"陉",陝:"陕",陞:"升",陣:"阵",陰:"阴",陳:"陈",陸:"陆",陽:"阳",隉:"陧",隊:"队",階:"阶",隑:"𬮿",隕:"陨",際:"际",隤:"𬯎",隨:"随",險:"险",隮:"𬯀",隯:"陦",隱:"隐",隴:"陇",隸:"隶",隻:"只",雋:"隽",雖:"虽",雙:"双",雛:"雏",雜:"杂",雞:"鸡",離:"离",難:"难",雲:"云",電:"电",霑:"沾",霢:"霡",霧:"雾",霽:"霁",靂:"雳",靄:"霭",靆:"叇",靈:"灵",靉:"叆",靚:"靓",靜:"静",靝:"靔",靦:"腼",靨:"靥",鞏:"巩",鞝:"绱",鞦:"秋",鞽:"鞒",韁:"缰",韃:"鞑",韆:"千",韉:"鞯",韋:"韦",韌:"韧",韍:"韨",韓:"韩",韙:"韪",韜:"韬",韝:"鞲",韞:"韫",韻:"韵",響:"响",頁:"页",頂:"顶",頃:"顷",項:"项",順:"顺",頇:"顸",須:"须",頊:"顼",頌:"颂",頍:"𫠆",頎:"颀",頏:"颃",預:"预",頑:"顽",頒:"颁",頓:"顿",頔:"𬱖",頗:"颇",領:"领",頜:"颌",頠:"𬱟",頡:"颉",頤:"颐",頦:"颏",頫:"𫖯",頭:"头",頮:"颒",頰:"颊",頲:"颋",頴:"颕",頵:"𫖳",頷:"颔",頸:"颈",頹:"颓",頻:"频",頽:"颓",顆:"颗",題:"题",額:"额",顎:"颚",顏:"颜",顒:"颙",顓:"颛",顔:"颜",顗:"𫖮",願:"愿",顙:"颡",顛:"颠",類:"类",顢:"颟",顥:"颢",顧:"顾",顫:"颤",顬:"颥",顯:"显",顰:"颦",顱:"颅",顳:"颞",顴:"颧",風:"风",颭:"飐",颮:"飑",颯:"飒",颱:"台",颳:"刮",颶:"飓",颸:"飔",颺:"飏",颻:"飖",颼:"飕",飀:"飗",飄:"飘",飆:"飙",飈:"飚",飛:"飞",飠:"饣",飢:"饥",飣:"饤",飥:"饦",飩:"饨",飪:"饪",飫:"饫",飭:"饬",飯:"饭",飱:"飧",飲:"饮",飴:"饴",飼:"饲",飽:"饱",飾:"饰",飿:"饳",餃:"饺",餄:"饸",餅:"饼",餈:"糍",餉:"饷",養:"养",餌:"饵",餎:"饹",餏:"饻",餑:"饽",餒:"馁",餓:"饿",餕:"馂",餖:"饾",餗:"𫗧",餘:"余",餚:"肴",餛:"馄",餜:"馃",餞:"饯",餡:"馅",館:"馆",餬:"糊",餱:"糇",餳:"饧",餵:"喂",餶:"馉",餷:"馇",餸:"𩠌",餺:"馎",餼:"饩",餾:"馏",餿:"馊",饁:"馌",饃:"馍",饅:"馒",饈:"馐",饉:"馑",饊:"馓",饋:"馈",饌:"馔",饑:"饥",饒:"饶",饗:"飨",饘:"𫗴",饜:"餍",饞:"馋",饢:"馕",馬:"马",馭:"驭",馮:"冯",馱:"驮",馳:"驰",馴:"驯",馹:"驲",馼:"𫘜",駁:"驳",駃:"𫘝",駉:"𬳶",駐:"驻",駑:"驽",駒:"驹",駓:"𬳵",駔:"驵",駕:"驾",駘:"骀",駙:"驸",駛:"驶",駝:"驼",駟:"驷",駡:"骂",駢:"骈",駪:"𬳽",駭:"骇",駰:"骃",駱:"骆",駸:"骎",駼:"𬳿",駿:"骏",騁:"骋",騂:"骍",騄:"𫘧",騅:"骓",騊:"𫘦",騌:"骔",騍:"骒",騎:"骑",騏:"骐",騑:"𬴂",騖:"骛",騙:"骗",騞:"𬴃",騠:"𫘨",騤:"骙",騧:"䯄",騫:"骞",騭:"骘",騮:"骝",騰:"腾",騱:"𫘬",騵:"𫘪",騶:"驺",騷:"骚",騸:"骟",騾:"骡",驀:"蓦",驁:"骜",驂:"骖",驃:"骠",驄:"骢",驅:"驱",驊:"骅",驌:"骕",驍:"骁",驎:"𬴊",驏:"骣",驕:"骄",驗:"验",驚:"惊",驛:"驿",驟:"骤",驢:"驴",驤:"骧",驥:"骥",驦:"骦",驪:"骊",驫:"骉",骯:"肮",髏:"髅",髒:"脏",體:"体",髕:"髌",髖:"髋",髮:"发",鬆:"松",鬍:"胡",鬚:"须",鬢:"鬓",鬥:"斗",鬧:"闹",鬨:"哄",鬩:"阋",鬮:"阄",鬱:"郁",鬹:"鬶",魎:"魉",魘:"魇",魚:"鱼",魛:"鱽",魟:"𫚉",魢:"鱾",魨:"鲀",魯:"鲁",魴:"鲂",魷:"鱿",魺:"鲄",鮀:"𬶍",鮁:"鲅",鮃:"鲆",鮆:"𫚖",鮈:"𬶋",鮊:"鲌",鮋:"鲉",鮍:"鲏",鮎:"鲇",鮐:"鲐",鮑:"鲍",鮒:"鲋",鮓:"鲊",鮚:"鲒",鮜:"鲘",鮝:"鲞",鮞:"鲕",鮟:"𩽾",鮠:"𬶏",鮡:"𬶐",鮣:"䲟",鮦:"鲖",鮪:"鲔",鮫:"鲛",鮭:"鲑",鮮:"鲜",鮳:"鲓",鮶:"鲪",鮸:"𩾃",鮺:"鲝",鯀:"鲧",鯁:"鲠",鯇:"鲩",鯉:"鲤",鯊:"鲨",鯒:"鲬",鯔:"鲻",鯕:"鲯",鯖:"鲭",鯗:"鲞",鯛:"鲷",鯝:"鲴",鯡:"鲱",鯢:"鲵",鯤:"鲲",鯧:"鲳",鯨:"鲸",鯪:"鲮",鯫:"鲰",鯰:"鲶",鯴:"鲺",鯷:"鳀",鯻:"𬶟",鯽:"鲫",鯿:"鳊",鰁:"鳈",鰂:"鲗",鰃:"鳂",鰆:"䲠",鰈:"鲽",鰉:"鳇",鰊:"𬶠",鰌:"䲡",鰍:"鳅",鰏:"鲾",鰐:"鳄",鰒:"鳆",鰓:"鳃",鰛:"鳁",鰜:"鳒",鰟:"鳑",鰠:"鳋",鰣:"鲥",鰤:"𫚕",鰥:"鳏",鰧:"䲢",鰨:"鳎",鰩:"鳐",鰭:"鳍",鰮:"鳁",鰱:"鲢",鰲:"鳌",鰳:"鳓",鰵:"鳘",鰶:"𬶭",鰷:"鲦",鰹:"鲣",鰺:"鲹",鰻:"鳗",鰼:"鳛",鰾:"鳔",鱀:"𬶨",鱂:"鳉",鱅:"鳙",鱇:"𩾌",鱈:"鳕",鱉:"鳖",鱒:"鳟",鱔:"鳝",鱖:"鳜",鱗:"鳞",鱘:"鲟",鱚:"𬶮",鱝:"鲼",鱟:"鲎",鱠:"鲙",鱣:"鳣",鱤:"鳡",鱧:"鳢",鱨:"鲿",鱭:"鲚",鱯:"鳠",鱲:"𫚭",鱷:"鳄",鱸:"鲈",鱺:"鲡",鳥:"鸟",鳧:"凫",鳩:"鸠",鳬:"凫",鳲:"鸤",鳳:"凤",鳴:"鸣",鳶:"鸢",鳾:"䴓",鴆:"鸩",鴇:"鸨",鴉:"鸦",鴒:"鸰",鴕:"鸵",鴛:"鸳",鴝:"鸲",鴞:"鸮",鴟:"鸱",鴣:"鸪",鴦:"鸯",鴨:"鸭",鴯:"鸸",鴰:"鸹",鴴:"鸻",鴷:"䴕",鴻:"鸿",鴿:"鸽",鵁:"䴔",鵂:"鸺",鵃:"鸼",鵏:"𬷕",鵐:"鹀",鵑:"鹃",鵒:"鹆",鵓:"鹁",鵜:"鹈",鵝:"鹅",鵟:"𫛭",鵠:"鹄",鵡:"鹉",鵪:"鹌",鵬:"鹏",鵮:"鹐",鵯:"鹎",鵰:"雕",鵲:"鹊",鵷:"鹓",鵾:"鹍",鶄:"䴖",鶇:"鸫",鶉:"鹑",鶊:"鹒",鶓:"鹋",鶖:"鹙",鶘:"鹕",鶚:"鹗",鶠:"𬸘",鶡:"鹖",鶥:"鹛",鶩:"鹜",鶪:"䴗",鶬:"鸧",鶯:"莺",鶱:"𬸣",鶲:"鹟",鶴:"鹤",鶹:"鹠",鶺:"鹡",鶻:"鹘",鶼:"鹣",鶿:"鹚",鷀:"鹚",鷁:"鹢",鷂:"鹞",鷄:"鸡",鷉:"䴘",鷊:"鹝",鷓:"鹧",鷖:"鹥",鷗:"鸥",鷙:"鸷",鷚:"鹨",鷟:"𬸦",鷥:"鸶",鷦:"鹪",鷫:"鹔",鷭:"𬸪",鷯:"鹩",鷲:"鹫",鷳:"鹇",鷴:"鹇",鷸:"鹬",鷹:"鹰",鷺:"鹭",鷽:"鸴",鸂:"㶉",鸇:"鹯",鸊:"䴙",鸌:"鹱",鸏:"鹲",鸑:"𬸚",鸕:"鸬",鸘:"鹴",鸚:"鹦",鸛:"鹳",鸝:"鹂",鸞:"鸾",鹵:"卤",鹹:"咸",鹺:"鹾",鹼:"碱",鹽:"盐",麗:"丽",麥:"麦",麩:"麸",麪:"面",麫:"面",麬:"𤿲",麯:"曲",麳:"𪎌",麴:"曲",麵:"面",麼:"么",麽:"么",黃:"黄",黌:"黉",點:"点",黨:"党",黲:"黪",黴:"霉",黶:"黡",黷:"黩",黽:"黾",黿:"鼋",鼂:"鼌",鼉:"鼍",鼕:"冬",鼴:"鼹",齊:"齐",齋:"斋",齎:"赍",齏:"齑",齒:"齿",齔:"龀",齕:"龁",齗:"龂",齘:"𬹼",齙:"龅",齜:"龇",齟:"龃",齠:"龆",齡:"龄",齣:"出",齦:"龈",齧:"啮",齪:"龊",齬:"龉",齮:"𬺈",齯:"𫠜",齲:"龋",齶:"腭",齷:"龌",齼:"𬺓",龍:"龙",龎:"厐",龐:"庞",龑:"䶮",龔:"龚",龕:"龛",龜:"龟","鿁":"䜤","鿓":"鿒","𠁞":"𠀾","𠗣":"㓆","𡃕":"𠴛","𡅏":"𠲥","𡑍":"𫭼","𡑭":"𡋗","𡓾":"𡋀","𡔖":"𡍣","𡞵":"㛟","𡠹":"㛿","𡢃":"㛠","𡮉":"𡭜","𡮣":"𡭬","𡳳":"𡳃","𡻕":"岁","𡾱":"㟜","𢣚":"𢘝","𢶫":"𢫞","𢹿":"𢬦","𣈶":"暅","𣙎":"㭣","𣞻":"𣘓","𣠩":"𣞎","𣠲":"𣑶","𣯶":"毶","𣾷":"㳢","𤁣":"𣺽","𤅶":"𣷷","𤓩":"𤊰","𤪺":"㻘","𤫩":"㻏","𤳸":"𤳄","𥊝":"𥅿","𥌃":"𥅘","𥕥":"𥐰","𥖅":"𥐯","𥗽":"𬒗","𥢢":"䅪","𥸠":"𥮋","𥼽":"𥹥","𦘧":"𡳒","𦣎":"𦟗","𦪙":"䑽","𧜗":"䘞","𧜵":"䙊","𧝞":"䘛","𧟀":"𧝧","𧩙":"䜥","𧵳":"䞌","𧶧":"䞎","𨊰":"䢀","𨊸":"䢁","𨋢":"䢂","𨤻":"𨤰","𨦫":"䦀","𨧀":"𬭊","𨧜":"䦁","𨨏":"𬭛","𨭆":"𬭶","𨭎":"𬭳","𨯅":"䥿","𩞯":"䭪","𩠴":"𩠠","𩣑":"䯃","𩶘":"䲞","𰻞":"𰻝","「":"“","」":"”","『":"‘","』":"’"},gr={一坏:"一坯",一目瞭然:"一目了然",七逕:"七迳",上逕:"上迳",上鍊:"上链",不可貲計:"不可赀計",不瞭解:"不了解",么麼:"幺麽",么麽:"幺麽",九逕山:"九迳山",乾佑縣:"乾佑县",乾元:"乾元",乾卦:"乾卦",乾嘉:"乾嘉",乾圖:"乾图",乾坤:"乾坤",乾坤一擲:"乾坤一掷",乾坤再造:"乾坤再造",乾坤大挪移:"乾坤大挪移",乾宅:"乾宅",乾安縣:"乾安县",乾安鎮:"乾安镇",乾州:"乾州",乾斷:"乾断",乾旦:"乾旦",乾曜:"乾曜",乾清宮:"乾清宫",乾盛世:"乾盛世",乾紅:"乾红",乾綱:"乾纲",乾縣:"乾县",乾象:"乾象",乾造:"乾造",乾道:"乾道",乾闥婆:"乾闼婆",乾陵:"乾陵",乾隆:"乾隆",乾隆年間:"乾隆年间",乾隆皇帝:"乾隆皇帝",二噁英:"二𫫇英",以免藉口:"以免借口",傢俱:"家具",允祕:"允祕",八濛山:"八濛山",其陰多蒐:"其阴多蒐",凌藉:"凌借",函覆:"函复",剋架:"剋架",剋毒:"剋毒",千鍾粟:"千锺粟",南氾:"南氾",南逕:"南迳",反反覆覆:"反反复复",反覆:"反复",反覆思維:"反复思维",反覆思量:"反复思量",反覆性:"反复性",名覆金甌:"名复金瓯",吳祕:"吴祕",吳育昇:"吴育昇",哪吒:"哪吒",回覆:"回复",土坏:"土坯",坏土:"坯土",坏子:"坯子",坏布:"坯布",坏戶:"坯户",墨沈沈:"墨沉沉",壺裏乾坤:"壶里乾坤",大目乾連冥間救母變文:"大目乾连冥间救母变文",宫商角徵羽:"宫商角徵羽",尼乾子:"尼乾子",尼乾陀:"尼乾陀",年釐:"年釐",幺麼:"幺麽",幺麼小丑:"幺麽小丑",幺麼小醜:"幺麽小丑",康乾:"康乾",張昇:"张昇",張法乾:"张法乾",彷彿:"仿佛",徐胤昇:"徐胤昇",復甦:"复苏",徵弦:"徵弦",徵絃:"徵弦",徵羽摩柯:"徵羽摩柯",徵聲:"徵声",徵調:"徵调",徵音:"徵音",意志消沈:"意志消沉",憑藉:"凭借",憑藉着:"凭借着",懷釐:"怀釐",手鍊:"手链",打坏:"打坯",扞格:"扞格",扭轉乾坤:"扭转乾坤",批覆:"批复",找藉口:"找借口",折戟沈沙:"折戟沉沙",折戟沈河:"折戟沉河",拉坏:"拉坯",拉鍊:"拉链",拉鍊工程:"拉链工程",拜覆:"拜复",挨剋:"挨剋",捏坏:"捏坯",擊沈:"击沉",據瞭解:"据了解",於世成:"於世成",於乎:"於乎",於仲完:"於仲完",於倫:"於伦",於其一:"於其一",於則:"於则",於勇明:"於勇明",於呼哀哉:"於呼哀哉",於單:"於单",於坦:"於坦",於崇文:"於崇文",於忠祥:"於忠祥",於惟一:"於惟一",於戲:"於戏",於敖:"於敖",於梨華:"於梨华",於清言:"於清言",於潛:"於潜",於琳:"於琳",於穆:"於穆",於竹屋:"於竹屋",於菟:"於菟",於邑:"於邑",於陵子:"於陵子",旋乾轉坤:"旋乾转坤",旋轉乾坤:"旋转乾坤",旋轉乾坤之力:"旋转乾坤之力",明瞭:"明了",明覆:"明复",昏沈:"昏沉",春蒐:"春蒐",春釐:"春釐",暗沈沈:"暗沉沉",書中自有千鍾粟:"书中自有千锺粟",朝乾夕惕:"朝乾夕惕",木吒:"木吒",李乾德:"李乾德",李昇:"李昇",李昇勳:"李昇勋",李澤鉅:"李泽钜",李祕:"李祕",李鍊福:"李链福",李鍾郁:"李锺郁",束脩:"束脩",東氾:"东氾",梁昇卿:"梁昇卿",梁章鉅:"梁章钜",楊聯陞:"杨联陞",樊於期:"樊於期",死氣沈沈:"死气沉沉",段脩:"段脩",毛坏:"毛坯",水逕:"水迳",氾勝之:"氾胜之",氾南:"氾南",氾國:"氾国",氾水:"氾水",沈下:"沉下",沈不住氣:"沉不住气",沈住氣:"沉住气",沈冤:"沉冤",沈厚:"沉厚",沈吟:"沉吟",沈寂:"沉寂",沈得住氣:"沉得住气",沈思:"沉思",沈思往事:"沉思往事",沈悶:"沉闷",沈沒:"沉没",沈沒成本:"沉没成本",沈浮:"沉浮",沈浸:"沉浸",沈浸於:"沉浸于",沈淪:"沉沦",沈湎:"沉湎",沈湎酒色:"沉湎酒色",沈溺:"沉溺",沈滯:"沉滞",沈滯性:"沉滞性",沈澱:"沉淀",沈澱出來:"沉淀出来",沈澱劑:"沉淀剂",沈澱法:"沉淀法",沈澱物:"沉淀物",沈濁:"沉浊",沈甸甸:"沉甸甸",沈痛:"沉痛",沈痼:"沉痼",沈痾:"沉疴",沈睡:"沉睡",沈睡不醒:"沉睡不醒",沈砂池:"沉砂池",沈積:"沉积",沈積岩:"沉积岩",沈積石:"沉积石",沈筒:"沉筒",沈船:"沉船",沈落:"沉落",沈迷:"沉迷",沈迷不醒:"沉迷不醒",沈醉:"沉醉",沈重:"沉重",沈降:"沉降",沈陷:"沉陷",沈靜:"沉静",沈靜下來:"沉静下来",沈香:"沉香",沈鬱:"沉郁",沈魚落雁:"沉鱼落雁",沈默:"沉默",沈默不語:"沉默不语",沈默寡言:"沉默寡言",沙逕:"沙迳",河逕:"河迳",流徵:"流徵",浪蕩乾坤:"浪荡乾坤",浮沈:"浮沉",海哩:"海里",深沈:"深沉",深沈不露:"深沉不露",溫昇豪:"温昇豪",滑藉:"滑借",烏昇:"乌昇",烏沈沈:"乌沉沉",烏逕:"乌迳",狐藉虎威:"狐借虎威",王彥昇:"王彦昇",珍珠項鍊:"珍珠项链",甚鉅:"甚钜",甦生:"苏生",甦醒:"苏醒",申昇勳:"申昇勋",申覆:"申复",畢昇:"毕昇",盧象昇:"卢象昇",目劄:"目劄",瞭如:"了如",瞭如指掌:"了如指掌",瞭然:"了然",瞭然於心:"了然于心",瞭若指掌:"了若指掌",瞭解:"了解",瞭解到:"了解到",破釜沈舟:"破釜沉舟",磚坏:"砖坯",示覆:"示复",社逕:"社迳",祕丕笈:"祕丕笈",祕彭祖:"祕彭祖",祕瓊:"祕琼",祝釐:"祝釐",稟覆:"禀复",竺乾:"竺乾",答覆:"答复",篤麼:"笃麽",簡單明瞭:"简单明了",籌畫:"筹划",素藉:"素借",耳沈:"耳沉",肉脩:"肉脩",肘手鍊足:"肘手链足",胤祕:"胤祕",脩敬:"脩敬",脩炳:"脩炳",脩脡:"脩脡",脩脯:"脩脯",脩金:"脩金",脫坏:"脱坯",腶脩:"腶脩",英哩:"英里",茅蒐:"茅蒐",茵藉:"茵借",萬鍾:"万锺",落雁沈魚:"落雁沉鱼",蒐于紅:"蒐于红",蒐於紅:"蒐于红",蒐狩:"蒐狩",蒐獮:"蒐狝",蒐獵:"蒐猎",蒐田:"蒐田",蒐畋:"蒐畋",蒐苗:"蒐苗",蒜薹:"蒜薹",蔣昇:"蒋昇",蕓薹:"芸薹",蕭乾:"萧乾",藉代:"借代",藉以:"借以",藉助:"借助",藉助於:"借助于",藉卉:"借卉",藉口:"借口",藉喻:"借喻",藉寇兵:"借寇兵",藉寇兵齎盜糧:"借寇兵赍盗粮",藉手:"借手",藉據:"借据",藉故:"借故",藉故推辭:"借故推辞",藉方:"借方",藉條:"借条",藉槁:"借槁",藉機:"借机",藉此:"借此",藉此機會:"借此机会",藉甚:"借甚",藉由:"借由",藉着:"借着",藉端:"借端",藉端生事:"借端生事",藉箸代籌:"借箸代筹",藉草枕塊:"借草枕块",藉詞:"借词",藉讀:"借读",藉資:"借资",衹得:"只得",衹見樹木:"只见树木",衹見樹木不見森林:"只见树木不见森林",袁祕:"袁祕",袖裏乾坤:"袖里乾坤",袷袢:"袷袢",製坏:"制坯",覆信:"复信",覆呈:"复呈",覆命:"复命",覆墓:"复墓",覆帳:"复帐",覆按:"复按",覆文:"复文",覆校:"复校",覆電:"复电",見覆:"见复",角徵:"角徵",角徵羽:"角徵羽",計畫:"计划",變徵:"变徵",變徵之聲:"变徵之声",變徵之音:"变徵之音",谿工:"谿工",赤石逕:"赤石迳",踅門瞭戶:"踅门了户",躪藉:"躏借",載沈載浮:"载沉载浮",載浮載沈:"载浮载沉",辛祕:"辛祕",逆釐:"逆釐",逕口:"迳口",逕聯:"迳联",逕頭:"迳头",郭子乾:"郭子乾",酒逢知己千鍾少:"酒逢知己千锺少",醞藉:"酝借",重覆:"重复",金吒:"金吒",金昇玟:"金昇玟",金鍊:"金链",鈞覆:"钧复",鉅子:"钜子",鉅萬:"钜万",鉅防:"钜防",鉸鍊:"铰链",銀鍊:"银链",鋼坏:"钢坯",錢鍾書:"钱锺书",鍊墜:"链坠",鍊子:"链子",鍊形:"链形",鍊條:"链条",鍊錘:"链锤",鍊鎖:"链锁",鍛鍾:"锻锺",鍾繇:"锺繇",鍾萬梅:"锺万梅",鍾重發:"锺重发",鍾鍛:"锺锻",鍾馗:"锺馗",鎖鍊:"锁链",鐵鍊:"铁链",鑽石項���:"钻石项链",鑿坏:"凿坯",閻鶴昇:"阎鹤昇",陰沈:"阴沉",陰沈沈:"阴沉沉",陰陰沈沈:"阴阴沉沉",陳志昇:"陈志昇",陳昇:"陈昇",陶坏:"陶坯",雁杳魚沈:"雁杳鱼沉",電覆:"电复",韓昇延:"韩昇延",項鍊:"项链",頸鍊:"颈链",顛乾倒坤:"颠乾倒坤",顛倒乾坤:"颠倒乾坤",顧藉:"顾借",魏徵:"魏徵",魚沈雁杳:"鱼沉雁杳",麪坏兒:"面坯儿",麼些族:"麽些族",黃鍾公:"黄锺公",黑沈沈:"黑沉沉",龔昇:"龚昇"};let cn=null,lt=null;function Vo(){cn=new Map(Object.entries(Ko)),lt=new Map;for(const e of Object.keys(gr)){const t=e[0];let n=lt.get(t);n||lt.set(t,n=[]),n.push(e)}for(const e of lt.values())e.sort((t,n)=>n.length-t.length)}function qo(e){cn||Vo();let t="",n=0,r=0;const o=e.length;for(;r=3?o.slice(1,-1).join(", "):o[o.length-1]}const r=t.match(/^Vulkan[\s\d.]+\((.+)\)$/i);return r&&(t=r[1]),t=t.replace(/ANGLE Metal Renderer:\s*/i,"").replace(/\(0x[0-9A-Fa-f]+\)/g,"").replace(/\b(Direct3D\d+|vs_\d+_\d+|ps_\d+_\d+|OpenGL(?: ES)?[\d. ]*)\b/g,"").replace(/\((TM|R|C)\)/gi,"").replace(/\s{2,}/g," ").trim().replace(/[,;·]+$/,"").replace(/\s+GPU$/i,"").trim().replace(/^(\S+)( \1)+(?= |$)/i,"$1"),t||null}const Qo={nvidia:["nvidia","geforce"],amd:["amd","radeon","ati"],intel:["intel"],apple:["apple"],qualcomm:["qualcomm","adreno"],arm:["arm","mali"],samsung:["samsung","xclipse"]};function br(e,t,n){const r=String(e??"").toLowerCase().trim();if(!r)return!1;const o=`${t??""} ${n??""}`.toLowerCase();return(Qo[r]??[r]).some(i=>o.includes(i))}function Yo(e,t){return t&&/\d/.test(t)?t:e}function Xo(e){if(typeof e!="string"||!e.trim())return e;const t=i=>/\S\s+\S/.test(i);let n=e.trim();const r=n.replace(/^(NVIDIA\s+(GeForce\s+)?|AMD\s+|Qualcomm\s+)/i,"");t(r)&&(n=r);const o=n.replace(/\s+(Graphics|GPU)$/i,"");return t(o)&&(n=o),n}function Zo(e){const t=String(e??"");return/\b[ab]\d{3}\b/i.test(t)||/hpg/i.test(t)?!1:/\b(intel|iris|uhd|xe)\b/i.test(t)?!0:/\bradeon\b/i.test(t)&&(/\b\d{3}m\b/i.test(t)||/\bradeon(\s*\(tm\))?\s+graphics$/i.test(t))}function vr(){try{const e=document.createElement("canvas"),t=e.getContext("webgl2",{powerPreference:"high-performance"})??e.getContext("webgl",{powerPreference:"high-performance"});if(!t)return null;const n=t.getExtension("WEBGL_debug_renderer_info"),r=n?{vendor:String(t.getParameter(n.UNMASKED_VENDOR_WEBGL)??""),renderer:String(t.getParameter(n.UNMASKED_RENDERER_WEBGL)??"")}:null;return t.getExtension("WEBGL_lose_context")?.loseContext(),r}catch{return null}}function ei(e,t,n=vr()){return!n||!br(e?.vendor,n.vendor,n.renderer)?t:Yo(t,Jo(n.renderer))}function ln(e){let t;try{t=window[`${e}Storage`];const n="moxhi.storage.probe";t.setItem(n,"1"),t.removeItem(n)}catch{const n=new Map;return{persistent:!1,getItem:r=>n.get(r)??null,setItem:(r,o)=>{n.set(r,String(o))},removeItem:r=>{n.delete(r)}}}return{persistent:!0,getItem:n=>{try{return t.getItem(n)}catch{return null}},setItem:(n,r)=>{try{t.setItem(n,r)}catch{}},removeItem:n=>{try{t.removeItem(n)}catch{}}}}const ti=1,Pt=1e3,Vt="moxhi.scheduleAuto.seed.v1",ni=new Set(["off","shadow","apply","auto"]),ri=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;if(!Number.isInteger(Pt)||Pt<0||Pt>1e4)throw new Error("schedule auto rollout basis points must be an integer from 0 to 10000");function Jn(e){return typeof e!="string"||!ri.test(e)?null:Number.parseInt(e.slice(0,8),16)%1e4}function we(e,t,n,r){return{mode:e,source:t,reason:n,revision:ti,rolloutBps:r}}function oi({enabled:e=!1,explicitMode:t=null,rolloutBps:n=Pt,getStorage:r=()=>null,createSeed:o=()=>null}={}){if(t!==null){const u=ni.has(t)?t:"off";return we(u,"explicit",u===t?"explicit":"explicit-invalid",n)}if(e!==!0)return we("off","default","caller-disabled",n);if(!Number.isInteger(n)||n<0||n>1e4)return we("off","default","rollout-invalid",0);if(n===0)return we("off","default","rollout-disabled",0);let i;try{i=r()}catch{return we("off","default","storage-error",n)}if(i?.persistent!==!0)return we("off","default","storage-unavailable",n);let s;try{s=i.getItem(Vt)}catch{return we("off","default","storage-error",n)}if(s===null){try{s=o()}catch{return we("off","default","seed-generation-failed",n)}if(Jn(s)===null)return we("off","default","seed-generation-failed",n);try{if(i.setItem(Vt,s),i.getItem(Vt)!==s)return we("off","default","seed-write-failed",n)}catch{return we("off","default","seed-write-failed",n)}}const c=Jn(s);return c===null?we("off","default","seed-invalid",n):cn)throw new Error(`${t} must be a non-empty string of at most ${n} chars`);return e}function ht(e,t){return Le(e,t),e===0?0:2**Math.ceil(Math.log2(e))}function ft(e){if(!Array.isArray(e)||e.length===0)return null;const t=[...e].sort((r,o)=>r-o),n=t.length>>1;return t.length%2?t[n]:(t[n-1]+t[n])/2}function Yn(e,t){if(!Array.isArray(e)||!Array.isArray(t)||e.length===0||e.length!==t.length)return null;let n=0,r=0;for(let o=0;o0?n/r:null}function un(e,t){if(!Array.isArray(e)||e.length===0)return null;const n=[...e].sort((s,c)=>s-c),r=(n.length-1)*t,o=Math.floor(r),i=Math.ceil(r);return o===i?n[o]:n[o]+(n[i]-n[o])*(r-o)}function dn(e){if(Array.isArray(e))return e.map(dn);if(e&&typeof e=="object"){const t={};for(const n of Object.keys(e).sort())t[n]=dn(e[n]);return t}return e}function Mn(e){return JSON.stringify(dn(e))}function wi(e){return!!e&&dt.some(t=>e.inFlight===t.inFlight&&e.groupSteps===t.groupSteps)}function Ei(e){return me(e,"groupSteps")}function ki(e,t=null){const n=me(e,"groupSteps");return t==null?n:Math.min(n,me(t,"carry groupSteps"))}function Mi(e,t){const n=me(e,"carry groupSteps"),r=me(t,"groupStepsFinal");return Math.min(n,r)}function Ci(e){return e===1/0?"inf":ht(e,"policy.tokenBudget")}function Xn(e,t,n){return t.map(r=>ht(un(e,r),n))}function xi(e){const t=new Map;for(const n of e){const r=me(n,"plannedSourceBuckets value");t.set(r,(t.get(r)??0)+1)}return[...t.entries()].sort((n,r)=>n[0]-r[0]).map(([n,r])=>[n,ht(r,"bucket count")])}function Ai({batchSizes:e,plannedSourceBuckets:t,sourceTokenLengths:n,modelId:r,weightsId:o,dtype:i,policy:s}={}){if(!Array.isArray(e)||e.length===0)throw new Error("batchSizes must be a non-empty array");const c=e.map(h=>me(h,"batchSizes value"));if(!Array.isArray(t)||t.length!==c.length)throw new Error("plannedSourceBuckets must align with batchSizes");if(!Array.isArray(n))throw new Error("sourceTokenLengths must be an array");const u=c.reduce((h,f)=>h+f,0);if(n.length!==u)throw new Error("sourceTokenLengths must contain one value per planned row");const l=n.map(h=>me(h,"sourceTokenLengths value"));if(!s||typeof s!="object")throw new Error("policy must be an object");return{protocolRev:je,rowCountBand:ht(u,"rowCount"),batchCountBand:ht(c.length,"batchCount"),plannedSourceBucketHistogram:xi(t),batchSizeQuantiles:Xn(c,[.25,.5,.75],"batchSize quantile"),sourceTokenQuantiles:Xn(l,[.25,.5,.75,.9],"sourceToken quantile"),model:[q(r,"modelId"),q(o,"weightsId"),q(i,"dtype",32)],policy:{pack:s.pack===!0,kvPlanner:q(s.kvPlanner,"policy.kvPlanner"),tokenBudgetBand:Ci(s.tokenBudget),immediates:q(s.immediates,"policy.immediates",32),uniformPool:s.uniformPool===!0}}}function Pi(e){if(!e||typeof e!="object")throw new Error("signature must be an object");return Mn(e)}function Ti(e,t=wn,n=null){if(!Array.isArray(e)||e.length===0)throw new Error("batch cost list must be non-empty");const r=e.map(f=>G(f,"batch cost"));if(!Array.isArray(t)||t.length===0||t.some(f=>!Number.isFinite(f)||f<=0||f>=1))throw new Error("sample quantiles must be finite values between zero and one");let o=null;if(n!=null){if(!Array.isArray(n)||n.length!==r.length)throw new Error("batch regions must align with batch costs");o=n.map((f,g)=>{if(Number.isInteger(f)&&f>0||typeof f=="string"&&f.length>0&&f.length<=64)return f;throw new Error(`batch region at index ${g} is invalid`)})}if(r.length<=t.length)return r.map((f,g)=>g);const i=r.reduce((f,g)=>f+g,0);let s=0;const c=r.map(f=>{const g=(s+f/2)/i;return s+=f,g}),u=new Set,l=new Set,h=o?Math.min(t.length,new Set(o.map(String)).size):0;for(const f of t){let g=null;const S=o&&l.sizef-g)}function It(e){return`${typeof e}:${String(e)}`}function Ri(e,t){return typeof e=="number"&&typeof t=="number"?e-t:typeof e=="number"?-1:typeof t=="number"?1:String(e).localeCompare(String(t))}function qt(e,t,n){return e.filter(({index:r})=>!n.has(r)).map(r=>({...r,distance:Math.abs(r.center-t)})).sort((r,o)=>r.distance-o.distance||r.index-o.index)[0]??null}function Zn(e,t){const n=e.entries.filter(({index:i})=>t.has(i));if(n.length===0)return null;const r=n.reduce((i,s)=>i+s.cost,0);return n.reduce((i,s)=>i+s.center*s.cost,0)/r<.5?.75:.25}function Jt(e){return[...e].sort((t,n)=>n.mass-t.mass||Ri(t.region,n.region)||t.entries[0].index-n.entries[0].index)}function Bi(e,t,n=null){if(!Array.isArray(e)||e.length===0)throw new Error("batch cost list must be non-empty");const r=e.map(M=>G(M,"batch cost"));if(!Array.isArray(t)||t.length===0)throw new Error("sample batch indices must be a non-empty array");const o=t.map(M=>{if(!Number.isInteger(M)||M<0||M>=r.length)throw new Error("sample batch index is out of range");return M});if(new Set(o).size!==o.length)throw new Error("sample batch indices contain a duplicate");if(r.length-o.length<2)throw new Error("confirmation planning requires two unused batches");let i;if(n==null)i=new Array(r.length).fill("all");else{if(!Array.isArray(n)||n.length!==r.length)throw new Error("batch regions must align with batch costs");i=n.map((M,F)=>{if(Number.isInteger(M)&&M>0||typeof M=="string"&&M.length>0&&M.length<=64)return M;throw new Error(`batch region at index ${F} is invalid`)})}const s=new Map;for(let M=0;MIt(i[M]))),f=M=>M.entries.some(({index:F})=>!l.has(F)),S=Jt(c.filter(M=>h.has(M.key)&&f(M)))[0];if(!S)throw new Error("confirmation planning requires an unused stability batch");const A=Zn(S,u),y=qt(S.entries,A,l);if(!y)throw new Error("confirmation planning could not select a stability batch");l.add(y.index);let v=Jt(c.filter(M=>!h.has(M.key)&&f(M)))[0]??null,oe=.5;v||(v=Jt(c.filter(F=>h.has(F.key)&&F.key!==S.key&&f(F)))[0]??null,v&&(oe=Zn(v,u)));let Ee;if(v)Ee=qt(v.entries,oe,l);else{let M=0;const F=r.reduce((B,ve)=>B+ve,0),X=r.map((B,ve)=>{const pe={index:ve,cost:B,center:(M+B/2)/F};return M+=B,pe});Ee=qt(X,.5,l)}if(!Ee)throw new Error("confirmation planning could not select a coverage batch");return Object.freeze([Object.freeze({role:"stability",batchIndex:y.index,region:i[y.index]}),Object.freeze({role:"coverage",batchIndex:Ee.index,region:i[Ee.index]})])}function Ni(e,t){if(!Array.isArray(e)||e.length===0)throw new Error("batch cost list must be non-empty");const n=e.map(l=>G(l,"batch cost"));if(!Array.isArray(t)||t.length===0)throw new Error("sample batch indices must be a non-empty array");const r=t.map(l=>{if(!Number.isInteger(l)||l<0||l>=n.length)throw new Error("sample batch indices must address the batch cost list");return l});if(new Set(r).size!==r.length)throw new Error("sample batch indices must not contain duplicates");r.sort((l,h)=>l-h);const o=n.reduce((l,h)=>l+h,0);let i=0;const s=n.map(l=>{const h=(i+l/2)/o;return i+=l,h}),c=r.map(l=>s[l]),u=new Array(r.length).fill(0);for(let l=0;lMath.abs(s[l]-S)),f=Math.min(...h),g=h.map((S,A)=>({distance:S,owner:A})).filter(({distance:S})=>Math.abs(S-f)<=Number.EPSILON*8);for(const{owner:S}of g)u[S]+=n[l]/g.length}return u.map(l=>l/o)}function Ii({fileMode:e=!1,pack:t=!1,isMobile:n=!1,uncachedRows:r=0,plannedBatches:o=0,kernelTuneSource:i=null,manualOverrides:s={},memorySafe:c=!1}={}){if(!e)return{eligible:!1,reason:"typed-text"};if(!t)return{eligible:!1,reason:"packing-disabled"};if(n)return{eligible:!1,reason:"mobile-v1-skip"};for(const u of hi){const l=s?.[u];if(l!=null)return{eligible:!1,reason:`manual-override:${u}`}}return i==="partial"?{eligible:!1,reason:"kernel-autotune-partial"}:i!=="measured"&&i!=="cache"?{eligible:!1,reason:"kernel-autotune-untrusted"}:c?!Number.isInteger(r)||r0||typeof e?.region=="number"&&Number.isFinite(e.region))&&Number.isFinite(e?.baselineWallMs)&&e.baselineWallMs>0&&Number.isFinite(e?.candidateWallMs)&&e.candidateWallMs>0&&Number.isFinite(e?.baselineDecodeMs)&&e.baselineDecodeMs>0&&Number.isFinite(e?.candidateDecodeMs)&&e.candidateDecodeMs>0}function mt(e){return Number.isInteger(e)&&e>=0}function hn(e){if(!Array.isArray(e)||e.length===0)return{pairCount:0,wallGain:null,decodeGain:null,medianWallGain:null,medianDecodeGain:null,weightedWallGain:null,weightedDecodeGain:null,favorableRegions:0,complete:!1,exact:!1,shrinkFree:!1};const t=e.some(b=>b?.weight!==void 0),r=(!t||e.every(b=>Number.isFinite(b?.weight)&&b.weight>0))&&e.every(Mr),o=r&&e.every(b=>b.complete===!0),i=e.every(b=>b.exact===!0),c=e.every(b=>mt(b.baselineSubmitShrinks)&&mt(b.candidateSubmitShrinks))&&e.every(b=>b.baselineSubmitShrinks===0&&b.candidateSubmitShrinks===0),u=r?e.map(b=>$t(b.baselineWallMs,b.candidateWallMs)):[],l=r?e.map(b=>$t(b.baselineDecodeMs,b.candidateDecodeMs)):[],h=t&&r?e.map(b=>b.weight):[],f=ft(u),g=ft(l),S=t?Yn(u,h):null,A=t?Yn(l,h):null,y=new Set;return r&&e.forEach((b,v)=>{u[v]>0&&y.add(String(b.region))}),{pairCount:e.length,wallGain:S===null?f:Math.min(f,S),decodeGain:A===null?g:Math.min(g,A),medianWallGain:f,medianDecodeGain:g,weightedWallGain:S,weightedDecodeGain:A,favorableRegions:y.size,complete:o,exact:i,shrinkFree:c}}function $i(e,t="base"){if(!Array.isArray(e)||e.length===0)throw new Error("screen results must be a non-empty array");const n=e.find(o=>o?.id===t);if(!n)throw new Error(`screen results are missing baseline ${t}`);const r=e.filter(o=>o?.id!==t&&o?.exact===!0&&o?.submitShrinks===0&&Number.isFinite(o?.score)&&o.score>0).sort((o,i)=>o.score-i.score||String(o.id).localeCompare(String(i.id)))[0]??null;return{base:n,candidate:r}}function er({screenPairs:e,confirmationPairs:t=[]}={}){const n=hn(e),r=Array.isArray(t)?t:[],o=hn(r),i=Array.isArray(t)&&r.length<=qe.length&&r.every((v,oe)=>v?.role===qe[oe]),s=r.every(Mr),c=s?r.map(v=>$t(v.baselineWallMs,v.candidateWallMs)):[],u=s?r.map(v=>$t(v.baselineDecodeMs,v.candidateDecodeMs)):[],l=c.length>0?Math.min(...c):null,h=Number.isFinite(n.wallGain)?Math.min(n.wallGain,...c):n.wallGain,f=Number.isFinite(n.decodeGain)?Math.min(n.decodeGain,...u):n.decodeGain,g=[...Array.isArray(e)?e:[],...r],S=g.every(v=>mt(v?.baselineSubmitShrinks)&&mt(v?.candidateSubmitShrinks)&&v.baselineSubmitShrinks===0&&v.candidateSubmitShrinks===0),A=g.every(v=>v?.exact===!0),y={promote:!1,reason:null,wallGain:h,screenWallGain:n.wallGain,confirmationMinWallGain:l,decodeGain:f,favorableRegions:n.favorableRegions,confirmationCount:Array.isArray(t)?r.filter(v=>v?.complete===!0).length:0,requiredConfirmations:qe.length,completedRoles:r.filter(v=>v?.complete===!0).map(v=>v.role)};return!n.complete||!i||r.length>0&&!o.complete?{...y,reason:"incomplete"}:S?A?n.favorableRegions=ai?n.decodeGain>=0?c.some(v=>v<=0)||u.some(v=>v<0)?{...y,reason:"confirmation-regression"}:c.some(v=>vG(u,"run cost"));G(r,"safetyFactor");const c=s.reduce((u,l)=>u+o*(l/i),0);return{rawGpuMs:c,projectedMs:c*r,runCount:s.length}}function Fi({kernelReferenceMs:e,kernelReferenceCost:t,sampleCosts:n,armCount:r=_e.length,confirmationRounds:o=2,pretokenizeMs:i=0,safetyFactor:s=Gt}={}){const c=G(e,"kernelReferenceMs"),u=G(t,"kernelReferenceCost");if(!Array.isArray(n)||n.length===0)throw new Error("sampleCosts must be a non-empty array");const l=n.map(S=>G(S,"sample cost"));if(me(r,"armCount"),!Number.isInteger(o)||o<0)throw new Error("confirmationRounds must be a non-negative integer");Le(i,"pretokenizeMs"),G(s,"safetyFactor");const h=l.flatMap(S=>Array(r).fill(S)),f=o*2;h.push(...Array(f).fill(ft(l)));const g=fn({referenceMs:c,referenceCost:u,runCosts:h,safetyFactor:s});return{rawGpuMs:g.rawGpuMs,rawProjectedMs:i+g.rawGpuMs,projectedMs:i+g.projectedMs,screenRuns:l.length*r,confirmationRuns:f,completeRuns:h.length,runCosts:h}}function Oi(e,t=Lt,n=En){const r=e?.projectedMs,o=e?.rawProjectedMs;if(!Number.isFinite(r)||r<0||!Number.isFinite(t)||t<=0||!Number.isFinite(n)||n<0||n>=t)return{admit:!1,reason:"invalid-projection",projectedMs:Number.isFinite(r)?r:null,rawProjectedMs:Number.isFinite(o)?o:null,budgetMs:Number.isFinite(t-n)?t-n:null,admission:null};const i=t-n,s=r<=i,c=!s&&Number.isFinite(o)&&o>=0&&o<=i,u=s||c;return{admit:u,reason:u?null:"projected-over-budget",projectedMs:r,rawProjectedMs:Number.isFinite(o)?o:null,budgetMs:i,admission:s?"full":c?"pilot":null}}function _i({elapsedMs:e,projectedRunMs:t,deadlineMs:n=Lt,marginMs:r=En,safetyFactor:o=Gt}={}){if(!(Number.isFinite(e)&&e>=0&&Number.isFinite(t)&&t>0&&Number.isFinite(n)&&n>0&&Number.isFinite(r)&&r>=0&&Number.isFinite(o)&&o>0))return{admit:!1,reason:"invalid-projection",projectedEndMs:null,remainingMs:Number.isFinite(n-e)?n-e:null};const s=e+t*o+r;return{admit:s<=n,reason:s<=n?null:"projected-over-budget",projectedEndMs:s,remainingMs:n-e}}function Qt({elapsedMs:e,deadlineMs:t=Lt}={}){Le(e,"elapsedMs"),G(t,"deadlineMs");const n=Math.max(0,e-t);return{elapsedMs:e,deadlineMs:t,deadlineExceeded:n>0,overrunMs:n}}function Cr({adapterKey:e,modelId:t,weightsId:n,dtype:r,browserMajor:o,kernelTuneId:i,modes:s,signature:c}={}){if(!Number.isInteger(o)||o<0)throw new Error(`browserMajor must be a non-negative integer, got ${o}`);if(!s||typeof s!="object"||Array.isArray(s))throw new Error("modes must be an object");if(!c||typeof c!="object")throw new Error("signature must be an object");const u={};for(const[l,h]of Object.entries(s)){if(!gi.has(l))throw new Error(`modes contains unknown key ${l}`);if(bi.has(l)){if(typeof h!="boolean")throw new Error(`modes.${l} must be boolean`);u[l]=h}else l==="tokenBudget"?u[l]=h===1/0?"inf":G(h,"modes.tokenBudget"):u[l]=q(h,`modes.${l}`)}return Mn({protocolRev:je,adapterKey:q(e,"adapterKey"),modelId:q(t,"modelId"),weightsId:q(n,"weightsId"),dtype:q(r,"dtype",32),browserMajor:o,kernelTuneId:q(i,"kernelTuneId"),modes:u,signature:c})}function Li(e={}){const t=Mn({amortizationRev:bt,scheduleIdentity:Cr(e)});return q(t,"observation identity",We)}function xr(e){let t=2166136261;for(let n=0;n>>0).toString(16).padStart(8,"0")}function Gi(e){return q(e,"cache identity",We),`moxhi.schedule.v${je}.${xr(e)}`}function Di(e){return q(e,"observation scope identity",We),`moxhi.schedule-observation.v${bt}.${xr(e)}`}function mn(e,t="observedShape"){if(e!=null){if(!e||typeof e!="object")throw new Error(`${t} must be an object`);if(G(e.targetTokenP50,`${t}.targetTokenP50`),G(e.targetTokenP90,`${t}.targetTokenP90`),e.targetTokenP901)throw new Error(`${t}.compactionRate must be between zero and one`)}}function pt(e){if(!e||typeof e!="object"||Array.isArray(e))throw new Error("cache entry must be an object");if(!Number.isInteger(e.protocolRev)||e.protocolRev<=0)throw new Error("cache entry protocolRev must be a positive integer");if(q(e.identity,"cache entry identity",We),q(e.scopeKey,"cache entry scopeKey",512),q(e.kernelTuneId,"cache entry kernelTuneId",512),q(e.signatureKey,"cache entry signatureKey",We),Le(e.createdAt,"cache entry createdAt"),Le(e.lastUsedAt,"cache entry lastUsedAt"),!fi.has(e.ttlClass))throw new Error(`cache entry ttlClass is invalid: ${e.ttlClass}`);if(!mi.has(e.verdict))throw new Error(`cache entry verdict is invalid: ${e.verdict}`);if(!wi(e.schedule))throw new Error("cache entry schedule is not a version-1 arm");if(!Number.isInteger(e.screenSubmitShrinks)||e.screenSubmitShrinks<0)throw new Error("cache entry screenSubmitShrinks must be a non-negative integer");const t=e.schedule.inFlight===Te.inFlight&&e.schedule.groupSteps===Te.groupSteps,n=pi.has(e.verdict);if(n&&e.ttlClass!=="negative"||!n&&e.ttlClass!=="normal")throw new Error("cache entry ttlClass does not match its verdict");if(e.verdict==="selected"){if(t)throw new Error("selected cache verdict must use a non-default schedule");if(e.screenSubmitShrinks!==0)throw new Error("selected cache verdict requires zero-shrink proof")}else if(!t)throw new Error("non-selected cache verdict must use the default schedule");if(e.verdict==="keep-default"&&e.screenSubmitShrinks!==0)throw new Error("keep-default cache verdict requires zero-shrink proof");if(e.verdict==="safety-fallback"&&e.screenSubmitShrinks===0)throw new Error("safety-fallback cache verdict requires a submit shrink");if(n&&e.screenSubmitShrinks!==0)throw new Error("negative cache verdict cannot contain completed shrink evidence");if(mn(e.observedShape),e.invalidatedReason!==void 0&&(typeof e.invalidatedReason!="string"||e.invalidatedReason.length===0||e.invalidatedReason.length>128))throw new Error("cache entry invalidatedReason is invalid");if(!e.evidence||typeof e.evidence!="object"||Array.isArray(e.evidence))throw new Error("cache entry evidence must be an object");for(const[o,i]of Object.entries(e.evidence)){if(!vi.has(o))throw new Error(`cache entry evidence contains unknown key ${o}`);if(yi.has(o)){if(!Number.isInteger(i)||i<0)throw new Error(`cache entry evidence.${o} must be a non-negative integer`)}else if(Si.has(o))Le(i,`cache entry evidence.${o}`);else if(o==="exact"){if(typeof i!="boolean")throw new Error("cache entry evidence.exact must be boolean")}else if(!Number.isFinite(i))throw new Error(`cache entry evidence.${o} must be finite`)}if(e.verdict==="selected"&&e.evidence.confirmationCount!==qe.length)throw new Error("selected cache verdict requires both confirmation roles");let r;try{r=JSON.stringify(e.evidence??null).length}catch{throw new Error("cache entry evidence is not serializable")}if(r>di)throw new Error("cache entry evidence exceeds the bounded payload limit");return e}function Ar(e){e.forEach(pt);const t=new Map;for(const n of e){const r=(t.get(n.scopeKey)??0)+1;if(r>kn)throw new Error("cache entries exceed the per-scope LRU bound");t.set(n.scopeKey,r)}}function Ui({identity:e,scopeKey:t,kernelTuneId:n,signatureKey:r,createdAt:o,lastUsedAt:i=o,ttlClass:s,verdict:c,schedule:u,observedShape:l=null,screenSubmitShrinks:h=0,evidence:f={}}={}){const g={protocolRev:je,identity:e,scopeKey:t,kernelTuneId:n,signatureKey:r,createdAt:o,lastUsedAt:i,ttlClass:s,verdict:c,schedule:u&&{inFlight:u.inFlight,groupSteps:u.groupSteps},observedShape:l?{...l}:null,screenSubmitShrinks:h,evidence:{...f}};return pt(g),g}function ji(e){if(!Array.isArray(e)||e.length>Bt)throw new Error(`cache entries must be an array of at most ${Bt}`);return Ar(e),JSON.stringify({schema:Er,entries:e})}function Hi(e){if(e==null||e==="")return{status:"miss",entries:[]};try{const t=JSON.parse(e);return t?.schema!==Er||!Array.isArray(t.entries)||t.entries.length>Bt?{status:"corrupt",entries:[]}:(Ar(t.entries),{status:null,entries:t.entries})}catch{return{status:"corrupt",entries:[]}}}function tr(e,t){return Math.max(e,t)/Math.min(e,t)}function Pr(e,t){try{mn(e,"storedShape"),mn(t,"currentShape")}catch{return!0}return!e||!t?!1:tr(e.targetTokenP50,t.targetTokenP50)>Qn||tr(e.targetTokenP90,t.targetTokenP90)>Qn}function zi(e,{now:t=Date.now(),identity:n,kernelTuneId:r,signatureKey:o,observedShape:i=null}={}){try{pt(e)}catch{return{status:"corrupt-entry",entry:null}}if(e.protocolRev!==je)return{status:"protocol-mismatch",entry:null};if(e.invalidatedReason)return{status:e.invalidatedReason,entry:null};if(e.identity!==n)return{status:"identity-mismatch",entry:null};if(e.kernelTuneId!==r)return{status:"kernel-tune-mismatch",entry:null};if(e.signatureKey!==o)return{status:"signature-mismatch",entry:null};const s=e.ttlClass==="negative"?li:Sr,c=t-e.createdAt;return!Number.isFinite(t)||c<0||c>=s?{status:"expired",entry:null}:i&&e.observedShape&&Pr(e.observedShape,i)?{status:"shape-drift",entry:null}:{status:null,entry:e}}function nr(e,t,n=kn){if(!Array.isArray(e))throw new Error("cache entries must be an array");pt(t),me(n,"maxPerScope");const r=e.map(s=>pt(s)).filter(s=>s.identity!==t.identity);r.push(t);const o=new Map;for(const s of r){const c=o.get(s.scopeKey)??[];c.push(s),o.set(s.scopeKey,c)}const i=[];for(const s of o.values())s.sort((c,u)=>u.lastUsedAt-c.lastUsedAt||u.createdAt-c.createdAt||c.identity.localeCompare(u.identity)),i.push(...s.slice(0,n));return i.sort((s,c)=>c.lastUsedAt-s.lastUsedAt||c.createdAt-s.createdAt||s.identity.localeCompare(c.identity)).slice(0,Bt)}function Yt(e,t){if(!Array.isArray(e))throw new Error("cache entries must be an array");return q(t,"cache identity",We),e.filter(n=>n?.identity!==t)}const Wi=new Set(["amortizationRev","protocolRev","identity","scopeKey","kernelTuneId","signatureKey","createdAt","lastUsedAt","schedule","profiledWallMs","profiledDecodeMs","rowCount","batchCount","tokenCount","submitShrinks"]);function it(e){if(!e||typeof e!="object"||Array.isArray(e))throw new Error("observation entry must be an object");for(const t of Object.keys(e))if(!Wi.has(t))throw new Error(`observation entry contains unknown key ${t}`);if(!Number.isInteger(e.amortizationRev)||e.amortizationRev<=0)throw new Error("observation entry amortizationRev must be a positive integer");if(!Number.isInteger(e.protocolRev)||e.protocolRev<=0)throw new Error("observation entry protocolRev must be a positive integer");if(q(e.identity,"observation entry identity",We),q(e.scopeKey,"observation entry scopeKey",512),q(e.kernelTuneId,"observation entry kernelTuneId",512),q(e.signatureKey,"observation entry signatureKey",We),Le(e.createdAt,"observation entry createdAt"),Le(e.lastUsedAt,"observation entry lastUsedAt"),e.lastUsedAtwr)throw new Error("observations exceed the per-scope LRU bound");t.set(n.scopeKey,r)}}function Ki({amortizationRev:e,protocolRev:t,identity:n,scopeKey:r,kernelTuneId:o,signatureKey:i,createdAt:s,lastUsedAt:c=s,schedule:u=Te,profiledWallMs:l,profiledDecodeMs:h,rowCount:f,batchCount:g,tokenCount:S,submitShrinks:A=0,...y}={}){const b=Object.keys(y)[0];if(b)throw new Error(`observation entry contains unknown key ${b}`);const v={amortizationRev:bt,protocolRev:je,identity:n,scopeKey:r,kernelTuneId:o,signatureKey:i,createdAt:s,lastUsedAt:c,schedule:u&&{inFlight:u.inFlight,groupSteps:u.groupSteps},profiledWallMs:l,profiledDecodeMs:h,rowCount:f,batchCount:g,tokenCount:S,submitShrinks:A};return it(v),v}function Vi(e){if(!Array.isArray(e)||e.length>Nt)throw new Error(`observations must be an array of at most ${Nt}`);return Tr(e),JSON.stringify({schema:kr,entries:e})}function rr(e){if(e==null||e==="")return{status:"miss",entries:[]};try{const t=JSON.parse(e);return t?.schema!==kr||!Array.isArray(t.entries)||t.entries.length>Nt||Object.keys(t).some(n=>!["schema","entries"].includes(n))?{status:"corrupt",entries:[]}:(Tr(t.entries),{status:null,entries:t.entries})}catch{return{status:"corrupt",entries:[]}}}function qi(e,{now:t=Date.now(),identity:n,kernelTuneId:r,signatureKey:o}={}){try{it(e)}catch{return{status:"corrupt-entry",entry:null}}return e.amortizationRev!==bt?{status:"amortization-mismatch",entry:null}:e.protocolRev!==je?{status:"protocol-mismatch",entry:null}:e.identity!==n?{status:"identity-mismatch",entry:null}:e.kernelTuneId!==r?{status:"kernel-tune-mismatch",entry:null}:e.signatureKey!==o?{status:"signature-mismatch",entry:null}:!Number.isFinite(t)||t=ui?{status:"expired",entry:null}:{status:null,entry:e}}function or(e,t,n=wr){if(!Array.isArray(e))throw new Error("observations must be an array");it(t),me(n,"maxPerScope");const r=e.map(s=>it(s)).filter(s=>s.identity!==t.identity);r.push(t);const o=new Map;for(const s of r){const c=o.get(s.scopeKey)??[];c.push(s),o.set(s.scopeKey,c)}const i=[];for(const s of o.values())s.sort((c,u)=>u.lastUsedAt-c.lastUsedAt||u.createdAt-c.createdAt||c.identity.localeCompare(u.identity)),i.push(...s.slice(0,n));return i.sort((s,c)=>c.lastUsedAt-s.lastUsedAt||c.createdAt-s.createdAt||s.identity.localeCompare(c.identity)).slice(0,Nt)}function Xt(e){return{status:"needs-baseline-observation",reason:e,admit:!1,observedProfiledWallMs:null,minimumExpectedSavingMs:null,projectedWorstCaseScreenMs:null,paybackRatio:null}}function Ji({observation:e=null,projection:t=null,promotionGain:n=yr}={}){if(!e)return Xt("missing-observation");try{it(e)}catch{return Xt("invalid-observation")}const r=t?.projectedMs;if(!(Number.isFinite(r)&&r>0&&Number.isFinite(n)&&n>0&&n<=1))return Xt("invalid-projection");const o=e.profiledWallMs,i=o*n,s=i/r,c=i>=r;return{status:c?"admitted":"unamortized",reason:c?null:"insufficient-payback",admit:c,observedProfiledWallMs:o,minimumExpectedSavingMs:i,projectedWorstCaseScreenMs:r,paybackRatio:s}}function Qi(e,t,{required:n=!1,max:r=1/0}={}){if(!Array.isArray(e)||n&&e.length===0)throw new Error(`${t} must be ${n?"a non-empty":"an"} array`);if(e.length>r)throw new Error(`${t} exceeds its bounded size`);const o=e.map(i=>{if(!Number.isInteger(i)||i<0)throw new Error(`${t} must contain non-negative integers`);return i});if(new Set(o).size!==o.length)throw new Error(`${t} must not contain duplicates`);return[...o].sort((i,s)=>i-s)}function Yi(e){if(!Array.isArray(e))throw new Error("confirmationPlan must be an array");if(e.length>qe.length)throw new Error("confirmationPlan exceeds its bounded size");const t=e.map((n,r)=>{if(!n||typeof n!="object"||Array.isArray(n))throw new Error(`confirmationPlan[${r}] must be an object`);if(Object.keys(n).some(c=>!["role","batchIndex","region"].includes(c)))throw new Error(`confirmationPlan[${r}] contains an unknown key`);const i=qe[r];if(n.role!==i)throw new Error(`confirmationPlan[${r}] must have role ${i}`);if(!Number.isInteger(n.batchIndex)||n.batchIndex<0)throw new Error(`confirmationPlan[${r}].batchIndex must be non-negative`);if(!(Number.isInteger(n.region)&&n.region>0||typeof n.region=="string"&&n.region.length>0&&n.region.length<=64))throw new Error(`confirmationPlan[${r}].region is invalid`);return{role:n.role,batchIndex:n.batchIndex,region:n.region}});if(new Set(t.map(({batchIndex:n})=>n)).size!==t.length)throw new Error("confirmationPlan batch indices must not contain duplicates");return t}function Xi(e,t){const n=t%e.length;return[...e.slice(n),...e.slice(0,n)]}function ir(e,t=e.groupSteps){return{inFlight:e.inFlight,groupSteps:ki(e.groupSteps,t)}}function Zi(e,t){return`${e}:${t}`}function es(e){if(!Array.isArray(e)||e.length===0)throw new Error("runBatch rows must be a non-empty array");const t=e.map((n,r)=>{if(!n||typeof n!="object"||!Array.isArray(n.ids)||n.ids.length<2||n.ids.some(o=>!Number.isInteger(o)||o<0)||typeof n.forcedEos!="boolean")throw new Error(`runBatch rows[${r}] is invalid`);return[n.ids,n.forcedEos]});return{fingerprint:JSON.stringify(t),targetTokenLengths:e.map(n=>n.ids.length-1)}}function ts(e,t){if(!e||typeof e!="object"||Array.isArray(e))throw new Error("runBatch result must be an object");if(e.cleanupComplete!==!0)throw new Error("runBatch cleanupComplete evidence must be true");const n=me(e.groupStepsStart,"runBatch groupStepsStart"),r=me(e.groupStepsFinal,"runBatch groupStepsFinal");if(n!==t.groupSteps)throw new Error("runBatch groupStepsStart does not match the admitted schedule");if(r>n)throw new Error("runBatch groupStepsFinal must not grow");if(!mt(e.submitShrinks))throw new Error("runBatch submitShrinks must be a non-negative integer");if(e.submitShrinks===0&&r!==n||e.submitShrinks>0&&r>=n)throw new Error("runBatch submitShrinks and groupStepsFinal are inconsistent");if(!Number.isInteger(e.compactions)||e.compactions<0)throw new Error("runBatch compactions must be a non-negative integer");return{...es(e.rows),groupStepsStart:n,groupStepsFinal:r,submitShrinks:e.submitShrinks,wallMs:G(e.wallMs,"runBatch wallMs"),decodeMs:G(e.decodeMs,"runBatch decodeMs"),compactions:e.compactions}}function ns(e){return _e.map(t=>{const n=e.get(t.id),r=ft(n.records.map(s=>s.wallMs)),o=ft(n.records.map(s=>s.decodeMs)),i={id:t.id,status:n.status==="pending"&&n.records.length>0?"partial":n.status,completedRuns:n.records.length,submitShrinks:n.records.reduce((s,c)=>s+c.submitShrinks,0)};return r!==null&&(i.medianWallMs=r),o!==null&&(i.medianDecodeMs=o),i})}function rs(e){if(!e||e.records.length===0)return null;const t=e.records.filter(r=>r.phase==="screen"),n=t.flatMap(r=>r.targetTokenLengths);return n.length===0?null:{targetTokenP50:un(n,.5),targetTokenP90:un(n,.9),compactionRate:t.filter(r=>r.compactions>0).length/t.length}}function os(e){if(!e||typeof e!="object"||Array.isArray(e))throw new Error("safetyOptions must be an object");if(G(e.submitBudgetMs,"safetyOptions.submitBudgetMs"),typeof e.encSplitSubmits!="boolean")throw new Error("safetyOptions.encSplitSubmits must be boolean");return Object.freeze({...e})}function sr(e){const t=e();if(!Number.isFinite(t))throw new Error("schedule tuner clock must be finite");return t}function ar({decision:e=null,sampleCount:t=0,confirmationCount:n=0,tuneMs:r,projectedMs:o,actualMs:i,overrunMs:s,exact:c=!1,includePerformance:u=!0}){const l={sampleCount:t,confirmationCount:n,tuneMs:r,projectedMs:o,actualMs:i,overrunMs:s,exact:c};return u&&(l.favorableRegions=e?.favorableRegions??0,Number.isFinite(e?.wallGain)&&(l.wallGain=e.wallGain),Number.isFinite(e?.screenWallGain)&&(l.screenWallGain=e.screenWallGain),Number.isFinite(e?.confirmationMinWallGain)&&(l.confirmationMinWallGain=e.confirmationMinWallGain),Number.isFinite(e?.decodeGain)&&(l.decodeGain=e.decodeGain)),l}async function Rr({sampleBatchIndices:e,confirmationPlan:t=[],workloadBatchCosts:n,batchRegions:r=null,kernelReferenceMs:o,kernelReferenceCost:i,safetyOptions:s,pretokenize:c,estimateBatch:u,runBatch:l,now:h=Date.now,isCancelled:f=()=>!1,isDeviceHealthy:g=()=>!1,deadlineMs:S=Lt,marginMs:A=En,safetyFactor:y=Gt,pretokenizeEstimateMs:b=0}={}){const v=Qi(e,"sampleBatchIndices",{required:!0,max:wn.length}),oe=Yi(t);if(oe.some(({batchIndex:m})=>v.includes(m)))throw new Error("confirmationPlan batches must be unused by the screen");const Ee=Ni(n,v),M=new Map(v.map((m,w)=>[m,Ee[w]]));let F=null;if(r!=null){if(!Array.isArray(r)||r.length===0)throw new Error("batchRegions must be a non-empty array");if(F=r.map((w,E)=>{if(Number.isInteger(w)&&w>0||typeof w=="string"&&w.length>0&&w.length<=64)return w;throw new Error(`batchRegions[${E}] is invalid`)}),Math.max(...v,...oe.map(({batchIndex:w})=>w))>=F.length)throw new Error("batchRegions must cover every screen and confirmation batch");for(const w of oe)if(It(w.region)!==It(F[w.batchIndex]))throw new Error(`confirmationPlan ${w.role} region does not match batchRegions`)}for(const[m,w]of[[c,"pretokenize"],[u,"estimateBatch"],[l,"runBatch"],[h,"now"],[f,"isCancelled"],[g,"isDeviceHealthy"]])if(typeof m!="function")throw new Error(`${w} must be a function`);if(G(o,"kernelReferenceMs"),G(i,"kernelReferenceCost"),G(S,"deadlineMs"),Le(A,"marginMs"),A>=S)throw new Error("marginMs must be below deadlineMs");G(y,"safetyFactor"),Le(b,"pretokenizeEstimateMs");const X=os(s),B=new Map(_e.map(m=>[m.id,{arm:m,carry:Ei(m.groupSteps),status:"pending",records:[]}])),ve=v.flatMap((m,w)=>Xi(_e,w).map(E=>({phase:"screen",batchIndex:m,samplePosition:w,region:F?.[m]??`sample-${w+1}`,arm:E}))),pe=new Map,Re=async(m,w)=>{const E=Zi(m,w.id);if(pe.has(E))return pe.get(E);const I=G(await u(m,ir(w)),`estimateBatch(${m}, ${w.id})`);return pe.set(E,I),I};let p=null,D=null,Ce=0,He=null,xe=0,L=!1,ge=[];const be=[],ne=()=>{if(He===null)return 0;const m=sr(h)-He;if(!Number.isFinite(m)||m<0)throw new Error("schedule tuner clock must be monotonic");return m},U=({verdict:m,reason:w=m,schedule:E=Te,source:I="default",cacheable:H,ttlClass:R,decision:z=null,exact:ae=!1,includeCandidateEvidence:ce=!0,includeObservedShape:Ge=!0})=>{const ee=ne(),Se=Qt({elapsedMs:ee,deadlineMs:S}),st=ar({decision:z,sampleCount:L?v.length:ge.length,confirmationCount:be.length,tuneMs:ee,projectedMs:Ce,actualMs:ee,overrunMs:Se.overrunMs,exact:ae,includePerformance:!0}),Ye=H?ar({decision:z,sampleCount:L?v.length:ge.length,confirmationCount:be.length,tuneMs:ee,projectedMs:Ce,actualMs:ee,overrunMs:Se.overrunMs,exact:ae,includePerformance:R!=="negative"}):{};return{protocolRev:je,verdict:m,reason:w,schedule:{inFlight:E.inFlight,groupSteps:E.groupSteps},source:I,screenSubmitShrinks:xe,scheduleTuneMs:ee,evidence:st,confirmationPlan:oe.map(Xe=>({...Xe})),completedConfirmationRoles:z?.completedRoles?[...z.completedRoles]:[],candidateEvidence:ce?ns(B):[],observedShape:Ge?rs(B.get("base")):null,projection:{preGate:p?{rawGpuMs:p.rawGpuMs,rawProjectedMs:p.rawProjectedMs,projectedMs:p.projectedMs,runCount:p.runCount,budgetMs:p.budgetMs,admission:p.admission}:null,postPilot:D?{...D}:null},deadline:Se,cache:{cacheable:H,ttlClass:R,evidence:Ye}}},ie=()=>U({verdict:"cancelled",cacheable:!1,ttlClass:null,includeCandidateEvidence:!1,includeObservedShape:!1}),re=m=>U({verdict:m,cacheable:!0,ttlClass:"negative",includeCandidateEvidence:!1,includeObservedShape:!1});if(f())return ie();const _=[];for(const m of ve){if(f())return ie();_.push(await Re(m.batchIndex,m.arm))}const se=fn({referenceMs:o,referenceCost:i,runCosts:_,safetyFactor:y});p={...se,rawProjectedMs:b+se.rawGpuMs,projectedMs:b+se.projectedMs},Ce=p.projectedMs;const Be=Oi(p,S,A);if(p.budgetMs=Be.budgetMs,p.admission=Be.admission,!Be.admit)return re("projected-over-budget");He=sr(h);const Ne=[...new Set([...v,...oe.map(({batchIndex:m})=>m)])].sort((m,w)=>m-w);for(const m of Ne)if(f()||(await c(m),f()))return ie();if(ne()>=S)return re("timeout");let he={ms:o,cost:i};const $=async m=>{if(f())return{terminal:ie()};const w=ne();if(w>=S)return{terminal:re("timeout")};const E=B.get(m.arm.id),I=ir(m.arm,E.carry),H=await Re(m.batchIndex,m.arm),R=he.ms*(H/he.cost),z=_i({elapsedMs:w,projectedRunMs:R,deadlineMs:S,marginMs:A,safetyFactor:y});if(!z.admit)return Number.isFinite(z.projectedEndMs)&&(Ce=z.projectedEndMs),{terminal:re("projected-over-budget")};let ae;try{ae=await l(m.batchIndex,I,X)}catch(ee){if(f())return{terminal:ie()};if(m.arm.id==="base"||!await g(ee))throw ee;return E.status="error",Qt({elapsedMs:ne(),deadlineMs:S}).deadlineExceeded?{terminal:re("admission-overrun")}:{candidateError:!0}}const ce=ts(ae,I);if(f())return{terminal:ie()};if(ce.submitShrinks>0){xe+=ce.submitShrinks;const ee={...ce};return delete ee.fingerprint,E.status="submit-shrink",E.records.push({phase:m.phase,batchIndex:m.batchIndex,region:m.region,...ee}),{terminal:U({verdict:"safety-fallback",reason:"submit-shrink",source:"measured",cacheable:!0,ttlClass:"normal",exact:!1})}}return E.carry=Mi(E.carry,ce.groupStepsFinal),Qt({elapsedMs:ne(),deadlineMs:S}).deadlineExceeded?{terminal:re("admission-overrun")}:{trial:{...ce,cost:H}}},x=new Map,Qe=(m,w)=>{const E=B.get(m.arm.id),{fingerprint:I,...H}=w,R={phase:"screen",batchIndex:m.batchIndex,region:m.region,...H};E.records.push(R);const z=x.get(m.batchIndex)??new Map;if(z.set(m.arm.id,I),x.set(m.batchIndex,z),m.arm.id==="base")for(const ae of _e.slice(1)){const ce=z.get(ae.id);ce!==void 0&&ce!==I&&(B.get(ae.id).status="output-mismatch")}else{const ae=z.get("base");ae!==void 0&&ae!==I&&(E.status="output-mismatch")}},k=ve[0],J=await $(k);if(J.terminal)return J.terminal;Qe(k,J.trial),he={ms:J.trial.wallMs,cost:J.trial.cost};const Q=_.slice(1);if(Q.length>0){const m=fn({referenceMs:he.ms,referenceCost:he.cost,runCosts:Q,safetyFactor:y}),w=ne(),E=w+m.rawGpuMs+A,I=w+m.projectedMs+A,H=I<=S,R=!H&&E<=S;if(D={rawGpuMs:m.rawGpuMs,projectedMs:m.projectedMs,runCount:m.runCount,rawProjectedEndMs:E,projectedEndMs:I,admission:H?"full":R?"per-run":null},Ce=D.projectedEndMs,!H&&!R)return re("projected-over-budget")}let N=k.batchIndex;for(const m of ve.slice(1)){m.batchIndex!==N&&(x.delete(N),N=m.batchIndex);const w=B.get(m.arm.id);if(m.arm.id!=="base"&&w.status!=="pending")continue;const E=await $(m);if(E.terminal)return E.terminal;E.candidateError||Qe(m,E.trial)}x.clear(),L=!0,B.get("base").status="complete";for(const m of _e.slice(1)){const w=B.get(m.id),E=w.records.filter(I=>I.phase==="screen");w.status==="pending"&&(w.status=E.length===v.length?"complete":"incomplete")}const ye=new Map,Z=m=>{const w=B.get(m.id);return v.map(E=>{const I=B.get("base").records.find(R=>R.phase==="screen"&&R.batchIndex===E),H=w.records.find(R=>R.phase==="screen"&&R.batchIndex===E);return{region:I.region,weight:M.get(E),baselineWallMs:I.wallMs,candidateWallMs:H.wallMs,baselineDecodeMs:I.decodeMs,candidateDecodeMs:H.decodeMs,complete:!0,exact:!0,baselineSubmitShrinks:I.submitShrinks,candidateSubmitShrinks:H.submitShrinks}})},Ae=_e.map(m=>{const w=B.get(m.id),E=w.records.filter(R=>R.phase==="screen"),I=m.id==="base"||w.status==="complete";let H=1;if(m.id!=="base"&&I){const R=Z(m);ye.set(m.id,R);const z=hn(R);H=1-(z.weightedWallGain??z.wallGain)}return{id:m.id,score:H,exact:I,submitShrinks:E.reduce((R,z)=>R+z.submitShrinks,0)}}),{candidate:O}=$i(Ae);if(!O)return U({verdict:"keep-default",reason:"no-exact-candidate",source:"measured",cacheable:!0,ttlClass:"normal",exact:!1});const j=B.get(O.id).arm,le=B.get(O.id);ge=ye.get(O.id);let K=er({screenPairs:ge});if(K.reason!=="needs-confirmation")return U({verdict:"keep-default",reason:K.reason,source:"measured",cacheable:!0,ttlClass:"normal",decision:K,exact:!0});for(let m=0;mn.inFlight===e.inFlight&&n.groupSteps===e.groupSteps);if(!t)throw new Error("decodeScheduleOverride must be a version-1 schedule arm");return{inFlight:t.inFlight,groupSteps:t.groupSteps}}function cr(e=null){return e==="shadow"?"shadow":e==="1"||e==="apply"?"apply":e==="auto"?"auto":"off"}function ls(e,t,n,r={}){const o=e??{},i=["dModel","heads","headDim","ffn","encLayers","decLayers","vocab","maxPos","srcCap","decodeCap"].map(l=>t[l]??"").join("x"),s=`${r.subgroupMinSize??0}-${r.subgroupMaxSize??0}`,c=r.immediates==="on"?"on":"off",u=r.uniformPool===!0||r.uniformPool==="on"||r.uniformPool==="b64"?"b64":"off";return[`moxhi.autotune.v${pr}`,o.vendor??"",o.architecture??"",o.device??"",`sg${s}`,i,n,`imm${c}`,`pool${u}`,r.browserMajor??"unknown"].join("|")}const us=720*3600*1e3;function ds(e){if(e==null)return{parsed:null,status:"miss"};try{const t=JSON.parse(e);return!t||typeof t!="object"||Array.isArray(t)?{parsed:null,status:"corrupt"}:{parsed:t,status:null}}catch{return{parsed:null,status:"corrupt"}}}function hs(e,t,n=Date.now(),r=us){const o=Date.parse(e?.date??""),i=n-o;return!Number.isFinite(o)||i<0||i>=r?{status:"expired",measuredAt:null}:go(e?.tuned,t)?{status:null,measuredAt:o}:{status:"safety-rejected",measuredAt:null}}function fs(e,t){return bo(e,t)?"accepted":"mismatch"}const ms=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,ps=e=>typeof e=="string"&&ms.test(e)?e:null,ct=(e,{priorTuneId:t=null,cachedUs:n=null,currentUs:r=null,error:o=null}={})=>({status:e,priorTuneId:t,cachedUs:n,currentUs:r,error:o});function gs(e){return e.map((t,n)=>n).sort((t,n)=>e[t]-e[n])}function bs(e,t=192,n=576){return Math.max(t,Math.min(n,Math.floor(t*224/e)))}function xn({ua:e="",maxTouchPoints:t=0}={}){const n=typeof e=="string"?e:"";return/iPhone|iPad|iPod|Android/.test(n)||/Macintosh/.test(n)&&t>1}function vs({ua:e=""}={}){return/Android/.test(typeof e=="string"?e:"")}function Br({ua:e="",maxTouchPoints:t=0,capParam:n=null}={}){const r=Math.floor(Number(n));return Number.isFinite(r)&&r>=1?Math.min(r,2048):xn({ua:e,maxTouchPoints:t})?192:576}function Nr({ua:e="",maxTouchPoints:t=0,budgetParam:n=null}={}){if(typeof n=="string"&&n.trim()==="0")return 1/0;const r=Math.floor(Number(n));return n!==""&&n!==null&&n!==void 0&&Number.isFinite(r)&&r>=1?Math.min(r,1024*1024):xn({ua:e,maxTouchPoints:t})?16*1024:1/0}const lr="moxhi-mobile-kv-v2";function Ir(e=null){if(e==null||String(e).trim()==="")return{mode:"auto",capacity:null};const t=String(e).trim();if(t==="0")return{mode:"legacy",capacity:null};if(!/^\d+$/.test(t))return{mode:"legacy",capacity:null};const n=Number(t);return!Number.isInteger(n)||n<1||n>vn?{mode:"legacy",capacity:null}:{mode:"forced",capacity:n}}function ys(e,{modelId:t="",mobile:n=!1,plannerParam:r=null,kvcapParam:o=null,tokenBudget:i=1/0}={}){if(!Number.isInteger(e)||e<1)throw new Error(`file KV policy: bad S=${e}`);const s=Ir(o),c=r==="1"&&n&&t==="moxhi"&&s.mode!=="legacy",u=s.mode==="forced"?s.capacity:null;if(!c)return{rowCap:null,tokenBudget:i,kvCapacity:u,label:u?`forced-kv${u}`:"legacy-full-kv",autoRows:!1};let l=192,h=vn,f=i;return e<=32?(l=384,h=64,f=1/0):e<=64?(l=192,h=112,f=1/0):e<=96&&(l=192,h=128,f=1/0),{rowCap:l,tokenBudget:f,kvCapacity:u??h,label:u?`${lr}+forced-kv${u}`:lr,autoRows:!0}}function Ss({modelId:e="",ua:t="",maxTouchPoints:n=0,plannerParam:r=null,kvcapParam:o=null,capParam:i=null,budgetParam:s=null}={}){const c=xn({ua:t,maxTouchPoints:n}),u=Ir(o),l=r==="1"&&c&&e==="moxhi"&&u.mode!=="legacy",h=Nr({ua:t,maxTouchPoints:n,budgetParam:s}),f=Br({ua:t,maxTouchPoints:n,capParam:i}),g=i!=null&&String(i).trim()!==""&&Number.isFinite(Number(i))&&Math.floor(Number(i))>=1,S=l&&!g?576:f,A=b=>ys(b,{modelId:e,mobile:c,plannerParam:r,kvcapParam:o,tokenBudget:h}),y=A(32);return{mobile:c,autoRows:l,absCap:S,tokenBudget:h,forcedCapacity:u.mode==="forced"?u.capacity:null,policyLabel:y.label,policyForS:A,kvCapacityForS:b=>A(b).kvCapacity}}function ws({param:e=null}={}){return e==="1"}function ur(){return Br({ua:navigator.userAgent??"",maxTouchPoints:navigator.maxTouchPoints??0,capParam:new URLSearchParams(location.search).get("cap")})}function Es(){return Nr({ua:navigator.userAgent??"",maxTouchPoints:navigator.maxTouchPoints??0,budgetParam:new URLSearchParams(location.search).get("tokenbudget")})}function $r(e,t,n,r=192,o=576,i=1/0,s=null){const c=[],u=[];for(let l=0;lM)break;f=A,g=y,h++}c.push([l,h]),u.push(g),l=h}return{ranges:c,buckets:u}}function ks(e,t,n,r=192,o=576,i=1/0,s=null){return $r(e,t,n,r,o,i,s).ranges}function Ms(){return ws({param:new URLSearchParams(location.search).get("inplacecompact")})}const Me=e=>Math.round(e*10)/10,Zt=e=>Math.round(e*100)/100;async function Cs(e,t=globalThis.crypto){if(!t?.subtle?.digest)throw new Error("SHA-256 unavailable");const n=new TextEncoder().encode(String(e));return[...new Uint8Array(await t.subtle.digest("SHA-256",n))].map(o=>o.toString(16).padStart(2,"0")).join("")}function xs(e,t=null){if(!Array.isArray(e))throw new Error("aggregateBatchProfile needs an array");const n=e.reduce((i,s)=>i+(Number(s.ms)||0),0),r=e.reduce((i,s)=>i+(Number(s.decodeMs)||0),0),o={};for(const i of e){if(!Number.isInteger(i.S)||i.S<1)throw new Error(`aggregateBatchProfile: bad S=${i.S}`);const s=o[i.S]??={batches:0,rows:0,tokens:0,compactions:0,kvGrows:0,kvGrowsWithPending:0,kvGrowBindGroupsPurged:0,ms:0,encoderMs:0,decodeMs:0,maxB:0,maxCap:0,maxSteps:0,maxSourceTokenArea:0,minInitialKvCapacity:1/0,maxInitialKvCapacity:0,maxFinalKvCapacity:0,logicalArenaPeakMB:0,submittedArenaPeakMB:0};s.batches++,s.rows+=Number(i.B)||0,s.tokens+=Number(i.tokens)||0,s.compactions+=Number(i.compactions)||0,s.kvGrows+=Number(i.kvGrows)||0,s.kvGrowsWithPending+=Number(i.kvGrowsWithPending)||0,s.kvGrowBindGroupsPurged+=Number(i.kvGrowBindGroupsPurged)||0,s.ms+=Number(i.ms)||0,s.encoderMs+=Number(i.encoderMs)||0,s.decodeMs+=Number(i.decodeMs)||0,s.maxB=Math.max(s.maxB,Number(i.B)||0),s.maxCap=Math.max(s.maxCap,Number(i.cap)||0),s.maxSteps=Math.max(s.maxSteps,Number(i.steps)||0);const c=Number(i.initialKvCapacity)||0;c>0&&(s.minInitialKvCapacity=Math.min(s.minInitialKvCapacity,c)),s.maxInitialKvCapacity=Math.max(s.maxInitialKvCapacity,c),s.maxFinalKvCapacity=Math.max(s.maxFinalKvCapacity,Number(i.finalKvCapacity)||0),s.maxSourceTokenArea=Math.max(s.maxSourceTokenArea,(Number(i.B)||0)*i.S),s.logicalArenaPeakMB=Math.max(s.logicalArenaPeakMB,Number(i.logicalArenaPeakMB)||0),s.submittedArenaPeakMB=Math.max(s.submittedArenaPeakMB,Number(i.submittedArenaPeakMB)||0)}for(const i of Object.values(o))Number.isFinite(i.minInitialKvCapacity)||(i.minInitialKvCapacity=0),i.ms=Me(i.ms),i.encoderMs=Me(i.encoderMs),i.decodeMs=Me(i.decodeMs),i.batchWallPct=n>0?Zt(i.ms/n*100):0,i.decodeSharePct=r>0?Zt(i.decodeMs/r*100):0,i.fileWallPct=Number.isFinite(t)&&t>0?Zt(i.ms/t*100):null;return{profiledMs:Me(n),profiledDecodeMs:Me(r),sBuckets:o}}const pn=64,As=pn;function Tt(e,t="unknown"){return(String(e??"").trim()||t).slice(0,96)}function Ps(e={},{subgroupMinSize:t=0,subgroupMaxSize:n=0}={}){return[Tt(e.vendor),Tt(e.architecture),Tt(e.device),`sg${Number(t)||0}-${Number(n)||0}`].join("|")}function Ts({batchSize:e,plannedS:t,maxChars:n}={}){if(!Number.isInteger(e)||e<1)throw new Error(`schedule batchSize must be positive, got ${e}`);if(!Number.isInteger(t)||t<1)throw new Error(`schedule plannedS must be positive, got ${t}`);if(!Number.isFinite(n)||n<0)throw new Error(`schedule maxChars must be non-negative, got ${n}`);const r=Eo(n),o=Math.sqrt(e/pn),i=Math.max(1,t/96);return pn*o*r*i}function dr(e,t){const n=[...e].sort((s,c)=>s-c),r=(n.length-1)*t,o=Math.floor(r),i=Math.ceil(r);return o===i?n[o]:n[o]+(n[i]-n[o])*(r-o)}function Rs(e,t,n){return e.length===0||n<1?null:{targetTokenP50:dr(e,.5),targetTokenP90:dr(e,.9),compactionRate:t/n}}function en(e,t){if(!e?.getItem)return null;try{return e.getItem(t)}catch{return null}}function rt(e,t,n){if(e)try{n.length===0?e.removeItem?.(t):e.setItem?.(t,ji(n))}catch{}}function xt(e,t,n){if(!e)return!1;try{if(n.length===0){if(typeof e.removeItem!="function")return!1;e.removeItem(t)}else{if(typeof e.setItem!="function")return!1;e.setItem(t,Vi(n))}return!0}catch{return!1}}function At({selectedSchedule:e,telemetry:t,cacheHit:n=!1,cachedObservedShape:r=null,driftBatchIndices:o=[],invalidate:i=()=>{},recordBaselineObservation:s=()=>!1}){return{selectedSchedule:{inFlight:e.inFlight,groupSteps:e.groupSteps},telemetry:t,cacheHit:n,cachedObservedShape:r,driftBatchIndices:[...o],invalidate:i,recordBaselineObservation:s}}async function Bs({enabled:e=!1,amortizationPolicy:t="bypass",configuredSchedule:n=Te,eligibilityInput:r={},buildWorkload:o,adapterKey:i,modelId:s,weightsId:c,dtype:u,browserMajor:l,kernelTuneId:h,modes:f,scopeKey:g,kernelReferenceMs:S,kernelReferenceCost:A=As,safetyOptions:y,storage:b=null,runner:v=Rr,pretokenize:oe,estimateBatch:Ee,runBatch:M,isCancelled:F=()=>!1,isDeviceHealthy:X=()=>!1,clock:B=()=>performance.now(),cacheNow:ve=()=>Date.now()}={}){const pe={inFlight:n.inFlight,groupSteps:n.groupSteps},Re=t==="automatic",p={protocolRev:je,enabled:e===!0,eligible:!1,source:"default",reason:e===!0?null:"disabled",configuredSchedule:{...pe},selectedSchedule:{...pe},effectiveSchedule:{...pe},workload:null,evidence:null,candidateEvidence:[],observedShape:null,projection:null,deadline:null,screenSubmitShrinks:0,selectedGain:null,screenGain:null,confirmationMinGain:null,sampleCount:0,confirmationCount:0,confirmationPlan:[],completedConfirmationRoles:[],scheduleTuneMs:0,invalidatedReason:null,cache:{status:"not-checked",write:null,verdict:null,persistent:b?.persistent!==!1},amortization:{revision:bt,status:e&&!Re?"bypass":"not-checked",reason:null,observationCacheState:"not-checked",observationAgeMs:null,observedProfiledWallMs:null,minimumExpectedSavingMs:null,projectedWorstCaseScreenMs:null,paybackRatio:null,write:null,persistent:b?.persistent!==!1}},D=()=>At({selectedSchedule:pe,telemetry:p});if(!e)return D();const Ce=Ii(r);if(p.eligible=Ce.eligible,p.reason=Ce.reason,!Ce.eligible)return D();if(!(Number.isFinite(S)&&S>0))return p.reason="kernel-reference-missing",D();if(typeof o!="function"||typeof v!="function")return p.reason="integration-unavailable",D();if(F())return p.reason="cancelled",D();const He=B(),xe=()=>{const k=B()-He;p.scheduleTuneMs=Number.isFinite(k)&&k>0?k:0};let L,ge,be,ne,U,ie,re,_=[],se,Be;try{if(L=await o(),!L||!Array.isArray(L.batchCosts)||L.batchCosts.length===0)throw new Error("schedule workload is missing batch costs");const k=L.batchRegions??L.signatureInput?.plannedSourceBuckets??null;se=Ti(L.batchCosts,wn,k),Be=Bi(L.batchCosts,se,k),ge=Ai(L.signatureInput),be=Pi(ge);const J={adapterKey:i,modelId:s,weightsId:c,dtype:u,browserMajor:l,kernelTuneId:h,modes:f,signature:ge};ne=Cr(J),U=Gi(g),Re&&(ie=Li(J),re=Di(g))}catch(k){return p.reason="workload-preparation-error",p.error=String(k?.message??k).slice(0,160),xe(),D()}p.workload=ge;const Ne=Hi(en(b,U));_=Ne.entries,p.cache.status=Ne.status??"miss",Ne.status==="corrupt"&&rt(b,U,[]);const he=ve();let $=_.find(k=>k.identity===ne)??null;if($){const k=zi($,{now:he,identity:ne,kernelTuneId:h,signatureKey:be});if(k.entry){$={...k.entry,lastUsedAt:he},_=nr(_,$),rt(b,U,_),p.source="cache",p.reason=$.verdict,p.selectedSchedule={...$.schedule},p.effectiveSchedule={...$.schedule},p.evidence={...$.evidence},p.observedShape=$.observedShape?{...$.observedShape}:null,p.screenSubmitShrinks=$.screenSubmitShrinks,p.selectedGain=$.evidence.wallGain??null,p.screenGain=$.evidence.screenWallGain??null,p.confirmationMinGain=$.evidence.confirmationMinWallGain??null,p.sampleCount=$.evidence.sampleCount??0,p.confirmationCount=$.evidence.confirmationCount??0,p.cache.status="hit",p.cache.verdict=$.verdict,Re&&(p.amortization.status="cache-hit",p.amortization.reason=null),xe();const J=Q=>{_=Yt(_,ne),rt(b,U,_),$=null,p.invalidatedReason=Q,p.cache.status=Q};return At({selectedSchedule:$.schedule,telemetry:p,cacheHit:!0,cachedObservedShape:$.observedShape,driftBatchIndices:se,invalidate:J})}_=Yt(_,ne),rt(b,U,_),p.cache.status=k.status,$=null}if(F())return p.reason="cancelled",xe(),D();if(Re){const k=rr(en(b,re));let J=k.entries;p.amortization.observationCacheState=k.status??"miss",k.status==="corrupt"&&xt(b,re,[]);let Q=J.find(Z=>Z.identity===ie)??null;if(Q){const Z=qi(Q,{now:he,identity:ie,kernelTuneId:h,signatureKey:be});Z.entry?(Q={...Z.entry,lastUsedAt:he},J=or(J,Q),xt(b,re,J),p.amortization.observationCacheState="hit",p.amortization.observationAgeMs=he-Q.createdAt):(J=J.filter(Ae=>Ae.identity!==ie),xt(b,re,J),p.amortization.observationCacheState=Z.status,Q=null)}let N=null;if(Q)try{N=Fi({kernelReferenceMs:S,kernelReferenceCost:A,sampleCosts:se.map(Z=>L.batchCosts[Z]),armCount:_e.length,confirmationRounds:2,pretokenizeMs:0})}catch{N=null}const ye=Ji({observation:Q,projection:N});if(Object.assign(p.amortization,ye),!ye.admit){p.reason=ye.status;let Z=!1;const Ae=(O={})=>{if(Z)return p.amortization.write="duplicate",!1;Z=!0;const j=K=>K?.inFlight===Te.inFlight&&K?.groupSteps===Te.groupSteps;if(!(O.complete===!0&&O.cancelled===!1&&O.deviceHealthy===!0&&j(O.configuredSchedule)&&j(O.effectiveSchedule)&&O.rowCount===r.uncachedRows&&O.batchCount===L.batchCosts.length&&O.submitShrinks===0))return p.amortization.write="rejected",!1;try{const K=ve(),m=Ki({identity:ie,scopeKey:g,kernelTuneId:h,signatureKey:be,createdAt:K,schedule:Te,profiledWallMs:O.profiledWallMs,profiledDecodeMs:O.profiledDecodeMs,rowCount:O.rowCount,batchCount:O.batchCount,tokenCount:O.tokenCount,submitShrinks:O.submitShrinks}),w=rr(en(b,re)),E=or(w.status===null?w.entries:[],m),I=xt(b,re,E);return p.amortization.write=I?"stored":"unavailable",I}catch{return p.amortization.write="rejected",!1}};return xe(),At({selectedSchedule:pe,telemetry:p,recordBaselineObservation:Ae})}}const x=await v({sampleBatchIndices:se,confirmationPlan:Be,workloadBatchCosts:[...L.batchCosts],batchRegions:L.batchRegions??L.signatureInput?.plannedSourceBuckets??null,kernelReferenceMs:S,kernelReferenceCost:A,safetyOptions:y,pretokenize:oe,estimateBatch:Ee,runBatch:M,now:B,isCancelled:F,isDeviceHealthy:X});if(xe(),F())return p.source="default",p.reason="cancelled",p.cache.write="not-cacheable",D();p.source=x.source,p.reason=x.reason,p.selectedSchedule={...x.schedule},p.effectiveSchedule={...x.schedule},p.evidence=x.evidence?{...x.evidence}:null,p.candidateEvidence=Array.isArray(x.candidateEvidence)?x.candidateEvidence.map(k=>({...k})):[],p.observedShape=x.observedShape?{...x.observedShape}:null,p.projection=x.projection?{...x.projection}:null,p.deadline=x.deadline?{...x.deadline}:null,p.screenSubmitShrinks=x.screenSubmitShrinks??0,p.selectedGain=x.evidence?.wallGain??null,p.screenGain=x.evidence?.screenWallGain??null,p.confirmationMinGain=x.evidence?.confirmationMinWallGain??null,p.sampleCount=x.evidence?.sampleCount??0,p.confirmationCount=x.evidence?.confirmationCount??0,p.confirmationPlan=Array.isArray(x.confirmationPlan)?x.confirmationPlan.map(k=>({...k})):Be.map(k=>({...k})),p.completedConfirmationRoles=Array.isArray(x.completedConfirmationRoles)?[...x.completedConfirmationRoles]:[],p.cache.verdict=x.verdict,x.cache?.cacheable?($=Ui({identity:ne,scopeKey:g,kernelTuneId:h,signatureKey:be,createdAt:he,ttlClass:x.cache.ttlClass,verdict:x.verdict,schedule:x.schedule,observedShape:x.observedShape,screenSubmitShrinks:x.screenSubmitShrinks,evidence:x.cache.evidence}),_=nr(_,$),rt(b,U,_),p.cache.write="stored"):p.cache.write="not-cacheable";const Qe=k=>{$&&(_=Yt(_,ne),rt(b,U,_),$=null),p.invalidatedReason=k,p.cache.status=k};return At({selectedSchedule:x.schedule,telemetry:p,invalidate:Qe})}async function Ns({model:e=yn(Sn),onPhase:t,onProgress:n,onDeviceLost:r,scheduleAutotuneRunner:o=Rr,scheduleCacheStorage:i=null,scheduleDefaultEnabled:s=!1,scheduleDefaultSeedFactory:c=()=>globalThis.crypto?.randomUUID?.()}={}){t?.("gpu");const u=await so(),l=u.hasF16?"f16":"f32";let h=null;u.device.lost.then(k=>{k?.reason!=="destroyed"&&(h={reason:k?.reason??"unknown",message:k?.message??""},console.error(`WebGPU device lost (${h.reason}): ${h.message}`),r?.(h))}),t?.("tokenizer");const f=await ao(e.tokenizerId,e.tokRev),g=new URLSearchParams(location.search);let S=i;const y=["shortlist","directq8","immediates","uniformpool","kvplanner","kvcap","cap","tokenbudget","tm","inplacecompact","submitbudget","encsplit","inflight","groupsteps","scheduletune"].filter(k=>g.get(k)!==null).map(k=>`${k}=${String(g.get(k)).slice(0,24)}`),b=g.has("scheduletune")?cr(g.get("scheduletune")):null,v=oi({enabled:s===!0,explicitMode:b,getStorage:()=>S??=ln("local"),createSeed:c}),oe=v.mode,Ee=g.get("shortlist")!=="0",M=g.get("directq8")!=="0",F=g.get("immediates")==="0"?"off":"auto",X=F==="auto"&&u.hasImmediates?"on":"off",B=ss(X,g.get("uniformpool")),ve=g.get("submitbudget"),pe=ve===null?void 0:Number(ve)>0?Number(ve):null,Re=Ms(),p=as({inFlightParam:g.get("inflight"),groupStepsParam:g.get("groupsteps")}),D=Ss({modelId:e.id,ua:navigator.userAgent??"",maxTouchPoints:navigator.maxTouchPoints??0,plannerParam:g.get("kvplanner"),kvcapParam:g.get("kvcap"),capParam:g.get("cap"),budgetParam:g.get("tokenbudget")}),Ce=g.get("encsplit"),He=Ce===null?vs({ua:navigator.userAgent??""}):Ce==="1",xe=l==="f16"&&Ee?co(f.idToToken):null;t?.("weights");const L=await lo(u.device,e.weightsUrl,{targetDtype:l,lmHeadQ8:l==="f16",ffnWT:l==="f16",projWT:l==="f16",directQ8:M,...xe?{lmHeadIds:xe}:{},onProgress:n});t?.("autotune");let ge=null,be=null,ne=null,U="default",ie=null,re=null,_=null;try{const k=ls(u.adapterInfo,uo(),l,{subgroupMinSize:u.subgroupMinSize,subgroupMaxSize:u.subgroupMaxSize,immediates:X,uniformPool:B,browserMajor:Cn(navigator.userAgent??"")}),J=localStorage.getItem(k),Q=ds(J),N=Q.parsed;if(Q.status==="corrupt")try{localStorage.removeItem(k)}catch{}Q.status&&(_=ct(Q.status));const ye=await ho({...u,dtype:l});ge=ye;let Z=!1;const Ae=N?hs(N,ye):null,O=ps(N?.tuneId);if(Ae?.status&&(_=ct(Ae.status,{priorTuneId:O})),N&&!Ae?.status){const j=N.timings?.b64?.def?.medianUs;try{const le=await fo({...u,dtype:l},L,{immediates:F,uniformPool:B});if(Z=fs(j,le.medianUs)==="accepted",Z){let K=O,m="accepted";if(!K){K=crypto.randomUUID(),m="legacy-upgraded";try{localStorage.setItem(k,JSON.stringify({...N,tuneId:K}))}catch{}}ne=N.tuned,U="cache",be=N.timings??null,ie=K,re=Ae.measuredAt,_=ct(m,{priorTuneId:O,cachedUs:Number.isFinite(j)?j:null,currentUs:le.medianUs})}else _=ct("mismatch",{priorTuneId:O,cachedUs:Number.isFinite(j)?j:null,currentUs:le.medianUs}),console.info(`autotune cache power-state mismatch (${j??"missing"}us -> ${le.medianUs}us); remeasuring`)}catch(le){_=ct("canary-error",{priorTuneId:O,cachedUs:Number.isFinite(j)?j:null,error:String(le?.message??le).slice(0,128)}),console.warn("autotune cache canary failed; remeasuring:",le)}}if(!Z){const j=await mo({...u,dtype:l},L,{reductionSafety:ye,immediates:F,uniformPool:B,maxB:ur()});if(ne=j.tuned,be=j.timings??null,ie=crypto.randomUUID(),re=Date.now(),U=j.partial?"partial":"measured",!j.partial)try{localStorage.setItem(k,JSON.stringify({tuned:ne,timings:j.timings,tuneId:ie,date:new Date(re).toISOString()}))}catch{}}}catch(k){if(k?.code==="WEBMT_NO_SAFE_REDUCTION")throw k;console.warn("autotune unavailable, falling back to auto routing:",k)}t?.("ready");const se=u.adapterInfo,Be=se.description||[se.vendor,se.architecture].filter(Boolean).join(" ")||"GPU",Ne=vr(),he=ei(se,Be,Ne),$=[he!==Be?Be:null,se.subgroupMinSize&&se.subgroupMaxSize?`subgroup ${se.subgroupMinSize}–${se.subgroupMaxSize}`:null,navigator.deviceMemory?`RAM ${navigator.deviceMemory>=32?"≥":"~"}${navigator.deviceMemory}GB`:null,navigator.hardwareConcurrency?`~${navigator.hardwareConcurrency} luồng CPU`:null].filter(Boolean).join(" · "),x=l==="f16"?2:4;async function Qe(k,{onBatch:J,shouldStop:Q,pack:N=!1,resume:ye=null,tm:Z=null,scheduleTuneMode:Ae=oe,decodeScheduleOverride:O=null,onScheduleTune:j=null}={}){const le=cs(O)??{...p},K=performance.now(),m=qo(k);k=m.text;const w=Ho(k);let E=w.sentences,I=w.paras;if(N){const P=zo(E,I);E=P.rows,I=P.rowParas}if(E.length===0)return{text:"",cancelled:!1,stats:{sentences:0,tokens:0,ms:0,tokPerSec:0}};const H=Array.isArray(ye)&&ye.length===E.length,R=H?[...ye]:new Array(E.length).fill(""),z=H?R.reduce((P,te)=>P+(te?1:0),0):0;let ae=0,ce=0;if(N&&Z?.get){const P=performance.now();try{const te=await Z.get(E);for(let V=0;VP.length)):E.map((P,te)=>te)).filter(P=>!R[P]),ee=N?D.absCap:ur(),Se=Math.min(192,ee),st=N?D.tokenBudget:Es(),Ye=Ge.map(P=>E[P].length),Xe=N?$r(Ye,u,x,Se,ee,st,D.policyForS):{ranges:ks(Ye,u,x,Se,Se),buckets:[]},{ranges:Oe}=Xe,Dt=P=>{const[te,V]=Oe[P],Y=Ge.slice(te,V),Pe=N?Xe.buckets[P]:null;return{start:te,end:V,idx:Y,plannedS:Pe,sources:Y.map(ke=>E[ke]),initialKvCapacity:N?D.kvCapacityForS(Pe):D.forcedCapacity}},Nn=async(P,te,{primeNext:V=!1,safetyOptions:Y=null}={})=>{if(h)throw new Error(`GPU device lost (${h.reason}): ${h.message}`);const Pe=Dt(P),ke=Y?Y.submitBudgetMs:pe,T=Y?Y.encSplitSubmits:He;ko();const Wt=performance.now(),{rows:kt,metrics:at}=await yo({...u,dtype:l},L,f,Pe.sources,{...So(ne,Pe.end-Pe.start),immediates:F,uniformPool:B,...te,...ke!==void 0?{submitBudgetMs:ke}:{},encSplitSubmits:T,inPlaceCompact:N&&Re,kvCapacity:Pe.initialKvCapacity,...N?{maxNewTokens:vn}:{},onPrimed:V&&P+1{const Ct=Dt(P+1);Ct.idx.every(nt=>R[nt])||zn(f,Ct.sources).catch(()=>{})}:null}),Mt=performance.now();return{plan:Pe,rows:kt,metrics:at,wallMs:Mt-Wt,endedAt:Mt,arenaStats:wo()}};let vt=0,yt=0,St=0,wt=!1;const ze={timingMode:"overlapping-gpu-windows",gpuWindowsOverlap:!0,prepMs:0,tmMs:ce,scheduleTuneMs:0,tokenizeMs:0,encoderMs:0,decodeMs:0,detokMs:0,gapMs:0},Ze=[],In=performance.now();ze.prepMs=In-K-ce;const De=O===null&&N?cr(Ae):"off",$n=Ps(u.adapterInfo,{subgroupMinSize:u.subgroupMinSize,subgroupMaxSize:u.subgroupMaxSize}),Ut=Tt(L.weightsTag??e.weightsUrl,"dev"),to=[$n,e.id,Ut,l].join("|").slice(0,512);let jt=null;const Fn=P=>{if(typeof j=="function")try{j({active:P,mode:De})}catch{}},no=typeof o=="function"?async P=>{Fn(!0);try{return await o(P)}finally{Fn(!1)}}:null,W=await Bs({enabled:De!=="off",amortizationPolicy:De==="auto"?"automatic":"bypass",configuredSchedule:le,eligibilityInput:{fileMode:N,pack:N,isMobile:D.mobile,uncachedRows:Ge.length,plannedBatches:Oe.length,kernelTuneSource:U,manualOverrides:{inflight:O===null?g.get("inflight"):String(le.inFlight),groupsteps:O===null?g.get("groupsteps"):String(le.groupSteps),submitbudget:g.get("submitbudget"),encsplit:g.get("encsplit")},memorySafe:N&&Oe.length>0},buildWorkload:async()=>{const P=Ye.map(V=>Math.max(1,Math.min(on,V+1)));return jt={batchCosts:Oe.map(([V,Y],Pe)=>{let ke=0;for(let T=V;TY-V),plannedSourceBuckets:[...Xe.buckets],sourceTokenLengths:P,modelId:e.id,weightsId:Ut,dtype:l,policy:{pack:N,kvPlanner:D.policyLabel,tokenBudget:D.tokenBudget,immediates:X,uniformPool:B}}},jt},adapterKey:$n,modelId:e.id,weightsId:Ut,dtype:l,browserMajor:is(navigator.userAgent??""),kernelTuneId:ie??"untrusted",modes:{pack:N,kvPlanner:D.policyLabel,kvPolicy:D.policyLabel,tokenBudget:D.tokenBudget,immediates:X,uniformPool:B,inPlaceCompact:N&&Re,compact:!0,parameterMode:X},scopeKey:to,kernelReferenceMs:Number(be?.b64?.def?.medianUs)/1e3,safetyOptions:{submitBudgetMs:pe===void 0?1e3:pe,encSplitSubmits:He},storage:De!=="off"?S??=ln("local"):S,runner:no,pretokenize:async P=>{const te=Dt(P);await zn(f,te.sources)},estimateBatch:async P=>jt.batchCosts[P],runBatch:async(P,te,V)=>{const Y=await Nn(P,te,{safetyOptions:V});return{rows:Y.rows,groupStepsStart:Y.metrics.groupStepsStart,groupStepsFinal:Y.metrics.groupStepsFinal,submitShrinks:Y.metrics.submitShrinks,wallMs:Y.wallMs,decodeMs:Y.metrics.decodeMs,compactions:Y.metrics.compactions,cleanupComplete:!0}},isCancelled:()=>Q?.()===!0,isDeviceHealthy:()=>!h,clock:()=>performance.now()});ze.scheduleTuneMs=W.telemetry.scheduleTuneMs;const On={...W.selectedSchedule},et=De==="apply"||De==="auto"?{...On}:{...le};W.telemetry.mode=De,W.telemetry.requestedSchedule={...le},W.telemetry.predictedSchedule={...On},W.telemetry.configuredSchedule={...et};const ro=De==="auto"&&["admitted","cache-hit"].includes(W.telemetry.amortization?.status);W.telemetry.canonicalUsesTunerVerdict=W.telemetry.eligible&&(De==="apply"||ro);let Ve={...et},tt=Ve.groupSteps;W.telemetry.effectiveSchedule={...Ve};const _n=[];let Ln=0,Ht=0;const Gn=new Set(W.driftBatchIndices);let zt=performance.now();for(let P=0;P0)nt="submit-shrink";else if(W.cacheHit&&!W.telemetry.invalidatedReason&&W.cachedObservedShape&&Gn.has(P)){for(const Ie of ke)_n.push(Math.max(1,(Ie.ids?.length??1)-1));if(T.compactions>0&&Ln++,Ht++,Ht===Gn.size){const Ie=Rs(_n,Ln,Ht);W.telemetry.canonicalObservedShape=Ie,Pr(W.cachedObservedShape,Ie)&&(nt="shape-drift")}}if(nt&&(W.invalidate(nt),Ve={...Te},tt=Math.min(tt,Te.groupSteps)),W.telemetry.effectiveSchedule={inFlight:Ve.inFlight,groupSteps:Math.min(Ve.groupSteps,tt)},ke.forEach((Ie,Kt)=>{R[at[Kt]]=Ie.text.normalize("NFC"),Ie.forcedEos&&yt++}),St+=ke.length,vt+=T.tokensGenerated,N&&Z?.put){const Ie=[];if(ke.forEach((Kt,jn)=>{Kt.forcedEos||Ie.push([E[at[jn]],R[at[jn]]])}),Ie.length)try{Z.put(Ie)}catch{}}J?.(P+1,Oe.length,R)}const Et=performance.now()-In;yt>0&&console.warn(`translateText: ${yt}/${E.length} rows hit the token cap (tail may be cut)`);const{profiledMs:Dn,profiledDecodeMs:Un,sBuckets:oo}=xs(Ze,Et),io=Ze.reduce((P,te)=>P+(te.submitShrinks??0),0);return W.recordBaselineObservation({complete:!wt&&St===Ge.length&&Ze.length===Oe.length,cancelled:wt,deviceHealthy:!h,configuredSchedule:et,effectiveSchedule:W.telemetry.effectiveSchedule,profiledWallMs:Dn,profiledDecodeMs:Un,rowCount:St,batchCount:Ze.length,tokenCount:vt,submitShrinks:io}),{text:Wo(I,R),rowTexts:R,cancelled:wt,stats:{sentences:E.length,tokens:vt,ms:Et,forcedEos:yt,t2s:m.changed,batches:Oe.length,stages:ze,resumeHits:z,tmHits:ae,decodedRows:St,batchStats:Ze,decodeSchedule:{...et},requestedDecodeSchedule:{...le},effectiveDecodeSchedule:{...W.telemetry.effectiveSchedule},scheduleAutotune:W.telemetry,profiledMs:Dn,profiledDecodeMs:Un,sBuckets:oo,tokPerSec:Et>0?vt/Et*1e3:0}}}return{info:{gpuName:he,gpuTitle:$,dtype:l,lmHeadQ8:l==="f16",lmShortN:xe?.length??0,directQ8:L.q8Stats.directTensors>0,immediates:X,uniformPool:B?"b64":"off",inPlaceCompact:Re?"explicit":"off",decodeSchedule:{...p},scheduleTuneMode:oe,scheduleDefault:{source:v.source,reason:v.reason,revision:v.revision,rolloutBps:v.rolloutBps},kvPolicy:D.policyLabel,kvPlannerOverride:g.get("kvplanner"),kvCapacityOverride:g.get("kvcap"),q8Stats:L.q8Stats,tunedFrom:U,modelId:e.id,modelName:e.name,weightsTag:L.weightsTag??"dev",tokRev:e.tokRev??null,bench:{adapterInfo:{...u.adapterInfo},subgroupMinSize:u.subgroupMinSize,subgroupMaxSize:u.subgroupMaxSize,hasF16:u.hasF16,limits:{...u.limits},kernelRev:pr,safety:ge?{...ge.verdicts,forceSg:ge.forceSg}:null,tuned:ne,tunedFrom:U,timings:be,protocolRev:po,tuneId:ie,measuredAt:re,cacheCheck:_,flags:y,gpuName:he,gpuWebgl:Ne?.renderer??null,webglSameGpu:!!(Ne&&br(se.vendor,Ne.vendor,Ne.renderer)),adapterLimits:{...u.adapterLimits},features:[...u.features??[]],wgslFeatures:(()=>{try{return[...navigator.gpu?.wgslLanguageFeatures??[]]}catch{return[]}})()}},translateText:Qe,isLost:()=>h,destroy:()=>{try{L.buffer.destroy()}catch{}try{u.device.destroy()}catch{}}}}const Is=["auto","utf-8","gb18030","big5","utf-16le","utf-16be"],$s=new Set("的一是不了人我在有他这为之大来以个中上们到说国和地也子时道出而要于就下得可你年生自会那后能对着事其里所去行过家十用发天如然作方成者多日都三小军二无同么经法当起与好看学进种将还分此心前面又定见只主没公从知世什两次使身被高已亲话常活正感明问力理尔点文几本特做外孩相西果走月实向声车全信重机工物气每并别真打太新比才便夫再书部水像眼等体却加电主界门利海受听表德少克代员许先口由死安写性马光白或住难望教命花结乐色更拉东神记处让母父应直字场平报友关放至张认接告入笑内英军候民岁往何度山觉路带万男边风解叫任金快原吃妈变通师立象数四失满战远格士音轻目条呢病始达深完今提求清王化空业思切怎非找片罗钱吗语元喜曾离飞科言干流欢约各即指合反题必该论交终林请医晚制球决传画保读运及则房早院量苦火布品近坐产答星精视五连司巴這為來個們說國時過還進裡著見兩麼開關門問間東車書興學實現點戰處條讓報馬場話認遠飛樂氣師難聽當義務長員島洋歐陽於億敵獨隊淚類燈爾談請諸講謝證識護賽選遺醫錢鐵閒陳陰險陸雙雞離電靈頭頗題顧風餘體高鬥魚鳥龍發夢舊聲應轉醒覺對藥雲會後".split("")).add(",").add("。").add("、"),tn=(e,...t)=>t.every((n,r)=>e[r]===n);function hr(e){let t=0,n=0,r=0;for(const o of e){const i=o.codePointAt(0);if(i===65533){r++;continue}(i>=19968&&i<=40959||i>=12288&&i<=12351||i>=65280&&i<=65374)&&(t++,$s.has(o)&&n++)}return t+r===0?-1:(n-4*r)/(t+r)}function Fs(e){if(e.length>=3&&tn(e,239,187,191))return"utf-8";if(e.length>=2&&tn(e,255,254))return"utf-16le";if(e.length>=2&&tn(e,254,255))return"utf-16be";try{return new TextDecoder("utf-8",{fatal:!0}).decode(e),"utf-8"}catch{}const t=e.subarray(0,65536),n=new TextDecoder("gb18030").decode(t),r=new TextDecoder("big5").decode(t),o=hr(n),i=hr(r);return i>o*1.05&&i>0?"big5":"gb18030"}function Fr(e,t="auto"){const n=t==="auto"?Fs(e):t;return{text:new TextDecoder(n).decode(e),encoding:n}}const Os=/[\s:,;(\-–—…]/;function Or(e){const t=[];let n="",r=!1;const o=i=>{n&&(t.push({text:n,q:i}),n="")};for(let i=0;i_s){e.textContent=t;return}const n=document.createDocumentFragment(),r=t.split(`
-`);for(let o=0;o0&&n.appendChild(document.createTextNode(`
-`));for(const i of Or(r[o]))if(i.q){const s=document.createElement("span");s.className="dlg",s.textContent=i.text,n.appendChild(s)}else n.appendChild(document.createTextNode(i.text))}e.replaceChildren(n)}function Ls(e){const t=[],n=/[.!?…:;"”]\s+/g;let r=0;for(let o;o=n.exec(e);)t.push(e.slice(r,o.index+o[0].length)),r=o.index+o[0].length;return rOr(s).map(c=>({q:c.q,pieces:Ls(c.text)}))),o=r.reduce((s,c)=>s+c.reduce((u,l)=>u+l.pieces.length,0),0);if(n||o>Gs){_r(e,t);return}e.replaceChildren();let i=0;for(let s=0;s0&&e.appendChild(document.createTextNode(`
-`));for(const c of r[s])for(const u of c.pieces){if(!u)continue;const l=document.createElement("span");l.className=c.q?"ink-in dlg":"ink-in",l.style.animationDelay=`${Math.min(i*40,1200)}ms`,l.textContent=u,l.addEventListener("animationend",()=>{l.className=c.q?"dlg":"",l.style.animationDelay=""},{once:!0}),e.appendChild(l),i++}}}function Lr(e){e&&e.addEventListener("click",t=>{const n=e.getBoundingClientRect(),r=document.createElement("span");r.className="ripple",r.style.left=`${t.clientX-n.left||n.width/2}px`,r.style.top=`${t.clientY-n.top||n.height/2}px`,e.appendChild(r),r.addEventListener("animationend",()=>r.remove())})}const Us="moxhi",js=2,Ft="tm",Gr="\0",Hs=15e4;function zs({modelId:e,weightsTag:t,dtype:n,tokRev:r}={}){const o=[e??"unknown",t??"dev",n??"f16"];return r&&o.push(r),o.join("|")}function Ws(e,t){return!!e&&!e.complete&&(e.done??0)>0&&e.file===t.file&&e.size===t.size&&e.encoding===t.encoding&&e.model===t.model}function Ks(){return new Promise((e,t)=>{const n=indexedDB.open(Us,js);n.onupgradeneeded=()=>{const r=n.result;r.objectStoreNames.contains(Ft)||r.createObjectStore(Ft).createIndex("ts","ts"),r.objectStoreNames.contains("partial")&&r.deleteObjectStore("partial")},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)})}async function Ot(e,t){const n=await Ks();try{return await new Promise((r,o)=>{const i=n.transaction(Ft,e),s=t(i.objectStore(Ft));i.oncomplete=()=>r(typeof s=="function"?s():s),i.onerror=()=>o(i.error),i.onabort=()=>o(i.error??new Error("tx aborted"))})}finally{n.close()}}async function Vs(e,t){const n=new Array(t.length).fill(null);try{await Ot("readonly",r=>{t.forEach((o,i)=>{const s=r.get(e+Gr+o);s.onsuccess=()=>{s.result&&(n[i]=s.result.t)}})})}catch{}return n}async function qs(e,t){try{const n=Date.now();await Ot("readwrite",r=>{for(const[o,i]of t)r.put({t:i,ts:n},e+Gr+o)})}catch{}}async function Js(e=Hs){try{const t=await Ot("readonly",r=>{const o=r.count();return()=>o.result});if(t<=e)return;let n=t-Math.floor(e*.9);await Ot("readwrite",r=>{const o=r.index("ts").openCursor();o.onsuccess=()=>{const i=o.result;!i||n<=0||(i.delete(),n--,i.continue())}})}catch{}}const Qs=3;function Dr(e){return(e.flags?.length??0)>0?"flags":e.schedule!==void 0&&e.schedule!==null?"schedule-autotune":((e.tmHits??0)+(e.resumeHits??0))/Math.max(1,e.sentences??0)>.05?"tm-reuse":e.decodedRows!==void 0&&e.decodedRows!==null&&e.decodedRows<30?"few-rows":e.mode==="file"||(e.sentences??0)>=30?null:"small"}const Ys={gpuWebgl:512,gpuName:256,model:128,platformVersion:64,cpuArch:32,browserFull:128};[...Object.keys(Ys)];const Xs=e=>[...e].map(t=>t.toString(16).padStart(2,"0")).join("");async function Zs(e){if(!e.persistent)return null;let t=e.getItem(Wn);return t||(t=Xs(crypto.getRandomValues(new Uint8Array(16))),e.setItem(Wn,t)),Mo(t)}function Ur(e=navigator){return e.userAgentData?.platform||e.platform||""}const Fe=(e,t=1)=>typeof e=="number"&&Number.isFinite(e)?Math.round(e*10**t)/10**t:null;function ea(e){if(!e||typeof e!="object")return null;const t=Array.isArray(e.plannedSourceBucketHistogram)?e.plannedSourceBucketHistogram:[];return{rowCountBand:e.rowCountBand,batchCountBand:e.batchCountBand,sourceBucketHistogram:Object.fromEntries(t),batchSizeQuantiles:[...e.batchSizeQuantiles??[]],sourceTokenQuantiles:[...e.sourceTokenQuantiles??[]]}}function ta(e){return!e||typeof e!="object"?null:{amortizationRev:e.revision,amortizationStatus:e.status,amortizationAdmitted:e.admit??null,observationCacheState:e.observationCacheState,observationAgeMs:Fe(e.observationAgeMs),observationWrite:e.write??null,observedProfiledWallMs:Fe(e.observedProfiledWallMs),minimumExpectedSavingMs:Fe(e.minimumExpectedSavingMs),projectedWorstCaseScreenMs:Fe(e.projectedWorstCaseScreenMs),paybackRatio:Fe(e.paybackRatio,6)}}function na(e){const t=e?.scheduleAutotune;if(!t||!["shadow","apply","auto"].includes(t.mode))return null;const n=t.requestedSchedule??e.requestedDecodeSchedule,r=t.predictedSchedule??t.selectedSchedule,o=e.decodeSchedule??t.configuredSchedule,i=e.effectiveDecodeSchedule??t.effectiveSchedule,s=(e.batchStats??[]).reduce((g,S)=>g+(Number.isInteger(S?.submitShrinks)?S.submitShrinks:0),0),c=t.screenSubmitShrinks??0,u=t.invalidatedReason??(c>0?"submit-shrink":null)??(["promoted","selected"].includes(t.reason)?null:t.reason??null),l=ta(t.amortization),h=Fe(t.screenGain,6),f=Fe(t.confirmationMinGain,6);return{mode:t.mode,protocolRev:t.protocolRev,requested:{...n},predicted:{...r},configured:{...o},effective:{...i},source:t.source,cacheState:t.cache?.status??"not-checked",cacheWrite:t.cache?.write??null,scheduleTuneMs:Fe(t.scheduleTuneMs??e.stages?.scheduleTuneMs??0),selectedGain:Fe(t.selectedGain,6),...h!==null?{screenGain:h}:{},...f!==null?{confirmationMinGain:f}:{},sampleCount:t.sampleCount??0,confirmationCount:t.confirmationCount??0,projectedMs:Fe(t.evidence?.projectedMs??t.projection?.postPilot?.projectedMs??t.projection?.preGate?.projectedMs),overrunMs:Fe(t.deadline?.overrunMs??t.evidence?.overrunMs),screenSubmitShrinks:c,canonicalSubmitShrinks:s,fallbackReason:u,...l??{},workload:ea(t.workload)}}function jr({info:e,stats:t,mode:n,srcChars:r,build:o,pseudo:i,ua:s,platform:c,extras:u=null}){const l=e.bench,h=na(t);return{v:Qs,id:crypto.randomUUID(),ts:Date.now(),pseudo:i,run:{build:o,model:e.modelId,dtype:e.dtype,t2s:!!t.t2s,mode:n,srcChars:r,sentences:t.sentences,ms:Math.round(t.ms),tokPerSec:Math.round(t.tokPerSec*10)/10,outputTokens:t.tokens??null,decodedRows:t.decodedRows??null,batches:t.batches??null,tmHits:t.tmHits??null,resumeHits:t.resumeHits??null,forcedEos:t.forcedEos??null,stages:t.stages?Object.fromEntries(Object.entries(t.stages).map(([f,g])=>[f,typeof g=="number"?Math.round(g):g])):null,sBuckets:t.sBuckets??null,flags:[...l.flags??[]],weightsTag:e.weightsTag??null,...h?{schedule:h}:{}},device:{...l.adapterInfo,subgroupMin:l.subgroupMinSize,subgroupMax:l.subgroupMaxSize,fp16:l.hasF16,immediates:e.immediates,uniformPool:e.uniformPool,browserMajor:Cn(s),platform:c,limits:{...l.limits},gpuName:l.gpuName??null,gpuWebgl:l.gpuWebgl??null,webglSameGpu:l.webglSameGpu??null,adapterLimits:l.adapterLimits?{...l.adapterLimits}:null,features:l.features?[...l.features]:null,wgslFeatures:l.wgslFeatures?[...l.wgslFeatures]:null,...u??{}},autotune:{kernelRev:l.kernelRev,cacheState:l.tunedFrom,tuned:l.tuned,probeTimings:l.timings,safety:l.safety,protocolRev:l.protocolRev??null,tuneId:l.tuneId??null,measuredAt:l.measuredAt??null,cacheCheck:l.cacheCheck??null}}}function ra({base:e,reason:t,phase:n,deviceLostReason:r=null,attachedSegment:o=null,comment:i=null,crumb:s=null}){return{...e,reason:t,phase:n,deviceLostReason:r,attachedSegment:o,comment:i,...s?{crumb:s}:{}}}let nn=null;const gn="moxhi.deviceLost";async function Hr(e=navigator,t=null){if(!nn){let i={};try{i=await e.userAgentData?.getHighEntropyValues?.(["model","platformVersion","architecture","bitness","fullVersionList"])??{}}catch{i={}}const s=(i.fullVersionList??[]).find(c=>!/Not.A.Brand/i.test(c.brand));nn={model:i.model||null,platformVersion:i.platformVersion||null,cpuArch:i.architecture?`${i.architecture}${i.bitness?`-${i.bitness}`:""}`:null,browserFull:s?`${s.brand} ${s.version}`:null,deviceMemory:e.deviceMemory??null,cpuThreads:e.hardwareConcurrency??null}}let n=null,r=null;try{const i=await e.getBattery?.();n=i?.charging??null,r=i?.level??null}catch{}let o=null;if(t){const i=Math.floor(Number(t.getItem(gn)??0));o=Number.isFinite(i)&&i>=0?i:0}return{...nn,charging:n,batteryLevel:r,deviceLostCount:o}}async function zr(e,t){const n=await fetch(Co()+e,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)});if(!n.ok)throw new Error(`HTTP ${n.status}`);return n.json()}const oa=20*1024*1024,ia=600,sa=900,Wr="moxhi.autotranslate",An="moxhi.model",de=ln("local"),rn={auto:"Tự động","utf-8":"UTF-8",gb18030:"GB18030 / GBK",big5:"Big5","utf-16le":"UTF-16 LE","utf-16be":"UTF-16 BE"},aa=matchMedia("(prefers-reduced-motion: reduce)").matches,a=Bo(document.querySelector("#app"));Lr(a.goBtn);Lr(a.fileGoBtn);const ca=new URLSearchParams(location.search).get("profilestats")==="1",d={engine:null,busy:!1,queued:!1,stopFlag:!1,file:null,fileResultText:null,fileProfileText:null,filePartial:null,lastRun:null,pseudo:void 0};let Ue=null;async function Kr(){if(!(Ue&&!Ue.released))try{Ue=await navigator.wakeLock?.request("screen")??null,Ue?.addEventListener("release",()=>{Ue=null})}catch{Ue=null}}function la(){Ue?.release().catch(()=>{}),Ue=null}document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&d.busy&&!Ue&&Kr()});const C=(e,t=!0)=>{e.hidden=!t},gt=e=>(e/1048576).toFixed(1),Rt=e=>e<950?`${Math.round(e)}ms`:`${(e/1e3).toFixed(1)}s`;function Ke(e,t,n=null){a.errMsg.textContent=e,C(a.errBanner),a.retryBtn.onclick=()=>{C(a.errBanner,!1),t()},C(a.reportErrBtn,!!n),a.reportErrBtn.onclick=n?()=>Jr(n):null}function Vr({title:e,summary:t,payload:n,attach:r=!1,comment:o=!1,send:i}){a.benchModalTitle.textContent=e,a.benchSummary.textContent=t,a.benchPrivacyHint.textContent=r?"Mặc định không gửi nội dung văn bản — chỉ gửi đoạn lỗi nếu bạn tick ô bên dưới.":"Không gửi nội dung văn bản — chỉ các thông số bên dưới.",C(a.benchAttachRow,r),a.benchAttachTgl.checked=!1,C(a.benchComment,o),a.benchComment.value="",a.benchStatus.textContent="",a.benchCancelBtn.textContent="Hủy";const s=()=>{const c=typeof n=="function"?n():n;return a.benchJson.textContent=JSON.stringify(c,null,2),c};s(),a.benchAttachTgl.onchange=s,a.benchSendBtn.disabled=!1,a.benchSendBtn.onclick=async()=>{a.benchSendBtn.disabled=!0,a.benchStatus.textContent="đang gửi…";try{await i(s(),c=>{c instanceof Node?a.benchStatus.replaceChildren(c):a.benchStatus.textContent=c}),a.benchCancelBtn.textContent="Đóng"}catch(c){a.benchStatus.textContent=navigator.onLine===!1?"đang offline — thử lại sau nhé":`gửi lỗi: ${c?.message??c}`,a.benchSendBtn.disabled=!1}},a.benchCancelBtn.onclick=()=>a.benchModal.close(),a.benchModal.showModal()}async function qr(){return d.pseudo===void 0&&(d.pseudo=await Zs(de)),d.pseudo}function ua(){const e=Math.floor(Number(de.getItem(gn)??0));de.setItem(gn,String((Number.isFinite(e)&&e>=0?e:0)+1))}function da(e){const t=Dr(e);if(t==="tm-reuse"){const n=(e.tmHits??0)+(e.resumeHits??0);return`Đã ghi nhận — cảm ơn bạn! Run này không xếp hạng: ${Math.round(n/Math.max(1,e.sentences??0)*100)}% câu lấy sẵn từ bộ nhớ dịch (${e.decodedRows??0} hàng dịch mới) nên tốc độ không phản ánh sức GPU.`}return t==="flags"?"Đã ghi nhận! Run chạy với cờ thử nghiệm trên URL nên không xếp hạng — data debug vẫn quý.":t==="schedule-autotune"?"Đã ghi nhận! Run autotune lịch giải mã hiện chỉ dùng để phân tích, chưa xếp hạng cho đến khi board có policy tách cold/warm rõ ràng.":t==="few-rows"||t==="small"?"Đã ghi nhận — cảm ơn bạn! Run nhỏ không xếp hạng (bảng cần ≥30 câu dịch mới), vẫn là data quý.":"Đã ghi nhận — cảm ơn bạn!"}function ha(e=null){const t="3f588de";if(d.engine){const n=d.lastRun?.stats??{sentences:0,ms:0,tokPerSec:0,t2s:!1};return jr({info:d.engine.info,stats:n,mode:d.lastRun?.mode??"paste",srcChars:d.lastRun?.srcChars??0,build:t,pseudo:d.pseudo??null,ua:navigator.userAgent??"",platform:Ur(),extras:e})}return{v:1,id:crypto.randomUUID(),ts:Date.now(),pseudo:d.pseudo??null,run:null,device:null,autotune:null}}async function Jr(e){await qr();const t=ha(await Hr(navigator,de));Vr({title:e.title??"Báo lỗi",summary:e.summary??"",attach:!!e.attach,comment:!0,payload:()=>ra({base:t,reason:e.reason,phase:e.phase,deviceLostReason:e.deviceLostReason??null,attachedSegment:e.attach&&a.benchAttachTgl.checked?{src:a.src.value.slice(0,1e3),dst:a.out.textContent.slice(0,1e3)}:null,comment:a.benchComment.value.trim()||null,crumb:e.crumb??null}),send:async(n,r)=>{await zr("/api/report",n),r("Đã ghi nhận — cảm ơn bạn!")}})}const Pn="moxhi.lastfile";function fa(e){de.setItem(Pn,JSON.stringify(e))}function Qr(){try{return JSON.parse(de.getItem(Pn)??"null")}catch{return null}}function ma(){de.removeItem(Pn)}const Tn="moxhi.crumb";function fr(e){de.setItem(Tn,JSON.stringify({...e,ts:Date.now(),build:"3f588de"}))}function Rn(){de.removeItem(Tn)}async function pa(){let e=null;try{e=JSON.parse(de.getItem(Tn)??"null")}catch{}if(!e)return;Rn(),console.warn("[moxhi] phiên dịch trước dừng đột ngột (nghi hệ điều hành ngắt vì thiếu bộ nhớ):",e);const t=Qr(),n=!!t&&!t.complete&&(t.done??0)>0&&t.file===e.file;Ke(`Phiên dịch file trước dừng đột ngột ở cụm ${e.done??0}/${e.rows??"?"} (batch ${e.batch??0}/${e.batches??"?"}) — thường do thiết bị cạn bộ nhớ.`+(n?' Phần đã dịch vẫn còn: mở lại đúng file đó rồi bấm "Dịch file" để dịch tiếp.':" Hãy dịch lại từ đầu."),()=>{},{reason:"oom",phase:"translate",title:"Báo lỗi văng phiên dịch",crumb:{batch:e.batch,batches:e.batches,done:e.done,rows:e.rows,build:e.build,model:e.model}})}addEventListener("pagehide",Rn);const ga={gpu:"Gọi linh khí GPU…",weights:"Tải trọng số…",tokenizer:"Nạp từ điển…",autotune:"Đo mạch thiết bị (chỉ lần đầu)…"};async function Je(){C(a.gate,!1),C(a.studio,!1),C(a.loading,!0);const e=yn(de.getItem(An)??Sn);a.modelSelect.value=e.id,a.modelSelect.disabled=!0,a.loadNote.innerHTML=`Lần đầu tải ~${e.downloadMB} MB trọng số (${e.name}) — các lần sau mở nhanh nhờ bộ nhớ đệm của trình duyệt.`;try{d.engine=await Ns({model:e,scheduleDefaultEnabled:!0,onPhase:y=>{y!=="ready"&&(a.phaseLabel.textContent=ga[y]??y,y==="tokenizer"&&(a.brushFill.style.width="100%",a.brushBar.setAttribute("aria-valuenow","100")))},onProgress:(y,b)=>{const v=b?Math.round(y/b*100):0;a.brushFill.style.width=`${v}%`,a.brushBar.setAttribute("aria-valuenow",String(v)),a.phaseLabel.textContent=`Tải trọng số — ${gt(y)} / ${gt(b)} MB (${v}%)`},onDeviceLost:y=>{ua(),!d.busy&&Ke(`GPU bị ngắt kết nối (${y.reason}): ${y.message||"không rõ nguyên nhân"}. Bấm thử lại để khởi động lại bộ dịch.`,Je,{reason:"device-lost",phase:"idle",deviceLostReason:`${y.reason}: ${y.message??""}`})}})}catch(y){console.error(y),a.modelSelect.disabled=!1,C(a.chipBadge,!1),C(a.gpuTip,!1),window.__moxhi=null;const b=String(y?.message??y);/WebGPU unavailable|no adapter/i.test(b)?(C(a.loading,!1),ya(b),C(a.gate,!0)):Ke(`Không khởi động được bộ dịch: ${b}`,Je,{reason:"other",phase:"load"});return}a.modelSelect.disabled=!1;const{gpuName:t,dtype:n,lmHeadQ8:r,lmShortN:o,tunedFrom:i,modelName:s}=d.engine.info,c=i==="cache"?"autotune đệm":i==="measured"?"autotune":i==="partial"?"autotune một phần":"routing mặc định",u="3f588de",l=new URLSearchParams(location.search).get("cap"),h=new URLSearchParams(location.search).get("tokenbudget"),f=new URLSearchParams(location.search).get("kvplanner"),g=new URLSearchParams(location.search).get("inplacecompact"),S=r?`·int8${o?` ${Math.round(o/1e3)}k`:""}`:"",A=Xo(t);a.modelLink.textContent=s,e.credit?.url?(a.modelLink.href=e.credit.url,a.modelLink.title=e.credit.label):(a.modelLink.removeAttribute("href"),a.modelLink.removeAttribute("title")),a.statGpu.textContent=` · ${A} · ${n}${S} · ${c} · ${u}`+(l?` · cap=${l}`:"")+(h!==null?` · tokenbudget=${h}`:"")+(f!==null?` · kvplanner=${f}`:"")+(g!==null?` · inplacecompact=${g}`:""),C(a.chipBadge),a.chipBadge.title=[A!==t?t:null,d.engine.info.gpuTitle||null].filter(Boolean).join(" · "),C(a.gpuTip,Zo(t)),C(a.loading,!1),C(a.studio,!0),a.src.focus(),window.__moxhi={engine:d.engine,build:u,translate:y=>d.engine.translateText(y)},document.dispatchEvent(new CustomEvent("moxhi:ready"))}function ut(e){a.dstNote.textContent=e?`${e.length} ký tự`:""}function _t(e){d.busy=e,e?Kr():la(),a.goBtn.classList.toggle("busy",e),a.chipBadge.classList.toggle("busy",e),a.goBtn.disabled=e,a.fileGoBtn.disabled=e,a.modelSelect.disabled=e}async function ot(){if(!d.engine)return;if(d.busy){d.queued=!0;return}const e=a.src.value;if(!e.trim()){a.out.textContent="",ut(""),a.progress.textContent="";return}_t(!0),C(a.benchSubmitBtn,!1),d.stopFlag=!1,C(a.cancelBtn,!0),a.progress.textContent="đang dịch…";try{const t=await d.engine.translateText(e,{shouldStop:()=>d.stopFlag,onBatch:(n,r,o)=>{const i=o.filter(Boolean).length;if(a.progress.textContent=`câu ${i}/${o.length}`,r>1){const s=o.filter(Boolean).join(" ");_r(a.out,s),ut(s)}}});t.cancelled?(a.progress.textContent="đã hủy",ut(a.out.textContent)):(Ds(a.out,t.text,{reduced:aa}),ut(t.text),a.progress.textContent="",a.statPerf.textContent=`${Math.round(t.stats.tokPerSec)} tok/s · ${Rt(t.stats.ms)} · ${t.stats.sentences} câu`+(t.stats.t2s?" · phồn→giản":""),d.lastRun={stats:t.stats,mode:"paste",srcChars:e.length,submitted:!1},de.persistent&&C(a.benchSubmitBtn,!0),C(a.reportOutBtn,!0))}catch(t){if(console.error(t),a.progress.textContent="",d.engine?.isLost?.()){const{reason:n,message:r}=d.engine.isLost();Ke(`GPU bị ngắt kết nối (${n}): ${r||"không rõ nguyên nhân"}. Thử lại sẽ khởi động lại bộ dịch.`,async()=>{await Je(),ot()},{reason:"device-lost",phase:"translate",deviceLostReason:`${n}: ${r??""}`})}else Ke(`Dịch lỗi: ${t?.message??t}`,ot,{reason:"other",phase:"translate"})}finally{C(a.cancelBtn,!1),_t(!1),d.queued&&(d.queued=!1,ot())}}a.goBtn.addEventListener("click",ot);a.cancelBtn.addEventListener("click",()=>{d.stopFlag=!0});a.src.addEventListener("keydown",e=>{(e.ctrlKey||e.metaKey)&&e.key==="Enter"&&(e.preventDefault(),ot())});a.reportOutBtn.addEventListener("click",()=>Jr({title:"Báo lỗi dịch",reason:"wrong-output",phase:"translate",attach:!0,summary:"Bản dịch sai/lệch nghĩa? Tick ô bên dưới để đính kèm đoạn đang hiển thị."}));a.benchSubmitBtn.addEventListener("click",async()=>{if(!d.engine||!d.lastRun||d.lastRun.submitted)return;const e=await qr();if(!e)return;const t=await Hr(navigator,de);d.lastRun.payload??=jr({info:d.engine.info,stats:d.lastRun.stats,mode:d.lastRun.mode,srcChars:d.lastRun.srcChars,build:"3f588de",pseudo:e,ua:navigator.userAgent??"",platform:Ur(),extras:t});const n=d.lastRun.payload;Vr({title:"Gửi benchmark",summary:`${Ao(e).emoji} ${Po(e)} · ${d.engine.info.gpuName} · ${d.engine.info.modelName} · ${Math.round(n.run.tokPerSec)} tok/s · ${n.run.sentences} câu`+(Dr(n.run)?" · sẽ không xếp hạng":""),payload:n,send:async(r,o)=>{const i=await zr("/api/submit",r);if(d.lastRun.submitted=!0,C(a.benchSubmitBtn,!1),i.rank){const s=document.createDocumentFragment(),c=document.createElement("a");c.href="/board",c.textContent="xem bảng tốc độ",s.append(`Hạng ${i.rank} bảng ${d.engine.info.modelName} — `,c),o(s)}else o(da(r.run))}})});a.autoTgl.checked=(de.getItem(Wr)??"1")==="1";a.autoTgl.addEventListener("change",()=>{de.setItem(Wr,a.autoTgl.checked?"1":"0")});a.modelSelect.replaceChildren(...xo.map(e=>{const t=document.createElement("option");return t.value=e.id,t.textContent=e.name,t}));a.modelSelect.value=yn(de.getItem(An)??Sn).id;a.modelSelect.addEventListener("change",()=>{de.setItem(An,a.modelSelect.value),d.filePartial=null,a.fileProgress.textContent="",d.engine?.destroy?.(),d.engine=null,d.lastRun=null,C(a.benchSubmitBtn,!1),C(a.reportOutBtn,!1),Je()});let mr=0;a.src.addEventListener("input",()=>{if(a.srcCount.textContent=`${a.src.value.length} ký tự`,clearTimeout(mr),!(!a.autoTgl.checked||!d.engine)){if(a.src.value.length>ia){a.progress.textContent="văn bản dài — bấm Dịch";return}a.progress.textContent="",mr=setTimeout(ot,sa)}});a.pasteBtn.addEventListener("click",async()=>{try{a.src.value=await navigator.clipboard.readText(),a.src.dispatchEvent(new Event("input"))}catch{a.src.focus(),a.progress.textContent="trình duyệt chặn đọc clipboard — dán bằng Ctrl+V"}});a.clearBtn.addEventListener("click",()=>{a.src.value="",a.out.textContent="",ut(""),C(a.reportOutBtn,!1),a.src.dispatchEvent(new Event("input")),a.src.focus()});a.copyBtn.addEventListener("click",async()=>{const e=a.out.textContent;e&&await navigator.clipboard.writeText(e).catch(()=>{})});function Bn(e,t){const n=document.createElement("a");n.href=URL.createObjectURL(new Blob([t],{type:"text/plain;charset=utf-8"})),n.download=e,n.click(),URL.revokeObjectURL(n.href)}a.saveBtn.addEventListener("click",()=>{const e=a.out.textContent;e&&Bn("mac-hi.txt",e)});function ba(e){a.encSelect.replaceChildren(...Is.map(t=>{const n=document.createElement("option");return n.value=t,n.textContent=t==="auto"?`${rn.auto} (${rn[e]??e})`:rn[t],n})),a.encSelect.value="auto"}function Yr(){a.filePreview.textContent=d.file.text.slice(0,500)+(d.file.text.length>500?" …":"")}function Xr(){return{file:d.file.name,size:d.file.bytes.length,encoding:d.file.encoding,model:d.engine?.info.modelId??""}}async function Zr(e){if(!e)return;if(e.size>oa){Ke(`File ${gt(e.size)} MB vượt giới hạn 20 MB.`,()=>{});return}const t=new Uint8Array(await e.arrayBuffer()),{text:n,encoding:r}=Fr(t,"auto");d.file={name:e.name,bytes:t,text:n,encoding:r},d.fileResultText=null,d.fileProfileText=null,d.filePartial=null,a.fileName.textContent=e.name,a.fileSize.textContent=`${gt(e.size)} MB · ${r}`,ba(r),Yr(),C(a.drop,!1),C(a.filecard,!0),C(a.fileSaveBtn,!1),C(a.fileProfileBtn,!1),C(a.fileResult,!1),a.fileProgress.textContent="";const o=Qr(),i=Xr();Ws(o,i)?a.fileProgress.textContent=`phiên trước dừng ở ${o.done}/${o.rows} cụm — "Dịch file" sẽ dịch tiếp từ bộ nhớ dịch`:o&&!o.complete&&(o.done??0)>0&&o.file===i.file&&o.model===i.model&&(a.fileProgress.textContent="file đã thay đổi so phiên dịch dở trước — phần trùng sẽ lấy lại từ bộ nhớ dịch")}a.browseBtn.addEventListener("click",()=>a.fileInput.click());a.fileInput.addEventListener("change",()=>Zr(a.fileInput.files[0]));for(const[e,t]of[["dragover",!0],["dragleave",!1]])a.drop.addEventListener(e,n=>{n.preventDefault(),a.drop.classList.toggle("dragover",t)});a.drop.addEventListener("drop",e=>{e.preventDefault(),a.drop.classList.remove("dragover"),Zr(e.dataTransfer.files[0])});a.encSelect.addEventListener("change",()=>{const e=a.encSelect.value,{text:t,encoding:n}=Fr(d.file.bytes,e);d.file.text=t,d.file.encoding=n,d.filePartial=null,d.fileProfileText=null,C(a.fileProfileBtn,!1),a.fileProgress.textContent="",a.fileSize.textContent=`${gt(d.file.bytes.length)} MB · ${n}`,Yr()});a.fileDropBtn.addEventListener("click",()=>{d.file=null,d.fileResultText=null,d.fileProfileText=null,d.filePartial=null,a.fileInput.value="",C(a.filecard,!1),C(a.drop,!0)});async function bn(){if(!d.engine||!d.file||d.busy)return;_t(!0),C(a.benchSubmitBtn,!1),d.stopFlag=!1,C(a.fileCancelBtn,!0),C(a.fileSaveBtn,!1),C(a.fileProfileBtn,!1),C(a.fileResult,!1),d.fileProfileText=null,fr({file:d.file.name,batch:0,model:d.engine?.info.modelId??""});const e=Xr(),t=zs(d.engine.info),n=new URLSearchParams(location.search).get("tm")!=="0"?{get:async o=>{a.fileProgress.textContent="tra bộ nhớ dịch…";const i=await Vs(t,o),s=i.filter(Boolean).length;return a.fileProgress.textContent=s?`khôi phục ${s}/${o.length} cụm từ bộ nhớ dịch`:"",i},put:o=>qs(t,o)}:null,r=performance.now();try{const o=await d.engine.translateText(d.file.text,{pack:!0,scheduleTuneMode:d.engine.info.scheduleTuneMode,onScheduleTune:({active:i})=>{i?a.fileProgress.textContent="đang tối ưu GPU…":a.fileProgress.textContent==="đang tối ưu GPU…"&&(a.fileProgress.textContent="")},resume:d.filePartial,tm:n,shouldStop:()=>d.stopFlag,onBatch:(i,s,c)=>{d.filePartial=c;const u=c.filter(Boolean).length;fr({file:d.file.name,batch:i,batches:s,done:u,rows:c.length,model:d.engine?.info.modelId??""}),fa({...e,done:u,rows:c.length});const l=Math.round(i/s*100),h=(performance.now()-r)/1e3,f=i>0?Math.max(0,h/i*(s-i)):0;a.fileProgress.textContent=`${u}/${c.length} cụm câu · ${l}% · còn ~${Math.ceil(f)}s`}});if(o.cancelled||(d.filePartial=null,ma(),Js()),d.fileResultText=o.text+(o.cancelled?`
-
-[— bản dịch dở dang —]`:""),a.fileProgress.textContent=o.cancelled?"đã hủy — phần dịch dở vẫn tải được":`xong — ${Rt(o.stats.ms)} · ${Math.round(o.stats.tokPerSec)} tok/s`+(o.stats.tmHits?` · ${o.stats.tmHits} cụm từ bộ nhớ dịch`:"")+(o.stats.forcedEos?` · ⚠ ${o.stats.forcedEos} cụm chạm trần token`:""),a.fileResult.textContent=d.fileResultText.slice(0,1e3)+(d.fileResultText.length>1e3?" …":""),C(a.fileResult,!0),C(a.fileSaveBtn,!0),ca){const i=new URLSearchParams(location.search);let s=null;try{s=await Cs(d.fileResultText)}catch(l){console.warn("[moxhi profile] output SHA-256 unavailable:",l)}const c=o.stats.scheduleAutotune??{},u={build:"3f588de",capturedAt:new Date().toISOString(),file:{name:d.file.name,bytes:d.file.bytes.length,encoding:d.file.encoding},engine:{modelId:d.engine.info.modelId,modelName:d.engine.info.modelName,gpuName:d.engine.info.gpuName,dtype:d.engine.info.dtype,immediates:d.engine.info.immediates,uniformPool:d.engine.info.uniformPool,inPlaceCompact:d.engine.info.inPlaceCompact,scheduleTuneMode:d.engine.info.scheduleTuneMode,scheduleDefault:{...d.engine.info.scheduleDefault},kvPolicy:d.engine.info.kvPolicy,kvPlannerOverride:d.engine.info.kvPlannerOverride,kvCapacityOverride:d.engine.info.kvCapacityOverride},policy:{cap:i.get("cap"),tokenbudget:i.get("tokenbudget"),kvplanner:i.get("kvplanner"),kvcap:i.get("kvcap"),inplacecompact:i.get("inplacecompact"),scheduletune:i.get("scheduletune"),tm:i.get("tm")},totals:{cancelled:o.cancelled,sentences:o.stats.sentences,tokens:o.stats.tokens,ms:Math.round(o.stats.ms*10)/10,tokPerSec:Math.round(o.stats.tokPerSec*10)/10,forcedEos:o.stats.forcedEos,batches:o.stats.batches,resumeHits:o.stats.resumeHits,tmHits:o.stats.tmHits,decodedRows:o.stats.decodedRows,profiledMs:o.stats.profiledMs,profiledDecodeMs:o.stats.profiledDecodeMs,stages:o.stats.stages,outputSha256:s},schedule:{featureMode:c.mode??"off",requested:o.stats.requestedDecodeSchedule??null,predicted:c.predictedSchedule??null,configured:o.stats.decodeSchedule??null,effective:o.stats.effectiveDecodeSchedule??null,canonicalUsesTunerVerdict:c.canonicalUsesTunerVerdict??!1,source:c.source??"default",protocolRev:c.protocolRev??null,reason:c.reason??null,fallbackReason:c.invalidatedReason??(c.source==="default"?c.reason??null:null),invalidatedReason:c.invalidatedReason??null,cache:c.cache??null,workload:c.workload??null,evidence:c.evidence??null,candidateEvidence:c.candidateEvidence??[],projection:c.projection??null,deadline:c.deadline??null,screenSubmitShrinks:c.screenSubmitShrinks??0,selectedGain:c.selectedGain??null,sampleCount:c.sampleCount??0,confirmationCount:c.confirmationCount??0,scheduleTuneMs:c.scheduleTuneMs??0},sBuckets:o.stats.sBuckets,batchStats:o.stats.batchStats};d.fileProfileText=JSON.stringify(u,null,2),globalThis.__moxhiLastProfile=u,console.log("[moxhi profile]",u),C(a.fileProfileBtn,!0)}if(a.statPerf.textContent=`${Math.round(o.stats.tokPerSec)} tok/s · ${Rt(o.stats.ms)} · ${o.stats.sentences} cụm câu`+(o.stats.t2s?" · phồn→giản":""),o.cancelled||(d.lastRun={stats:o.stats,mode:"file",srcChars:d.file.text.length,submitted:!1},de.persistent&&C(a.benchSubmitBtn,!0)),o.stats.stages){const i=o.stats.stages,s=c=>`${(c/1e3).toFixed(1)}s ${Math.round(c/o.stats.ms*100)}%`;console.log(`[moxhi] ${o.stats.batches} batch · ${Rt(o.stats.ms)} — tokenize ${s(i.tokenizeMs)} · encoder ${s(i.encoderMs)} · decode ${s(i.decodeMs)} · detok ${s(i.detokMs)} · gap ${s(i.gapMs)} · encoder/decode là cửa sổ chồng lấn (không cộng)`+(i.tmMs?` · tm ${(i.tmMs/1e3).toFixed(1)}s (ngoài wall)`:""))}}catch(o){console.error(o);const i=d.filePartial?d.filePartial.filter(Boolean).length:0;if(d.engine?.isLost?.()){const{reason:s,message:c}=d.engine.isLost();a.fileProgress.textContent=i?`đã dịch ${i} cụm — sẽ tiếp tục từ đó`:"",Ke(`GPU bị ngắt kết nối (${s}): ${c||"không rõ nguyên nhân"}. Thử lại sẽ khởi động lại bộ dịch và dịch tiếp từ chỗ dừng.`,async()=>{await Je(),bn()},{reason:"device-lost",phase:"translate",deviceLostReason:`${s}: ${c??""}`})}else a.fileProgress.textContent="",Ke(`Dịch file lỗi: ${o?.message??o}`,bn,{reason:"other",phase:"translate"})}finally{Rn(),C(a.fileCancelBtn,!1),_t(!1)}}a.fileGoBtn.addEventListener("click",bn);a.fileCancelBtn.addEventListener("click",()=>{d.stopFlag=!0});a.fileSaveBtn.addEventListener("click",()=>{if(!d.fileResultText)return;const e=d.file.name.replace(/\.txt$/i,"");Bn(`${e}.vi.txt`,d.fileResultText)});a.fileProfileBtn.addEventListener("click",async()=>{if(d.fileProfileText)try{await navigator.clipboard.writeText(d.fileProfileText),a.fileProfileBtn.title="Đã chép profile"}catch{const e=d.file?.name?.replace(/\.txt$/i,"")||"moxhi";Bn(`${e}.profile.json`,d.fileProfileText)}});function eo(e){const t=document.createElement("div");t.className="gate-address";const n=document.createElement("code");n.textContent=e;const r=document.createElement("button");return r.type="button",r.className="ghost gate-copy",r.dataset.copyAddress=e,r.textContent="Sao chép",r.setAttribute("aria-label",`Sao chép địa chỉ ${e}`),t.append(n,r),t}function va(e){const t=document.createElement("li"),n=document.createElement("span");return n.className="gate-step-text",n.textContent=e.text,t.append(n),e.address&&t.append(eo(e.address)),t}function ya(e){const t=navigator.userAgentData,n=Go({userAgent:navigator.userAgent,platform:t?.platform??navigator.platform,mobile:t?.mobile,maxTouchPoints:navigator.maxTouchPoints,message:e});if(a.gateSummary.textContent=n.summary,a.gateSteps.replaceChildren(...n.steps.map(va)),a.gateCopyStatus.textContent="",a.gateAdvanced.open=!1,a.gateAdvancedBody.replaceChildren(),C(a.gateAdvanced,!!n.advanced),n.advanced){const r=document.createElement("p");r.textContent=n.advanced.text,a.gateAdvancedBody.append(r),n.advanced.address&&a.gateAdvancedBody.append(eo(n.advanced.address))}a.gateErr.textContent=`Chi tiết kỹ thuật: ${e}`}a.gate.addEventListener("click",async e=>{const t=e.target.closest?.("[data-copy-address]");if(!t||!a.gate.contains(t))return;const n=t.dataset.copyAddress;try{if(!navigator.clipboard?.writeText)throw new Error("clipboard unavailable");await navigator.clipboard.writeText(n),a.gateCopyStatus.textContent=`Đã sao chép ${n}`}catch{a.gateCopyStatus.textContent="Trình duyệt chặn sao chép tự động — hãy chọn địa chỉ rồi sao chép thủ công."}});a.gateRetryBtn.addEventListener("click",Je);pa();Je();"serviceWorker"in navigator&&window.addEventListener("load",()=>{navigator.serviceWorker.register("/sw.js").catch(()=>{})});