ngocdang83 commited on
Commit
374e336
·
verified ·
1 Parent(s): a592199

moxhi 1d05277

Browse files
assets/{bench-Cxje7vnD.js → bench-CNBcu3F_.js} RENAMED
@@ -1,5 +1,5 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/reference-BgleqVd6.js","assets/preload-helper-DpiWnaYd.js"])))=>i.map(i=>d[i]);
2
- import"./modulepreload-polyfill-B5Qt9EMX.js";import{E as G,_ as W,t as U,a as V,m as z,b as K,i as Y,l as X,e as Z,c as nn,d as tn}from"./preload-helper-DpiWnaYd.js";function F(t){for(let e=1;e<t.length;e++)if(t[e]===G)return t.slice(0,e+1);return t.slice()}function en(t,e){const i=F(t),c=F(e),n=Math.min(i.length,c.length);let a=0;for(;a<n&&i[a]===c[a];)a++;if(a===i.length&&a===c.length)return{verdict:"exact"};if(a===n){const d=i.length>c.length?i:c;if(d.length===n+1&&d[n]===G)return{verdict:"forced-eos"}}return{verdict:"mismatch",step:a}}function I(t,e=220){const i=String(t).replace(/\r\n/g,`
3
  `).split(`
4
  `),c=[],n=[],a=Math.max(80,Number(e)||220),d=/[^。!?!?;;]+[。!?!?;;]*/g;for(const m of i){const g=m.trim();if(!g){n.push(null);continue}const f=g.match(d)||[g];let u="";const r=[],k=()=>{u&&(r.push(c.length),c.push(u),u="")};for(const h of f){if(h.length>a){k();for(let o=0;o<h.length;o+=a)r.push(c.length),c.push(h.slice(o,o+a));continue}u&&(u+h).length>a&&k(),u+=h}k(),n.push(r)}return{chunks:c,plan:n}}const cn=["他缓缓拔出长剑,目光冷得像冰。","夜色渐深,客栈里只剩下几盏残灯。","“你到底是什么人?”她低声问道。","山风呼啸,卷起满地的落叶。","老者捋了捋胡须,微微一笑。","这一掌的力道,足以开碑裂石!","“师父,弟子知错了。”少年跪在地上。","江湖上的恩怨,从来没有那么简单。","她转身离去,再也没有回头。","剑光一闪,血溅三尺。","大殿之内,众人鸦雀无声。","他喝了口酒,眼中闪过一丝痛楚。","“今晚三更,后山竹林见。”","马蹄声由远及近,尘土飞扬。","这门功夫,他练了整整二十年。","暮色四合之际,一行人马终于抵达了山脚下的小镇,镇口的酒旗在风中猎猎作响;为首的中年汉子翻身下马,环顾四周,见街道两旁的店铺早已关门闭户,只有远处一家客栈还透出昏黄的灯光,他皱了皱眉,低声吩咐众人收起兵刃,不要惊扰了镇上的百姓。","传闻中的藏剑山庄坐落在群山环抱之中,庄内古木参天,流水潺潺,青石铺就的小径蜿蜒曲折;每逢三月桃花盛开,四方豪杰便会齐聚于此,或论剑,或品茶,或只是远远地望一眼那位传说中的庄主,据说他已经三十年没有拔过剑了,可江湖上没有人敢小看他。","那一夜大雨倾盆,雷声滚滚,破庙里的火堆忽明忽暗;少年抱着怀中的剑谱,听着庙外杂乱的脚步声越来越近,心跳如鼓,他知道,追兵一旦破门而入,自己便再无生路,可师父临终前的嘱托犹在耳边,这本剑谱无论如何都不能落入奸人之手。","掌门之位悬空已有三年,门中各脉明争暗斗从未停歇;大师兄稳重却优柔寡断,二师姐剑法超群却性情孤傲,三师弟聪明伶俐却资历尚浅,长老们各怀心思,谁也不肯先开口,直到那个雪夜,山门外传来一声长啸,所有人都放下了手中的茶盏。","集市上人声鼎沸,卖艺的汉子赤膊耍着一杆铁枪,围观的人群不时爆发出阵阵喝彩声;忽然人群一阵骚动,几名黑衣人分开众人径直走向那名枪手,为首之人冷冷地丢下一块乌黑的令牌,喧闹的集市霎时安静了下来,连风都仿佛停了。","信使跪在堂下,双手呈上一封火漆密函,堂上众人面面相觑;老庄主拆开信笺,只看了一眼,脸色便骤然大变,他缓缓起身,望着窗外沉沉的夜色,半晌才道:传令下去,即刻封山,任何人不得进出,违令者一律逐出师门,永不再录。","三十年前的那场大火烧毁了半座城池,也烧断了两大世家百年的情谊;如今旧事重提,当年的幸存者死的死,散的散,唯有城南那口枯井旁的老槐树还记得一切,树下埋着的,不只是一坛陈年的女儿红,还有一个再也无人敢提起的名字。","渡口的老船夫眯着眼打量来客,见那书生衣衫褴褛却腰悬长剑,不由得多问了一句;书生笑而不答,只将一锭碎银放在船头,转身望向对岸茫茫的芦苇荡,江风吹起他的衣角,露出内衬上暗绣的金线纹样,老船夫握着船桨的手,忽然抖了一下。","林昭推门而入,林昭的剑还在滴着血,可林昭的声音却平静得可怕。","沈青山望着窗外,沈青山知道,今夜之后江湖上再无沈青山这个名字。","“林昭!林昭你给我站住!”她追出门外,可林昭的身影早已消失在夜色之中。","众人都说沈青山败了,可沈青山不这么认为,沈青山收剑入鞘,转身走下擂台。","林昭救过他一次,林昭也骗过他一次,所以当林昭再次出现时,他不知该拔剑还是敬酒。","沈青山的刀快,沈青山的心更狠,凡是见过沈青山出手的人,都不愿再与他为敌。","有人说林昭死在了雁门关外,有人说林昭隐居山林,还有人说,林昭根本就没有存在过。"],j=`第三章 夜雨断魂崖
5
 
@@ -34,7 +34,7 @@ import"./modulepreload-polyfill-B5Qt9EMX.js";import{E as G,_ as W,t as U,a as V,
34
  赵师叔趁乱引着柳如烟等人坠下涧底,冰冷的涧水没过头顶的一瞬,柳如烟犹自回头,只见崖畔两道身影在电光中分而复合,合而复分,那柄断剑的寒芒每一次亮起都比前一次更接近咽喉,也更接近深渊,她张口想喊,灌进来的却只有一口冰水,赵师叔死死攥住她的手腕,两人顺着湍流向下游卷去,耳边的厮杀声、雷声、马嘶声渐渐都被水声吞没,唯有那一点剑芒烙在她眼底,任凭涧水如何冲刷也冲刷不去,多年以后她仍会在雨夜里惊醒,梦见那点寒星坠向无底的黑暗。
35
 
36
  那一夜断魂崖的厮杀声直到五更方歇。后来江湖上有人说,曾见一个青衫剑客独战数百人,剑折之后夺刀再战,刀卷之后赤手空拳;也有人说,天明时分崖下的涧水都是红的。唯一可以确证的是,半月之后,一份写满名字的血书送到了武林盟主的案头,落款只有八个字:青城沈氏,以剑为凭。自那以后,川中道上再无血狼堡的旗号,而断魂崖顶的老松之下,多了一座无碑的剑冢,年年秋深,总有人遥遥望见一个白衣女子在冢前置酒三杯,风雨无阻。
37
- `,an=["刀出如龙,寒气逼人。","他在桥头站了一夜。","“放下剑,我饶你不死。”","钟声响起,山门缓缓开启。","她的暗器从不落空。","灯火摇曳,人影散乱。","一杯酒,敬当年的兄弟。","掌风过处,烛火尽灭。","他背上的伤疤又开始疼了。","“来者何人,报上名来!”","雪落无声,剑亦无声。","这条路,他走了半生。","密道尽头透出一线微光。","恩人一诺,死生不忘。","毒发之时,他咬碎了牙关。","旗帜倒下,城头易主。","江水东流,带不走旧恨。"];function A(t){if(t==="short32")return[...cn.slice(0,15),...an];if(t==="chapter3k")return I(j).chunks;if(t==="file23k"){const e=I(j).chunks;return Array.from({length:8},()=>e).flat()}throw new Error(`unknown preset: ${t}`)}const D=t=>[...t].sort((e,i)=>i.length-e.length),$=t=>Number(t.toFixed(1));function hn(t){const e=[...t].sort((c,n)=>c-n),i=e.length>>1;return e.length%2?e[i]:(e[i-1]+e[i])/2}async function H(t,e,i,c,n,a=null,d={}){let m=0,g=0,f=0,u=0;const r={uniformBuffersCreated:0,dummyBuffersCreated:0,bindGroupsCreated:0,bindGroupCacheHits:0,bindGroupEvictions:0,immediateSets:0};for(let h=0;h<c.length;h+=n){const o=c.slice(h,h+n),{metrics:w}=await U(t,e,i,o,{...V(a,o.length),...d});m+=w.encoderMs,g+=w.decodeMs,f+=w.tokensGenerated,u+=w.submits;for(const L of Object.keys(r))r[L]+=w.dispatch?.[L]??0}const k=c.reduce((h,o)=>h+o.length,0);return{encoderMs:$(m),decodeMs:$(g),tokens:f,submits:u,dispatch:r,tokPerSec:$(f/g*1e3),e2eCharsPerSec:$(k/(m+g)*1e3)}}const on=["encoderMs","decodeMs","tokens","tokPerSec","e2eCharsPerSec"],_={"tfjs-wasm-q8":{device:"wasm",dtype:"q8"},"tfjs-webgpu-fp16":{device:"webgpu",dtype:"fp16"}};async function sn(t,e,i,{presets:c=["short32","chapter3k"],batches:n=[1,4,8,16],repeats:a=3,includeReference:d=!1,referencePresets:m=c,referenceBatches:g=[1,4],referenceCells:f=Object.keys(_).flatMap(h=>m.flatMap(o=>g.map(w=>({runtime:h,preset:o,batch:w})))),tuned:u=null,engineOptions:r={},onStatus:k=()=>{}}={}){const h=[],o=Object.fromEntries(c.map(p=>[p,D(A(p))])),w=p=>Array.isArray(n)?n:n[p],L=e.dtype==="f16"?2:4,B=async p=>{const b=i.encode(o[p][0]),y=z(t,K(b.length),L),l=[];for(const T of w(p)){const s=Math.min(T,y);s!==T&&k(`${p}: batch ${T} clamped to device max ${s}`),l.some(N=>N.batch===s)||l.push({batch:s,...s!==T?{requestedBatch:T}:{}})}return l};k("warmup…"),await H(t,e,i,o[c[0]],(await B(c[0]))[0].batch,u,r);for(const p of c)for(const{batch:b,requestedBatch:y}of await B(p)){const l=[];for(let s=0;s<a;s++)k(`webmt ${p} b${b} repeat ${s+1}/${a}…`),l.push(await H(t,e,i,o[p],b,u,r));const T=Object.fromEntries(on.map(s=>[s,$(hn(l.map(N=>N[s])))]));h.push({runtime:"webmt",preset:p,batch:b,...y?{requestedBatch:y}:{},repeats:l,median:T,min:{tokPerSec:Math.min(...l.map(s=>s.tokPerSec)),e2eCharsPerSec:Math.min(...l.map(s=>s.e2eCharsPerSec))},max:{tokPerSec:Math.max(...l.map(s=>s.tokPerSec)),e2eCharsPerSec:Math.max(...l.map(s=>s.e2eCharsPerSec))}})}if(d){const{runReference:p}=await W(async()=>{const{runReference:b}=await import("./reference-BgleqVd6.js");return{runReference:b}},__vite__mapDeps([0,1]));for(const{runtime:b,preset:y,batch:l}of f){const{device:T,dtype:s}=_[b]??{};if(!T)throw new Error(`unknown reference runtime: ${b}`);const N=o[y]??D(A(y));k(`${b} ${y} b${l} (single run)…`);try{const S=await p({device:T,dtype:s,sources:N,batchSize:l,onStatus:Q=>k(`${b} ${y} b${l}: ${Q}`)}),O={loadMs:Math.round(S.loadMs),translateMs:Math.round(S.translateMs),tokens:S.tokens,tokPerSec:$(S.tokPerSec),e2eCharsPerSec:$(S.charsPerSec)};h.push({runtime:b,preset:y,batch:l,repeats:[O],median:O})}catch(S){h.push({runtime:b,preset:y,batch:l,error:String(S?.message??S)})}}}return h}function rn(t,e,{date:i,stack:c}={}){const n=new Date,a=`${n.getFullYear()}-${String(n.getMonth()+1).padStart(2,"0")}-${String(n.getDate()).padStart(2,"0")}`;return{schema:"webmt-bench-v1",date:i??a,adapterInfo:e,...c?{stack:c}:{},baselineRef:"docs/bench/baseline.json",runs:t}}const mn={repetitionPenalty:1.2,greedy:!0,maxNewTokensFormula:"max(24, min(192, ceil(chars*3.2)+12))",dtype:"fp32"},gn=JSON.parse('[{"source":"他缓缓拔出长剑,目光冷得像冰。","ids":[0,754,1237,1501,1594,1039,654,339,18937,821,475,1072,321,1951,18948,2],"maxNewTokens":60,"text":"Hắn chậm rãi rút trường kiếm ra, ánh mắt lạnh như băng."},{"source":"夜色渐深,客栈里只剩下几盏残灯。","ids":[0,4988,1082,2875,659,18937,332,1542,7495,394,404,329,889,1742,3286,1631,18948,2],"maxNewTokens":64,"text":"Đêm dần buông xuống, trong khách điếm chỉ còn lại vài ngọn đèn tàn."},{"source":"“你到底是什么人?”她低声问道。","ids":[0,337,11090,997,514,292,843,632,1958,1460,1298,848,18948,2],"maxNewTokens":64,"text":"\\"Rốt cuộc ngươi là ai?\\" Nàng thấp giọng hỏi."},{"source":"山风呼啸,卷起满地的落叶。","ids":[0,7521,976,2771,2813,2164,448,2189,8052,916,871,18948,2],"maxNewTokens":54,"text":"Gió núi gào thét cuốn lên lá rụng đầy đất."},{"source":"老者捋了捋胡须,微微一笑。","ids":[0,1577,732,3592,12443,5089,18937,1820,708,18948,2],"maxNewTokens":54,"text":"Lão giả vuốt chòm râu, mỉm cười."},{"source":"这一掌的力道,足以开碑裂石!","ids":[0,4522,565,313,309,1724,324,1004,469,1057,4088,3282,1155,19020,2],"maxNewTokens":57,"text":"Lực đạo của một chưởng này đủ để mở bia nứt đá!"},{"source":"“师父,弟子知错了。”少年跪在地上。","ids":[0,337,4338,1129,18937,739,576,498,1621,483,482,2439,1356,3199,459,477,871,18948,2],"maxNewTokens":70,"text":"\\"Sư phụ, đệ tử biết sai rồi.\\" Thiếu niên quỳ trên mặt đất."},{"source":"江湖上的恩怨,从来没有那么简单。","ids":[0,4489,3247,5634,1071,667,616,1463,1790,321,488,18948,2],"maxNewTokens":64,"text":"Ân oán giang hồ chưa từng đơn giản như vậy."},{"source":"她转身离去,再也没有回头。","ids":[0,1958,1795,331,1044,367,18937,290,404,1143,437,329,551,18948,2],"maxNewTokens":54,"text":"Nàng xoay người rời đi, không còn quay đầu lại nữa."},{"source":"剑光一闪,血溅三尺。","ids":[0,1089,1017,2213,448,18937,1073,2126,1549,8635,692,4479,18948,2],"maxNewTokens":44,"text":"Kiếm quang lóe lên, máu bắn tung tóe ba thước."},{"source":"大殿之内,众人鸦雀无声。","ids":[0,795,497,1140,18937,874,331,2505,15669,284,399,18948,2],"maxNewTokens":51,"text":"Trong đại điện, mọi người im phăng phắc."},{"source":"他喝了口酒,眼中闪过一丝痛楚。","ids":[0,754,2184,309,3793,2251,18937,332,475,2213,448,775,1879,3822,18948,2],"maxNewTokens":60,"text":"Hắn uống một ngụm rượu, trong mắt lóe lên vẻ đau đớn."},{"source":"“今晚三更,后山竹林见。”","ids":[0,337,18955,396,781,2124,692,18937,1035,453,2507,3016,1262,1523,482,2],"maxNewTokens":54,"text":"\\"Tối nay canh ba, gặp ở rừng trúc hậu sơn.\\""},{"source":"马蹄声由远及近,尘土飞扬。","ids":[0,3469,10058,1853,389,863,372,935,18937,2772,871,1549,1033,18948,2],"maxNewTokens":54,"text":"Tiếng vó ngựa từ xa đến gần, bụi đất tung bay."},{"source":"这门功夫,他练了整整二十年。","ids":[0,1322,583,1895,324,18937,343,335,627,1557,480,1195,549,18948,2],"maxNewTokens":57,"text":"Môn công phu này, hắn đã luyện suốt hai mươi năm."},{"source":"暮色四合之际,一行人马终于抵达了山脚下的小镇,镇口的酒旗在风中猎猎作响;为首的中年汉子翻身下马,环顾四周,见街道两旁的店铺早已关门闭户,只有远处一家客栈还透出昏黄的灯光,他皱了皱眉,低声吩咐众人收起兵刃,不要惊扰了镇上的百姓。","ids":[0,6394,561,1601,2738,2875,659,18937,2161,331,870,434,334,372,369,1054,1722,810,777,640,976,18937,2542,2251,453,981,1722,1549,1033,332,1423,19873,5623,576,921,1356,1062,437,2187,659,1853,18937,439,1100,1156,559,18937,458,591,981,1159,480,569,653,335,1157,2348,981,2348,3509,18937,394,298,309,2688,14099,863,863,404,10866,339,821,3286,1058,3305,18937,343,2012,1317,18937,1460,1298,3323,1830,874,331,493,1036,1327,535,18937,290,369,4688,5916,3393,832,332,1722,18948,2],"maxNewTokens":192,"text":"Vào lúc hoàng hôn buông xuống, đoàn người cuối cùng cũng đến được thị trấn nhỏ dưới chân núi, cờ rượu ở cửa trấn tung bay trong gió; hán tử trung niên dẫn đầu nhảy xuống ngựa, nhìn quanh bốn phía, thấy các cửa hàng hai bên đường đã sớm đóng cửa đóng kín, chỉ có một quán trọ xa xa còn hắt ra ánh đèn vàng vọt, hắn nhíu mày, thấp giọng dặn dò mọi người thu hồi binh khí, không được quấy nhiễu bách tính trong trấn."},{"source":"传闻中的藏剑山庄坐落在群山环抱之中,庄内古木参天,流水潺潺,青石铺就的小径蜿蜒曲折;每逢三月桃花盛开,四方豪杰便会齐聚于此,或论剑,或品茶,或只是远远地望一眼那位传说中的庄主,据说他已经三十年没有拔过剑了,可江湖上没有人敢小看他。","ids":[0,4694,1089,1523,1814,332,813,2410,2494,1630,929,1378,1868,313,4822,976,18937,569,332,2826,1160,1994,651,5765,862,18937,911,2133,15966,3276,18937,620,653,810,1576,1155,1402,10574,4220,4402,1134,19290,18939,19873,1224,455,1499,692,1391,2842,3389,6259,18937,2333,3778,1156,690,329,1410,5781,617,606,18937,1153,2013,654,18937,1153,2525,2686,18937,1153,394,439,863,466,559,555,3664,691,332,813,2410,598,309,625,18937,772,383,343,335,692,1195,549,290,1594,654,483,18937,428,459,5634,1071,290,843,1126,1179,705,343,18948,2],"maxNewTokens":192,"text":"Tàng Kiếm sơn trang trong truyền thuyết tọa lạc giữa vòng vây của dãy núi, bên trong thôn cổ thụ cao ngất trời, nước chảy róc rách, con đường nhỏ lát đá xanh uốn lượn khúc khuỷu; mỗi khi tháng ba hoa đào nở rộ, hào kiệt bốn phương lại tụ họp tại đây, hoặc luận kiếm, hoặc thưởng trà, hoặc chỉ nhìn xa về phía vị Trang chủ trong truyền thuyết kia một cái, nghe nói hắn đã ba mươi năm không rút kiếm rồi, nhưng trên giang hồ không ai dám coi thường hắn."},{"source":"那一夜大雨倾盆,雷声滚滚,破庙里的火堆忽明忽暗;少年抱着怀中的剑谱,听着庙外杂乱的脚步声越来越近,心跳如鼓,他知道,追兵一旦破门而入,自己便再无生路,可师父临终前的嘱托犹在耳边,这本剑谱无论如何都不能落入奸人之手。","ids":[0,4988,393,2121,321,4987,911,18937,3950,12395,1272,18937,3342,1481,332,5354,1654,561,857,561,1381,19873,1248,1356,2567,654,7636,332,626,18937,1871,772,623,736,640,2564,1587,569,688,5354,696,715,935,18937,3825,2399,10836,15013,18948,754,498,18937,309,455,763,2062,1824,373,981,1996,416,18937,512,508,290,404,653,1037,551,18937,428,725,3323,1830,452,455,3028,2870,313,595,1129,521,5290,270,518,569,1776,18937,2164,654,7636,324,658,457,506,334,290,338,1132,416,464,680,501,18948,2],"maxNewTokens":192,"text":"Đêm đó mưa như trút nước, sấm rền vang, đống lửa trong miếu đổ lúc sáng lúc tối; thiếu niên ôm kiếm phổ trong lòng, lắng nghe tiếng bước chân hỗn loạn bên ngoài miếu ngày càng gần, tim đập thình thịch. Hắn biết, một khi quân truy đuổi phá cửa xông vào, mình sẽ không còn đường sống nữa, nhưng lời dặn dò trước khi lâm chung của sư phụ vẫn văng vẳng bên tai, cuốn kiếm phổ này dù thế nào cũng không thể rơi vào tay gian nhân."},{"source":"掌门之位悬空已有三年,门中各脉明争暗斗从未停歇;大师兄稳重却优柔寡断,二师姐剑法超群却性情孤傲,三师弟聪明伶俐却资历尚浅,长老们各怀心思,谁也不肯先开口,直到那个雪夜,山门外传来一声长啸,所有人都放下了手中的茶盏。","ids":[0,2404,1092,1724,716,335,3547,3248,3761,692,549,18937,591,1454,332,716,1184,1097,1155,3852,667,616,1234,2653,19873,741,595,1144,1310,1870,428,329,720,820,1248,1124,1439,18937,2186,595,1691,654,496,3450,2745,428,832,803,1158,3324,18937,1451,595,739,833,1441,11877,1125,428,1020,2338,404,5002,3454,18937,591,841,655,471,922,649,1020,1854,18937,290,843,1131,1057,1172,452,18937,432,372,1368,2051,1053,18937,569,688,1523,716,813,372,309,623,269,18991,1012,18937,948,363,874,331,471,1414,3969,2686,332,464,659,18948,2],"maxNewTokens":192,"text":"Vị trí chưởng môn đã treo lơ lửng ba năm, các mạch trong môn phái đấu đá ngầm chưa từng ngừng nghỉ; Đại sư huynh trầm ổn nhưng lại do dự thiếu quyết đoán, Nhị sư tỷ kiếm pháp siêu quần nhưng tính tình cô ngạo, Tam sư đệ thông minh lanh lợi nhưng tư lịch còn nông cạn, các trưởng lão đều mang tâm tư riêng, không ai chịu mở miệng trước, cho đến đêm tuyết ấy, bên ngoài sơn môn truyền đến một tiếng hú dài, tất cả mọi người đều đặt chén trà trong tay xuống."},{"source":"集市上人声鼎沸,卖艺的汉子赤膊耍着一杆铁枪,围观的人群不时爆发出阵阵喝彩声;忽然人群一阵骚动,几名黑衣人分开众人径直走向那名枪手,为首之人冷冷地丢下一块乌黑的令牌,喧闹的集市霎时安静了下来,连风都仿佛停了。","ids":[0,1521,453,7196,5922,4759,3588,2359,18937,2328,1899,989,1920,3938,8267,2961,4687,309,1328,1562,829,18937,1014,331,1868,884,2287,2554,329,714,339,616,6261,623,8860,7359,1263,2525,18948,15010,558,1014,331,7694,6091,18937,713,790,2275,613,501,3671,874,331,339,367,1112,466,559,790,829,672,598,18937,757,1400,437,1072,2527,2690,659,309,2641,1696,1739,1019,6325,18937,7196,5922,4759,332,2414,1576,1800,1239,660,329,18937,801,363,1423,334,321,1234,329,18948,2],"maxNewTokens":192,"text":"Người ở chợ ồn ào náo nhiệt, gã đàn ông bán nghệ cởi trần múa một cây thiết thương, đám người vây xem thỉnh thoảng lại phát ra từng tràng tiếng reo hò tán thưởng. Bỗng nhiên đám người xôn xao, mấy tên hắc y nhân tách mọi người ra đi thẳng về phía tên thương thủ kia, kẻ cầm đầu lạnh lùng ném xuống một khối lệnh bài đen nhánh, chợ ồn ào trong chốc lát yên tĩnh trở lại, ngay cả gió cũng như ngừng lại."},{"source":"信使跪在堂下,双手呈上一封火漆密函,堂上众人面面相觑;老庄主拆开信笺,只看了一眼,脸色便骤然大变,他缓缓起身,望着窗外沉沉的夜色,半晌才道:传令下去,即刻封山,任何人不得进出,违令者一律逐出师门,永不再录。","ids":[0,7964,732,3199,777,653,18937,480,464,2549,448,309,906,1300,1693,1523,1383,18937,874,331,459,653,439,962,3456,5611,19873,655,1814,691,1057,906,1300,339,18937,394,1982,475,309,625,18937,853,477,746,842,558,497,818,18948,3866,1237,1501,844,1777,18937,439,1924,1368,2339,1133,688,981,2644,18937,1250,696,534,383,19026,3471,1696,659,18937,770,647,906,1523,18937,729,643,843,290,369,339,416,18937,757,887,2028,1696,471,449,7938,762,828,595,716,18937,4487,3830,290,2282,329,551,18948,2],"maxNewTokens":192,"text":"Sứ giả quỳ dưới đường, hai tay dâng lên một phong thư mật sơn đỏ, mọi người trên đường nhìn nhau ngơ ngác; lão trang chủ mở phong thư ra, chỉ liếc mắt một cái, sắc mặt liền đột nhiên đại biến. Ông chậm rãi đứng dậy, nhìn màn đêm dày đặc ngoài cửa sổ, nửa ngày mới nói: Truyền lệnh xuống, lập tức phong sơn, bất kỳ ai không được ra vào, kẻ vi phạm lệnh đều bị trục xuất khỏi sư môn, vĩnh viễn không ghi lại nữa."},{"source":"三十年前的那场大火烧毁了半座城池,也烧断了两大世家百年的情谊;如今旧事重提,当年的幸存者死的死,散的散,唯有城南那口枯井旁的老槐树还记得一切,树下埋着的,不只是一坛陈年的女儿红,还有一个再也无人敢提起的名字。","ids":[0,1839,1624,14105,692,1195,549,452,335,373,2464,1250,1888,442,1593,18937,334,3626,11367,803,1526,988,549,313,480,497,457,619,19873,781,631,2145,1663,329,18937,331,1037,2204,549,1791,784,784,18937,1408,6677,18937,394,298,1328,7359,19014,1932,569,8833,3163,559,1582,442,404,1455,719,948,363,18937,777,2762,1328,5951,290,394,309,4725,2280,1823,1199,909,1307,18937,368,404,298,625,790,290,843,1126,1663,372,551,18948,2],"maxNewTokens":192,"text":"Trận hỏa hoạn ba mươi năm trước đã phá hủy nửa tòa thành trì, cũng thiêu rụi tình nghĩa trăm năm của hai đại thế gia; nay chuyện cũ nhắc lại, người sống sót năm xưa chết chết, tan rã, chỉ có cây hòe già bên giếng khô phía nam thành còn nhớ rõ tất cả, dưới gốc cây chôn không chỉ một vò Nữ Nhi Hồng lâu đời, mà còn có cái tên không ai dám nhắc đến nữa."},{"source":"渡口的老船夫眯着眼打量来客,见那书生衣衫褴褛却腰悬长剑,不由得多问了一句;书生笑而不答,只将一锭碎银放在船头,转身望向对岸茫茫的芦苇荡,江风吹起他的衣角,露出内衬上暗绣的金线纹样,老船夫握着船桨的手,忽然抖了一下。","ids":[0,1577,2200,1895,453,7445,263,19013,4280,475,793,1149,1542,563,18937,458,1300,687,598,2745,1290,3276,286,1984,428,6834,1390,3547,1039,654,18937,290,828,848,785,309,1055,19873,1698,687,708,368,290,1361,18937,394,1414,309,266,573,1807,2922,453,1866,2200,18937,1795,331,439,466,559,5205,278,446,5032,3814,569,598,2658,18948,7521,2408,3424,1549,2747,1290,313,343,18937,950,339,1391,1634,1563,3038,11130,1918,18938,569,332,18948,9126,655,2200,1895,1175,2670,17524,1689,558,2169,448,309,625,18948,2],"maxNewTokens":192,"text":"Lão thuyền phu ở bến đò nheo mắt đánh giá khách tới, thấy thư sinh kia quần áo rách rưới nhưng thắt lưng treo trường kiếm, không khỏi hỏi thêm một câu; Thư sinh cười mà không đáp, chỉ đặt một thỏi bạc vụn ở mũi thuyền, xoay người nhìn về phía lau sậy mênh mông bên kia bờ. Gió sông thổi tung góc áo của hắn, lộ ra hoa văn kim tuyến thêu thùa bên trong. Tay lão thuyền phu nắm mái chèo bỗng nhiên run lên một cái."},{"source":"林昭推门而入,林昭的剑还在滴着血,可林昭的声音却平静得可怕。","ids":[0,1090,4264,2182,981,736,416,18937,654,313,1090,4264,521,404,520,810,1073,18937,428,877,1096,313,343,329,815,1239,372,1094,953,18948,2],"maxNewTokens":108,"text":"Lâm Chiêu đẩy cửa bước vào, kiếm của Lâm Chiêu vẫn còn đang nhỏ máu, nhưng thanh âm của hắn lại bình tĩnh đến đáng sợ."},{"source":"沈青山望着窗外,沈青山知道,今夜之后江湖上再无沈青山这个名字。","ids":[0,3560,734,730,439,339,688,981,2644,18937,3560,734,730,498,776,18937,465,1368,781,459,5634,1071,290,404,625,790,3560,734,730,506,551,18948,2],"maxNewTokens":112,"text":"Thẩm Thanh Sơn nhìn ra ngoài cửa sổ, Thẩm Thanh Sơn biết rằng, sau đêm nay trên giang hồ không còn cái tên Thẩm Thanh Sơn nào nữa."},{"source":"“林昭!林昭你给我站住!”她追出门外,可林昭的身影早已消失在夜色之中。","ids":[0,415,18989,424,4264,19020,1090,4264,18937,514,844,329,432,382,568,1958,1824,339,688,981,18937,428,479,1249,313,1090,4264,335,1157,818,920,332,1924,1368,18948,2],"maxNewTokens":124,"text":"“Lâm Chiêu! Lâm Chiêu, ngươi đứng lại cho ta!” Nàng đuổi ra ngoài cửa, nhưng thân ảnh của Lâm Chiêu đã sớm biến mất trong màn đêm."},{"source":"众人都说沈青山败了,可沈青山不这么认为,沈青山收剑入鞘,转身走下擂台。","ids":[0,3032,331,471,383,3560,734,730,335,2665,18937,428,3560,734,730,290,676,488,18937,3560,734,730,493,654,416,3998,18937,1795,331,736,659,1963,2058,18948,2],"maxNewTokens":124,"text":"Mọi người đều nói Thẩm Thanh Sơn đã thua, nhưng Thẩm Thanh Sơn không nghĩ vậy, Thẩm Thanh Sơn thu kiếm vào vỏ, xoay người bước xuống lôi đài."},{"source":"林昭救过他一次,林昭也骗过他一次,所以当林昭再次出现时,他不知该拔剑还是敬酒。","ids":[0,1090,4264,335,1372,343,309,638,18937,1090,4264,334,3539,5136,343,309,638,18937,432,599,455,1090,4264,762,516,638,551,18937,343,290,498,599,1594,654,802,292,1809,2251,18948,2],"maxNewTokens":137,"text":"Lâm Chiêu đã cứu hắn một lần, Lâm Chiêu cũng lừa gạt hắn một lần, cho nên khi Lâm Chiêu xuất hiện lần nữa, hắn không biết nên rút kiếm hay là kính rượu."},{"source":"沈青山的刀快,沈青山的心更狠,凡是见过沈青山出手的人,都不愿再与他为敌。","ids":[0,3271,313,3560,734,730,894,18937,626,3560,734,730,715,785,1631,2492,18937,729,749,843,616,458,3560,734,730,339,464,471,290,582,660,442,757,1734,412,343,551,18948,2],"maxNewTokens":128,"text":"Đao của Thẩm Thanh Sơn nhanh, lòng Thẩm Thanh Sơn càng thêm tàn nhẫn, bất cứ ai từng thấy Thẩm Thanh Sơn ra tay đều không muốn trở thành kẻ địch với hắn nữa."},{"source":"有人说林昭死在了雁门关外,有人说林昭隐居山林,还有人说,林昭根本就没有存在过。","ids":[0,1480,331,383,1090,4264,784,453,688,10521,1322,1592,18937,298,331,383,343,1279,3715,332,2507,976,18937,329,404,298,331,383,18937,1090,4264,1107,624,667,616,1512,617,18948,2],"maxNewTokens":137,"text":"Có người nói Lâm Chiêu chết ở ngoài Nhạn Môn Quan, có người nói hắn ẩn cư trong rừng núi, lại còn có người nói, Lâm Chiêu căn bản chưa từng tồn tại."}]'),P={config:mn,items:gn},un=document.querySelector("#app");un.innerHTML=`
38
  <h1>webMT bench</h1>
39
  <p>
40
  <button id="load">Load engine</button>
 
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/reference-CfIaZkZf.js","assets/preload-helper-BSrbm-kb.js"])))=>i.map(i=>d[i]);
2
+ import"./modulepreload-polyfill-B5Qt9EMX.js";import{E as G,_ as W,t as U,a as V,m as z,b as K,i as Y,l as X,e as Z,c as nn,d as tn}from"./preload-helper-BSrbm-kb.js";function F(t){for(let e=1;e<t.length;e++)if(t[e]===G)return t.slice(0,e+1);return t.slice()}function en(t,e){const i=F(t),c=F(e),n=Math.min(i.length,c.length);let a=0;for(;a<n&&i[a]===c[a];)a++;if(a===i.length&&a===c.length)return{verdict:"exact"};if(a===n){const d=i.length>c.length?i:c;if(d.length===n+1&&d[n]===G)return{verdict:"forced-eos"}}return{verdict:"mismatch",step:a}}function I(t,e=220){const i=String(t).replace(/\r\n/g,`
3
  `).split(`
4
  `),c=[],n=[],a=Math.max(80,Number(e)||220),d=/[^。!?!?;;]+[。!?!?;;]*/g;for(const m of i){const g=m.trim();if(!g){n.push(null);continue}const f=g.match(d)||[g];let u="";const r=[],k=()=>{u&&(r.push(c.length),c.push(u),u="")};for(const h of f){if(h.length>a){k();for(let o=0;o<h.length;o+=a)r.push(c.length),c.push(h.slice(o,o+a));continue}u&&(u+h).length>a&&k(),u+=h}k(),n.push(r)}return{chunks:c,plan:n}}const cn=["他缓缓拔出长剑,目光冷得像冰。","夜色渐深,客栈里只剩下几盏残灯。","“你到底是什么人?”她低声问道。","山风呼啸,卷起满地的落叶。","老者捋了捋胡须,微微一笑。","这一掌的力道,足以开碑裂石!","“师父,弟子知错了。”少年跪在地上。","江湖上的恩怨,从来没有那么简单。","她转身离去,再也没有回头。","剑光一闪,血溅三尺。","大殿之内,众人鸦雀无声。","他喝了口酒,眼中闪过一丝痛楚。","“今晚三更,后山竹林见。”","马蹄声由远及近,尘土飞扬。","这门功夫,他练了整整二十年。","暮色四合之际,一行人马终于抵达了山脚下的小镇,镇口的酒旗在风中猎猎作响;为首的中年汉子翻身下马,环顾四周,见街道两旁的店铺早已关门闭户,只有远处一家客栈还透出昏黄的灯光,他皱了皱眉,低声吩咐众人收起兵刃,不要惊扰了镇上的百姓。","传闻中的藏剑山庄坐落在群山环抱之中,庄内古木参天,流水潺潺,青石铺就的小径蜿蜒曲折;每逢三月桃花盛开,四方豪杰便会齐聚于此,或论剑,或品茶,或只是远远地望一眼那位传说中的庄主,据说他已经三十年没有拔过剑了,可江湖上没有人敢小看他。","那一夜大雨倾盆,雷声滚滚,破庙里的火堆忽明忽暗;少年抱着怀中的剑谱,听着庙外杂乱的脚步声越来越近,心跳如鼓,他知道,追兵一旦破门而入,自己便再无生路,可师父临终前的嘱托犹在耳边,这本剑谱无论如何都不能落入奸人之手。","掌门之位悬空已有三年,门中各脉明争暗斗从未停歇;大师兄稳重却优柔寡断,二师姐剑法超群却性情孤傲,三师弟聪明伶俐却资历尚浅,长老们各怀心思,谁也不肯先开口,直到那个雪夜,山门外传来一声长啸,所有人都放下了手中的茶盏。","集市上人声鼎沸,卖艺的汉子赤膊耍着一杆铁枪,围观的人群不时爆发出阵阵喝彩声;忽然人群一阵骚动,几名黑衣人分开众人径直走向那名枪手,为首之人冷冷地丢下一块乌黑的令牌,喧闹的集市霎时安静了下来,连风都仿佛停了。","信使跪在堂下,双手呈上一封火漆密函,堂上众人面面相觑;老庄主拆开信笺,只看了一眼,脸色便骤然大变,他缓缓起身,望着窗外沉沉的夜色,半晌才道:传令下去,即刻封山,任何人不得进出,违令者一律逐出师门,永不再录。","三十年前的那场大火烧毁了半座城池,也烧断了两大世家百年的情谊;如今旧事重提,当年的幸存者死的死,散的散,唯有城南那口枯井旁的老槐树还记得一切,树下埋着的,不只是一坛陈年的女儿红,还有一个再也无人敢提起的名字。","渡口的老船夫眯着眼打量来客,见那书生衣衫褴褛却腰悬长剑,不由得多问了一句;书生笑而不答,只将一锭碎银放在船头,转身望向对岸茫茫的芦苇荡,江风吹起他的衣角,露出内衬上暗绣的金线纹样,老船夫握着船桨的手,忽然抖了一下。","林昭推门而入,林昭的剑还在滴着血,可林昭的声音却平静得可怕。","沈青山望着窗外,沈青山知道,今夜之后江湖上再无沈青山这个名字。","“林昭!林昭你给我站住!”她追出门外,可林昭的身影早已消失在夜色之中。","众人都说沈青山败了,可沈青山不这么认为,沈青山收剑入鞘,转身走下擂台。","林昭救过他一次,林昭也骗过他一次,所以当林昭再次出现时,他不知该拔剑还是敬酒。","沈青山的刀快,沈青山的心更狠,凡是见过沈青山出手的人,都不愿再与他为敌。","有人说林昭死在了雁门关外,有人说林昭隐居山林,还有人说,林昭根本就没有存在过。"],j=`第三章 夜雨断魂崖
5
 
 
34
  赵师叔趁乱引着柳如烟等人坠下涧底,冰冷的涧水没过头顶的一瞬,柳如烟犹自回头,只见崖畔两道身影在电光中分而复合,合而复分,那柄断剑的寒芒每一次亮起都比前一次更接近咽喉,也更接近深渊,她张口想喊,灌进来的却只有一口冰水,赵师叔死死攥住她的手腕,两人顺着湍流向下游卷去,耳边的厮杀声、雷声、马嘶声渐渐都被水声吞没,唯有那一点剑芒烙在她眼底,任凭涧水如何冲刷也冲刷不去,多年以后她仍会在雨夜里惊醒,梦见那点寒星坠向无底的黑暗。
35
 
36
  那一夜断魂崖的厮杀声直到五更方歇。后来江湖上有人说,曾见一个青衫剑客独战数百人,剑折之后夺刀再战,刀卷之后赤手空拳;也有人说,天明时分崖下的涧水都是红的。唯一可以确证的是,半月之后,一份写满名字的血书送到了武林盟主的案头,落款只有八个字:青城沈氏,以剑为凭。自那以后,川中道上再无血狼堡的旗号,而断魂崖顶的老松之下,多了一座无碑的剑冢,年年秋深,总有人遥遥望见一个白衣女子在冢前置酒三杯,风雨无阻。
37
+ `,an=["刀出如龙,寒气逼人。","他在桥头站了一夜。","“放下剑,我饶你不死。”","钟声响起,山门缓缓开启。","她的暗器从不落空。","灯火摇曳,人影散乱。","一杯酒,敬当年的兄弟。","掌风过处,烛火尽灭。","他背上的伤疤又开始疼了。","“来者何人,报上名来!”","雪落无声,剑亦无声。","这条路,他走了半生。","密道尽头透出一线微光。","恩人一诺,死生不忘。","毒发之时,他咬碎了牙关。","旗帜倒下,城头易主。","江水东流,带不走旧恨。"];function A(t){if(t==="short32")return[...cn.slice(0,15),...an];if(t==="chapter3k")return I(j).chunks;if(t==="file23k"){const e=I(j).chunks;return Array.from({length:8},()=>e).flat()}throw new Error(`unknown preset: ${t}`)}const D=t=>[...t].sort((e,i)=>i.length-e.length),$=t=>Number(t.toFixed(1));function hn(t){const e=[...t].sort((c,n)=>c-n),i=e.length>>1;return e.length%2?e[i]:(e[i-1]+e[i])/2}async function H(t,e,i,c,n,a=null,d={}){let m=0,g=0,f=0,u=0;const r={uniformBuffersCreated:0,dummyBuffersCreated:0,bindGroupsCreated:0,bindGroupCacheHits:0,bindGroupEvictions:0,immediateSets:0};for(let h=0;h<c.length;h+=n){const o=c.slice(h,h+n),{metrics:w}=await U(t,e,i,o,{...V(a,o.length),...d});m+=w.encoderMs,g+=w.decodeMs,f+=w.tokensGenerated,u+=w.submits;for(const L of Object.keys(r))r[L]+=w.dispatch?.[L]??0}const k=c.reduce((h,o)=>h+o.length,0);return{encoderMs:$(m),decodeMs:$(g),tokens:f,submits:u,dispatch:r,tokPerSec:$(f/g*1e3),e2eCharsPerSec:$(k/(m+g)*1e3)}}const on=["encoderMs","decodeMs","tokens","tokPerSec","e2eCharsPerSec"],_={"tfjs-wasm-q8":{device:"wasm",dtype:"q8"},"tfjs-webgpu-fp16":{device:"webgpu",dtype:"fp16"}};async function sn(t,e,i,{presets:c=["short32","chapter3k"],batches:n=[1,4,8,16],repeats:a=3,includeReference:d=!1,referencePresets:m=c,referenceBatches:g=[1,4],referenceCells:f=Object.keys(_).flatMap(h=>m.flatMap(o=>g.map(w=>({runtime:h,preset:o,batch:w})))),tuned:u=null,engineOptions:r={},onStatus:k=()=>{}}={}){const h=[],o=Object.fromEntries(c.map(p=>[p,D(A(p))])),w=p=>Array.isArray(n)?n:n[p],L=e.dtype==="f16"?2:4,B=async p=>{const b=i.encode(o[p][0]),y=z(t,K(b.length),L),l=[];for(const T of w(p)){const s=Math.min(T,y);s!==T&&k(`${p}: batch ${T} clamped to device max ${s}`),l.some(N=>N.batch===s)||l.push({batch:s,...s!==T?{requestedBatch:T}:{}})}return l};k("warmup…"),await H(t,e,i,o[c[0]],(await B(c[0]))[0].batch,u,r);for(const p of c)for(const{batch:b,requestedBatch:y}of await B(p)){const l=[];for(let s=0;s<a;s++)k(`webmt ${p} b${b} repeat ${s+1}/${a}…`),l.push(await H(t,e,i,o[p],b,u,r));const T=Object.fromEntries(on.map(s=>[s,$(hn(l.map(N=>N[s])))]));h.push({runtime:"webmt",preset:p,batch:b,...y?{requestedBatch:y}:{},repeats:l,median:T,min:{tokPerSec:Math.min(...l.map(s=>s.tokPerSec)),e2eCharsPerSec:Math.min(...l.map(s=>s.e2eCharsPerSec))},max:{tokPerSec:Math.max(...l.map(s=>s.tokPerSec)),e2eCharsPerSec:Math.max(...l.map(s=>s.e2eCharsPerSec))}})}if(d){const{runReference:p}=await W(async()=>{const{runReference:b}=await import("./reference-CfIaZkZf.js");return{runReference:b}},__vite__mapDeps([0,1]));for(const{runtime:b,preset:y,batch:l}of f){const{device:T,dtype:s}=_[b]??{};if(!T)throw new Error(`unknown reference runtime: ${b}`);const N=o[y]??D(A(y));k(`${b} ${y} b${l} (single run)…`);try{const S=await p({device:T,dtype:s,sources:N,batchSize:l,onStatus:Q=>k(`${b} ${y} b${l}: ${Q}`)}),O={loadMs:Math.round(S.loadMs),translateMs:Math.round(S.translateMs),tokens:S.tokens,tokPerSec:$(S.tokPerSec),e2eCharsPerSec:$(S.charsPerSec)};h.push({runtime:b,preset:y,batch:l,repeats:[O],median:O})}catch(S){h.push({runtime:b,preset:y,batch:l,error:String(S?.message??S)})}}}return h}function rn(t,e,{date:i,stack:c}={}){const n=new Date,a=`${n.getFullYear()}-${String(n.getMonth()+1).padStart(2,"0")}-${String(n.getDate()).padStart(2,"0")}`;return{schema:"webmt-bench-v1",date:i??a,adapterInfo:e,...c?{stack:c}:{},baselineRef:"docs/bench/baseline.json",runs:t}}const mn={repetitionPenalty:1.2,greedy:!0,maxNewTokensFormula:"max(24, min(192, ceil(chars*3.2)+12))",dtype:"fp32"},gn=JSON.parse('[{"source":"他缓缓拔出长剑,目光冷得像冰。","ids":[0,754,1237,1501,1594,1039,654,339,18937,821,475,1072,321,1951,18948,2],"maxNewTokens":60,"text":"Hắn chậm rãi rút trường kiếm ra, ánh mắt lạnh như băng."},{"source":"夜色渐深,客栈里只剩下几盏残灯。","ids":[0,4988,1082,2875,659,18937,332,1542,7495,394,404,329,889,1742,3286,1631,18948,2],"maxNewTokens":64,"text":"Đêm dần buông xuống, trong khách điếm chỉ còn lại vài ngọn đèn tàn."},{"source":"“你到底是什么人?”她低声问道。","ids":[0,337,11090,997,514,292,843,632,1958,1460,1298,848,18948,2],"maxNewTokens":64,"text":"\\"Rốt cuộc ngươi là ai?\\" Nàng thấp giọng hỏi."},{"source":"山风呼啸,卷起满地的落叶。","ids":[0,7521,976,2771,2813,2164,448,2189,8052,916,871,18948,2],"maxNewTokens":54,"text":"Gió núi gào thét cuốn lên lá rụng đầy đất."},{"source":"老者捋了捋胡须,微微一笑。","ids":[0,1577,732,3592,12443,5089,18937,1820,708,18948,2],"maxNewTokens":54,"text":"Lão giả vuốt chòm râu, mỉm cười."},{"source":"这一掌的力道,足以开碑裂石!","ids":[0,4522,565,313,309,1724,324,1004,469,1057,4088,3282,1155,19020,2],"maxNewTokens":57,"text":"Lực đạo của một chưởng này đủ để mở bia nứt đá!"},{"source":"“师父,弟子知错了。”少年跪在地上。","ids":[0,337,4338,1129,18937,739,576,498,1621,483,482,2439,1356,3199,459,477,871,18948,2],"maxNewTokens":70,"text":"\\"Sư phụ, đệ tử biết sai rồi.\\" Thiếu niên quỳ trên mặt đất."},{"source":"江湖上的恩怨,从来没有那么简单。","ids":[0,4489,3247,5634,1071,667,616,1463,1790,321,488,18948,2],"maxNewTokens":64,"text":"Ân oán giang hồ chưa từng đơn giản như vậy."},{"source":"她转身离去,再也没有回头。","ids":[0,1958,1795,331,1044,367,18937,290,404,1143,437,329,551,18948,2],"maxNewTokens":54,"text":"Nàng xoay người rời đi, không còn quay đầu lại nữa."},{"source":"剑光一闪,血溅三尺。","ids":[0,1089,1017,2213,448,18937,1073,2126,1549,8635,692,4479,18948,2],"maxNewTokens":44,"text":"Kiếm quang lóe lên, máu bắn tung tóe ba thước."},{"source":"大殿之内,众人鸦雀无声。","ids":[0,795,497,1140,18937,874,331,2505,15669,284,399,18948,2],"maxNewTokens":51,"text":"Trong đại điện, mọi người im phăng phắc."},{"source":"他喝了口酒,眼中闪过一丝痛楚。","ids":[0,754,2184,309,3793,2251,18937,332,475,2213,448,775,1879,3822,18948,2],"maxNewTokens":60,"text":"Hắn uống một ngụm rượu, trong mắt lóe lên vẻ đau đớn."},{"source":"“今晚三更,后山竹林见。”","ids":[0,337,18955,396,781,2124,692,18937,1035,453,2507,3016,1262,1523,482,2],"maxNewTokens":54,"text":"\\"Tối nay canh ba, gặp ở rừng trúc hậu sơn.\\""},{"source":"马蹄声由远及近,尘土飞扬。","ids":[0,3469,10058,1853,389,863,372,935,18937,2772,871,1549,1033,18948,2],"maxNewTokens":54,"text":"Tiếng vó ngựa từ xa đến gần, bụi đất tung bay."},{"source":"这门功夫,他练了整整二十年。","ids":[0,1322,583,1895,324,18937,343,335,627,1557,480,1195,549,18948,2],"maxNewTokens":57,"text":"Môn công phu này, hắn đã luyện suốt hai mươi năm."},{"source":"暮色四合之际,一行人马终于抵达了山脚下的小镇,镇口的酒旗在风中猎猎作响;为首的中年汉子翻身下马,环顾四周,见街道两旁的店铺早已关门闭户,只有远处一家客栈还透出昏黄的灯光,他皱了皱眉,低声吩咐众人收起兵刃,不要惊扰了镇上的百姓。","ids":[0,6394,561,1601,2738,2875,659,18937,2161,331,870,434,334,372,369,1054,1722,810,777,640,976,18937,2542,2251,453,981,1722,1549,1033,332,1423,19873,5623,576,921,1356,1062,437,2187,659,1853,18937,439,1100,1156,559,18937,458,591,981,1159,480,569,653,335,1157,2348,981,2348,3509,18937,394,298,309,2688,14099,863,863,404,10866,339,821,3286,1058,3305,18937,343,2012,1317,18937,1460,1298,3323,1830,874,331,493,1036,1327,535,18937,290,369,4688,5916,3393,832,332,1722,18948,2],"maxNewTokens":192,"text":"Vào lúc hoàng hôn buông xuống, đoàn người cuối cùng cũng đến được thị trấn nhỏ dưới chân núi, cờ rượu ở cửa trấn tung bay trong gió; hán tử trung niên dẫn đầu nhảy xuống ngựa, nhìn quanh bốn phía, thấy các cửa hàng hai bên đường đã sớm đóng cửa đóng kín, chỉ có một quán trọ xa xa còn hắt ra ánh đèn vàng vọt, hắn nhíu mày, thấp giọng dặn dò mọi người thu hồi binh khí, không được quấy nhiễu bách tính trong trấn."},{"source":"传闻中的藏剑山庄坐落在群山环抱之中,庄内古木参天,流水潺潺,青石铺就的小径蜿蜒曲折;每逢三月桃花盛开,四方豪杰便会齐聚于此,或论剑,或品茶,或只是远远地望一眼那位传说中的庄主,据说他已经三十年没有拔过剑了,可江湖上没有人敢小看他。","ids":[0,4694,1089,1523,1814,332,813,2410,2494,1630,929,1378,1868,313,4822,976,18937,569,332,2826,1160,1994,651,5765,862,18937,911,2133,15966,3276,18937,620,653,810,1576,1155,1402,10574,4220,4402,1134,19290,18939,19873,1224,455,1499,692,1391,2842,3389,6259,18937,2333,3778,1156,690,329,1410,5781,617,606,18937,1153,2013,654,18937,1153,2525,2686,18937,1153,394,439,863,466,559,555,3664,691,332,813,2410,598,309,625,18937,772,383,343,335,692,1195,549,290,1594,654,483,18937,428,459,5634,1071,290,843,1126,1179,705,343,18948,2],"maxNewTokens":192,"text":"Tàng Kiếm sơn trang trong truyền thuyết tọa lạc giữa vòng vây của dãy núi, bên trong thôn cổ thụ cao ngất trời, nước chảy róc rách, con đường nhỏ lát đá xanh uốn lượn khúc khuỷu; mỗi khi tháng ba hoa đào nở rộ, hào kiệt bốn phương lại tụ họp tại đây, hoặc luận kiếm, hoặc thưởng trà, hoặc chỉ nhìn xa về phía vị Trang chủ trong truyền thuyết kia một cái, nghe nói hắn đã ba mươi năm không rút kiếm rồi, nhưng trên giang hồ không ai dám coi thường hắn."},{"source":"那一夜大雨倾盆,雷声滚滚,破庙里的火堆忽明忽暗;少年抱着怀中的剑谱,听着庙外杂乱的脚步声越来越近,心跳如鼓,他知道,追兵一旦破门而入,自己便再无生路,可师父临终前的嘱托犹在耳边,这本剑谱无论如何都不能落入奸人之手。","ids":[0,4988,393,2121,321,4987,911,18937,3950,12395,1272,18937,3342,1481,332,5354,1654,561,857,561,1381,19873,1248,1356,2567,654,7636,332,626,18937,1871,772,623,736,640,2564,1587,569,688,5354,696,715,935,18937,3825,2399,10836,15013,18948,754,498,18937,309,455,763,2062,1824,373,981,1996,416,18937,512,508,290,404,653,1037,551,18937,428,725,3323,1830,452,455,3028,2870,313,595,1129,521,5290,270,518,569,1776,18937,2164,654,7636,324,658,457,506,334,290,338,1132,416,464,680,501,18948,2],"maxNewTokens":192,"text":"Đêm đó mưa như trút nước, sấm rền vang, đống lửa trong miếu đổ lúc sáng lúc tối; thiếu niên ôm kiếm phổ trong lòng, lắng nghe tiếng bước chân hỗn loạn bên ngoài miếu ngày càng gần, tim đập thình thịch. Hắn biết, một khi quân truy đuổi phá cửa xông vào, mình sẽ không còn đường sống nữa, nhưng lời dặn dò trước khi lâm chung của sư phụ vẫn văng vẳng bên tai, cuốn kiếm phổ này dù thế nào cũng không thể rơi vào tay gian nhân."},{"source":"掌门之位悬空已有三年,门中各脉明争暗斗从未停歇;大师兄稳重却优柔寡断,二师姐剑法超群却性情孤傲,三师弟聪明伶俐却资历尚浅,长老们各怀心思,谁也不肯先开口,直到那个雪夜,山门外传来一声长啸,所有人都放下了手中的茶盏。","ids":[0,2404,1092,1724,716,335,3547,3248,3761,692,549,18937,591,1454,332,716,1184,1097,1155,3852,667,616,1234,2653,19873,741,595,1144,1310,1870,428,329,720,820,1248,1124,1439,18937,2186,595,1691,654,496,3450,2745,428,832,803,1158,3324,18937,1451,595,739,833,1441,11877,1125,428,1020,2338,404,5002,3454,18937,591,841,655,471,922,649,1020,1854,18937,290,843,1131,1057,1172,452,18937,432,372,1368,2051,1053,18937,569,688,1523,716,813,372,309,623,269,18991,1012,18937,948,363,874,331,471,1414,3969,2686,332,464,659,18948,2],"maxNewTokens":192,"text":"Vị trí chưởng môn đã treo lơ lửng ba năm, các mạch trong môn phái đấu đá ngầm chưa từng ngừng nghỉ; Đại sư huynh trầm ổn nhưng lại do dự thiếu quyết đoán, Nhị sư tỷ kiếm pháp siêu quần nhưng tính tình cô ngạo, Tam sư đệ thông minh lanh lợi nhưng tư lịch còn nông cạn, các trưởng lão đều mang tâm tư riêng, không ai chịu mở miệng trước, cho đến đêm tuyết ấy, bên ngoài sơn môn truyền đến một tiếng hú dài, tất cả mọi người đều đặt chén trà trong tay xuống."},{"source":"集市上人声鼎沸,卖艺的汉子赤膊耍着一杆铁枪,围观的人群不时爆发出阵阵喝彩声;忽然人群一阵骚动,几名黑衣人分开众人径直走向那名枪手,为首之人冷冷地丢下一块乌黑的令牌,喧闹的集市霎时安静了下来,连风都仿佛停了。","ids":[0,1521,453,7196,5922,4759,3588,2359,18937,2328,1899,989,1920,3938,8267,2961,4687,309,1328,1562,829,18937,1014,331,1868,884,2287,2554,329,714,339,616,6261,623,8860,7359,1263,2525,18948,15010,558,1014,331,7694,6091,18937,713,790,2275,613,501,3671,874,331,339,367,1112,466,559,790,829,672,598,18937,757,1400,437,1072,2527,2690,659,309,2641,1696,1739,1019,6325,18937,7196,5922,4759,332,2414,1576,1800,1239,660,329,18937,801,363,1423,334,321,1234,329,18948,2],"maxNewTokens":192,"text":"Người ở chợ ồn ào náo nhiệt, gã đàn ông bán nghệ cởi trần múa một cây thiết thương, đám người vây xem thỉnh thoảng lại phát ra từng tràng tiếng reo hò tán thưởng. Bỗng nhiên đám người xôn xao, mấy tên hắc y nhân tách mọi người ra đi thẳng về phía tên thương thủ kia, kẻ cầm đầu lạnh lùng ném xuống một khối lệnh bài đen nhánh, chợ ồn ào trong chốc lát yên tĩnh trở lại, ngay cả gió cũng như ngừng lại."},{"source":"信使跪在堂下,双手呈上一封火漆密函,堂上众人面面相觑;老庄主拆开信笺,只看了一眼,脸色便骤然大变,他缓缓起身,望着窗外沉沉的夜色,半晌才道:传令下去,即刻封山,任何人不得进出,违令者一律逐出师门,永不再录。","ids":[0,7964,732,3199,777,653,18937,480,464,2549,448,309,906,1300,1693,1523,1383,18937,874,331,459,653,439,962,3456,5611,19873,655,1814,691,1057,906,1300,339,18937,394,1982,475,309,625,18937,853,477,746,842,558,497,818,18948,3866,1237,1501,844,1777,18937,439,1924,1368,2339,1133,688,981,2644,18937,1250,696,534,383,19026,3471,1696,659,18937,770,647,906,1523,18937,729,643,843,290,369,339,416,18937,757,887,2028,1696,471,449,7938,762,828,595,716,18937,4487,3830,290,2282,329,551,18948,2],"maxNewTokens":192,"text":"Sứ giả quỳ dưới đường, hai tay dâng lên một phong thư mật sơn đỏ, mọi người trên đường nhìn nhau ngơ ngác; lão trang chủ mở phong thư ra, chỉ liếc mắt một cái, sắc mặt liền đột nhiên đại biến. Ông chậm rãi đứng dậy, nhìn màn đêm dày đặc ngoài cửa sổ, nửa ngày mới nói: Truyền lệnh xuống, lập tức phong sơn, bất kỳ ai không được ra vào, kẻ vi phạm lệnh đều bị trục xuất khỏi sư môn, vĩnh viễn không ghi lại nữa."},{"source":"三十年前的那场大火烧毁了半座城池,也烧断了两大世家百年的情谊;如今旧事重提,当年的幸存者死的死,散的散,唯有城南那口枯井旁的老槐树还记得一切,树下埋着的,不只是一坛陈年的女儿红,还有一个再也无人敢提起的名字。","ids":[0,1839,1624,14105,692,1195,549,452,335,373,2464,1250,1888,442,1593,18937,334,3626,11367,803,1526,988,549,313,480,497,457,619,19873,781,631,2145,1663,329,18937,331,1037,2204,549,1791,784,784,18937,1408,6677,18937,394,298,1328,7359,19014,1932,569,8833,3163,559,1582,442,404,1455,719,948,363,18937,777,2762,1328,5951,290,394,309,4725,2280,1823,1199,909,1307,18937,368,404,298,625,790,290,843,1126,1663,372,551,18948,2],"maxNewTokens":192,"text":"Trận hỏa hoạn ba mươi năm trước đã phá hủy nửa tòa thành trì, cũng thiêu rụi tình nghĩa trăm năm của hai đại thế gia; nay chuyện cũ nhắc lại, người sống sót năm xưa chết chết, tan rã, chỉ có cây hòe già bên giếng khô phía nam thành còn nhớ rõ tất cả, dưới gốc cây chôn không chỉ một vò Nữ Nhi Hồng lâu đời, mà còn có cái tên không ai dám nhắc đến nữa."},{"source":"渡口的老船夫眯着眼打量来客,见那书生衣衫褴褛却腰悬长剑,不由得多问了一句;书生笑而不答,只将一锭碎银放在船头,转身望向对岸茫茫的芦苇荡,江风吹起他的衣角,露出内衬上暗绣的金线纹样,老船夫握着船桨的手,忽然抖了一下。","ids":[0,1577,2200,1895,453,7445,263,19013,4280,475,793,1149,1542,563,18937,458,1300,687,598,2745,1290,3276,286,1984,428,6834,1390,3547,1039,654,18937,290,828,848,785,309,1055,19873,1698,687,708,368,290,1361,18937,394,1414,309,266,573,1807,2922,453,1866,2200,18937,1795,331,439,466,559,5205,278,446,5032,3814,569,598,2658,18948,7521,2408,3424,1549,2747,1290,313,343,18937,950,339,1391,1634,1563,3038,11130,1918,18938,569,332,18948,9126,655,2200,1895,1175,2670,17524,1689,558,2169,448,309,625,18948,2],"maxNewTokens":192,"text":"Lão thuyền phu ở bến đò nheo mắt đánh giá khách tới, thấy thư sinh kia quần áo rách rưới nhưng thắt lưng treo trường kiếm, không khỏi hỏi thêm một câu; Thư sinh cười mà không đáp, chỉ đặt một thỏi bạc vụn ở mũi thuyền, xoay người nhìn về phía lau sậy mênh mông bên kia bờ. Gió sông thổi tung góc áo của hắn, lộ ra hoa văn kim tuyến thêu thùa bên trong. Tay lão thuyền phu nắm mái chèo bỗng nhiên run lên một cái."},{"source":"林昭推门而入,林昭的剑还在滴着血,可林昭的声音却平静得可怕。","ids":[0,1090,4264,2182,981,736,416,18937,654,313,1090,4264,521,404,520,810,1073,18937,428,877,1096,313,343,329,815,1239,372,1094,953,18948,2],"maxNewTokens":108,"text":"Lâm Chiêu đẩy cửa bước vào, kiếm của Lâm Chiêu vẫn còn đang nhỏ máu, nhưng thanh âm của hắn lại bình tĩnh đến đáng sợ."},{"source":"沈青山望着窗外,沈青山知道,今夜之后江湖上再无沈青山这个名字。","ids":[0,3560,734,730,439,339,688,981,2644,18937,3560,734,730,498,776,18937,465,1368,781,459,5634,1071,290,404,625,790,3560,734,730,506,551,18948,2],"maxNewTokens":112,"text":"Thẩm Thanh Sơn nhìn ra ngoài cửa sổ, Thẩm Thanh Sơn biết rằng, sau đêm nay trên giang hồ không còn cái tên Thẩm Thanh Sơn nào nữa."},{"source":"“林昭!林昭你给我站住!”她追出门外,可林昭的身影早已消失在夜色之中。","ids":[0,415,18989,424,4264,19020,1090,4264,18937,514,844,329,432,382,568,1958,1824,339,688,981,18937,428,479,1249,313,1090,4264,335,1157,818,920,332,1924,1368,18948,2],"maxNewTokens":124,"text":"“Lâm Chiêu! Lâm Chiêu, ngươi đứng lại cho ta!” Nàng đuổi ra ngoài cửa, nhưng thân ảnh của Lâm Chiêu đã sớm biến mất trong màn đêm."},{"source":"众人都说沈青山败了,可沈青山不这么认为,沈青山收剑入鞘,转身走下擂台。","ids":[0,3032,331,471,383,3560,734,730,335,2665,18937,428,3560,734,730,290,676,488,18937,3560,734,730,493,654,416,3998,18937,1795,331,736,659,1963,2058,18948,2],"maxNewTokens":124,"text":"Mọi người đều nói Thẩm Thanh Sơn đã thua, nhưng Thẩm Thanh Sơn không nghĩ vậy, Thẩm Thanh Sơn thu kiếm vào vỏ, xoay người bước xuống lôi đài."},{"source":"林昭救过他一次,林昭也骗过他一次,所以当林昭再次出现时,他不知该拔剑还是敬酒。","ids":[0,1090,4264,335,1372,343,309,638,18937,1090,4264,334,3539,5136,343,309,638,18937,432,599,455,1090,4264,762,516,638,551,18937,343,290,498,599,1594,654,802,292,1809,2251,18948,2],"maxNewTokens":137,"text":"Lâm Chiêu đã cứu hắn một lần, Lâm Chiêu cũng lừa gạt hắn một lần, cho nên khi Lâm Chiêu xuất hiện lần nữa, hắn không biết nên rút kiếm hay là kính rượu."},{"source":"沈青山的刀快,沈青山的心更狠,凡是见过沈青山出手的人,都不愿再与他为敌。","ids":[0,3271,313,3560,734,730,894,18937,626,3560,734,730,715,785,1631,2492,18937,729,749,843,616,458,3560,734,730,339,464,471,290,582,660,442,757,1734,412,343,551,18948,2],"maxNewTokens":128,"text":"Đao của Thẩm Thanh Sơn nhanh, lòng Thẩm Thanh Sơn càng thêm tàn nhẫn, bất cứ ai từng thấy Thẩm Thanh Sơn ra tay đều không muốn trở thành kẻ địch với hắn nữa."},{"source":"有人说林昭死在了雁门关外,有人说林昭隐居山林,还有人说,林昭根本就没有存在过。","ids":[0,1480,331,383,1090,4264,784,453,688,10521,1322,1592,18937,298,331,383,343,1279,3715,332,2507,976,18937,329,404,298,331,383,18937,1090,4264,1107,624,667,616,1512,617,18948,2],"maxNewTokens":137,"text":"Có người nói Lâm Chiêu chết ở ngoài Nhạn Môn Quan, có người nói hắn ẩn cư trong rừng núi, lại còn có người nói, Lâm Chiêu căn bản chưa từng tồn tại."}]'),P={config:mn,items:gn},un=document.querySelector("#app");un.innerHTML=`
38
  <h1>webMT bench</h1>
39
  <p>
40
  <button id="load">Load engine</button>
assets/{main-CKq2fiQB.js → main-T9AnDmec.js} RENAMED
The diff for this file is too large to render. See raw diff
 
assets/{preload-helper-DpiWnaYd.js → preload-helper-BSrbm-kb.js} RENAMED
The diff for this file is too large to render. See raw diff
 
assets/{reference-BgleqVd6.js → reference-CfIaZkZf.js} RENAMED
The diff for this file is too large to render. See raw diff
 
bench.html CHANGED
@@ -13,9 +13,9 @@
13
  font-family: system-ui, sans-serif;
14
  }
15
  </style>
16
- <script type="module" crossorigin src="/assets/bench-Cxje7vnD.js"></script>
17
  <link rel="modulepreload" crossorigin href="/assets/modulepreload-polyfill-B5Qt9EMX.js">
18
- <link rel="modulepreload" crossorigin href="/assets/preload-helper-DpiWnaYd.js">
19
  </head>
20
  <body>
21
  <main id="app"></main>
 
13
  font-family: system-ui, sans-serif;
14
  }
15
  </style>
16
+ <script type="module" crossorigin src="/assets/bench-CNBcu3F_.js"></script>
17
  <link rel="modulepreload" crossorigin href="/assets/modulepreload-polyfill-B5Qt9EMX.js">
18
+ <link rel="modulepreload" crossorigin href="/assets/preload-helper-BSrbm-kb.js">
19
  </head>
20
  <body>
21
  <main id="app"></main>
index.html CHANGED
@@ -67,9 +67,9 @@
67
  ]
68
  }
69
  </script>
70
- <script type="module" crossorigin src="/assets/main-CKq2fiQB.js"></script>
71
  <link rel="modulepreload" crossorigin href="/assets/modulepreload-polyfill-B5Qt9EMX.js">
72
- <link rel="modulepreload" crossorigin href="/assets/preload-helper-DpiWnaYd.js">
73
  <link rel="modulepreload" crossorigin href="/assets/models-QsPq0tJ5.js">
74
  <link rel="stylesheet" crossorigin href="/assets/main-CNSay7C8.css">
75
  </head>
 
67
  ]
68
  }
69
  </script>
70
+ <script type="module" crossorigin src="/assets/main-T9AnDmec.js"></script>
71
  <link rel="modulepreload" crossorigin href="/assets/modulepreload-polyfill-B5Qt9EMX.js">
72
+ <link rel="modulepreload" crossorigin href="/assets/preload-helper-BSrbm-kb.js">
73
  <link rel="modulepreload" crossorigin href="/assets/models-QsPq0tJ5.js">
74
  <link rel="stylesheet" crossorigin href="/assets/main-CNSay7C8.css">
75
  </head>
sw.js CHANGED
@@ -1,5 +1,5 @@
1
- // Service worker TEMPLATE — deploy_pages.mjs stamps 5ff3a1f and
2
- // ["/","/about.html","/board.html","/manifest.webmanifest","/icon-192.png","/assets/main-CKq2fiQB.js","/assets/modulepreload-polyfill-B5Qt9EMX.js","/assets/preload-helper-DpiWnaYd.js","/assets/models-QsPq0tJ5.js","/assets/main-CNSay7C8.css","/assets/about-BRw9WSHl.css","/assets/board-DQggw35t.js","/assets/board-DFM1bO4t.css","/assets/playfair-vietnamese-Cabi7G8-.woff2","/assets/playfair-latin-BOwq7MWX.woff2"] and writes the result to dist/sw.js. Never served in dev.
3
  //
4
  // Cache layers (all same-origin GET only):
5
  // moxhi-shell-<build> app shell: precached index + hashed /assets/*
@@ -12,12 +12,12 @@
12
  // them in its own Cache Storage bucket (content-addressed names).
13
  /* global self, caches, fetch, location */
14
 
15
- // 20260818115834 (yyyymmddHHMMSS, stamped by deploy_pages.mjs) makes shell
16
  // generations SORTABLE by name — activate keeps the newest previous
17
  // generation instead of guessing which cache an old tab still needs.
18
- const SHELL = 'moxhi-shell-20260818115834-5ff3a1f';
19
  const DATA = 'moxhi-data-v1';
20
- const PRECACHE = ["/","/about.html","/board.html","/manifest.webmanifest","/icon-192.png","/assets/main-CKq2fiQB.js","/assets/modulepreload-polyfill-B5Qt9EMX.js","/assets/preload-helper-DpiWnaYd.js","/assets/models-QsPq0tJ5.js","/assets/main-CNSay7C8.css","/assets/about-BRw9WSHl.css","/assets/board-DQggw35t.js","/assets/board-DFM1bO4t.css","/assets/playfair-vietnamese-Cabi7G8-.woff2","/assets/playfair-latin-BOwq7MWX.woff2"];
21
  // Model/data files the app fetches during startup — often BEFORE this SW has
22
  // claimed the page on its very first visit, so runtime caching would miss
23
  // them and the first offline reload would fail engine init. Precache them
 
1
+ // Service worker TEMPLATE — deploy_pages.mjs stamps 1d05277 and
2
+ // ["/","/about.html","/board.html","/manifest.webmanifest","/icon-192.png","/assets/main-T9AnDmec.js","/assets/modulepreload-polyfill-B5Qt9EMX.js","/assets/preload-helper-BSrbm-kb.js","/assets/models-QsPq0tJ5.js","/assets/main-CNSay7C8.css","/assets/about-BRw9WSHl.css","/assets/board-DQggw35t.js","/assets/board-DFM1bO4t.css","/assets/playfair-vietnamese-Cabi7G8-.woff2","/assets/playfair-latin-BOwq7MWX.woff2"] and writes the result to dist/sw.js. Never served in dev.
3
  //
4
  // Cache layers (all same-origin GET only):
5
  // moxhi-shell-<build> app shell: precached index + hashed /assets/*
 
12
  // them in its own Cache Storage bucket (content-addressed names).
13
  /* global self, caches, fetch, location */
14
 
15
+ // 20260818124919 (yyyymmddHHMMSS, stamped by deploy_pages.mjs) makes shell
16
  // generations SORTABLE by name — activate keeps the newest previous
17
  // generation instead of guessing which cache an old tab still needs.
18
+ const SHELL = 'moxhi-shell-20260818124919-1d05277';
19
  const DATA = 'moxhi-data-v1';
20
+ const PRECACHE = ["/","/about.html","/board.html","/manifest.webmanifest","/icon-192.png","/assets/main-T9AnDmec.js","/assets/modulepreload-polyfill-B5Qt9EMX.js","/assets/preload-helper-BSrbm-kb.js","/assets/models-QsPq0tJ5.js","/assets/main-CNSay7C8.css","/assets/about-BRw9WSHl.css","/assets/board-DQggw35t.js","/assets/board-DFM1bO4t.css","/assets/playfair-vietnamese-Cabi7G8-.woff2","/assets/playfair-latin-BOwq7MWX.woff2"];
21
  // Model/data files the app fetches during startup — often BEFORE this SW has
22
  // claimed the page on its very first visit, so runtime caching would miss
23
  // them and the first offline reload would fail engine init. Precache them