diff --git "a/gemma-4-e2b.js" "b/gemma-4-e2b.js" --- "a/gemma-4-e2b.js" +++ "b/gemma-4-e2b.js" @@ -1,21 +1,21 @@ // Gemma-4 E2B (QAT mobile) WebGPU chat bundle. Import { Gemma4Mobile } from this file. -var xo=Object.defineProperty;var he=(e,n)=>()=>(e&&(n=e(e=0)),n);var Eo=(e,n)=>{for(var t in n)xo(e,t,{get:n[t],enumerable:!0})};function Lr(e){return/\w/.test(e)}function wn(e){return/[0-9]/.test(e)}function Cr(e){return/\s/.test(e)}function Fo(e,n={}){return e.endsWith(` -`)&&(e=e.slice(0,-1)),n.lstrip_blocks&&(e=e.replace(/^[ \t]*({[#%-])/gm,"$1")),n.trim_blocks&&(e=e.replace(/([#%-]})\n/g,"$1")),e.replace(/(\s*){%(-?)\s*(?:end)?generation\s*(-?)%}(\s*)/gs,(t,r,a,s,o)=>(a?"":r)+(s?"":o))}function $n(e,n={}){let t=[],r=Fo(e,n),a=0,s=0,o=l=>{let c="";for(;l(r[a]);){if(r[a]==="\\"){if(++a,a>=r.length)throw new SyntaxError("Unexpected end of input");let d=r[a++],p=Ro.get(d);if(p===void 0)throw new SyntaxError(`Unexpected escaped character: ${d}`);c+=p;continue}if(c+=r[a++],a>=r.length)throw new SyntaxError("Unexpected end of input")}return c},i=()=>{let l=t.at(-1);l&&l.type===h.Text&&(l.value=l.value.trimEnd(),l.value===""&&t.pop())},u=()=>{for(;a0){t.push(new Ge(d,h.Text));continue}}if(r[a]==="{"&&r[a+1]==="#"){a+=2;let d=r[a]==="-";d&&++a;let p="";for(;r[a]!=="#"||r[a+1]!=="}";){if(a+2>=r.length)throw new SyntaxError("Missing end of comment tag");p+=r[a++]}let f=p.endsWith("-");f&&(p=p.slice(0,-1)),d&&i(),t.push(new Ge(p,h.Comment)),a+=2,f&&u();continue}if(r.slice(a,a+3)==="{%-"){i(),t.push(new Ge("{%",h.OpenStatement)),a+=3;continue}if(r.slice(a,a+3)==="{{-"){i(),t.push(new Ge("{{",h.OpenExpression)),s=0,a+=3;continue}if(o(Cr),r.slice(a,a+3)==="-%}"){t.push(new Ge("%}",h.CloseStatement)),a+=3,u();continue}if(r.slice(a,a+3)==="-}}"){t.push(new Ge("}}",h.CloseExpression)),a+=3,u();continue}let c=r[a];if(c==="-"||c==="+"){let d=t.at(-1)?.type;if(d===h.Text||d===void 0)throw new SyntaxError(`Unexpected character: ${c}`);switch(d){case h.Identifier:case h.NumericLiteral:case h.StringLiteral:case h.CloseParen:case h.CloseSquareBracket:break;default:{++a;let p=o(wn);t.push(new Ge(`${c}${p}`,p.length>0?h.NumericLiteral:h.UnaryOperator));continue}}}for(let[d,p]of Oo){if(d==="}}"&&s>0)continue;if(r.slice(a,a+d.length)===d){t.push(new Ge(d,p)),p===h.OpenExpression?s=0:p===h.OpenCurlyBracket?++s:p===h.CloseCurlyBracket&&--s,a+=d.length;continue e}}if(c==="'"||c==='"'){++a;let d=o(p=>p!==c);t.push(new Ge(d,h.StringLiteral)),++a;continue}if(wn(c)){let d=o(wn);if(t.at(-1)?.type!==h.Dot&&r[a]==="."&&wn(r[a+1])){++a;let p=o(wn);d=`${d}.${p}`}t.push(new Ge(d,h.NumericLiteral));continue}if(Lr(c)){let d=o(Lr);t.push(new Ge(d,h.Identifier));continue}throw new SyntaxError(`Unexpected character: ${c}`)}return t}function Kn(e){let n=new Wo([]),t=0;function r(g,w){let S=e[t++];if(!S||S.type!==g)throw new Error(`Parser Error: ${w}. ${S.type} !== ${g}.`);return S}function a(g){if(!u(g))throw new SyntaxError(`Expected ${g}`);++t}function s(){switch(e[t].type){case h.Comment:return new Lo(e[t++].value);case h.Text:return l();case h.OpenStatement:return c();case h.OpenExpression:return d();default:throw new SyntaxError(`Unexpected token type: ${e[t].type}`)}}function o(...g){return t+g.length<=e.length&&g.every((w,S)=>w===e[t+S].type)}function i(...g){return e[t]?.type===h.OpenStatement&&e[t+1]?.type===h.Identifier&&g.includes(e[t+1]?.value)}function u(...g){return t+g.length<=e.length&&g.every((w,S)=>e[t+S].type==="Identifier"&&w===e[t+S].value)}function l(){return new zr(r(h.Text,"Expected text token").value)}function c(){if(r(h.OpenStatement,"Expected opening statement token"),e[t].type!==h.Identifier)throw new SyntaxError(`Unknown statement, got ${e[t].type}`);let g=e[t].value,w;switch(g){case"set":++t,w=p();break;case"if":++t,w=f(),r(h.OpenStatement,"Expected {% token"),a("endif"),r(h.CloseStatement,"Expected %} token");break;case"macro":++t,w=m(),r(h.OpenStatement,"Expected {% token"),a("endmacro"),r(h.CloseStatement,"Expected %} token");break;case"for":++t,w=E(),r(h.OpenStatement,"Expected {% token"),a("endfor"),r(h.CloseStatement,"Expected %} token");break;case"call":{++t;let S=null;o(h.OpenParen)&&(S=R());let X=Z();if(X.type!=="Identifier")throw new SyntaxError("Expected identifier following call statement");let Be=R();r(h.CloseStatement,"Expected closing statement token");let Se=[];for(;!i("endcall");)Se.push(s());r(h.OpenStatement,"Expected '{%'"),a("endcall"),r(h.CloseStatement,"Expected closing statement token");let Te=new Nr(X,Be);w=new ei(Te,S,Se);break}case"break":++t,r(h.CloseStatement,"Expected closing statement token"),w=new qo;break;case"continue":++t,r(h.CloseStatement,"Expected closing statement token"),w=new Io;break;case"filter":{++t;let S=Z();S instanceof sn&&o(h.OpenParen)&&(S=N(S)),r(h.CloseStatement,"Expected closing statement token");let X=[];for(;!i("endfilter");)X.push(s());r(h.OpenStatement,"Expected '{%'"),a("endfilter"),r(h.CloseStatement,"Expected '%}'"),w=new Ho(S,X);break}default:throw new SyntaxError(`Unknown statement type: ${g}`)}return w}function d(){r(h.OpenExpression,"Expected opening expression token");let g=b();return r(h.CloseExpression,"Expected closing expression token"),g}function p(){let g=_(),w=null,S=[];if(o(h.Equals))++t,w=_();else{for(r(h.CloseStatement,"Expected %} token");!i("endset");)S.push(s());r(h.OpenStatement,"Expected {% token"),a("endset")}return r(h.CloseStatement,"Expected closing statement token"),new Uo(g,w,S)}function f(){let g=b();r(h.CloseStatement,"Expected closing statement token");let w=[],S=[];for(;!i("elif","else","endif");)w.push(s());if(i("elif")){++t,++t;let X=f();S.push(X)}else if(i("else"))for(++t,++t,r(h.CloseStatement,"Expected closing statement token");!i("endif");)S.push(s());return new Mo(g,w,S)}function m(){let g=Z();if(g.type!=="Identifier")throw new SyntaxError("Expected identifier following macro statement");let w=R();r(h.CloseStatement,"Expected closing statement token");let S=[];for(;!i("endmacro");)S.push(s());return new Do(g,w,S)}function _(g=!1){let w=g?Z:b,S=[w()],X=o(h.Comma);for(;X&&(++t,S.push(w()),!!o(h.Comma)););return X?new jr(S):S[0]}function E(){let g=_(!0);if(!(g instanceof sn||g instanceof jr))throw new SyntaxError(`Expected identifier/tuple for the loop variable, got ${g.type} instead`);if(!u("in"))throw new SyntaxError("Expected `in` keyword following loop variable");++t;let w=b();r(h.CloseStatement,"Expected closing statement token");let S=[];for(;!i("endfor","else");)S.push(s());let X=[];if(i("else"))for(++t,++t,r(h.CloseStatement,"Expected closing statement token");!i("endfor");)X.push(s());return new Bo(g,w,S,X)}function b(){return F()}function F(){let g=q();if(u("if")){++t;let w=q();if(u("else")){++t;let S=F();return new ni(w,g,S)}else return new Vo(g,w)}return g}function q(){let g=G();for(;u("or");){let w=e[t];++t;let S=G();g=new _n(w,g,S)}return g}function G(){let g=C();for(;u("and");){let w=e[t];++t;let S=C();g=new _n(w,g,S)}return g}function C(){let g;for(;u("not");){let w=e[t];++t;let S=C();g=new Xo(w,S)}return g??T()}function T(){let g=U();for(;;){let w;if(u("not","in"))w=new Ge("not in",h.Identifier),t+=2;else if(u("in"))w=e[t++];else if(o(h.ComparisonBinaryOperator))w=e[t++];else break;let S=U();g=new _n(w,g,S)}return g}function U(){let g=ne();for(;o(h.AdditiveBinaryOperator);){let w=e[t];++t;let S=ne();g=new _n(w,g,S)}return g}function P(){let g=j(Z());return o(h.OpenParen)?N(g):g}function N(g){let w=new Nr(g,R());return w=j(w),o(h.OpenParen)&&(w=N(w)),w}function R(){r(h.OpenParen,"Expected opening parenthesis for arguments list");let g=V();return r(h.CloseParen,"Expected closing parenthesis for arguments list"),g}function V(){let g=[];for(;!o(h.CloseParen);){let w;if(e[t].type===h.MultiplicativeBinaryOperator&&e[t].value==="*"){++t;let S=b();w=new Jo(S)}else if(w=b(),o(h.Equals)){if(++t,!(w instanceof sn))throw new SyntaxError("Expected identifier for keyword argument");let S=b();w=new Yo(w,S)}g.push(w),o(h.Comma)&&++t}return g}function z(){let g=[],w=!1;for(;!o(h.CloseSquareBracket);)o(h.Colon)?(g.push(void 0),++t,w=!0):(g.push(b()),o(h.Colon)&&(++t,w=!0));if(g.length===0)throw new SyntaxError("Expected at least one argument for member/slice expression");if(w){if(g.length>3)throw new SyntaxError("Expected 0-3 arguments for slice expression");return new Zo(...g)}return g[0]}function j(g){for(;o(h.Dot)||o(h.OpenSquareBracket);){let w=e[t];++t;let S,X=w.type===h.OpenSquareBracket;if(X)S=z(),r(h.CloseSquareBracket,"Expected closing square bracket");else if(S=Z(),S.type!=="Identifier"&&S.type!=="IntegerLiteral")throw new SyntaxError("Expected identifier or integer following dot operator");g=new Co(g,S,X)}return g}function ne(){let g=Q();for(;o(h.MultiplicativeBinaryOperator);){let w=e[t++],S=Q();g=new _n(w,g,S)}return g}function Q(){let g=ve();for(;u("is");){++t;let w=u("not");w&&++t;let S=Z();if(!(S instanceof sn))throw new SyntaxError("Expected identifier for the test");g=new Qo(g,w,S)}return g}function ve(){let g=P();for(;o(h.Pipe);){++t;let w=Z();if(!(w instanceof sn))throw new SyntaxError("Expected identifier for the filter");o(h.OpenParen)&&(w=N(w)),g=new Ko(g,w)}return g}function Z(){let g=e[t++];switch(g.type){case h.NumericLiteral:{let w=g.value;return w.includes(".")?new zo(Number(w)):new No(Number(w))}case h.StringLiteral:{let w=g.value;for(;o(h.StringLiteral);)w+=e[t++].value;return new zr(w)}case h.Identifier:return new sn(g.value);case h.OpenParen:{let w=_();return r(h.CloseParen,"Expected closing parenthesis, got ${tokens[current].type} instead."),w}case h.OpenSquareBracket:{let w=[];for(;!o(h.CloseSquareBracket);)w.push(b()),o(h.Comma)&&++t;return++t,new jo(w)}case h.OpenCurlyBracket:{let w=new Map;for(;!o(h.CloseCurlyBracket);){let S=b();r(h.Colon,"Expected colon between key and value in object literal");let X=b();w.set(S,X),o(h.Comma)&&++t}return++t,new $o(w)}default:throw new SyntaxError(`Unexpected token: ${g.type}`)}}for(;t0)for(let a=e;an;a+=t)r.push(a);return r}function $r(e,n,t,r=1){let a=Math.sign(r);a>=0?(n=(n??=0)<0?Math.max(e.length+n,0):Math.min(n,e.length),t=(t??=e.length)<0?Math.max(e.length+t,0):Math.min(t,e.length)):(n=(n??=e.length-1)<0?Math.max(e.length+n,-1):Math.min(n,e.length-1),t=(t??=-1)<-1?Math.max(e.length+t,-1):Math.min(t,e.length-1));let s=[];for(let o=n;a*on.toUpperCase())}function ai(e){return si(new Date,e)}function si(e,n){let t=new Intl.DateTimeFormat(void 0,{month:"long"}),r=new Intl.DateTimeFormat(void 0,{month:"short"}),a=s=>s<10?"0"+s:s.toString();return n.replace(/%[YmdbBHM%]/g,s=>{switch(s){case"%Y":return e.getFullYear().toString();case"%m":return a(e.getMonth()+1);case"%d":return a(e.getDate());case"%b":return r.format(e);case"%B":return t.format(e);case"%H":return a(e.getHours());case"%M":return a(e.getMinutes());case"%%":return"%";default:return s}})}function oi(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function ii(e,n,t,r){if(r===0)return e;let a=r==null||r<0?1/0:r,s=n.length===0?new RegExp("(?=)","gu"):new RegExp(oi(n),"gu");return e.replaceAll(s,o=>a>0?(--a,t):o)}function Vr(e){return e.replace(li,n=>"\\u"+n.charCodeAt(0).toString(16).padStart(4,"0"))}function Ye(e,n={},t=0,r=!0){let{indent:a=null,ensureAscii:s=!1,separators:o=null,sortKeys:i=!1}=n,u,l;switch(o?[u,l]=o:a?(u=",",l=": "):(u=", ",l=": "),e.type){case"NullValue":return"null";case"UndefinedValue":return r?"null":"undefined";case"IntegerValue":case"FloatValue":case"BooleanValue":return JSON.stringify(e.value);case"StringValue":{let c=JSON.stringify(e.value);return s&&(c=Vr(c)),c}case"ArrayValue":case"ObjectValue":{let c=a?" ".repeat(a):"",d=` -`+c.repeat(t),p=d+c;if(e.type==="ArrayValue"){let f=e.value.map(m=>Ye(m,n,t+1,r));return a?`[${p}${f.join(`${u}${p}`)}${d}]`:`[${f.join(u)}]`}else{let f=Array.from(e.value.entries());i&&(f=f.sort(([_],[E])=>_.localeCompare(E)));let m=f.map(([_,E])=>{let b=JSON.stringify(_);s&&(b=Vr(b));let F=`${b}${l}${Ye(E,n,t+1,r)}`;return a?`${p}${F}`:F});return a?`{${m.join(u)}${d}}`:`{${m.join(u)}}`}}default:throw new Error(`Cannot convert to JSON: ${e.type}`)}}function ci(e){e.set("false",!1),e.set("true",!0),e.set("none",null),e.set("raise_exception",n=>{throw new Error(n)}),e.set("range",ti),e.set("strftime_now",ai),e.set("True",!0),e.set("False",!1),e.set("None",null)}function Xr(e,n){let t=n.split("."),r=e;for(let a of t)if(r instanceof ye)r=r.value.get(a)??new te;else if(r instanceof I){let s=parseInt(a,10);if(!isNaN(s)&&s>=0&&ss instanceof O||s instanceof ce||s instanceof A,a=s=>s instanceof A?s.value?1:0:s.value;if(r(e)&&r(n)){let s=a(e),o=a(n);return so?1:0}if(e.type!==n.type)throw new Error(`Cannot compare different types: ${e.type} and ${n.type}`);if(e.type==="StringValue"){let s=e.value,o=n.value;return t||(s=s.toLowerCase(),o=o.toLowerCase()),so?1:0}else throw new Error(`Cannot compare type: ${e.type}`)}function jn(e){switch(typeof e){case"number":return Number.isInteger(e)?new O(e):new ce(e);case"string":return new x(e);case"boolean":return new A(e);case"undefined":return new te;case"object":return e===null?new se:Array.isArray(e)?new I(e.map(jn)):new ye(new Map(Object.entries(e).map(([n,t])=>[n,jn(t)])));case"function":return new re((n,t)=>{let r=e(...n.map(a=>a.value))??null;return jn(r)});default:throw new Error(`Cannot convert to runtime value: ${e}`)}}function fi(e){switch(e.operator.type){case"MultiplicativeBinaryOperator":return 4;case"AdditiveBinaryOperator":return 3;case"ComparisonBinaryOperator":return 2;case"Identifier":return e.operator.value==="and"?1:e.operator.value==="in"||e.operator.value==="not in"?2:0}return 0}function mi(e,n=" "){let t=typeof n=="number"?" ".repeat(n):n;return Oe(e.body,0,t).replace(/\n$/,"")}function be(...e){return di+e.join(" ")+pi}function Oe(e,n,t){return e.map(r=>gi(r,n,t)).join(ge)}function gi(e,n,t){let r=t.repeat(n);switch(e.type){case"Program":return Oe(e.body,n,t);case"If":return hi(e,n,t);case"For":return yi(e,n,t);case"Set":return bi(e,n,t);case"Macro":return wi(e,n,t);case"Break":return r+be("break");case"Continue":return r+be("continue");case"CallStatement":return _i(e,n,t);case"FilterStatement":return vi(e,n,t);case"Comment":return r+"{# "+e.value+" #}";default:return r+"{{- "+D(e)+" -}}"}}function hi(e,n,t){let r=t.repeat(n),a=[],s=e;for(;s&&(a.push({test:s.test,body:s.body}),s.alternate.length===1&&s.alternate[0].type==="If");)s=s.alternate[0];let o=r+be("if",D(a[0].test))+ge+Oe(a[0].body,n+1,t);for(let i=1;i0&&(o+=ge+r+be("else")+ge+Oe(s.alternate,n+1,t)),o+=ge+r+be("endif"),o}function yi(e,n,t){let r=t.repeat(n),a="";if(e.iterable.type==="SelectExpression"){let o=e.iterable;a=`${D(o.lhs)} if ${D(o.test)}`}else a=D(e.iterable);let s=r+be("for",D(e.loopvar),"in",a)+ge+Oe(e.body,n+1,t);return e.defaultBlock.length>0&&(s+=ge+r+be("else")+ge+Oe(e.defaultBlock,n+1,t)),s+=ge+r+be("endfor"),s}function bi(e,n,t){let r=t.repeat(n),a=D(e.assignee),s=e.value?D(e.value):"",o=r+be("set",`${a}${e.value?" = "+s:""}`);return e.body.length===0?o:o+ge+Oe(e.body,n+1,t)+ge+r+be("endset")}function wi(e,n,t){let r=t.repeat(n),a=e.args.map(D).join(", ");return r+be("macro",`${e.name.value}(${a})`)+ge+Oe(e.body,n+1,t)+ge+r+be("endmacro")}function _i(e,n,t){let r=t.repeat(n),a=e.callerArgs&&e.callerArgs.length>0?`(${e.callerArgs.map(D).join(", ")})`:"",s=D(e.call),o=r+be(`call${a}`,s)+ge;return o+=Oe(e.body,n+1,t)+ge,o+=r+be("endcall"),o}function vi(e,n,t){let r=t.repeat(n),a=e.filter.type==="Identifier"?e.filter.value:D(e.filter),s=r+be("filter",a)+ge;return s+=Oe(e.body,n+1,t)+ge,s+=r+be("endfilter"),s}function D(e,n=-1){switch(e.type){case"SpreadExpression":return`*${D(e.argument)}`;case"Identifier":return e.value;case"IntegerLiteral":return`${e.value}`;case"FloatLiteral":return`${e.value}`;case"StringLiteral":return JSON.stringify(e.value);case"BinaryExpression":{let t=e,r=fi(t),a=D(t.left,r),s=D(t.right,r+1),o=`${a} ${t.operator.value} ${s}`;return r`${D(r)}: ${D(a)}`).join(", ")}}`;case"SliceExpression":{let t=e,r=t.start?D(t.start):"",a=t.stop?D(t.stop):"",s=t.step?`:${D(t.step)}`:"";return`${r}:${a}${s}`}case"KeywordArgumentExpression":{let t=e;return`${t.key.value}=${D(t.value)}`}case"Ternary":{let t=e,r=`${D(t.trueExpr)} if ${D(t.condition,0)} else ${D(t.falseExpr)}`;return n>-1?`(${r})`:r}default:throw new Error(`Unknown expression type: ${e.type}`)}}var Po,Ao,Go,h,Ge,Oo,Ro,Re,Wo,Mo,Bo,qo,Io,Uo,Do,Lo,Pe,Co,Nr,sn,on,No,zo,zr,jo,jr,$o,_n,Ko,Ho,Vo,Qo,Xo,Zo,Yo,Jo,ei,ni,Kr,Hr,ui,Ue,O,ce,x,A,li,ye,vn,I,Qr,re,se,te,Zr,Ie,Mt,ge,di,pi,Hn,Bt=he(()=>{Po=Object.defineProperty,Ao=(e,n,t)=>n in e?Po(e,n,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[n]=t,Go=(e,n,t)=>(Ao(e,typeof n!="symbol"?n+"":n,t),t),h=Object.freeze({Text:"Text",NumericLiteral:"NumericLiteral",StringLiteral:"StringLiteral",Identifier:"Identifier",Equals:"Equals",OpenParen:"OpenParen",CloseParen:"CloseParen",OpenStatement:"OpenStatement",CloseStatement:"CloseStatement",OpenExpression:"OpenExpression",CloseExpression:"CloseExpression",OpenSquareBracket:"OpenSquareBracket",CloseSquareBracket:"CloseSquareBracket",OpenCurlyBracket:"OpenCurlyBracket",CloseCurlyBracket:"CloseCurlyBracket",Comma:"Comma",Dot:"Dot",Colon:"Colon",Pipe:"Pipe",CallOperator:"CallOperator",AdditiveBinaryOperator:"AdditiveBinaryOperator",MultiplicativeBinaryOperator:"MultiplicativeBinaryOperator",ComparisonBinaryOperator:"ComparisonBinaryOperator",UnaryOperator:"UnaryOperator",Comment:"Comment"}),Ge=class{constructor(e,n){this.value=e,this.type=n}};Oo=[["{%",h.OpenStatement],["%}",h.CloseStatement],["{{",h.OpenExpression],["}}",h.CloseExpression],["(",h.OpenParen],[")",h.CloseParen],["{",h.OpenCurlyBracket],["}",h.CloseCurlyBracket],["[",h.OpenSquareBracket],["]",h.CloseSquareBracket],[",",h.Comma],[".",h.Dot],[":",h.Colon],["|",h.Pipe],["<=",h.ComparisonBinaryOperator],[">=",h.ComparisonBinaryOperator],["==",h.ComparisonBinaryOperator],["!=",h.ComparisonBinaryOperator],["<",h.ComparisonBinaryOperator],[">",h.ComparisonBinaryOperator],["+",h.AdditiveBinaryOperator],["-",h.AdditiveBinaryOperator],["~",h.AdditiveBinaryOperator],["*",h.MultiplicativeBinaryOperator],["/",h.MultiplicativeBinaryOperator],["%",h.MultiplicativeBinaryOperator],["=",h.Equals]],Ro=new Map([["n",` -`],["t"," "],["r","\r"],["b","\b"],["f","\f"],["v","\v"],["'","'"],['"','"'],["\\","\\"]]);Re=class{type="Statement"},Wo=class extends Re{constructor(e){super(),this.body=e}type="Program"},Mo=class extends Re{constructor(e,n,t){super(),this.test=e,this.body=n,this.alternate=t}type="If"},Bo=class extends Re{constructor(e,n,t,r){super(),this.loopvar=e,this.iterable=n,this.body=t,this.defaultBlock=r}type="For"},qo=class extends Re{type="Break"},Io=class extends Re{type="Continue"},Uo=class extends Re{constructor(e,n,t){super(),this.assignee=e,this.value=n,this.body=t}type="Set"},Do=class extends Re{constructor(e,n,t){super(),this.name=e,this.args=n,this.body=t}type="Macro"},Lo=class extends Re{constructor(e){super(),this.value=e}type="Comment"},Pe=class extends Re{type="Expression"},Co=class extends Pe{constructor(e,n,t){super(),this.object=e,this.property=n,this.computed=t}type="MemberExpression"},Nr=class extends Pe{constructor(e,n){super(),this.callee=e,this.args=n}type="CallExpression"},sn=class extends Pe{constructor(e){super(),this.value=e}type="Identifier"},on=class extends Pe{constructor(e){super(),this.value=e}type="Literal"},No=class extends on{type="IntegerLiteral"},zo=class extends on{type="FloatLiteral"},zr=class extends on{type="StringLiteral"},jo=class extends on{type="ArrayLiteral"},jr=class extends on{type="TupleLiteral"},$o=class extends on{type="ObjectLiteral"},_n=class extends Pe{constructor(e,n,t){super(),this.operator=e,this.left=n,this.right=t}type="BinaryExpression"},Ko=class extends Pe{constructor(e,n){super(),this.operand=e,this.filter=n}type="FilterExpression"},Ho=class extends Re{constructor(e,n){super(),this.filter=e,this.body=n}type="FilterStatement"},Vo=class extends Pe{constructor(e,n){super(),this.lhs=e,this.test=n}type="SelectExpression"},Qo=class extends Pe{constructor(e,n,t){super(),this.operand=e,this.negate=n,this.test=t}type="TestExpression"},Xo=class extends Pe{constructor(e,n){super(),this.operator=e,this.argument=n}type="UnaryExpression"},Zo=class extends Pe{constructor(e=void 0,n=void 0,t=void 0){super(),this.start=e,this.stop=n,this.step=t}type="SliceExpression"},Yo=class extends Pe{constructor(e,n){super(),this.key=e,this.value=n}type="KeywordArgumentExpression"},Jo=class extends Pe{constructor(e){super(),this.argument=e}type="SpreadExpression"},ei=class extends Re{constructor(e,n,t){super(),this.call=e,this.callerArgs=n,this.body=t}type="CallStatement"},ni=class extends Pe{constructor(e,n,t){super(),this.condition=e,this.trueExpr=n,this.falseExpr=t}type="Ternary"};Kr=class extends Error{},Hr=class extends Error{},ui=new Map,Ue=class{type="RuntimeValue";value;get builtins(){return ui}constructor(e=void 0){this.value=e}__bool__(){return new A(!!this.value)}toString(){return String(this.value)}},O=class extends Ue{type="IntegerValue"},ce=class extends Ue{type="FloatValue";toString(){return this.value%1===0?this.value.toFixed(1):this.value.toString()}},x=class extends Ue{type="StringValue";_builtins;get builtins(){return this._builtins??=new Map([["upper",new re(()=>new x(this.value.toUpperCase()))],["lower",new re(()=>new x(this.value.toLowerCase()))],["strip",new re(()=>new x(this.value.trim()))],["title",new re(()=>new x(ri(this.value)))],["capitalize",new re(()=>new x(this.value.charAt(0).toUpperCase()+this.value.slice(1)))],["length",new O(this.value.length)],["rstrip",new re(()=>new x(this.value.trimEnd()))],["lstrip",new re(()=>new x(this.value.trimStart()))],["startswith",new re(e=>{if(e.length===0)throw new Error("startswith() requires at least one argument");let n=e[0];if(n instanceof x)return new A(this.value.startsWith(n.value));if(n instanceof I){for(let t of n.value){if(!(t instanceof x))throw new Error("startswith() tuple elements must be strings");if(this.value.startsWith(t.value))return new A(!0)}return new A(!1)}throw new Error("startswith() argument must be a string or tuple of strings")})],["endswith",new re(e=>{if(e.length===0)throw new Error("endswith() requires at least one argument");let n=e[0];if(n instanceof x)return new A(this.value.endsWith(n.value));if(n instanceof I){for(let t of n.value){if(!(t instanceof x))throw new Error("endswith() tuple elements must be strings");if(this.value.endsWith(t.value))return new A(!0)}return new A(!1)}throw new Error("endswith() argument must be a string or tuple of strings")})],["split",new re(e=>{let n=e[0]??new se;if(!(n instanceof x||n instanceof se))throw new Error("sep argument must be a string or null");let t=e[1]??new O(-1);if(!(t instanceof O))throw new Error("maxsplit argument must be a number");let r=[];if(n instanceof se){let a=this.value.trimStart();for(let{0:s,index:o}of a.matchAll(/\S+/g)){if(t.value!==-1&&r.length>=t.value&&o!==void 0){r.push(s+a.slice(o+s.length));break}r.push(s)}}else{if(n.value==="")throw new Error("empty separator");r=this.value.split(n.value),t.value!==-1&&r.length>t.value&&r.push(r.splice(t.value).join(n.value))}return new I(r.map(a=>new x(a)))})],["replace",new re(e=>{if(e.length<2)throw new Error("replace() requires at least two arguments");let n=e[0],t=e[1];if(!(n instanceof x&&t instanceof x))throw new Error("replace() arguments must be strings");let r;if(e.length>2?e[2].type==="KeywordArgumentsValue"?r=e[2].value.get("count")??new se:r=e[2]:r=new se,!(r instanceof O||r instanceof se))throw new Error("replace() count argument must be a number or null");return new x(ii(this.value,n.value,t.value,r.value))})]])}},A=class extends Ue{type="BooleanValue"},li=/[\x7f-\uffff]/g;ye=class extends Ue{type="ObjectValue";_builtins;__bool__(){return new A(this.value.size>0)}get builtins(){return this._builtins??=new Map([["get",new re(([e,n])=>{if(!(e instanceof x))throw new Error(`Object key must be a string: got ${e.type}`);return this.value.get(e.value)??n??new se})],["items",new re(()=>this.items())],["keys",new re(()=>this.keys())],["values",new re(()=>this.values())],["dictsort",new re(e=>{let n=new Map,t=e.filter(i=>i instanceof vn?(n=i.value,!1):!0),r=t.at(0)??n.get("case_sensitive")??new A(!1);if(!(r instanceof A))throw new Error("case_sensitive must be a boolean");let a=t.at(1)??n.get("by")??new x("key");if(!(a instanceof x))throw new Error("by must be a string");if(!["key","value"].includes(a.value))throw new Error("by must be either 'key' or 'value'");let s=t.at(2)??n.get("reverse")??new A(!1);if(!(s instanceof A))throw new Error("reverse must be a boolean");let o=Array.from(this.value.entries()).map(([i,u])=>new I([new x(i),u])).sort((i,u)=>{let l=a.value==="key"?0:1,c=i.value[l],d=u.value[l],p=Wt(c,d,r.value);return s.value?-p:p});return new I(o)})]])}items(){return new I(Array.from(this.value.entries()).map(([e,n])=>new I([new x(e),n])))}keys(){return new I(Array.from(this.value.keys()).map(e=>new x(e)))}values(){return new I(Array.from(this.value.values()))}toString(){return Ye(this,{},0,!1)}},vn=class extends ye{type="KeywordArgumentsValue"},I=class extends Ue{type="ArrayValue";_builtins;get builtins(){return this._builtins??=new Map([["length",new O(this.value.length)]])}__bool__(){return new A(this.value.length>0)}toString(){return Ye(this,{},0,!1)}},Qr=class extends I{type="TupleValue"},re=class extends Ue{type="FunctionValue"},se=class extends Ue{type="NullValue"},te=class extends Ue{type="UndefinedValue"},Zr=class{constructor(e){this.parent=e}variables=new Map([["namespace",new re(e=>{if(e.length===0)return new ye(new Map);if(e.length!==1||!(e[0]instanceof ye))throw new Error("`namespace` expects either zero arguments or a single object argument");return e[0]})]]);tests=Zr.TESTS;set(e,n){return this.declareVariable(e,jn(n))}declareVariable(e,n){if(this.variables.has(e))throw new SyntaxError(`Variable already declared: ${e}`);return this.variables.set(e,n),n}setVariable(e,n){return this.variables.set(e,n),n}resolve(e){if(this.variables.has(e))return this;if(this.parent)return this.parent.resolve(e);throw new Error(`Unknown variable: ${e}`)}lookupVariable(e){try{return this.resolve(e).variables.get(e)??new te}catch{return new te}}},Ie=Zr;Go(Ie,"TESTS",new Map([["boolean",e=>e.type==="BooleanValue"],["callable",e=>e instanceof re],["odd",e=>{if(!(e instanceof O))throw new Error(`cannot odd on ${e.type}`);return e.value%2!==0}],["even",e=>{if(!(e instanceof O))throw new Error(`cannot even on ${e.type}`);return e.value%2===0}],["false",e=>e.type==="BooleanValue"&&!e.value],["true",e=>e.type==="BooleanValue"&&e.value],["none",e=>e.type==="NullValue"],["string",e=>e.type==="StringValue"],["number",e=>e instanceof O||e instanceof ce],["integer",e=>e instanceof O],["iterable",e=>e.type==="ArrayValue"||e.type==="StringValue"],["mapping",e=>e instanceof ye],["sequence",e=>e instanceof I||e instanceof ye||e instanceof x],["lower",e=>{let n=e.value;return e.type==="StringValue"&&n===n.toLowerCase()}],["upper",e=>{let n=e.value;return e.type==="StringValue"&&n===n.toUpperCase()}],["none",e=>e.type==="NullValue"],["defined",e=>e.type!=="UndefinedValue"],["undefined",e=>e.type==="UndefinedValue"],["equalto",(e,n)=>e.value===n.value],["eq",(e,n)=>e.value===n.value]]));Mt=class{global;constructor(e){this.global=e??new Ie}run(e){return this.evaluate(e,this.global)}evaluateBinaryExpression(e,n){let t=this.evaluate(e.left,n);switch(e.operator.value){case"and":return t.__bool__().value?this.evaluate(e.right,n):t;case"or":return t.__bool__().value?t:this.evaluate(e.right,n)}let r=this.evaluate(e.right,n);switch(e.operator.value){case"==":return new A(t.value==r.value);case"!=":return new A(t.value!=r.value)}if(t instanceof te||r instanceof te){if(r instanceof te&&["in","not in"].includes(e.operator.value))return new A(e.operator.value==="not in");throw new Error(`Cannot perform operation ${e.operator.value} on undefined values`)}else{if(t instanceof se||r instanceof se)throw new Error("Cannot perform operation on null values");if(e.operator.value==="~")return new x(t.value.toString()+r.value.toString());if((t instanceof O||t instanceof ce)&&(r instanceof O||r instanceof ce)){let a=t.value,s=r.value;switch(e.operator.value){case"+":case"-":case"*":{let o=e.operator.value==="+"?a+s:e.operator.value==="-"?a-s:a*s;return t instanceof ce||r instanceof ce?new ce(o):new O(o)}case"/":return new ce(a/s);case"%":{let o=a%s;return t instanceof ce||r instanceof ce?new ce(o):new O(o)}case"<":return new A(a":return new A(a>s);case">=":return new A(a>=s);case"<=":return new A(a<=s)}}else if(t instanceof I&&r instanceof I){if(e.operator.value==="+")return new I(t.value.concat(r.value))}else if(r instanceof I){let a=r.value.find(s=>s.value===t.value)!==void 0;switch(e.operator.value){case"in":return new A(a);case"not in":return new A(!a)}}}if((t instanceof x||r instanceof x)&&e.operator.value==="+")return new x(t.value.toString()+r.value.toString());if(t instanceof x&&r instanceof x)switch(e.operator.value){case"in":return new A(r.value.includes(t.value));case"not in":return new A(!r.value.includes(t.value))}if(t instanceof x&&r instanceof ye)switch(e.operator.value){case"in":return new A(r.value.has(t.value));case"not in":return new A(!r.value.has(t.value))}throw new SyntaxError(`Unknown operator "${e.operator.value}" between ${t.type} and ${r.type}`)}evaluateArguments(e,n){let t=[],r=new Map;for(let a of e)if(a.type==="SpreadExpression"){let s=a,o=this.evaluate(s.argument,n);if(!(o instanceof I))throw new Error(`Cannot unpack non-iterable type: ${o.type}`);for(let i of o.value)t.push(i)}else if(a.type==="KeywordArgumentExpression"){let s=a;r.set(s.key.value,this.evaluate(s.value,n))}else{if(r.size>0)throw new Error("Positional arguments must come before keyword arguments");t.push(this.evaluate(a,n))}return[t,r]}applyFilter(e,n,t){if(n.type==="Identifier"){let r=n;if(r.value==="safe")return e;if(r.value==="tojson")return new x(Ye(e,{}));if(e instanceof I)switch(r.value){case"list":return e;case"first":return e.value[0];case"last":return e.value[e.value.length-1];case"length":return new O(e.value.length);case"reverse":return new I(e.value.slice().reverse());case"sort":return new I(e.value.slice().sort((a,s)=>Wt(a,s,!1)));case"join":return new x(e.value.map(a=>a.value).join(""));case"string":return new x(Ye(e,{},0,!1));case"unique":{let a=new Set,s=[];for(let o of e.value)a.has(o.value)||(a.add(o.value),s.push(o));return new I(s)}default:throw new Error(`Unknown ArrayValue filter: ${r.value}`)}else if(e instanceof x)switch(r.value){case"length":case"upper":case"lower":case"title":case"capitalize":{let a=e.builtins.get(r.value);if(a instanceof re)return a.value([],t);if(a instanceof O)return a;throw new Error(`Unknown StringValue filter: ${r.value}`)}case"trim":return new x(e.value.trim());case"indent":return new x(e.value.split(` +var ko=Object.defineProperty;var he=(e,n)=>()=>(e&&(n=e(e=0)),n);var Eo=(e,n)=>{for(var r in n)ko(e,r,{get:n[r],enumerable:!0})};function Lt(e){return/\w/.test(e)}function wn(e){return/[0-9]/.test(e)}function Ct(e){return/\s/.test(e)}function Wo(e,n={}){return e.endsWith(` +`)&&(e=e.slice(0,-1)),n.lstrip_blocks&&(e=e.replace(/^[ \t]*({[#%-])/gm,"$1")),n.trim_blocks&&(e=e.replace(/([#%-]})\n/g,"$1")),e.replace(/(\s*){%(-?)\s*(?:end)?generation\s*(-?)%}(\s*)/gs,(r,t,a,s,o)=>(a?"":t)+(s?"":o))}function $n(e,n={}){let r=[],t=Wo(e,n),a=0,s=0,o=l=>{let c="";for(;l(t[a]);){if(t[a]==="\\"){if(++a,a>=t.length)throw new SyntaxError("Unexpected end of input");let d=t[a++],p=Ro.get(d);if(p===void 0)throw new SyntaxError(`Unexpected escaped character: ${d}`);c+=p;continue}if(c+=t[a++],a>=t.length)throw new SyntaxError("Unexpected end of input")}return c},i=()=>{let l=r.at(-1);l&&l.type===h.Text&&(l.value=l.value.trimEnd(),l.value===""&&r.pop())},u=()=>{for(;a0){r.push(new Ge(d,h.Text));continue}}if(t[a]==="{"&&t[a+1]==="#"){a+=2;let d=t[a]==="-";d&&++a;let p="";for(;t[a]!=="#"||t[a+1]!=="}";){if(a+2>=t.length)throw new SyntaxError("Missing end of comment tag");p+=t[a++]}let f=p.endsWith("-");f&&(p=p.slice(0,-1)),d&&i(),r.push(new Ge(p,h.Comment)),a+=2,f&&u();continue}if(t.slice(a,a+3)==="{%-"){i(),r.push(new Ge("{%",h.OpenStatement)),a+=3;continue}if(t.slice(a,a+3)==="{{-"){i(),r.push(new Ge("{{",h.OpenExpression)),s=0,a+=3;continue}if(o(Ct),t.slice(a,a+3)==="-%}"){r.push(new Ge("%}",h.CloseStatement)),a+=3,u();continue}if(t.slice(a,a+3)==="-}}"){r.push(new Ge("}}",h.CloseExpression)),a+=3,u();continue}let c=t[a];if(c==="-"||c==="+"){let d=r.at(-1)?.type;if(d===h.Text||d===void 0)throw new SyntaxError(`Unexpected character: ${c}`);switch(d){case h.Identifier:case h.NumericLiteral:case h.StringLiteral:case h.CloseParen:case h.CloseSquareBracket:break;default:{++a;let p=o(wn);r.push(new Ge(`${c}${p}`,p.length>0?h.NumericLiteral:h.UnaryOperator));continue}}}for(let[d,p]of Oo){if(d==="}}"&&s>0)continue;if(t.slice(a,a+d.length)===d){r.push(new Ge(d,p)),p===h.OpenExpression?s=0:p===h.OpenCurlyBracket?++s:p===h.CloseCurlyBracket&&--s,a+=d.length;continue e}}if(c==="'"||c==='"'){++a;let d=o(p=>p!==c);r.push(new Ge(d,h.StringLiteral)),++a;continue}if(wn(c)){let d=o(wn);if(r.at(-1)?.type!==h.Dot&&t[a]==="."&&wn(t[a+1])){++a;let p=o(wn);d=`${d}.${p}`}r.push(new Ge(d,h.NumericLiteral));continue}if(Lt(c)){let d=o(Lt);r.push(new Ge(d,h.Identifier));continue}throw new SyntaxError(`Unexpected character: ${c}`)}return r}function Kn(e){let n=new Fo([]),r=0;function t(g,w){let T=e[r++];if(!T||T.type!==g)throw new Error(`Parser Error: ${w}. ${T.type} !== ${g}.`);return T}function a(g){if(!u(g))throw new SyntaxError(`Expected ${g}`);++r}function s(){switch(e[r].type){case h.Comment:return new Lo(e[r++].value);case h.Text:return l();case h.OpenStatement:return c();case h.OpenExpression:return d();default:throw new SyntaxError(`Unexpected token type: ${e[r].type}`)}}function o(...g){return r+g.length<=e.length&&g.every((w,T)=>w===e[r+T].type)}function i(...g){return e[r]?.type===h.OpenStatement&&e[r+1]?.type===h.Identifier&&g.includes(e[r+1]?.value)}function u(...g){return r+g.length<=e.length&&g.every((w,T)=>e[r+T].type==="Identifier"&&w===e[r+T].value)}function l(){return new zt(t(h.Text,"Expected text token").value)}function c(){if(t(h.OpenStatement,"Expected opening statement token"),e[r].type!==h.Identifier)throw new SyntaxError(`Unknown statement, got ${e[r].type}`);let g=e[r].value,w;switch(g){case"set":++r,w=p();break;case"if":++r,w=f(),t(h.OpenStatement,"Expected {% token"),a("endif"),t(h.CloseStatement,"Expected %} token");break;case"macro":++r,w=m(),t(h.OpenStatement,"Expected {% token"),a("endmacro"),t(h.CloseStatement,"Expected %} token");break;case"for":++r,w=E(),t(h.OpenStatement,"Expected {% token"),a("endfor"),t(h.CloseStatement,"Expected %} token");break;case"call":{++r;let T=null;o(h.OpenParen)&&(T=R());let X=Z();if(X.type!=="Identifier")throw new SyntaxError("Expected identifier following call statement");let Be=R();t(h.CloseStatement,"Expected closing statement token");let Te=[];for(;!i("endcall");)Te.push(s());t(h.OpenStatement,"Expected '{%'"),a("endcall"),t(h.CloseStatement,"Expected closing statement token");let Se=new Nt(X,Be);w=new ei(Se,T,Te);break}case"break":++r,t(h.CloseStatement,"Expected closing statement token"),w=new qo;break;case"continue":++r,t(h.CloseStatement,"Expected closing statement token"),w=new Io;break;case"filter":{++r;let T=Z();T instanceof sn&&o(h.OpenParen)&&(T=N(T)),t(h.CloseStatement,"Expected closing statement token");let X=[];for(;!i("endfilter");)X.push(s());t(h.OpenStatement,"Expected '{%'"),a("endfilter"),t(h.CloseStatement,"Expected '%}'"),w=new Ho(T,X);break}default:throw new SyntaxError(`Unknown statement type: ${g}`)}return w}function d(){t(h.OpenExpression,"Expected opening expression token");let g=b();return t(h.CloseExpression,"Expected closing expression token"),g}function p(){let g=_(),w=null,T=[];if(o(h.Equals))++r,w=_();else{for(t(h.CloseStatement,"Expected %} token");!i("endset");)T.push(s());t(h.OpenStatement,"Expected {% token"),a("endset")}return t(h.CloseStatement,"Expected closing statement token"),new Do(g,w,T)}function f(){let g=b();t(h.CloseStatement,"Expected closing statement token");let w=[],T=[];for(;!i("elif","else","endif");)w.push(s());if(i("elif")){++r,++r;let X=f();T.push(X)}else if(i("else"))for(++r,++r,t(h.CloseStatement,"Expected closing statement token");!i("endif");)T.push(s());return new Mo(g,w,T)}function m(){let g=Z();if(g.type!=="Identifier")throw new SyntaxError("Expected identifier following macro statement");let w=R();t(h.CloseStatement,"Expected closing statement token");let T=[];for(;!i("endmacro");)T.push(s());return new Uo(g,w,T)}function _(g=!1){let w=g?Z:b,T=[w()],X=o(h.Comma);for(;X&&(++r,T.push(w()),!!o(h.Comma)););return X?new jt(T):T[0]}function E(){let g=_(!0);if(!(g instanceof sn||g instanceof jt))throw new SyntaxError(`Expected identifier/tuple for the loop variable, got ${g.type} instead`);if(!u("in"))throw new SyntaxError("Expected `in` keyword following loop variable");++r;let w=b();t(h.CloseStatement,"Expected closing statement token");let T=[];for(;!i("endfor","else");)T.push(s());let X=[];if(i("else"))for(++r,++r,t(h.CloseStatement,"Expected closing statement token");!i("endfor");)X.push(s());return new Bo(g,w,T,X)}function b(){return W()}function W(){let g=q();if(u("if")){++r;let w=q();if(u("else")){++r;let T=W();return new ni(w,g,T)}else return new Vo(g,w)}return g}function q(){let g=G();for(;u("or");){let w=e[r];++r;let T=G();g=new _n(w,g,T)}return g}function G(){let g=C();for(;u("and");){let w=e[r];++r;let T=C();g=new _n(w,g,T)}return g}function C(){let g;for(;u("not");){let w=e[r];++r;let T=C();g=new Xo(w,T)}return g??S()}function S(){let g=D();for(;;){let w;if(u("not","in"))w=new Ge("not in",h.Identifier),r+=2;else if(u("in"))w=e[r++];else if(o(h.ComparisonBinaryOperator))w=e[r++];else break;let T=D();g=new _n(w,g,T)}return g}function D(){let g=ne();for(;o(h.AdditiveBinaryOperator);){let w=e[r];++r;let T=ne();g=new _n(w,g,T)}return g}function P(){let g=j(Z());return o(h.OpenParen)?N(g):g}function N(g){let w=new Nt(g,R());return w=j(w),o(h.OpenParen)&&(w=N(w)),w}function R(){t(h.OpenParen,"Expected opening parenthesis for arguments list");let g=V();return t(h.CloseParen,"Expected closing parenthesis for arguments list"),g}function V(){let g=[];for(;!o(h.CloseParen);){let w;if(e[r].type===h.MultiplicativeBinaryOperator&&e[r].value==="*"){++r;let T=b();w=new Jo(T)}else if(w=b(),o(h.Equals)){if(++r,!(w instanceof sn))throw new SyntaxError("Expected identifier for keyword argument");let T=b();w=new Yo(w,T)}g.push(w),o(h.Comma)&&++r}return g}function z(){let g=[],w=!1;for(;!o(h.CloseSquareBracket);)o(h.Colon)?(g.push(void 0),++r,w=!0):(g.push(b()),o(h.Colon)&&(++r,w=!0));if(g.length===0)throw new SyntaxError("Expected at least one argument for member/slice expression");if(w){if(g.length>3)throw new SyntaxError("Expected 0-3 arguments for slice expression");return new Zo(...g)}return g[0]}function j(g){for(;o(h.Dot)||o(h.OpenSquareBracket);){let w=e[r];++r;let T,X=w.type===h.OpenSquareBracket;if(X)T=z(),t(h.CloseSquareBracket,"Expected closing square bracket");else if(T=Z(),T.type!=="Identifier"&&T.type!=="IntegerLiteral")throw new SyntaxError("Expected identifier or integer following dot operator");g=new Co(g,T,X)}return g}function ne(){let g=Q();for(;o(h.MultiplicativeBinaryOperator);){let w=e[r++],T=Q();g=new _n(w,g,T)}return g}function Q(){let g=ve();for(;u("is");){++r;let w=u("not");w&&++r;let T=Z();if(!(T instanceof sn))throw new SyntaxError("Expected identifier for the test");g=new Qo(g,w,T)}return g}function ve(){let g=P();for(;o(h.Pipe);){++r;let w=Z();if(!(w instanceof sn))throw new SyntaxError("Expected identifier for the filter");o(h.OpenParen)&&(w=N(w)),g=new Ko(g,w)}return g}function Z(){let g=e[r++];switch(g.type){case h.NumericLiteral:{let w=g.value;return w.includes(".")?new zo(Number(w)):new No(Number(w))}case h.StringLiteral:{let w=g.value;for(;o(h.StringLiteral);)w+=e[r++].value;return new zt(w)}case h.Identifier:return new sn(g.value);case h.OpenParen:{let w=_();return t(h.CloseParen,"Expected closing parenthesis, got ${tokens[current].type} instead."),w}case h.OpenSquareBracket:{let w=[];for(;!o(h.CloseSquareBracket);)w.push(b()),o(h.Comma)&&++r;return++r,new jo(w)}case h.OpenCurlyBracket:{let w=new Map;for(;!o(h.CloseCurlyBracket);){let T=b();t(h.Colon,"Expected colon between key and value in object literal");let X=b();w.set(T,X),o(h.Comma)&&++r}return++r,new $o(w)}default:throw new SyntaxError(`Unexpected token: ${g.type}`)}}for(;r0)for(let a=e;an;a+=r)t.push(a);return t}function $t(e,n,r,t=1){let a=Math.sign(t);a>=0?(n=(n??=0)<0?Math.max(e.length+n,0):Math.min(n,e.length),r=(r??=e.length)<0?Math.max(e.length+r,0):Math.min(r,e.length)):(n=(n??=e.length-1)<0?Math.max(e.length+n,-1):Math.min(n,e.length-1),r=(r??=-1)<-1?Math.max(e.length+r,-1):Math.min(r,e.length-1));let s=[];for(let o=n;a*on.toUpperCase())}function ai(e){return si(new Date,e)}function si(e,n){let r=new Intl.DateTimeFormat(void 0,{month:"long"}),t=new Intl.DateTimeFormat(void 0,{month:"short"}),a=s=>s<10?"0"+s:s.toString();return n.replace(/%[YmdbBHM%]/g,s=>{switch(s){case"%Y":return e.getFullYear().toString();case"%m":return a(e.getMonth()+1);case"%d":return a(e.getDate());case"%b":return t.format(e);case"%B":return r.format(e);case"%H":return a(e.getHours());case"%M":return a(e.getMinutes());case"%%":return"%";default:return s}})}function oi(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function ii(e,n,r,t){if(t===0)return e;let a=t==null||t<0?1/0:t,s=n.length===0?new RegExp("(?=)","gu"):new RegExp(oi(n),"gu");return e.replaceAll(s,o=>a>0?(--a,r):o)}function Vt(e){return e.replace(li,n=>"\\u"+n.charCodeAt(0).toString(16).padStart(4,"0"))}function Ye(e,n={},r=0,t=!0){let{indent:a=null,ensureAscii:s=!1,separators:o=null,sortKeys:i=!1}=n,u,l;switch(o?[u,l]=o:a?(u=",",l=": "):(u=", ",l=": "),e.type){case"NullValue":return"null";case"UndefinedValue":return t?"null":"undefined";case"IntegerValue":case"FloatValue":case"BooleanValue":return JSON.stringify(e.value);case"StringValue":{let c=JSON.stringify(e.value);return s&&(c=Vt(c)),c}case"ArrayValue":case"ObjectValue":{let c=a?" ".repeat(a):"",d=` +`+c.repeat(r),p=d+c;if(e.type==="ArrayValue"){let f=e.value.map(m=>Ye(m,n,r+1,t));return a?`[${p}${f.join(`${u}${p}`)}${d}]`:`[${f.join(u)}]`}else{let f=Array.from(e.value.entries());i&&(f=f.sort(([_],[E])=>_.localeCompare(E)));let m=f.map(([_,E])=>{let b=JSON.stringify(_);s&&(b=Vt(b));let W=`${b}${l}${Ye(E,n,r+1,t)}`;return a?`${p}${W}`:W});return a?`{${m.join(u)}${d}}`:`{${m.join(u)}}`}}default:throw new Error(`Cannot convert to JSON: ${e.type}`)}}function ci(e){e.set("false",!1),e.set("true",!0),e.set("none",null),e.set("raise_exception",n=>{throw new Error(n)}),e.set("range",ri),e.set("strftime_now",ai),e.set("True",!0),e.set("False",!1),e.set("None",null)}function Xt(e,n){let r=n.split("."),t=e;for(let a of r)if(t instanceof ye)t=t.value.get(a)??new re;else if(t instanceof I){let s=parseInt(a,10);if(!isNaN(s)&&s>=0&&ss instanceof O||s instanceof ce||s instanceof A,a=s=>s instanceof A?s.value?1:0:s.value;if(t(e)&&t(n)){let s=a(e),o=a(n);return so?1:0}if(e.type!==n.type)throw new Error(`Cannot compare different types: ${e.type} and ${n.type}`);if(e.type==="StringValue"){let s=e.value,o=n.value;return r||(s=s.toLowerCase(),o=o.toLowerCase()),so?1:0}else throw new Error(`Cannot compare type: ${e.type}`)}function jn(e){switch(typeof e){case"number":return Number.isInteger(e)?new O(e):new ce(e);case"string":return new k(e);case"boolean":return new A(e);case"undefined":return new re;case"object":return e===null?new se:Array.isArray(e)?new I(e.map(jn)):new ye(new Map(Object.entries(e).map(([n,r])=>[n,jn(r)])));case"function":return new te((n,r)=>{let t=e(...n.map(a=>a.value))??null;return jn(t)});default:throw new Error(`Cannot convert to runtime value: ${e}`)}}function fi(e){switch(e.operator.type){case"MultiplicativeBinaryOperator":return 4;case"AdditiveBinaryOperator":return 3;case"ComparisonBinaryOperator":return 2;case"Identifier":return e.operator.value==="and"?1:e.operator.value==="in"||e.operator.value==="not in"?2:0}return 0}function mi(e,n=" "){let r=typeof n=="number"?" ".repeat(n):n;return Oe(e.body,0,r).replace(/\n$/,"")}function be(...e){return di+e.join(" ")+pi}function Oe(e,n,r){return e.map(t=>gi(t,n,r)).join(ge)}function gi(e,n,r){let t=r.repeat(n);switch(e.type){case"Program":return Oe(e.body,n,r);case"If":return hi(e,n,r);case"For":return yi(e,n,r);case"Set":return bi(e,n,r);case"Macro":return wi(e,n,r);case"Break":return t+be("break");case"Continue":return t+be("continue");case"CallStatement":return _i(e,n,r);case"FilterStatement":return vi(e,n,r);case"Comment":return t+"{# "+e.value+" #}";default:return t+"{{- "+U(e)+" -}}"}}function hi(e,n,r){let t=r.repeat(n),a=[],s=e;for(;s&&(a.push({test:s.test,body:s.body}),s.alternate.length===1&&s.alternate[0].type==="If");)s=s.alternate[0];let o=t+be("if",U(a[0].test))+ge+Oe(a[0].body,n+1,r);for(let i=1;i0&&(o+=ge+t+be("else")+ge+Oe(s.alternate,n+1,r)),o+=ge+t+be("endif"),o}function yi(e,n,r){let t=r.repeat(n),a="";if(e.iterable.type==="SelectExpression"){let o=e.iterable;a=`${U(o.lhs)} if ${U(o.test)}`}else a=U(e.iterable);let s=t+be("for",U(e.loopvar),"in",a)+ge+Oe(e.body,n+1,r);return e.defaultBlock.length>0&&(s+=ge+t+be("else")+ge+Oe(e.defaultBlock,n+1,r)),s+=ge+t+be("endfor"),s}function bi(e,n,r){let t=r.repeat(n),a=U(e.assignee),s=e.value?U(e.value):"",o=t+be("set",`${a}${e.value?" = "+s:""}`);return e.body.length===0?o:o+ge+Oe(e.body,n+1,r)+ge+t+be("endset")}function wi(e,n,r){let t=r.repeat(n),a=e.args.map(U).join(", ");return t+be("macro",`${e.name.value}(${a})`)+ge+Oe(e.body,n+1,r)+ge+t+be("endmacro")}function _i(e,n,r){let t=r.repeat(n),a=e.callerArgs&&e.callerArgs.length>0?`(${e.callerArgs.map(U).join(", ")})`:"",s=U(e.call),o=t+be(`call${a}`,s)+ge;return o+=Oe(e.body,n+1,r)+ge,o+=t+be("endcall"),o}function vi(e,n,r){let t=r.repeat(n),a=e.filter.type==="Identifier"?e.filter.value:U(e.filter),s=t+be("filter",a)+ge;return s+=Oe(e.body,n+1,r)+ge,s+=t+be("endfilter"),s}function U(e,n=-1){switch(e.type){case"SpreadExpression":return`*${U(e.argument)}`;case"Identifier":return e.value;case"IntegerLiteral":return`${e.value}`;case"FloatLiteral":return`${e.value}`;case"StringLiteral":return JSON.stringify(e.value);case"BinaryExpression":{let r=e,t=fi(r),a=U(r.left,t),s=U(r.right,t+1),o=`${a} ${r.operator.value} ${s}`;return t`${U(t)}: ${U(a)}`).join(", ")}}`;case"SliceExpression":{let r=e,t=r.start?U(r.start):"",a=r.stop?U(r.stop):"",s=r.step?`:${U(r.step)}`:"";return`${t}:${a}${s}`}case"KeywordArgumentExpression":{let r=e;return`${r.key.value}=${U(r.value)}`}case"Ternary":{let r=e,t=`${U(r.trueExpr)} if ${U(r.condition,0)} else ${U(r.falseExpr)}`;return n>-1?`(${t})`:t}default:throw new Error(`Unknown expression type: ${e.type}`)}}var Po,Ao,Go,h,Ge,Oo,Ro,Re,Fo,Mo,Bo,qo,Io,Do,Uo,Lo,Pe,Co,Nt,sn,on,No,zo,zt,jo,jt,$o,_n,Ko,Ho,Vo,Qo,Xo,Zo,Yo,Jo,ei,ni,Kt,Ht,ui,De,O,ce,k,A,li,ye,vn,I,Qt,te,se,re,Zt,Ie,Mr,ge,di,pi,Hn,Br=he(()=>{Po=Object.defineProperty,Ao=(e,n,r)=>n in e?Po(e,n,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[n]=r,Go=(e,n,r)=>(Ao(e,typeof n!="symbol"?n+"":n,r),r),h=Object.freeze({Text:"Text",NumericLiteral:"NumericLiteral",StringLiteral:"StringLiteral",Identifier:"Identifier",Equals:"Equals",OpenParen:"OpenParen",CloseParen:"CloseParen",OpenStatement:"OpenStatement",CloseStatement:"CloseStatement",OpenExpression:"OpenExpression",CloseExpression:"CloseExpression",OpenSquareBracket:"OpenSquareBracket",CloseSquareBracket:"CloseSquareBracket",OpenCurlyBracket:"OpenCurlyBracket",CloseCurlyBracket:"CloseCurlyBracket",Comma:"Comma",Dot:"Dot",Colon:"Colon",Pipe:"Pipe",CallOperator:"CallOperator",AdditiveBinaryOperator:"AdditiveBinaryOperator",MultiplicativeBinaryOperator:"MultiplicativeBinaryOperator",ComparisonBinaryOperator:"ComparisonBinaryOperator",UnaryOperator:"UnaryOperator",Comment:"Comment"}),Ge=class{constructor(e,n){this.value=e,this.type=n}};Oo=[["{%",h.OpenStatement],["%}",h.CloseStatement],["{{",h.OpenExpression],["}}",h.CloseExpression],["(",h.OpenParen],[")",h.CloseParen],["{",h.OpenCurlyBracket],["}",h.CloseCurlyBracket],["[",h.OpenSquareBracket],["]",h.CloseSquareBracket],[",",h.Comma],[".",h.Dot],[":",h.Colon],["|",h.Pipe],["<=",h.ComparisonBinaryOperator],[">=",h.ComparisonBinaryOperator],["==",h.ComparisonBinaryOperator],["!=",h.ComparisonBinaryOperator],["<",h.ComparisonBinaryOperator],[">",h.ComparisonBinaryOperator],["+",h.AdditiveBinaryOperator],["-",h.AdditiveBinaryOperator],["~",h.AdditiveBinaryOperator],["*",h.MultiplicativeBinaryOperator],["/",h.MultiplicativeBinaryOperator],["%",h.MultiplicativeBinaryOperator],["=",h.Equals]],Ro=new Map([["n",` +`],["t"," "],["r","\r"],["b","\b"],["f","\f"],["v","\v"],["'","'"],['"','"'],["\\","\\"]]);Re=class{type="Statement"},Fo=class extends Re{constructor(e){super(),this.body=e}type="Program"},Mo=class extends Re{constructor(e,n,r){super(),this.test=e,this.body=n,this.alternate=r}type="If"},Bo=class extends Re{constructor(e,n,r,t){super(),this.loopvar=e,this.iterable=n,this.body=r,this.defaultBlock=t}type="For"},qo=class extends Re{type="Break"},Io=class extends Re{type="Continue"},Do=class extends Re{constructor(e,n,r){super(),this.assignee=e,this.value=n,this.body=r}type="Set"},Uo=class extends Re{constructor(e,n,r){super(),this.name=e,this.args=n,this.body=r}type="Macro"},Lo=class extends Re{constructor(e){super(),this.value=e}type="Comment"},Pe=class extends Re{type="Expression"},Co=class extends Pe{constructor(e,n,r){super(),this.object=e,this.property=n,this.computed=r}type="MemberExpression"},Nt=class extends Pe{constructor(e,n){super(),this.callee=e,this.args=n}type="CallExpression"},sn=class extends Pe{constructor(e){super(),this.value=e}type="Identifier"},on=class extends Pe{constructor(e){super(),this.value=e}type="Literal"},No=class extends on{type="IntegerLiteral"},zo=class extends on{type="FloatLiteral"},zt=class extends on{type="StringLiteral"},jo=class extends on{type="ArrayLiteral"},jt=class extends on{type="TupleLiteral"},$o=class extends on{type="ObjectLiteral"},_n=class extends Pe{constructor(e,n,r){super(),this.operator=e,this.left=n,this.right=r}type="BinaryExpression"},Ko=class extends Pe{constructor(e,n){super(),this.operand=e,this.filter=n}type="FilterExpression"},Ho=class extends Re{constructor(e,n){super(),this.filter=e,this.body=n}type="FilterStatement"},Vo=class extends Pe{constructor(e,n){super(),this.lhs=e,this.test=n}type="SelectExpression"},Qo=class extends Pe{constructor(e,n,r){super(),this.operand=e,this.negate=n,this.test=r}type="TestExpression"},Xo=class extends Pe{constructor(e,n){super(),this.operator=e,this.argument=n}type="UnaryExpression"},Zo=class extends Pe{constructor(e=void 0,n=void 0,r=void 0){super(),this.start=e,this.stop=n,this.step=r}type="SliceExpression"},Yo=class extends Pe{constructor(e,n){super(),this.key=e,this.value=n}type="KeywordArgumentExpression"},Jo=class extends Pe{constructor(e){super(),this.argument=e}type="SpreadExpression"},ei=class extends Re{constructor(e,n,r){super(),this.call=e,this.callerArgs=n,this.body=r}type="CallStatement"},ni=class extends Pe{constructor(e,n,r){super(),this.condition=e,this.trueExpr=n,this.falseExpr=r}type="Ternary"};Kt=class extends Error{},Ht=class extends Error{},ui=new Map,De=class{type="RuntimeValue";value;get builtins(){return ui}constructor(e=void 0){this.value=e}__bool__(){return new A(!!this.value)}toString(){return String(this.value)}},O=class extends De{type="IntegerValue"},ce=class extends De{type="FloatValue";toString(){return this.value%1===0?this.value.toFixed(1):this.value.toString()}},k=class extends De{type="StringValue";_builtins;get builtins(){return this._builtins??=new Map([["upper",new te(()=>new k(this.value.toUpperCase()))],["lower",new te(()=>new k(this.value.toLowerCase()))],["strip",new te(()=>new k(this.value.trim()))],["title",new te(()=>new k(ti(this.value)))],["capitalize",new te(()=>new k(this.value.charAt(0).toUpperCase()+this.value.slice(1)))],["length",new O(this.value.length)],["rstrip",new te(()=>new k(this.value.trimEnd()))],["lstrip",new te(()=>new k(this.value.trimStart()))],["startswith",new te(e=>{if(e.length===0)throw new Error("startswith() requires at least one argument");let n=e[0];if(n instanceof k)return new A(this.value.startsWith(n.value));if(n instanceof I){for(let r of n.value){if(!(r instanceof k))throw new Error("startswith() tuple elements must be strings");if(this.value.startsWith(r.value))return new A(!0)}return new A(!1)}throw new Error("startswith() argument must be a string or tuple of strings")})],["endswith",new te(e=>{if(e.length===0)throw new Error("endswith() requires at least one argument");let n=e[0];if(n instanceof k)return new A(this.value.endsWith(n.value));if(n instanceof I){for(let r of n.value){if(!(r instanceof k))throw new Error("endswith() tuple elements must be strings");if(this.value.endsWith(r.value))return new A(!0)}return new A(!1)}throw new Error("endswith() argument must be a string or tuple of strings")})],["split",new te(e=>{let n=e[0]??new se;if(!(n instanceof k||n instanceof se))throw new Error("sep argument must be a string or null");let r=e[1]??new O(-1);if(!(r instanceof O))throw new Error("maxsplit argument must be a number");let t=[];if(n instanceof se){let a=this.value.trimStart();for(let{0:s,index:o}of a.matchAll(/\S+/g)){if(r.value!==-1&&t.length>=r.value&&o!==void 0){t.push(s+a.slice(o+s.length));break}t.push(s)}}else{if(n.value==="")throw new Error("empty separator");t=this.value.split(n.value),r.value!==-1&&t.length>r.value&&t.push(t.splice(r.value).join(n.value))}return new I(t.map(a=>new k(a)))})],["replace",new te(e=>{if(e.length<2)throw new Error("replace() requires at least two arguments");let n=e[0],r=e[1];if(!(n instanceof k&&r instanceof k))throw new Error("replace() arguments must be strings");let t;if(e.length>2?e[2].type==="KeywordArgumentsValue"?t=e[2].value.get("count")??new se:t=e[2]:t=new se,!(t instanceof O||t instanceof se))throw new Error("replace() count argument must be a number or null");return new k(ii(this.value,n.value,r.value,t.value))})]])}},A=class extends De{type="BooleanValue"},li=/[\x7f-\uffff]/g;ye=class extends De{type="ObjectValue";_builtins;__bool__(){return new A(this.value.size>0)}get builtins(){return this._builtins??=new Map([["get",new te(([e,n])=>{if(!(e instanceof k))throw new Error(`Object key must be a string: got ${e.type}`);return this.value.get(e.value)??n??new se})],["items",new te(()=>this.items())],["keys",new te(()=>this.keys())],["values",new te(()=>this.values())],["dictsort",new te(e=>{let n=new Map,r=e.filter(i=>i instanceof vn?(n=i.value,!1):!0),t=r.at(0)??n.get("case_sensitive")??new A(!1);if(!(t instanceof A))throw new Error("case_sensitive must be a boolean");let a=r.at(1)??n.get("by")??new k("key");if(!(a instanceof k))throw new Error("by must be a string");if(!["key","value"].includes(a.value))throw new Error("by must be either 'key' or 'value'");let s=r.at(2)??n.get("reverse")??new A(!1);if(!(s instanceof A))throw new Error("reverse must be a boolean");let o=Array.from(this.value.entries()).map(([i,u])=>new I([new k(i),u])).sort((i,u)=>{let l=a.value==="key"?0:1,c=i.value[l],d=u.value[l],p=Fr(c,d,t.value);return s.value?-p:p});return new I(o)})]])}items(){return new I(Array.from(this.value.entries()).map(([e,n])=>new I([new k(e),n])))}keys(){return new I(Array.from(this.value.keys()).map(e=>new k(e)))}values(){return new I(Array.from(this.value.values()))}toString(){return Ye(this,{},0,!1)}},vn=class extends ye{type="KeywordArgumentsValue"},I=class extends De{type="ArrayValue";_builtins;get builtins(){return this._builtins??=new Map([["length",new O(this.value.length)]])}__bool__(){return new A(this.value.length>0)}toString(){return Ye(this,{},0,!1)}},Qt=class extends I{type="TupleValue"},te=class extends De{type="FunctionValue"},se=class extends De{type="NullValue"},re=class extends De{type="UndefinedValue"},Zt=class{constructor(e){this.parent=e}variables=new Map([["namespace",new te(e=>{if(e.length===0)return new ye(new Map);if(e.length!==1||!(e[0]instanceof ye))throw new Error("`namespace` expects either zero arguments or a single object argument");return e[0]})]]);tests=Zt.TESTS;set(e,n){return this.declareVariable(e,jn(n))}declareVariable(e,n){if(this.variables.has(e))throw new SyntaxError(`Variable already declared: ${e}`);return this.variables.set(e,n),n}setVariable(e,n){return this.variables.set(e,n),n}resolve(e){if(this.variables.has(e))return this;if(this.parent)return this.parent.resolve(e);throw new Error(`Unknown variable: ${e}`)}lookupVariable(e){try{return this.resolve(e).variables.get(e)??new re}catch{return new re}}},Ie=Zt;Go(Ie,"TESTS",new Map([["boolean",e=>e.type==="BooleanValue"],["callable",e=>e instanceof te],["odd",e=>{if(!(e instanceof O))throw new Error(`cannot odd on ${e.type}`);return e.value%2!==0}],["even",e=>{if(!(e instanceof O))throw new Error(`cannot even on ${e.type}`);return e.value%2===0}],["false",e=>e.type==="BooleanValue"&&!e.value],["true",e=>e.type==="BooleanValue"&&e.value],["none",e=>e.type==="NullValue"],["string",e=>e.type==="StringValue"],["number",e=>e instanceof O||e instanceof ce],["integer",e=>e instanceof O],["iterable",e=>e.type==="ArrayValue"||e.type==="StringValue"],["mapping",e=>e instanceof ye],["sequence",e=>e instanceof I||e instanceof ye||e instanceof k],["lower",e=>{let n=e.value;return e.type==="StringValue"&&n===n.toLowerCase()}],["upper",e=>{let n=e.value;return e.type==="StringValue"&&n===n.toUpperCase()}],["none",e=>e.type==="NullValue"],["defined",e=>e.type!=="UndefinedValue"],["undefined",e=>e.type==="UndefinedValue"],["equalto",(e,n)=>e.value===n.value],["eq",(e,n)=>e.value===n.value]]));Mr=class{global;constructor(e){this.global=e??new Ie}run(e){return this.evaluate(e,this.global)}evaluateBinaryExpression(e,n){let r=this.evaluate(e.left,n);switch(e.operator.value){case"and":return r.__bool__().value?this.evaluate(e.right,n):r;case"or":return r.__bool__().value?r:this.evaluate(e.right,n)}let t=this.evaluate(e.right,n);switch(e.operator.value){case"==":return new A(r.value==t.value);case"!=":return new A(r.value!=t.value)}if(r instanceof re||t instanceof re){if(t instanceof re&&["in","not in"].includes(e.operator.value))return new A(e.operator.value==="not in");throw new Error(`Cannot perform operation ${e.operator.value} on undefined values`)}else{if(r instanceof se||t instanceof se)throw new Error("Cannot perform operation on null values");if(e.operator.value==="~")return new k(r.value.toString()+t.value.toString());if((r instanceof O||r instanceof ce)&&(t instanceof O||t instanceof ce)){let a=r.value,s=t.value;switch(e.operator.value){case"+":case"-":case"*":{let o=e.operator.value==="+"?a+s:e.operator.value==="-"?a-s:a*s;return r instanceof ce||t instanceof ce?new ce(o):new O(o)}case"/":return new ce(a/s);case"%":{let o=a%s;return r instanceof ce||t instanceof ce?new ce(o):new O(o)}case"<":return new A(a":return new A(a>s);case">=":return new A(a>=s);case"<=":return new A(a<=s)}}else if(r instanceof I&&t instanceof I){if(e.operator.value==="+")return new I(r.value.concat(t.value))}else if(t instanceof I){let a=t.value.find(s=>s.value===r.value)!==void 0;switch(e.operator.value){case"in":return new A(a);case"not in":return new A(!a)}}}if((r instanceof k||t instanceof k)&&e.operator.value==="+")return new k(r.value.toString()+t.value.toString());if(r instanceof k&&t instanceof k)switch(e.operator.value){case"in":return new A(t.value.includes(r.value));case"not in":return new A(!t.value.includes(r.value))}if(r instanceof k&&t instanceof ye)switch(e.operator.value){case"in":return new A(t.value.has(r.value));case"not in":return new A(!t.value.has(r.value))}throw new SyntaxError(`Unknown operator "${e.operator.value}" between ${r.type} and ${t.type}`)}evaluateArguments(e,n){let r=[],t=new Map;for(let a of e)if(a.type==="SpreadExpression"){let s=a,o=this.evaluate(s.argument,n);if(!(o instanceof I))throw new Error(`Cannot unpack non-iterable type: ${o.type}`);for(let i of o.value)r.push(i)}else if(a.type==="KeywordArgumentExpression"){let s=a;t.set(s.key.value,this.evaluate(s.value,n))}else{if(t.size>0)throw new Error("Positional arguments must come before keyword arguments");r.push(this.evaluate(a,n))}return[r,t]}applyFilter(e,n,r){if(n.type==="Identifier"){let t=n;if(t.value==="safe")return e;if(t.value==="tojson")return new k(Ye(e,{}));if(e instanceof I)switch(t.value){case"list":return e;case"first":return e.value[0];case"last":return e.value[e.value.length-1];case"length":return new O(e.value.length);case"reverse":return new I(e.value.slice().reverse());case"sort":return new I(e.value.slice().sort((a,s)=>Fr(a,s,!1)));case"join":return new k(e.value.map(a=>a.value).join(""));case"string":return new k(Ye(e,{},0,!1));case"unique":{let a=new Set,s=[];for(let o of e.value)a.has(o.value)||(a.add(o.value),s.push(o));return new I(s)}default:throw new Error(`Unknown ArrayValue filter: ${t.value}`)}else if(e instanceof k)switch(t.value){case"length":case"upper":case"lower":case"title":case"capitalize":{let a=e.builtins.get(t.value);if(a instanceof te)return a.value([],r);if(a instanceof O)return a;throw new Error(`Unknown StringValue filter: ${t.value}`)}case"trim":return new k(e.value.trim());case"indent":return new k(e.value.split(` `).map((a,s)=>s===0||a.length===0?a:" "+a).join(` -`));case"join":case"string":return e;case"int":{let a=parseInt(e.value,10);return new O(isNaN(a)?0:a)}case"float":{let a=parseFloat(e.value);return new ce(isNaN(a)?0:a)}default:throw new Error(`Unknown StringValue filter: ${r.value}`)}else if(e instanceof O||e instanceof ce)switch(r.value){case"abs":return e instanceof O?new O(Math.abs(e.value)):new ce(Math.abs(e.value));case"int":return new O(Math.floor(e.value));case"float":return new ce(e.value);case"string":return new x(e.toString());default:throw new Error(`Unknown NumericValue filter: ${r.value}`)}else if(e instanceof ye)switch(r.value){case"items":return new I(Array.from(e.value.entries()).map(([a,s])=>new I([new x(a),s])));case"length":return new O(e.value.size);default:{let a=e.builtins.get(r.value);if(a)return a instanceof re?a.value([],t):a;throw new Error(`Unknown ObjectValue filter: ${r.value}`)}}else if(e instanceof A)switch(r.value){case"bool":return new A(e.value);case"int":return new O(e.value?1:0);case"float":return new ce(e.value?1:0);case"string":return new x(e.value?"true":"false");default:throw new Error(`Unknown BooleanValue filter: ${r.value}`)}throw new Error(`Cannot apply filter "${r.value}" to type: ${e.type}`)}else if(n.type==="CallExpression"){let r=n;if(r.callee.type!=="Identifier")throw new Error(`Unknown filter: ${r.callee.type}`);let a=r.callee.value;if(a==="tojson"){let[,s]=this.evaluateArguments(r.args,t),o=s.get("indent")??new se;if(!(o instanceof O||o instanceof se))throw new Error("If set, indent must be a number");let i=s.get("ensure_ascii")??new A(!1);if(!(i instanceof A))throw new Error("If set, ensure_ascii must be a boolean");let u=s.get("sort_keys")??new A(!1);if(!(u instanceof A))throw new Error("If set, sort_keys must be a boolean");let l=s.get("separators")??new se,c=null;if(l instanceof I||l instanceof Qr){if(l.value.length!==2)throw new Error("separators must be a tuple of two strings");let[d,p]=l.value;if(!(d instanceof x)||!(p instanceof x))throw new Error("separators must be a tuple of two strings");c=[d.value,p.value]}else if(!(l instanceof se))throw new Error("If set, separators must be a tuple of two strings");return new x(Ye(e,{indent:o.value,ensureAscii:i.value,sortKeys:u.value,separators:c}))}else if(a==="join"){let s;if(e instanceof x)s=Array.from(e.value);else if(e instanceof I)s=e.value.map(l=>l.value);else throw new Error(`Cannot apply filter "${a}" to type: ${e.type}`);let[o,i]=this.evaluateArguments(r.args,t),u=o.at(0)??i.get("separator")??new x("");if(!(u instanceof x))throw new Error("separator must be a string");return new x(s.join(u.value))}else if(a==="int"||a==="float"){let[s,o]=this.evaluateArguments(r.args,t),i=s.at(0)??o.get("default")??(a==="int"?new O(0):new ce(0));if(e instanceof x){let u=a==="int"?parseInt(e.value,10):parseFloat(e.value);return isNaN(u)?i:a==="int"?new O(u):new ce(u)}else{if(e instanceof O||e instanceof ce)return e;if(e instanceof A)return a==="int"?new O(e.value?1:0):new ce(e.value?1:0);throw new Error(`Cannot apply filter "${a}" to type: ${e.type}`)}}else if(a==="default"){let[s,o]=this.evaluateArguments(r.args,t),i=s[0]??new x(""),u=s[1]??o.get("boolean")??new A(!1);if(!(u instanceof A))throw new Error("`default` filter flag must be a boolean");return e instanceof te||u.value&&!e.__bool__().value?i:e}if(e instanceof I){switch(a){case"sort":{let[s,o]=this.evaluateArguments(r.args,t),i=s.at(0)??o.get("reverse")??new A(!1);if(!(i instanceof A))throw new Error("reverse must be a boolean");let u=s.at(1)??o.get("case_sensitive")??new A(!1);if(!(u instanceof A))throw new Error("case_sensitive must be a boolean");let l=s.at(2)??o.get("attribute")??new se;if(!(l instanceof x||l instanceof O||l instanceof se))throw new Error("attribute must be a string, integer, or null");let c=d=>{if(l instanceof se)return d;let p=l instanceof O?String(l.value):l.value;return Xr(d,p)};return new I(e.value.slice().sort((d,p)=>{let f=c(d),m=c(p),_=Wt(f,m,u.value);return i.value?-_:_}))}case"selectattr":case"rejectattr":{let s=a==="selectattr";if(e.value.some(d=>!(d instanceof ye)))throw new Error(`\`${a}\` can only be applied to array of objects`);if(r.args.some(d=>d.type!=="StringLiteral"))throw new Error(`arguments of \`${a}\` must be strings`);let[o,i,u]=r.args.map(d=>this.evaluate(d,t)),l;if(i){let d=t.tests.get(i.value);if(!d)throw new Error(`Unknown test: ${i.value}`);l=d}else l=(...d)=>d[0].__bool__().value;let c=e.value.filter(d=>{let p=d.value.get(o.value),f=p?l(p,u):!1;return s?f:!f});return new I(c)}case"map":{let[,s]=this.evaluateArguments(r.args,t);if(s.has("attribute")){let o=s.get("attribute");if(!(o instanceof x))throw new Error("attribute must be a string");let i=s.get("default"),u=e.value.map(l=>{if(!(l instanceof ye))throw new Error("items in map must be an object");let c=Xr(l,o.value);return c instanceof te?i??new te:c});return new I(u)}else throw new Error("`map` expressions without `attribute` set are not currently supported.")}}throw new Error(`Unknown ArrayValue filter: ${a}`)}else if(e instanceof x){switch(a){case"indent":{let[s,o]=this.evaluateArguments(r.args,t),i=s.at(0)??o.get("width")??new O(4);if(!(i instanceof O))throw new Error("width must be a number");let u=s.at(1)??o.get("first")??new A(!1),l=s.at(2)??o.get("blank")??new A(!1),c=e.value.split(` -`),d=" ".repeat(i.value),p=c.map((f,m)=>!u.value&&m===0||!l.value&&f.length===0?f:d+f);return new x(p.join(` -`))}case"replace":{let s=e.builtins.get("replace");if(!(s instanceof re))throw new Error("replace filter not available");let[o,i]=this.evaluateArguments(r.args,t);return s.value([...o,new vn(i)],t)}}throw new Error(`Unknown StringValue filter: ${a}`)}else if(e instanceof ye){let s=e.builtins.get(a);if(s&&s instanceof re){let[o,i]=this.evaluateArguments(r.args,t);return i.size>0&&o.push(new vn(i)),s.value(o,t)}throw new Error(`Unknown ObjectValue filter: ${a}`)}else throw new Error(`Cannot apply filter "${a}" to type: ${e.type}`)}throw new Error(`Unknown filter: ${n.type}`)}evaluateFilterExpression(e,n){let t=this.evaluate(e.operand,n);return this.applyFilter(t,e.filter,n)}evaluateTestExpression(e,n){let t=this.evaluate(e.operand,n),r=n.tests.get(e.test.value);if(!r)throw new Error(`Unknown test: ${e.test.value}`);let a=r(t);return new A(e.negate?!a:a)}evaluateSelectExpression(e,n){return this.evaluate(e.test,n).__bool__().value?this.evaluate(e.lhs,n):new te}evaluateUnaryExpression(e,n){let t=this.evaluate(e.argument,n);if(e.operator.value==="not")return new A(!t.value);throw new SyntaxError(`Unknown operator: ${e.operator.value}`)}evaluateTernaryExpression(e,n){return this.evaluate(e.condition,n).__bool__().value?this.evaluate(e.trueExpr,n):this.evaluate(e.falseExpr,n)}evalProgram(e,n){return this.evaluateBlock(e.body,n)}evaluateBlock(e,n){let t="";for(let r of e){let a=this.evaluate(r,n);a.type!=="NullValue"&&a.type!=="UndefinedValue"&&(t+=a.toString())}return new x(t)}evaluateIdentifier(e,n){return n.lookupVariable(e.value)}evaluateCallExpression(e,n){let[t,r]=this.evaluateArguments(e.args,n);r.size>0&&t.push(new vn(r));let a=this.evaluate(e.callee,n);if(a.type!=="FunctionValue")throw new Error(`Cannot call something that is not a function: got ${a.type}`);return a.value(t,n)}evaluateSliceExpression(e,n,t){if(!(e instanceof I||e instanceof x))throw new Error("Slice object must be an array or string");let r=this.evaluate(n.start,t),a=this.evaluate(n.stop,t),s=this.evaluate(n.step,t);if(!(r instanceof O||r instanceof te))throw new Error("Slice start must be numeric or undefined");if(!(a instanceof O||a instanceof te))throw new Error("Slice stop must be numeric or undefined");if(!(s instanceof O||s instanceof te))throw new Error("Slice step must be numeric or undefined");return e instanceof I?new I($r(e.value,r.value,a.value,s.value)):new x($r(Array.from(e.value),r.value,a.value,s.value).join(""))}evaluateMemberExpression(e,n){let t=this.evaluate(e.object,n),r;if(e.computed){if(e.property.type==="SliceExpression")return this.evaluateSliceExpression(t,e.property,n);r=this.evaluate(e.property,n)}else e.property.type==="IntegerLiteral"?r=new O(e.property.value):r=new x(e.property.value);let a;if(t instanceof ye){if(!(r instanceof x))throw new Error(`Cannot access property with non-string: got ${r.type}`);a=t.value.get(r.value)??t.builtins.get(r.value)}else if(t instanceof I||t instanceof x)if(r instanceof O)a=t.value.at(r.value),t instanceof x&&(a=new x(t.value.at(r.value)));else if(r instanceof x)a=t.builtins.get(r.value);else throw new Error(`Cannot access property with non-string/non-number: got ${r.type}`);else{if(!(r instanceof x))throw new Error(`Cannot access property with non-string: got ${r.type}`);a=t.builtins.get(r.value)}return a instanceof Ue?a:new te}evaluateSet(e,n){let t=e.value?this.evaluate(e.value,n):this.evaluateBlock(e.body,n);if(e.assignee.type==="Identifier"){let r=e.assignee.value;n.setVariable(r,t)}else if(e.assignee.type==="TupleLiteral"){let r=e.assignee;if(!(t instanceof I))throw new Error(`Cannot unpack non-iterable type in set: ${t.type}`);let a=t.value;if(a.length!==r.value.length)throw new Error(`Too ${r.value.length>a.length?"few":"many"} items to unpack in set`);for(let s=0;sf.setVariable(e.loopvar.value,d);else if(e.loopvar.type==="TupleLiteral"){let f=e.loopvar;if(d.type!=="ArrayValue")throw new Error(`Cannot unpack non-iterable type: ${d.type}`);let m=d;if(f.value.length!==m.value.length)throw new Error(`Too ${f.value.length>m.value.length?"few":"many"} items to unpack`);p=_=>{for(let E=0;E0?s[l-1]:new te],["nextitem",l{let a=new Ie(r);t=t.slice();let s;t.at(-1)?.type==="KeywordArgumentsValue"&&(s=t.pop());for(let o=0;o{let l=new Ie(u);if(e.callerArgs)for(let c=0;cthis.evaluate(t,n)));case"TupleLiteral":return new Qr(e.value.map(t=>this.evaluate(t,n)));case"ObjectLiteral":{let t=new Map;for(let[r,a]of e.value){let s=this.evaluate(r,n);if(!(s instanceof x))throw new Error(`Object keys must be strings: got ${s.type}`);t.set(s.value,this.evaluate(a,n))}return new ye(t)}case"Identifier":return this.evaluateIdentifier(e,n);case"CallExpression":return this.evaluateCallExpression(e,n);case"MemberExpression":return this.evaluateMemberExpression(e,n);case"UnaryExpression":return this.evaluateUnaryExpression(e,n);case"BinaryExpression":return this.evaluateBinaryExpression(e,n);case"FilterExpression":return this.evaluateFilterExpression(e,n);case"FilterStatement":return this.evaluateFilterStatement(e,n);case"TestExpression":return this.evaluateTestExpression(e,n);case"SelectExpression":return this.evaluateSelectExpression(e,n);case"Ternary":return this.evaluateTernaryExpression(e,n);case"Comment":return new se;default:throw new SyntaxError(`Unknown node type: ${e.type}`)}}};ge=` -`,di="{%- ",pi=" -%}";Hn=class{parsed;constructor(e){let n=$n(e,{lstrip_blocks:!0,trim_blocks:!0});this.parsed=Kn(n)}render(e){let n=new Ie;if(ci(n),e)for(let[a,s]of Object.entries(e))n.set(a,s);return new Mt(n).run(this.parsed).value}format(e){return mi(this.parsed,e?.indent||" ")}}});function ze(e=null){if(e!==null&&typeof e=="object"&&ma.has(e))return e;let n=Lt(e)?e:{},t=Lt(n.adapterInfo)?n.adapterInfo:{},r=Lt(n.limits)?n.limits:{},a={adapterInfo:Bl(t),features:Yn(n.features),wgslLanguageFeatures:Jn(n.wgslLanguageFeatures),limits:et(r)};return ma.add(a),a}function ga(e){let n=new Set(e),t={size:n.size,has(r){return n.has(r)},entries(){return n.entries()},forEach(r,a){n.forEach(s=>r.call(a,s,s,t))},keys(){return n.keys()},values(){return n.values()},[Symbol.iterator](){return n[Symbol.iterator]()}};return t}function Yn(e=[]){return ga(ya(e))}function Jn(e=[]){return ga(ya(e))}function kn(e=null){let n=ze(e);return{adapterInfo:{...n.adapterInfo},features:Array.from(n.features.values()).sort(),wgslLanguageFeatures:Array.from(n.wgslLanguageFeatures.values()).sort(),limits:{...n.limits}}}function Ct(e,n){if(!e)return null;for(let t of e.requiredFeatures??[])if(!n.features.has(t))return`requires device.features.has("${t}")`;for(let t of e.requiredWGSLLanguageFeatures??[])if(!n.wgslLanguageFeatures.has(t))return`requires device.wgslLanguageFeatures.has("${t}")`;for(let[t,r]of Object.entries(e.requiredLimits??{})){if(r===void 0)continue;let a=n.limits[t];if(typeof a!="number"||a= ${r}`}if(e.requiredSubgroupMinSize!==void 0){let t=n.adapterInfo.subgroupMinSize;if(typeof t!="number")return`requires adapterInfo.subgroupMinSize >= ${e.requiredSubgroupMinSize} (adapter does not report subgroup sizes)`;if(t= ${e.requiredSubgroupMinSize}`}return null}function ha(e){let n=e.adapterInfo;return{vendor:typeof n.vendor=="string"?n.vendor.toLowerCase():"",architecture:typeof n.architecture=="string"?n.architecture.toLowerCase():"",...typeof n.subgroupMinSize=="number"?{subgroupMinSize:n.subgroupMinSize}:{},...typeof n.subgroupMaxSize=="number"?{subgroupMaxSize:n.subgroupMaxSize}:{},isFallbackAdapter:n.isFallbackAdapter===!0}}function Bl(e){return{...Fl,...e}}function et(e){let n={...Ml};for(let t of Wl){let r=ql(e,t);r!==void 0&&(n[t]=r)}for(let[t,r]of Object.entries(e))typeof r=="number"&&Number.isFinite(r)&&(n[t]=r);return n}function ya(e){return e==null?[]:Array.isArray(e)?e.filter(Dt):typeof e[Symbol.iterator]=="function"?Array.from(e).filter(Dt):typeof e.values=="function"?Array.from(e.values()).filter(Dt):[]}function ql(e,n){let t=e[n];return typeof t=="number"&&Number.isFinite(t)?t:void 0}function Dt(e){return typeof e=="string"}function Lt(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}var Fl,Wl,Ml,ma,xn=he(()=>{"use strict";Fl=Object.freeze({vendor:"",architecture:"",device:"",description:""}),Wl=Object.freeze(["maxTextureDimension1D","maxTextureDimension2D","maxTextureDimension3D","maxTextureArrayLayers","maxBindGroups","maxBindGroupsPlusVertexBuffers","maxBindingsPerBindGroup","maxDynamicUniformBuffersPerPipelineLayout","maxDynamicStorageBuffersPerPipelineLayout","maxSampledTexturesPerShaderStage","maxSamplersPerShaderStage","maxStorageBuffersPerShaderStage","maxStorageTexturesPerShaderStage","maxUniformBuffersPerShaderStage","maxUniformBufferBindingSize","maxStorageBufferBindingSize","minUniformBufferOffsetAlignment","minStorageBufferOffsetAlignment","maxVertexBuffers","maxBufferSize","maxVertexAttributes","maxVertexBufferArrayStride","maxInterStageShaderVariables","maxColorAttachments","maxColorAttachmentBytesPerSample","maxComputeWorkgroupStorageSize","maxComputeInvocationsPerWorkgroup","maxComputeWorkgroupSizeX","maxComputeWorkgroupSizeY","maxComputeWorkgroupSizeZ","maxComputeWorkgroupsPerDimension","maxImmediateSize","maxStorageBuffersInVertexStage","maxStorageBuffersInFragmentStage","maxStorageTexturesInVertexStage","maxStorageTexturesInFragmentStage"]),Ml=Object.freeze({maxTextureDimension1D:8192,maxTextureDimension2D:8192,maxTextureDimension3D:2048,maxTextureArrayLayers:256,maxBindGroups:4,maxBindGroupsPlusVertexBuffers:24,maxBindingsPerBindGroup:1e3,maxDynamicUniformBuffersPerPipelineLayout:8,maxDynamicStorageBuffersPerPipelineLayout:4,maxSampledTexturesPerShaderStage:16,maxSamplersPerShaderStage:16,maxStorageBuffersPerShaderStage:8,maxStorageTexturesPerShaderStage:4,maxUniformBuffersPerShaderStage:12,maxUniformBufferBindingSize:64*1024,maxStorageBufferBindingSize:128*1024*1024,minUniformBufferOffsetAlignment:256,minStorageBufferOffsetAlignment:256,maxVertexBuffers:8,maxBufferSize:256*1024*1024,maxVertexAttributes:16,maxVertexBufferArrayStride:2048,maxInterStageShaderVariables:16,maxColorAttachments:8,maxColorAttachmentBytesPerSample:32,maxComputeInvocationsPerWorkgroup:256,maxComputeWorkgroupSizeX:256,maxComputeWorkgroupSizeY:256,maxComputeWorkgroupSizeZ:64,maxComputeWorkgroupStorageSize:16*1024,maxComputeWorkgroupsPerDimension:65535,maxImmediateSize:64}),ma=new WeakSet});function ba(e){return Object.fromEntries(Object.entries(e).filter(([,n])=>n!==void 0))}var wa=he(()=>{"use strict"});function va(e){if(e==="u32"||e==="i32"||e==="f32")return{align:4,size:4,scalar:e,components:1};let n=Il.exec(e);if(!n)throw new Error(`Unsupported uniform field type: ${e}`);let t=Number(n[1]);return{align:t===2?8:16,size:t===3?12:t*4,scalar:n[2],components:t}}function Ul(e){return e==="u32"||e==="i32"||e==="f32"}function _a(e,n){return Math.ceil(e/n)*n}function Nt(e,n={}){return En(e,"u32",n)}function zt(e,n={}){return En(e,"i32",n)}function jt(e,n={}){return En(e,"f32",n)}function En(e,n,t={}){return xa(e,"uniform field"),va(n),Object.freeze({kind:"uniform-field",name:e,type:n,semantic:t.semantic,required:t.required??!t.internal,internal:!!t.internal,default:t.default,description:t.description})}function Pn(e,n,t={}){if(xa(e,"uniform struct"),!Array.isArray(n)||n.length===0)throw new Error(`uniform struct ${e} requires at least one field`);let r=n.map(a=>Cl(a,e));return Object.freeze({kind:"uniform-struct",name:e,fields:Object.freeze(Nl(r,t))})}function $t(e){Kt(e);let n=e.fields.map(t=>`${t.name}: ${t.type}`).join(", ");return`struct ${e.name} { ${n} };`}function Ta(e,n={}){if(Kt(e),!e.fields.every(i=>Ul(i.type)))return Dl(e,n);let t=Math.max(16,Math.ceil(e.fields.length*4/16)*16),r=new ArrayBuffer(t),a=new Uint32Array(r),s=new Int32Array(r),o=new Float32Array(r);return e.fields.forEach((i,u)=>{let l=n[i.name];if(l===void 0&&i.required)throw new Error(`Missing uniform field ${e.name}.${i.name}`);if(l===void 0&&(l=i.default??0),typeof l!="number")throw new Error(`Uniform ${e.name}.${i.name} expects a scalar number`);zl({field:i,index:u,value:l,u32View:a,i32View:s,f32View:o})}),new Uint32Array(r)}function Dl(e,n){let t=[],r=0;for(let u of e.fields){let l=va(u.type);r=_a(r,l.align),t.push({field:u,layout:l,offset:r}),r+=l.size}let a=new ArrayBuffer(Math.max(16,_a(r,16))),s=new Uint32Array(a),o=new Int32Array(a),i=new Float32Array(a);for(let{field:u,layout:l,offset:c}of t){let d=n[u.name];if(d===void 0&&u.required)throw new Error(`Missing uniform field ${e.name}.${u.name}`);d===void 0&&(d=u.default??(l.components===1?0:new Array(l.components).fill(0)));let p=typeof d=="number"?[d]:d;if(p.length!==l.components)throw new Error(`Uniform ${e.name}.${u.name} expects ${l.components} component(s), got ${p.length}`);for(let f=0;f4294967295)throw new Error(`Uniform ${r} must be an integer u32 in [0, 4294967295]`);a[n]=t;return}if(e==="i32"){if(!Number.isInteger(t)||t<-2147483648||t>2147483647)throw new Error(`Uniform ${r} must be an integer i32 in [-2147483648, 2147483647]`);s[n]=t;return}if(!Number.isFinite(t))throw new Error(`Uniform ${r} must be a finite f32`);o[n]=t}function Sa(e,n,t,r){return e.createUniformU32(Ta(n,t),r)}function ka(e){return Kt(e),{kind:e.kind,name:e.name,fields:e.fields.map(n=>ba({name:n.name,type:n.type,required:n.required,internal:n.internal,semantic:n.semantic,default:n.default,description:n.description}))}}function Cl(e,n){if(!e||e.kind!=="uniform-field")throw new Error(`uniform struct ${n} fields must be created with u32(), i32(), or f32()`);return e}function Nl(e,n){let t=n.alignFieldsTo??4;if(!Number.isInteger(t)||t<=0)throw new Error(`alignFieldsTo must be a positive integer, got ${t}`);let r=[...e],a=r.length%t;if(a===0)return Object.freeze(r);let s=t-a,o=0,i=new Set(r.map(u=>u.name));for(let u=0;u4294967295)throw new Error(`Uniform ${e.name} must be an integer u32 in [0, 4294967295]`);r[n]=t;return}if(e.type==="i32"){if(!Number.isInteger(t)||t<-2147483648||t>2147483647)throw new Error(`Uniform ${e.name} must be an integer i32 in [-2147483648, 2147483647]`);a[n]=t;return}if(e.type==="f32"){if(!Number.isFinite(t))throw new Error(`Uniform ${e.name} must be a finite f32`);s[n]=t;return}throw new Error(`Unsupported uniform field type: ${e.type}`)}function Kt(e){if(!e||e.kind!=="uniform-struct")throw new Error("Expected a uniform struct schema")}function xa(e,n){if(typeof e!="string"||!/^[A-Za-z_][A-Za-z0-9_]*$/.test(e))throw new Error(`${n} name must be a WGSL-compatible identifier, got ${e}`)}var Il,nt=he(()=>{"use strict";wa();Il=/^vec([234])<(u32|i32|f32)>$/});function Ht(e,n={}){Ga(e,"storage binding"),Oa(e,n.required);let t=n.access??"read";if(!(t in Ea))throw new Error(`storage binding ${e} has unsupported access ${t}`);return Object.freeze({kind:"storage",name:e,arg:n.arg,access:t,elementType:n.elementType??"f32",semantic:n.semantic,role:n.role,layout:n.layout,binding:n.binding,group:n.group})}function Vt(e,n,t={}){Ga(e,"uniform binding"),Oa(e,t.required);let r;if(Vl(n)?r=Pn(t.structName??Kl(e),n):r=n,!r||r.kind!=="uniform-struct")throw new Error(`uniform binding ${e} requires a uniformStruct schema or field array`);return Object.freeze({kind:"uniform",name:e,struct:r,semantic:t.semantic,binding:t.binding,group:t.group})}function un(e){if(!Array.isArray(e)||e.length===0)throw new Error("bindGroup requires at least one binding");let n=new Set,t=new Set;return Object.freeze(e.map((r,a)=>{if(!r||r.kind!=="storage"&&r.kind!=="uniform")throw new Error("bindGroup entries must be storage() or uniform() bindings");if(n.has(r.name))throw new Error(`duplicate bindGroup binding name: ${r.name}`);n.add(r.name);let s=r.binding??a;if(!Number.isInteger(s)||s<0)throw new Error(`binding ${r.name} has invalid binding index ${s}`);let o=r.group??0;if(!Number.isInteger(o)||o<0)throw new Error(`binding ${r.name} has invalid bind group index ${o}`);let i=`${o}:${s}`;if(t.has(i))throw new Error(`duplicate bindGroup binding index ${s} in @group(${o})`);return t.add(i),Object.freeze({...r,binding:s})}))}function Qt(e,n={}){return un(e).map(t=>jl(t,n)).join(` -`)}function Pa(e){let n=[],t=new Map;for(let r of un(e)){if(r.kind!=="uniform")continue;let a=JSON.stringify(ka(r.struct)),s=t.get(r.struct.name);if(s!==void 0){if(s!==a)throw new Error(`uniform struct ${r.struct.name} is declared with conflicting schemas`);continue}t.set(r.struct.name,a),n.push($t(r.struct))}return n.join(` -`)}function Aa(e,n,t,r={}){let a=un(n),s=r.labelPrefix??"kernel",o=[];return{bindings:a.map(u=>{let l=t?.[u.name];if(l==null)throw new Error(`Missing resource for binding ${u.name}`);if(u.kind==="uniform"){let f;return Xt(l)?f=l:(f=Sa(e,u.struct,l,`${s}-${u.name}`),typeof f.destroy=="function"&&o.push(()=>f.destroy?.())),{buffer:f,type:"uniform",binding:u.binding,...u.group?{group:u.group}:{}}}let c=l,d=typeof c.byteOffset=="number"?c.byteOffset:0,p=typeof c.byteLength=="number"?Hl(c.byteLength):void 0;return{tensor:l,type:Ea[u.access],binding:u.binding,...u.group?{group:u.group}:{},...d?{offset:d}:{},...p!==void 0?{size:p}:{}}}),cleanup:()=>{for(let u of o)u()}}}function jl(e,n){let t=e.group??0;if(e.kind==="storage"){let r=e.access==="read_write"?"read_write":"read",a=$l(e.elementType,n,`binding ${e.name} elementType`);return`@group(${t}) @binding(${e.binding}) var ${e.name}: array<${a}>;`}return`@group(${t}) @binding(${e.binding}) var ${e.name}: ${e.struct.name};`}function $l(e,n,t){if(typeof e!="string"||!e.startsWith("$"))return e;let r=e.slice(1),a=n[r];if(a==null)throw new Error(`Missing template value ${r} for ${t}`);return a}function Xt(e){return e!==null&&typeof e=="object"&&typeof e.destroy=="function"&&!("shape"in e)}function Kl(e){return e.length===0?e:e[0].toUpperCase()+e.slice(1)}function Ga(e,n){if(typeof e!="string"||!/^[A-Za-z_][A-Za-z0-9_]*$/.test(e))throw new Error(`${n} name must be a WGSL-compatible identifier, got ${e}`)}function Oa(e,n){if(n===!1)throw new Error(`binding ${e} cannot be optional; use separate variants for different resource layouts`)}function Hl(e){return Math.max(4,Math.ceil(e/4)*4)}function Vl(e){return Array.isArray(e)}var Ea,An=he(()=>{"use strict";nt();Ea=Object.freeze({read:"read-only-storage",read_write:"storage"})});function Gn(e){return e==null?e:Array.isArray(e)?e.map(Gn):e instanceof Map?Object.fromEntries([...e].map(([n,t])=>[n,Gn(t)])):typeof e=="object"&&"value"in e?e.type==="NullValue"?null:Gn(e.value):e}function de(e){return((...n)=>e(...n.map(Gn)))}function Zt(e){if(e==="float32"||e==="f32")return"f32";if(e==="float16"||e==="f16")return"f16";if(e==="uint32"||e==="u32"||e==="uint8")return"u32";if(e==="int32"||e==="i32"||e==="int8")return"i32";throw new Error(`Unsupported WebGPU dtype: ${e}`)}function On(e){return e==="f32"?"float32":e==="f16"?"float16":e==="u32"?"uint32":e==="i32"?"int32":e}function qa(e={}){let n=e,t=Yt(e.device),r=t.features.has("shader-f16");return{...Ba,f16Ok:de(a=>a!=="f16"&&a!=="float16"||r),f16Allowed:de(a=>a==="f32"||a==="float32"||(a==="f16"||a==="float16")&&r),op:e.op,variant:e.variant,pass:e.pass,device:t,attrs:e.attrs??{},args:e.args??{},source:e.sourceContext??{},present:e.present??{},shapes:e.shapes??{},ranks:e.ranks??{},tensorDtypes:e.tensorDtypes??{},dtypes:e.dtypes??{},...e.derived??{},tunables:e.tunables??{},constants:e.constants??{},...e.constants??{},...n.env!==void 0?{env:n.env}:{}}}function Yt(e){let n=ze(e),t=Fa.get(n);return t===void 0&&(t={features:n.features,wgslLanguageFeatures:n.wgslLanguageFeatures,limits:n.limits,adapterInfo:ha(n)},Fa.set(n,t)),t}function Le(e,n={}){if(typeof e!="string")return e;let t=qa(n),r=nc(e),a=r.freeIdentifiers.filter(o=>!(o in t));if(a.length>0)throw new Error(`Unknown identifier${a.length===1?"":"s"} ${a.map(o=>`"${o}"`).join(", ")} in WebGPU expression: ${e} +`));case"join":case"string":return e;case"int":{let a=parseInt(e.value,10);return new O(isNaN(a)?0:a)}case"float":{let a=parseFloat(e.value);return new ce(isNaN(a)?0:a)}default:throw new Error(`Unknown StringValue filter: ${t.value}`)}else if(e instanceof O||e instanceof ce)switch(t.value){case"abs":return e instanceof O?new O(Math.abs(e.value)):new ce(Math.abs(e.value));case"int":return new O(Math.floor(e.value));case"float":return new ce(e.value);case"string":return new k(e.toString());default:throw new Error(`Unknown NumericValue filter: ${t.value}`)}else if(e instanceof ye)switch(t.value){case"items":return new I(Array.from(e.value.entries()).map(([a,s])=>new I([new k(a),s])));case"length":return new O(e.value.size);default:{let a=e.builtins.get(t.value);if(a)return a instanceof te?a.value([],r):a;throw new Error(`Unknown ObjectValue filter: ${t.value}`)}}else if(e instanceof A)switch(t.value){case"bool":return new A(e.value);case"int":return new O(e.value?1:0);case"float":return new ce(e.value?1:0);case"string":return new k(e.value?"true":"false");default:throw new Error(`Unknown BooleanValue filter: ${t.value}`)}throw new Error(`Cannot apply filter "${t.value}" to type: ${e.type}`)}else if(n.type==="CallExpression"){let t=n;if(t.callee.type!=="Identifier")throw new Error(`Unknown filter: ${t.callee.type}`);let a=t.callee.value;if(a==="tojson"){let[,s]=this.evaluateArguments(t.args,r),o=s.get("indent")??new se;if(!(o instanceof O||o instanceof se))throw new Error("If set, indent must be a number");let i=s.get("ensure_ascii")??new A(!1);if(!(i instanceof A))throw new Error("If set, ensure_ascii must be a boolean");let u=s.get("sort_keys")??new A(!1);if(!(u instanceof A))throw new Error("If set, sort_keys must be a boolean");let l=s.get("separators")??new se,c=null;if(l instanceof I||l instanceof Qt){if(l.value.length!==2)throw new Error("separators must be a tuple of two strings");let[d,p]=l.value;if(!(d instanceof k)||!(p instanceof k))throw new Error("separators must be a tuple of two strings");c=[d.value,p.value]}else if(!(l instanceof se))throw new Error("If set, separators must be a tuple of two strings");return new k(Ye(e,{indent:o.value,ensureAscii:i.value,sortKeys:u.value,separators:c}))}else if(a==="join"){let s;if(e instanceof k)s=Array.from(e.value);else if(e instanceof I)s=e.value.map(l=>l.value);else throw new Error(`Cannot apply filter "${a}" to type: ${e.type}`);let[o,i]=this.evaluateArguments(t.args,r),u=o.at(0)??i.get("separator")??new k("");if(!(u instanceof k))throw new Error("separator must be a string");return new k(s.join(u.value))}else if(a==="int"||a==="float"){let[s,o]=this.evaluateArguments(t.args,r),i=s.at(0)??o.get("default")??(a==="int"?new O(0):new ce(0));if(e instanceof k){let u=a==="int"?parseInt(e.value,10):parseFloat(e.value);return isNaN(u)?i:a==="int"?new O(u):new ce(u)}else{if(e instanceof O||e instanceof ce)return e;if(e instanceof A)return a==="int"?new O(e.value?1:0):new ce(e.value?1:0);throw new Error(`Cannot apply filter "${a}" to type: ${e.type}`)}}else if(a==="default"){let[s,o]=this.evaluateArguments(t.args,r),i=s[0]??new k(""),u=s[1]??o.get("boolean")??new A(!1);if(!(u instanceof A))throw new Error("`default` filter flag must be a boolean");return e instanceof re||u.value&&!e.__bool__().value?i:e}if(e instanceof I){switch(a){case"sort":{let[s,o]=this.evaluateArguments(t.args,r),i=s.at(0)??o.get("reverse")??new A(!1);if(!(i instanceof A))throw new Error("reverse must be a boolean");let u=s.at(1)??o.get("case_sensitive")??new A(!1);if(!(u instanceof A))throw new Error("case_sensitive must be a boolean");let l=s.at(2)??o.get("attribute")??new se;if(!(l instanceof k||l instanceof O||l instanceof se))throw new Error("attribute must be a string, integer, or null");let c=d=>{if(l instanceof se)return d;let p=l instanceof O?String(l.value):l.value;return Xt(d,p)};return new I(e.value.slice().sort((d,p)=>{let f=c(d),m=c(p),_=Fr(f,m,u.value);return i.value?-_:_}))}case"selectattr":case"rejectattr":{let s=a==="selectattr";if(e.value.some(d=>!(d instanceof ye)))throw new Error(`\`${a}\` can only be applied to array of objects`);if(t.args.some(d=>d.type!=="StringLiteral"))throw new Error(`arguments of \`${a}\` must be strings`);let[o,i,u]=t.args.map(d=>this.evaluate(d,r)),l;if(i){let d=r.tests.get(i.value);if(!d)throw new Error(`Unknown test: ${i.value}`);l=d}else l=(...d)=>d[0].__bool__().value;let c=e.value.filter(d=>{let p=d.value.get(o.value),f=p?l(p,u):!1;return s?f:!f});return new I(c)}case"map":{let[,s]=this.evaluateArguments(t.args,r);if(s.has("attribute")){let o=s.get("attribute");if(!(o instanceof k))throw new Error("attribute must be a string");let i=s.get("default"),u=e.value.map(l=>{if(!(l instanceof ye))throw new Error("items in map must be an object");let c=Xt(l,o.value);return c instanceof re?i??new re:c});return new I(u)}else throw new Error("`map` expressions without `attribute` set are not currently supported.")}}throw new Error(`Unknown ArrayValue filter: ${a}`)}else if(e instanceof k){switch(a){case"indent":{let[s,o]=this.evaluateArguments(t.args,r),i=s.at(0)??o.get("width")??new O(4);if(!(i instanceof O))throw new Error("width must be a number");let u=s.at(1)??o.get("first")??new A(!1),l=s.at(2)??o.get("blank")??new A(!1),c=e.value.split(` +`),d=" ".repeat(i.value),p=c.map((f,m)=>!u.value&&m===0||!l.value&&f.length===0?f:d+f);return new k(p.join(` +`))}case"replace":{let s=e.builtins.get("replace");if(!(s instanceof te))throw new Error("replace filter not available");let[o,i]=this.evaluateArguments(t.args,r);return s.value([...o,new vn(i)],r)}}throw new Error(`Unknown StringValue filter: ${a}`)}else if(e instanceof ye){let s=e.builtins.get(a);if(s&&s instanceof te){let[o,i]=this.evaluateArguments(t.args,r);return i.size>0&&o.push(new vn(i)),s.value(o,r)}throw new Error(`Unknown ObjectValue filter: ${a}`)}else throw new Error(`Cannot apply filter "${a}" to type: ${e.type}`)}throw new Error(`Unknown filter: ${n.type}`)}evaluateFilterExpression(e,n){let r=this.evaluate(e.operand,n);return this.applyFilter(r,e.filter,n)}evaluateTestExpression(e,n){let r=this.evaluate(e.operand,n),t=n.tests.get(e.test.value);if(!t)throw new Error(`Unknown test: ${e.test.value}`);let a=t(r);return new A(e.negate?!a:a)}evaluateSelectExpression(e,n){return this.evaluate(e.test,n).__bool__().value?this.evaluate(e.lhs,n):new re}evaluateUnaryExpression(e,n){let r=this.evaluate(e.argument,n);if(e.operator.value==="not")return new A(!r.value);throw new SyntaxError(`Unknown operator: ${e.operator.value}`)}evaluateTernaryExpression(e,n){return this.evaluate(e.condition,n).__bool__().value?this.evaluate(e.trueExpr,n):this.evaluate(e.falseExpr,n)}evalProgram(e,n){return this.evaluateBlock(e.body,n)}evaluateBlock(e,n){let r="";for(let t of e){let a=this.evaluate(t,n);a.type!=="NullValue"&&a.type!=="UndefinedValue"&&(r+=a.toString())}return new k(r)}evaluateIdentifier(e,n){return n.lookupVariable(e.value)}evaluateCallExpression(e,n){let[r,t]=this.evaluateArguments(e.args,n);t.size>0&&r.push(new vn(t));let a=this.evaluate(e.callee,n);if(a.type!=="FunctionValue")throw new Error(`Cannot call something that is not a function: got ${a.type}`);return a.value(r,n)}evaluateSliceExpression(e,n,r){if(!(e instanceof I||e instanceof k))throw new Error("Slice object must be an array or string");let t=this.evaluate(n.start,r),a=this.evaluate(n.stop,r),s=this.evaluate(n.step,r);if(!(t instanceof O||t instanceof re))throw new Error("Slice start must be numeric or undefined");if(!(a instanceof O||a instanceof re))throw new Error("Slice stop must be numeric or undefined");if(!(s instanceof O||s instanceof re))throw new Error("Slice step must be numeric or undefined");return e instanceof I?new I($t(e.value,t.value,a.value,s.value)):new k($t(Array.from(e.value),t.value,a.value,s.value).join(""))}evaluateMemberExpression(e,n){let r=this.evaluate(e.object,n),t;if(e.computed){if(e.property.type==="SliceExpression")return this.evaluateSliceExpression(r,e.property,n);t=this.evaluate(e.property,n)}else e.property.type==="IntegerLiteral"?t=new O(e.property.value):t=new k(e.property.value);let a;if(r instanceof ye){if(!(t instanceof k))throw new Error(`Cannot access property with non-string: got ${t.type}`);a=r.value.get(t.value)??r.builtins.get(t.value)}else if(r instanceof I||r instanceof k)if(t instanceof O)a=r.value.at(t.value),r instanceof k&&(a=new k(r.value.at(t.value)));else if(t instanceof k)a=r.builtins.get(t.value);else throw new Error(`Cannot access property with non-string/non-number: got ${t.type}`);else{if(!(t instanceof k))throw new Error(`Cannot access property with non-string: got ${t.type}`);a=r.builtins.get(t.value)}return a instanceof De?a:new re}evaluateSet(e,n){let r=e.value?this.evaluate(e.value,n):this.evaluateBlock(e.body,n);if(e.assignee.type==="Identifier"){let t=e.assignee.value;n.setVariable(t,r)}else if(e.assignee.type==="TupleLiteral"){let t=e.assignee;if(!(r instanceof I))throw new Error(`Cannot unpack non-iterable type in set: ${r.type}`);let a=r.value;if(a.length!==t.value.length)throw new Error(`Too ${t.value.length>a.length?"few":"many"} items to unpack in set`);for(let s=0;sf.setVariable(e.loopvar.value,d);else if(e.loopvar.type==="TupleLiteral"){let f=e.loopvar;if(d.type!=="ArrayValue")throw new Error(`Cannot unpack non-iterable type: ${d.type}`);let m=d;if(f.value.length!==m.value.length)throw new Error(`Too ${f.value.length>m.value.length?"few":"many"} items to unpack`);p=_=>{for(let E=0;E0?s[l-1]:new re],["nextitem",l{let a=new Ie(t);r=r.slice();let s;r.at(-1)?.type==="KeywordArgumentsValue"&&(s=r.pop());for(let o=0;o{let l=new Ie(u);if(e.callerArgs)for(let c=0;cthis.evaluate(r,n)));case"TupleLiteral":return new Qt(e.value.map(r=>this.evaluate(r,n)));case"ObjectLiteral":{let r=new Map;for(let[t,a]of e.value){let s=this.evaluate(t,n);if(!(s instanceof k))throw new Error(`Object keys must be strings: got ${s.type}`);r.set(s.value,this.evaluate(a,n))}return new ye(r)}case"Identifier":return this.evaluateIdentifier(e,n);case"CallExpression":return this.evaluateCallExpression(e,n);case"MemberExpression":return this.evaluateMemberExpression(e,n);case"UnaryExpression":return this.evaluateUnaryExpression(e,n);case"BinaryExpression":return this.evaluateBinaryExpression(e,n);case"FilterExpression":return this.evaluateFilterExpression(e,n);case"FilterStatement":return this.evaluateFilterStatement(e,n);case"TestExpression":return this.evaluateTestExpression(e,n);case"SelectExpression":return this.evaluateSelectExpression(e,n);case"Ternary":return this.evaluateTernaryExpression(e,n);case"Comment":return new se;default:throw new SyntaxError(`Unknown node type: ${e.type}`)}}};ge=` +`,di="{%- ",pi=" -%}";Hn=class{parsed;constructor(e){let n=$n(e,{lstrip_blocks:!0,trim_blocks:!0});this.parsed=Kn(n)}render(e){let n=new Ie;if(ci(n),e)for(let[a,s]of Object.entries(e))n.set(a,s);return new Mr(n).run(this.parsed).value}format(e){return mi(this.parsed,e?.indent||" ")}}});function ze(e=null){if(e!==null&&typeof e=="object"&&ma.has(e))return e;let n=Lr(e)?e:{},r=Lr(n.adapterInfo)?n.adapterInfo:{},t=Lr(n.limits)?n.limits:{},a={adapterInfo:Bl(r),features:Yn(n.features),wgslLanguageFeatures:Jn(n.wgslLanguageFeatures),limits:er(t)};return ma.add(a),a}function ga(e){let n=new Set(e),r={size:n.size,has(t){return n.has(t)},entries(){return n.entries()},forEach(t,a){n.forEach(s=>t.call(a,s,s,r))},keys(){return n.keys()},values(){return n.values()},[Symbol.iterator](){return n[Symbol.iterator]()}};return r}function Yn(e=[]){return ga(ya(e))}function Jn(e=[]){return ga(ya(e))}function xn(e=null){let n=ze(e);return{adapterInfo:{...n.adapterInfo},features:Array.from(n.features.values()).sort(),wgslLanguageFeatures:Array.from(n.wgslLanguageFeatures.values()).sort(),limits:{...n.limits}}}function Cr(e,n){if(!e)return null;for(let r of e.requiredFeatures??[])if(!n.features.has(r))return`requires device.features.has("${r}")`;for(let r of e.requiredWGSLLanguageFeatures??[])if(!n.wgslLanguageFeatures.has(r))return`requires device.wgslLanguageFeatures.has("${r}")`;for(let[r,t]of Object.entries(e.requiredLimits??{})){if(t===void 0)continue;let a=n.limits[r];if(typeof a!="number"||a= ${t}`}if(e.requiredSubgroupMinSize!==void 0){let r=n.adapterInfo.subgroupMinSize;if(typeof r!="number")return`requires adapterInfo.subgroupMinSize >= ${e.requiredSubgroupMinSize} (adapter does not report subgroup sizes)`;if(r= ${e.requiredSubgroupMinSize}`}return null}function ha(e){let n=e.adapterInfo;return{vendor:typeof n.vendor=="string"?n.vendor.toLowerCase():"",architecture:typeof n.architecture=="string"?n.architecture.toLowerCase():"",...typeof n.subgroupMinSize=="number"?{subgroupMinSize:n.subgroupMinSize}:{},...typeof n.subgroupMaxSize=="number"?{subgroupMaxSize:n.subgroupMaxSize}:{},isFallbackAdapter:n.isFallbackAdapter===!0}}function Bl(e){return{...Wl,...e}}function er(e){let n={...Ml};for(let r of Fl){let t=ql(e,r);t!==void 0&&(n[r]=t)}for(let[r,t]of Object.entries(e))typeof t=="number"&&Number.isFinite(t)&&(n[r]=t);return n}function ya(e){return e==null?[]:Array.isArray(e)?e.filter(Ur):typeof e[Symbol.iterator]=="function"?Array.from(e).filter(Ur):typeof e.values=="function"?Array.from(e.values()).filter(Ur):[]}function ql(e,n){let r=e[n];return typeof r=="number"&&Number.isFinite(r)?r:void 0}function Ur(e){return typeof e=="string"}function Lr(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}var Wl,Fl,Ml,ma,kn=he(()=>{"use strict";Wl=Object.freeze({vendor:"",architecture:"",device:"",description:""}),Fl=Object.freeze(["maxTextureDimension1D","maxTextureDimension2D","maxTextureDimension3D","maxTextureArrayLayers","maxBindGroups","maxBindGroupsPlusVertexBuffers","maxBindingsPerBindGroup","maxDynamicUniformBuffersPerPipelineLayout","maxDynamicStorageBuffersPerPipelineLayout","maxSampledTexturesPerShaderStage","maxSamplersPerShaderStage","maxStorageBuffersPerShaderStage","maxStorageTexturesPerShaderStage","maxUniformBuffersPerShaderStage","maxUniformBufferBindingSize","maxStorageBufferBindingSize","minUniformBufferOffsetAlignment","minStorageBufferOffsetAlignment","maxVertexBuffers","maxBufferSize","maxVertexAttributes","maxVertexBufferArrayStride","maxInterStageShaderVariables","maxColorAttachments","maxColorAttachmentBytesPerSample","maxComputeWorkgroupStorageSize","maxComputeInvocationsPerWorkgroup","maxComputeWorkgroupSizeX","maxComputeWorkgroupSizeY","maxComputeWorkgroupSizeZ","maxComputeWorkgroupsPerDimension","maxImmediateSize","maxStorageBuffersInVertexStage","maxStorageBuffersInFragmentStage","maxStorageTexturesInVertexStage","maxStorageTexturesInFragmentStage"]),Ml=Object.freeze({maxTextureDimension1D:8192,maxTextureDimension2D:8192,maxTextureDimension3D:2048,maxTextureArrayLayers:256,maxBindGroups:4,maxBindGroupsPlusVertexBuffers:24,maxBindingsPerBindGroup:1e3,maxDynamicUniformBuffersPerPipelineLayout:8,maxDynamicStorageBuffersPerPipelineLayout:4,maxSampledTexturesPerShaderStage:16,maxSamplersPerShaderStage:16,maxStorageBuffersPerShaderStage:8,maxStorageTexturesPerShaderStage:4,maxUniformBuffersPerShaderStage:12,maxUniformBufferBindingSize:64*1024,maxStorageBufferBindingSize:128*1024*1024,minUniformBufferOffsetAlignment:256,minStorageBufferOffsetAlignment:256,maxVertexBuffers:8,maxBufferSize:256*1024*1024,maxVertexAttributes:16,maxVertexBufferArrayStride:2048,maxInterStageShaderVariables:16,maxColorAttachments:8,maxColorAttachmentBytesPerSample:32,maxComputeInvocationsPerWorkgroup:256,maxComputeWorkgroupSizeX:256,maxComputeWorkgroupSizeY:256,maxComputeWorkgroupSizeZ:64,maxComputeWorkgroupStorageSize:16*1024,maxComputeWorkgroupsPerDimension:65535,maxImmediateSize:64}),ma=new WeakSet});function ba(e){return Object.fromEntries(Object.entries(e).filter(([,n])=>n!==void 0))}var wa=he(()=>{"use strict"});function va(e){if(e==="u32"||e==="i32"||e==="f32")return{align:4,size:4,scalar:e,components:1};let n=Il.exec(e);if(!n)throw new Error(`Unsupported uniform field type: ${e}`);let r=Number(n[1]);return{align:r===2?8:16,size:r===3?12:r*4,scalar:n[2],components:r}}function Dl(e){return e==="u32"||e==="i32"||e==="f32"}function _a(e,n){return Math.ceil(e/n)*n}function Nr(e,n={}){return En(e,"u32",n)}function zr(e,n={}){return En(e,"i32",n)}function jr(e,n={}){return En(e,"f32",n)}function En(e,n,r={}){return ka(e,"uniform field"),va(n),Object.freeze({kind:"uniform-field",name:e,type:n,semantic:r.semantic,required:r.required??!r.internal,internal:!!r.internal,default:r.default,description:r.description})}function Pn(e,n,r={}){if(ka(e,"uniform struct"),!Array.isArray(n)||n.length===0)throw new Error(`uniform struct ${e} requires at least one field`);let t=n.map(a=>Cl(a,e));return Object.freeze({kind:"uniform-struct",name:e,fields:Object.freeze(Nl(t,r))})}function $r(e){Kr(e);let n=e.fields.map(r=>`${r.name}: ${r.type}`).join(", ");return`struct ${e.name} { ${n} };`}function Sa(e,n={}){if(Kr(e),!e.fields.every(i=>Dl(i.type)))return Ul(e,n);let r=Math.max(16,Math.ceil(e.fields.length*4/16)*16),t=new ArrayBuffer(r),a=new Uint32Array(t),s=new Int32Array(t),o=new Float32Array(t);return e.fields.forEach((i,u)=>{let l=n[i.name];if(l===void 0&&i.required)throw new Error(`Missing uniform field ${e.name}.${i.name}`);if(l===void 0&&(l=i.default??0),typeof l!="number")throw new Error(`Uniform ${e.name}.${i.name} expects a scalar number`);zl({field:i,index:u,value:l,u32View:a,i32View:s,f32View:o})}),new Uint32Array(t)}function Ul(e,n){let r=[],t=0;for(let u of e.fields){let l=va(u.type);t=_a(t,l.align),r.push({field:u,layout:l,offset:t}),t+=l.size}let a=new ArrayBuffer(Math.max(16,_a(t,16))),s=new Uint32Array(a),o=new Int32Array(a),i=new Float32Array(a);for(let{field:u,layout:l,offset:c}of r){let d=n[u.name];if(d===void 0&&u.required)throw new Error(`Missing uniform field ${e.name}.${u.name}`);d===void 0&&(d=u.default??(l.components===1?0:new Array(l.components).fill(0)));let p=typeof d=="number"?[d]:d;if(p.length!==l.components)throw new Error(`Uniform ${e.name}.${u.name} expects ${l.components} component(s), got ${p.length}`);for(let f=0;f4294967295)throw new Error(`Uniform ${t} must be an integer u32 in [0, 4294967295]`);a[n]=r;return}if(e==="i32"){if(!Number.isInteger(r)||r<-2147483648||r>2147483647)throw new Error(`Uniform ${t} must be an integer i32 in [-2147483648, 2147483647]`);s[n]=r;return}if(!Number.isFinite(r))throw new Error(`Uniform ${t} must be a finite f32`);o[n]=r}function Ta(e,n,r,t){return e.createUniformU32(Sa(n,r),t)}function xa(e){return Kr(e),{kind:e.kind,name:e.name,fields:e.fields.map(n=>ba({name:n.name,type:n.type,required:n.required,internal:n.internal,semantic:n.semantic,default:n.default,description:n.description}))}}function Cl(e,n){if(!e||e.kind!=="uniform-field")throw new Error(`uniform struct ${n} fields must be created with u32(), i32(), or f32()`);return e}function Nl(e,n){let r=n.alignFieldsTo??4;if(!Number.isInteger(r)||r<=0)throw new Error(`alignFieldsTo must be a positive integer, got ${r}`);let t=[...e],a=t.length%r;if(a===0)return Object.freeze(t);let s=r-a,o=0,i=new Set(t.map(u=>u.name));for(let u=0;u4294967295)throw new Error(`Uniform ${e.name} must be an integer u32 in [0, 4294967295]`);t[n]=r;return}if(e.type==="i32"){if(!Number.isInteger(r)||r<-2147483648||r>2147483647)throw new Error(`Uniform ${e.name} must be an integer i32 in [-2147483648, 2147483647]`);a[n]=r;return}if(e.type==="f32"){if(!Number.isFinite(r))throw new Error(`Uniform ${e.name} must be a finite f32`);s[n]=r;return}throw new Error(`Unsupported uniform field type: ${e.type}`)}function Kr(e){if(!e||e.kind!=="uniform-struct")throw new Error("Expected a uniform struct schema")}function ka(e,n){if(typeof e!="string"||!/^[A-Za-z_][A-Za-z0-9_]*$/.test(e))throw new Error(`${n} name must be a WGSL-compatible identifier, got ${e}`)}var Il,nr=he(()=>{"use strict";wa();Il=/^vec([234])<(u32|i32|f32)>$/});function Hr(e,n={}){Ga(e,"storage binding"),Oa(e,n.required);let r=n.access??"read";if(!(r in Ea))throw new Error(`storage binding ${e} has unsupported access ${r}`);return Object.freeze({kind:"storage",name:e,arg:n.arg,access:r,elementType:n.elementType??"f32",semantic:n.semantic,role:n.role,layout:n.layout,binding:n.binding,group:n.group})}function Vr(e,n,r={}){Ga(e,"uniform binding"),Oa(e,r.required);let t;if(Vl(n)?t=Pn(r.structName??Kl(e),n):t=n,!t||t.kind!=="uniform-struct")throw new Error(`uniform binding ${e} requires a uniformStruct schema or field array`);return Object.freeze({kind:"uniform",name:e,struct:t,semantic:r.semantic,binding:r.binding,group:r.group})}function un(e){if(!Array.isArray(e)||e.length===0)throw new Error("bindGroup requires at least one binding");let n=new Set,r=new Set;return Object.freeze(e.map((t,a)=>{if(!t||t.kind!=="storage"&&t.kind!=="uniform")throw new Error("bindGroup entries must be storage() or uniform() bindings");if(n.has(t.name))throw new Error(`duplicate bindGroup binding name: ${t.name}`);n.add(t.name);let s=t.binding??a;if(!Number.isInteger(s)||s<0)throw new Error(`binding ${t.name} has invalid binding index ${s}`);let o=t.group??0;if(!Number.isInteger(o)||o<0)throw new Error(`binding ${t.name} has invalid bind group index ${o}`);let i=`${o}:${s}`;if(r.has(i))throw new Error(`duplicate bindGroup binding index ${s} in @group(${o})`);return r.add(i),Object.freeze({...t,binding:s})}))}function Qr(e,n={}){return un(e).map(r=>jl(r,n)).join(` +`)}function Pa(e){let n=[],r=new Map;for(let t of un(e)){if(t.kind!=="uniform")continue;let a=JSON.stringify(xa(t.struct)),s=r.get(t.struct.name);if(s!==void 0){if(s!==a)throw new Error(`uniform struct ${t.struct.name} is declared with conflicting schemas`);continue}r.set(t.struct.name,a),n.push($r(t.struct))}return n.join(` +`)}function Aa(e,n,r,t={}){let a=un(n),s=t.labelPrefix??"kernel",o=[];return{bindings:a.map(u=>{let l=r?.[u.name];if(l==null)throw new Error(`Missing resource for binding ${u.name}`);if(u.kind==="uniform"){let f;return Xr(l)?f=l:(f=Ta(e,u.struct,l,`${s}-${u.name}`),typeof f.destroy=="function"&&o.push(()=>f.destroy?.())),{buffer:f,type:"uniform",binding:u.binding,...u.group?{group:u.group}:{}}}let c=l,d=typeof c.byteOffset=="number"?c.byteOffset:0,p=typeof c.byteLength=="number"?Hl(c.byteLength):void 0;return{tensor:l,type:Ea[u.access],binding:u.binding,...u.group?{group:u.group}:{},...d?{offset:d}:{},...p!==void 0?{size:p}:{}}}),cleanup:()=>{for(let u of o)u()}}}function jl(e,n){let r=e.group??0;if(e.kind==="storage"){let t=e.access==="read_write"?"read_write":"read",a=$l(e.elementType,n,`binding ${e.name} elementType`);return`@group(${r}) @binding(${e.binding}) var ${e.name}: array<${a}>;`}return`@group(${r}) @binding(${e.binding}) var ${e.name}: ${e.struct.name};`}function $l(e,n,r){if(typeof e!="string"||!e.startsWith("$"))return e;let t=e.slice(1),a=n[t];if(a==null)throw new Error(`Missing template value ${t} for ${r}`);return a}function Xr(e){return e!==null&&typeof e=="object"&&typeof e.destroy=="function"&&!("shape"in e)}function Kl(e){return e.length===0?e:e[0].toUpperCase()+e.slice(1)}function Ga(e,n){if(typeof e!="string"||!/^[A-Za-z_][A-Za-z0-9_]*$/.test(e))throw new Error(`${n} name must be a WGSL-compatible identifier, got ${e}`)}function Oa(e,n){if(n===!1)throw new Error(`binding ${e} cannot be optional; use separate variants for different resource layouts`)}function Hl(e){return Math.max(4,Math.ceil(e/4)*4)}function Vl(e){return Array.isArray(e)}var Ea,An=he(()=>{"use strict";nr();Ea=Object.freeze({read:"read-only-storage",read_write:"storage"})});function Gn(e){return e==null?e:Array.isArray(e)?e.map(Gn):e instanceof Map?Object.fromEntries([...e].map(([n,r])=>[n,Gn(r)])):typeof e=="object"&&"value"in e?e.type==="NullValue"?null:Gn(e.value):e}function de(e){return((...n)=>e(...n.map(Gn)))}function Zr(e){if(e==="float32"||e==="f32")return"f32";if(e==="float16"||e==="f16")return"f16";if(e==="uint32"||e==="u32"||e==="uint8")return"u32";if(e==="int32"||e==="i32"||e==="int8")return"i32";throw new Error(`Unsupported WebGPU dtype: ${e}`)}function On(e){return e==="f32"?"float32":e==="f16"?"float16":e==="u32"?"uint32":e==="i32"?"int32":e}function qa(e={}){let n=e,r=Yr(e.device),t=r.features.has("shader-f16");return{...Ba,f16Ok:de(a=>a!=="f16"&&a!=="float16"||t),f16Allowed:de(a=>a==="f32"||a==="float32"||(a==="f16"||a==="float16")&&t),op:e.op,variant:e.variant,pass:e.pass,device:r,attrs:e.attrs??{},args:e.args??{},source:e.sourceContext??{},present:e.present??{},shapes:e.shapes??{},ranks:e.ranks??{},tensorDtypes:e.tensorDtypes??{},dtypes:e.dtypes??{},...e.derived??{},tunables:e.tunables??{},constants:e.constants??{},...e.constants??{},...n.env!==void 0?{env:n.env}:{}}}function Yr(e){let n=ze(e),r=Wa.get(n);return r===void 0&&(r={features:n.features,wgslLanguageFeatures:n.wgslLanguageFeatures,limits:n.limits,adapterInfo:ha(n)},Wa.set(n,r)),r}function Le(e,n={}){if(typeof e!="string")return e;let r=qa(n),t=nc(e),a=t.freeIdentifiers.filter(o=>!(o in r));if(a.length>0)throw new Error(`Unknown identifier${a.length===1?"":"s"} ${a.map(o=>`"${o}"`).join(", ")} in WebGPU expression: ${e} Identifiers resolve against the expression scope. Namespaces: args, attrs, shapes, ranks, dtypes, tensorDtypes, present, constants, tunables, source, device (plus the bare names declared in \`derive\`). device sub-fields: features, wgslLanguageFeatures, limits, adapterInfo. Helper functions: ${[...Object.keys(Ba),...Ql].join(", ")}. -If a string literal was intended, quote it (e.g. '"${a[0]}"' not '${a[0]}').`);if(r.statement===void 0)throw r.parseError??new Error(`Empty WebGPU expression: ${e}`);let s=new Ie;for(let[o,i]of Xl)s.set(o,i);for(let o of r.freeIdentifiers)s.set(o,t[o]);for(let o of r.probedIdentifiers)o in t&&s.set(o,t[o]);return Gn(new Mt(s).evaluate(r.statement,s))}function Jt(e,n={}){return Zl(e,qa(n))}function Zl(e,n){let t=Ra.get(e);t||(t=new Hn(e),Ra.set(e,t));let r=Jl(e),a=r?Yl(n,r):n;return t.render(a)}function Yl(e,n){let t={};for(let r of Object.keys(e))n.has(r)&&(t[r]=e[r]);return t}function Jl(e){let n=Wa.get(e);if(n!==void 0)return n;let t;try{let r=Kn($n(e,Ia)),a=new Set,s=o=>{if(!o||typeof o!="object")return;if(Array.isArray(o)){for(let u of o)s(u);return}if(o instanceof Map){for(let[u,l]of o)s(u),s(l);return}let i=o;i.type==="Identifier"&&typeof i.value=="string"&&a.add(i.value);for(let u of Object.keys(i))u!=="type"&&s(i[u])};s(r),t=a}catch{t=null}return Wa.set(e,t),t}function nc(e){let n=Ma.get(e);if(n!==void 0)return n;let t=new Set,r=new Set,a=i=>{if(!i||typeof i!="object")return;if(Array.isArray(i)){for(let l of i)a(l);return}if(i instanceof Map){for(let[l,c]of i)a(l),a(c);return}let u=i;switch(u.type){case"Identifier":ec.has(u.value)||t.add(u.value);return;case"MemberExpression":a(u.object),u.computed&&a(u.property);return;case"BinaryExpression":a(u.left),a(u.right);return;case"UnaryExpression":a(u.argument);return;case"FilterExpression":{a(u.operand);let l=u.filter;l?.type==="CallExpression"&&a(l.args);return}case"TestExpression":{let l=u.test,c=u.operand;(l?.value==="defined"||l?.value==="undefined")&&c?.type==="Identifier"?r.add(c.value):a(u.operand);return}case"CallExpression":a(u.callee),a(u.args);return;case"KeywordArgumentExpression":a(u.value);return;default:{for(let[l,c]of Object.entries(u))l!=="type"&&a(c);return}}},s,o;try{let i=Kn($n(`{{ ${e} }}`,Ia));s=i.body[0],a(i)}catch(i){o=i}for(let i of t)r.delete(i);return n=Object.freeze({statement:s,...o!==void 0?{parseError:o}:{},freeIdentifiers:Object.freeze([...t]),probedIdentifiers:Object.freeze([...r])}),Ma.set(e,n),n}function He(e,n){let t={};for(let[r,a]of Object.entries(e??{}))t[r]=je(a,n);return t}function je(e,n){return typeof e=="string"?Le(e,n):Array.isArray(e)?e.map(t=>je(t,n)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([t,r])=>[t,je(r,n)])):e}var Ra,Ba,Ql,Fa,Xl,Wa,Ma,Ia,ec,tt=he(()=>{"use strict";Bt();xn();Ra=new Map;Ba=Object.freeze({ceil:de(e=>Math.ceil(e)),floor:de(e=>Math.floor(e)),min:de((...e)=>Math.min(...e)),max:de((...e)=>Math.max(...e)),pow:de((e,n)=>Math.pow(e,n)),ceilDiv:de((e,n)=>Math.ceil(e/n)),pow2ceil:de(e=>e<=1?1:2**Math.ceil(Math.log2(e))),numel:de(e=>e.reduce((n,t)=>n*t,1)),rank:de(e=>e.length),dim:de((e,n)=>{let t=(n%e.length+e.length)%e.length;return e[t]}),rows:de((e,n)=>{let t=(n%e.length+e.length)%e.length;return e.reduce((r,a,s)=>s===t?r:r*a,1)}),cols:de((e,n)=>{let t=(n%e.length+e.length)%e.length;return e[t]}),outer:de((e,n)=>{let t=(n%e.length+e.length)%e.length;return e.slice(0,t).reduce((r,a)=>r*a,1)}),inner:de((e,n)=>{let t=(n%e.length+e.length)%e.length;return e.slice(t+1).reduce((r,a)=>r*a,1)}),broadcastable:de((e,n)=>{if(e.length>n.length)return!1;let t=n.length-e.length;return e.every((r,a)=>r===1||r===n[a+t])}),sameShape:de((e,n)=>e.length===n.length&&e.every((t,r)=>t===n[r])),hasAxis:de((e,n,t)=>{let r=(n%t+t)%t;return e.some(a=>(a%t+t)%t===r)}),has:de((e,n)=>e instanceof Map?e.has(n):!!(e&&Object.prototype.hasOwnProperty.call(e,n))),dtypeBytes:de(e=>{if(e==="float16"||e==="f16")return 2;if(e==="float32"||e==="f32"||e==="uint32"||e==="u32"||e==="uint8"||e==="int32"||e==="i32"||e==="int8")return 4;throw new Error(`Unsupported dtype for dtypeBytes(): ${e}`)}),pick:de((e,n)=>{if(!Array.isArray(e))throw new Error("pick() expects a list of [condition, value] pairs as its first argument");for(let t of e){if(!Array.isArray(t)||t.length<2)throw new Error("pick() entries must be [condition, value] pairs");if(t[0])return t[1]}return n})});Ql=["f16Ok","f16Allowed"];Fa=new WeakMap;Xl=[["true",!0],["false",!1],["none",null],["True",!0],["False",!1],["None",null]];Wa=new Map;Ma=new Map,Ia=Object.freeze({lstrip_blocks:!0,trim_blocks:!0}),ec=new Set(["true","false","none","True","False","None"])});function er(e,n){let t=[];for(let r of e.split(` -`)){let a=tc.exec(r);if(a)for(let s of a[1].split(",")){let o=s.trim();if(o.length===0)continue;let i=Ua[o];i&&!n.has(i)&&t.push(`enable ${o}; (requires device feature "${i}")`)}}return t}var Ua,tc,nr=he(()=>{"use strict";Ua=Object.freeze({f16:"shader-f16",subgroups:"subgroups",chromium_experimental_subgroup_matrix:"chromium-experimental-subgroup-matrix"}),tc=/^\s*enable\s+([^;]+);/});function Je(e){let n=e instanceof Map?new Map(e):new Map(Object.entries(e));return Object.freeze({readText(t){let r=n.get(t);if(r===void 0)throw new Error(`WebGPU template asset is missing: ${t}`);return r},has(t){return n.has(t)}})}function tr(e){st(e,"WebGPU manifest");let n=e.schemaVersion??1;if(n!==1)throw new Error(`Unsupported WebGPU manifest schemaVersion: ${n}`);let t=e.domain??"ai.onnx";hc(t,"WebGPU manifest domain");let r=e.name;if(typeof r!="string"||r.length===0)throw new Error("WebGPU manifest requires a non-empty name");if(!Array.isArray(e.inputs))throw new Error(`WebGPU manifest ${t}.${r} requires inputs`);if(!Array.isArray(e.outputs))throw new Error(`WebGPU manifest ${t}.${r} requires outputs`);if(!rr(e.args)||Object.keys(e.args).length===0)throw new Error(`WebGPU manifest ${t}.${r} requires explicit args`);gc(e.args,`${t}.${r}.args`);let a=sc(e,`${t}.${r}`),s=oc(e,a);return Object.freeze({schemaVersion:1,domain:t,name:r,id:`${t}.${r}`,sinceVersion:e.sinceVersion,inputs:Object.freeze([...e.inputs]),outputs:Object.freeze([...e.outputs]),args:Object.freeze({...e.args}),attributes:Object.freeze({...e.attributes??{}}),derive:Object.freeze({...e.derive??{}}),typeConstraints:Object.freeze({...e.typeConstraints??{}}),tunables:Object.freeze({...e.tunables??{}}),staticShapes:Object.freeze([...e.staticShapes??[]]),variants:Object.freeze(s)})}function Da(e){return e.map(n=>{if(n.buffer.type==="uniform"){if(!n.struct)throw new Error(`WebGPU uniform binding ${n.name} requires struct`);return Vt(n.name,Pn(n.struct.name,n.struct.fields.map(mc)),{semantic:n.semantic,binding:n.binding,group:n.group})}return Ht(n.name,{arg:n.arg,access:n.buffer.type==="storage"?"read_write":"read",elementType:n.elementType,semantic:n.semantic??n.role,role:n.role,binding:n.binding,group:n.group})})}function sc(e,n){let t=new Map;for(let[r,a]of Object.entries(e.bindingSets??{})){if(!Array.isArray(a)||a.length===0)throw new Error(`WebGPU manifest ${n} bindingSet "${r}" must be a non-empty binding array`);t.set(r,a)}return t}function La(e,n,t){if(Array.isArray(e))return e;if(typeof e=="string"){let r=n.get(e);if(!r)throw new Error(`WebGPU ${t} references unknown bindingSet "${e}"`);return r}if(e&&typeof e=="object"&&typeof e.set=="string"){let r=e,a=n.get(r.set);if(!a)throw new Error(`WebGPU ${t} references unknown bindingSet "${r.set}"`);let s=r.overrides??{};for(let o of Object.keys(s))if(!a.some(i=>i.name===o))throw new Error(`WebGPU ${t} bindingSet "${r.set}" has no binding "${o}" to override`);return a.map(o=>{let i=o.name!==void 0?s[o.name]:void 0;return i?{...o,...i}:o})}throw new Error(`WebGPU ${t} bindings must be an array, a bindingSet name, or { set, overrides }`)}function oc(e,n){let t=`${e.domain??"ai.onnx"}.${e.name}`,r=ac.filter(s=>e[s]!==void 0);if(r.length>0)throw new Error(`WebGPU manifest ${t} uses the retired flattened dialect: top-level ${r.join(", ")} is no longer accepted. Declare ${r.length===1?"it":"them"} on variants[].passes[] instead (docs/kernel-authoring-framework.md \xA74).`);let a=at(e,t);if(a.length===0)throw new Error(`WebGPU manifest ${t} requires a non-empty variants list`);return a.map((s,o)=>uc(s,o,n))}function at(e,n){let t=[...e.variants??[]];for(let r of e.variantFamilies??[]){let a=Object.keys(r.axes??{});if(a.length===0)throw new Error(`WebGPU manifest ${n}: a variantFamily requires at least one axis`);if(!Array.isArray(r.variants)||r.variants.length===0)throw new Error(`WebGPU manifest ${n}: a variantFamily requires at least one base variant`);for(let s of a){let o=r.axes[s];if(!Array.isArray(o)||o.length===0)throw new Error(`WebGPU manifest ${n}: variantFamily axis "${s}" must be a non-empty array`)}for(let s of ic(a,r.axes))for(let o of r.variants)t.push(rt(o,s))}return t}function ic(e,n){let t=[{}];for(let r of e)t=t.flatMap(a=>n[r].map(s=>({...a,[r]:s})));return t}function rt(e,n){if(typeof e=="string")return e.replace(/\{([A-Za-z_]\w*)\}/g,(t,r)=>r in n?String(n[r]):t);if(Array.isArray(e))return e.map(t=>rt(t,n));if(e!==null&&typeof e=="object"){let t={};for(let[r,a]of Object.entries(e))t[rt(r,n)]=rt(a,n);return t}return e}function uc(e,n,t){st(e,"WebGPU variant");let r=e.id??e.name??`variant_${n}`;if(!/^[A-Za-z0-9][A-Za-z0-9_]*$/.test(r))throw new Error(`WebGPU variant id must be stable, got ${r}`);let a=e.passes;if(!Array.isArray(a)||a.length===0)throw new Error(`WebGPU variant ${r} requires passes`);let s=e.bindings!==void 0?La(e.bindings,t,`variant ${r}`):void 0,o=e.version??1;if(!Number.isInteger(o)||o<1)throw new Error(`WebGPU variant ${r} version must be an integer >= 1`);return Object.freeze({id:r,name:e.name??r,version:o,default:!!e.default,priority:e.priority??0,when:pc(e.when,r),selectAbove:typeof e.selectAbove=="string"&&e.selectAbove.length>0?e.selectAbove:null,requires:fc(e),tunables:Object.freeze({...e.tunables??{}}),derive:Object.freeze({...e.derive??{}}),constants:Object.freeze({...e.constants??{}}),intermediates:Object.freeze([...e.intermediates??[]]),passes:Object.freeze(a.map((i,u)=>lc(i,s,u,t)))})}function lc(e,n,t,r){let a=cc(e,t);if(!e.dispatch)throw new Error(`WebGPU pass ${e.id??t} requires dispatch`);let s=e.bindings!==void 0?La(e.bindings,r,`pass ${e.id??t}`):n;if(!Array.isArray(s)||s.length===0)throw new Error(`WebGPU pass ${e.id??t} requires bindings`);return Object.freeze({id:e.id??`pass_${t}`,...e.name?{name:e.name}:{},shader:a.shader,source:a,entryPoint:e.entryPoint??"main",bindings:Object.freeze(s.map(dc)),constants:Object.freeze({...e.constants??{}}),uniforms:Object.freeze({...e.uniforms??{}}),dispatch:e.dispatch,profile:Object.freeze({...e.profile??{}}),metadata:Object.freeze({...e.metadata??{}}),reads:Object.freeze([...e.reads??[]]),writes:Object.freeze([...e.writes??[]])})}function cc(e,n){let t=`WebGPU pass ${e.id??n}`,r=e.source;if(r!==void 0){if(st(r,`${t}.source`),r.kind==="template"){let a=r.shader??e.shader;if(typeof a!="string"||a.length===0)throw new Error(`${t} template source requires shader`);if(e.shader!==void 0&&e.shader!==a)throw new Error(`${t} has conflicting shader and source.shader`);if(r.version!==void 0&&typeof r.version!="string"&&typeof r.version!="number")throw new Error(`${t} template source version must be a string or number`);if(r.inputs!==void 0&&!rr(r.inputs))throw new Error(`${t} template source inputs must be an object`);return Object.freeze({kind:"template",shader:a,...r.version!==void 0?{version:r.version}:{},inputs:Object.freeze({...r.inputs??{}})})}throw new Error(`${t} source has unsupported kind ${r.kind}`)}if(typeof e.shader!="string"||e.shader.length===0)throw new Error(`${t} requires shader or source`);return Object.freeze({kind:"template",shader:e.shader,inputs:Object.freeze({})})}function dc(e,n){if(st(e,`WebGPU binding ${n}`),e.optional===!0)throw new Error(`WebGPU binding ${e.name??e.role??n} cannot be optional; use a separate variant`);let t=e.buffer?.type;if(!t||!rc.has(t))throw new Error(`WebGPU binding ${e.name??e.role??n} has invalid buffer type`);let r=e.name??e.role??e.semantic;if(typeof r!="string"||!/^[A-Za-z_][A-Za-z0-9_]*$/.test(r))throw new Error(`WebGPU binding requires a WGSL-compatible name, got ${String(r)}`);let a=Object.freeze({name:r,...e.role!==void 0?{role:e.role}:{},...e.semantic!==void 0?{semantic:e.semantic}:{},...e.arg!==void 0?{arg:e.arg}:{},buffer:{type:t},...e.elementType?{elementType:e.elementType}:{},...e.struct?{struct:e.struct}:{},...e.binding!==void 0?{binding:e.binding}:{},...e.group!==void 0?{group:e.group}:{}});if(t==="uniform"&&!a.struct)throw new Error(`WebGPU uniform binding ${r} requires struct`);if(t!=="uniform"&&!a.elementType)throw new Error(`WebGPU storage binding ${r} requires elementType`);return a}function pc(e,n){if(e===void 0)return!0;if(Array.isArray(e)){if(e.length===0)throw new Error(`WebGPU variant ${n} when[] must be a non-empty list of predicates`);for(let t of e)if(typeof t!="string"||t.length===0)throw new Error(`WebGPU variant ${n} when[] entries must be non-empty expression strings, got ${JSON.stringify(t)}`);return Object.freeze([...e])}if(typeof e!="string"&&typeof e!="boolean")throw new Error(`WebGPU variant ${n} when must be a string, boolean, or string[], got ${JSON.stringify(e)}`);return e}function fc(e){let n={...e.requiredFeatures?{requiredFeatures:e.requiredFeatures}:{},...e.requiredLimits?{requiredLimits:e.requiredLimits}:{},...e.requiredWGSLLanguageFeatures?{requiredWGSLLanguageFeatures:e.requiredWGSLLanguageFeatures}:{},...e.requiredSubgroupMinSize!==void 0?{requiredSubgroupMinSize:e.requiredSubgroupMinSize}:{}};if(n.requiredSubgroupMinSize!==void 0&&(!Number.isInteger(n.requiredSubgroupMinSize)||n.requiredSubgroupMinSize<1))throw new Error(`WebGPU variant ${e.id??e.name??"?"} requiredSubgroupMinSize must be a positive integer`);return Object.keys(n).length===0?null:n}function mc(e){if(e.type==="u32")return Nt(e.name,e);if(e.type==="i32")return zt(e.name,e);if(e.type==="f32")return jt(e.name,e);throw new Error(`Unsupported WebGPU uniform field type: ${e.type}`)}function gc(e,n){for(let[t,r]of Object.entries(e)){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(t))throw new Error(`${n}.${t} is not a valid arg name`);if(!["tensor","u32","i32","f32","bool","string"].includes(r.kind))throw new Error(`${n}.${t} has unsupported kind ${String(r.kind)}`)}}function hc(e,n){if(!/^[a-z][a-z0-9]*(?:\.[A-Za-z][A-Za-z0-9_]*)*$/.test(e))throw new Error(`${n} must be a dotted canonical domain, got ${e}`)}function st(e,n){if(!rr(e))throw new Error(`${n} must be an object`)}function rr(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}var rc,ac,ot=he(()=>{"use strict";An();nt();rc=new Set(["read-only-storage","storage","uniform"]);ac=["shader","entryPoint","bindings","constants","uniforms","profile","metadata","dispatch"]});function Rn(e){if(e===ee.float16)return 2;if(e===ee.float32||e===ee.int8||e===ee.int32||e===ee.uint8||e===ee.uint32)return 4;throw new Error(`Unsupported dtype: ${e}`)}function Ve(e){if(!Array.isArray(e))throw new Error("shape must be an array");let n=1;for(let t of e){if(!Number.isInteger(t)||t<0)throw new Error(`invalid shape dimension: ${t}`);n*=t}return n}function Ca(e){let n=new Array(e.length),t=1;for(let r=e.length-1;r>=0;--r)n[r]=t,t*=e[r];return n}function it(e){return e!==null&&typeof e=="object"&&typeof e.dtype=="string"&&Array.isArray(e.shape)&&typeof e.size=="number"&&typeof e.byteLength=="number"&&"buffer"in e&&"runtime"in e}var ee,Fn=he(()=>{"use strict";ee=Object.freeze({float16:"float16",float32:"float32",int8:"int8",int32:"int32",uint8:"uint8",uint32:"uint32"})});function ar(e){return{attrs:e.attrs,dtypes:e.dtypes,tensorDtypes:e.tensorDtypes,ranks:e.ranks,tunables:e.tunables}}function Na(e,n,t,r=null){return Qe({op:e.id,sinceVersion:e.sinceVersion,variant:n.id,variantVersion:n.version,...ar(t),staticShapes:bc(t,e.staticShapes),specialization:r,device:kn(t.device),bindings:n.passes.map(a=>a.bindings.map(s=>({name:s.name,binding:s.binding,group:s.group,type:s.buffer.type,elementType:s.elementType,struct:yc(s.struct)})))})}function yc(e){return e&&{name:e.name,fields:e.fields.map(n=>({name:n.name,type:n.type}))}}function za(e){return Qe({shapes:e.shapes,args:e.args})}function ja(e,n){return`${e}|shapes=${n}`}function Qe(e){return Array.isArray(e)?`[${e.map(Qe).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().map(n=>`${JSON.stringify(n)}:${Qe(e[n])}`).join(",")}}`:JSON.stringify(e)}function bc(e,n){let t={};for(let r of n){let[a,s]=r.split("."),o=e.shapes[a];if(!o)continue;if(s===void 0||s==="*"){t[r]=o;continue}let i=Number(s);Number.isInteger(i)&&(t[r]=o[i])}return t}var ut,lt,ct,$a=he(()=>{"use strict";xn();ut=class{entries=new Map;hits=0;misses=0;get(n){let t=this.entries.get(n);if(t===void 0){this.misses+=1;return}return this.hits+=1,t}getOrCreate(n,t){let r=this.get(n);if(r!==void 0)return r;let a=t();return this.entries.set(n,a),a}clear(){this.entries.clear(),this.hits=0,this.misses=0}},lt=class extends ut{},ct=class extends ut{}});function Ka(e,n,t){return e.map(r=>{let a=je(r.shape,t),s=_c(a,r.id),o=On(r.dtype),i=wc(r.id,n);return Object.freeze({id:r.id,dtype:o,shape:s,firstWrite:i.firstWrite,lastRead:i.lastRead,byteLength:Ve(s)*Rn(o)})})}function wc(e,n){let t=Number.POSITIVE_INFINITY,r=-1;for(let a=0;a{if(!Number.isInteger(r)||Number(r)<0)throw new Error(`WebGPU scratch ${n} shape dimension must be a nonnegative integer, got ${String(r)}`);return Number(r)}))}var Ha=he(()=>{"use strict";Fn();tt()});var Za={};Eo(Za,{executeWebGpuPlan:()=>vc,materializeComputePassDescriptorTemplate:()=>Qa,materializeWebGpuExecutionPlan:()=>Wn});async function vc(e,n,t={}){let r=Wn(e,n);try{if(r.programs.length===0)return;if(typeof e.runProgramSequence=="function")await e.runProgramSequence(r.programs,t);else for(let a of r.programs)await e.runProgram(a,t)}finally{r.cleanup()}}function Wn(e,n){let t=Sc(e,n),r=[],a=[];for(let s=0;sl[d.name]);let c=Aa(e,o.bindings,l,{labelPrefix:o.name});r.push(c.cleanup),a.push({name:o.name,source:o.source,entryPoint:o.entryPoint,cacheKey:`webgpu:${n.program.key}:pass=${o.id}`,bindings:c.bindings,dispatchWorkgroups:i.dispatchWorkgroups,...o.profile?{profile:o.profile}:{},...o.semantic!==void 0?{semantic:o.semantic}:{},...o.metadata?{metadata:o.metadata}:{},plan:{webgpuPlanKey:n.plan.key,pass:i.id,scratches:n.plan.scratches}})}return{programs:a,cleanup:()=>{for(let s of r)s();for(let s of Object.values(t))typeof s.destroy=="function"&&s.destroy()}}}function Qa(e,n){return Xa(`${e.name} (program ${e.programKey}, pass ${e.id})`,e.bindingSpecs,t=>or(t,n)),{name:e.name,source:e.source,entryPoint:e.entryPoint,cacheKey:e.cacheKey,bindings:e.bindingSpecs.map((t,r)=>Tc(e,t,n,r)),dispatchWorkgroups:e.dispatchWorkgroups,...e.profile?{profile:e.profile}:{},...e.metadata?{metadata:e.metadata}:{},plan:{webgpuProgramKey:e.programKey,webgpuPlanKey:e.planKey,pass:e.id}}}function Tc(e,n,t,r){let a=or(n,t);if(a==null)throw new Error(`Missing resource for compute pass descriptor template binding ${n.name}`);let s=n.binding??r;if(n.buffer.type==="uniform"){if(!Xt(a))throw new Error(`Compute pass descriptor template ${e.name} requires caller-owned uniform buffer for ${n.name}`);return{buffer:a,type:"uniform",binding:s,...n.group?{group:n.group}:{}}}let o=a,i=typeof o.byteOffset=="number"?o.byteOffset:0,u=typeof o.byteLength=="number"?o.byteLength:void 0;return{tensor:a,type:n.buffer.type,binding:s,...n.group?{group:n.group}:{},...i?{offset:i}:{},...u!==void 0?{size:u}:{}}}function or(e,n){return n[e.arg??""]??n[e.name]??n[e.role??""]??n[e.semantic??""]}function Sc(e,n){let t={};if(n.plan.scratches.length===0)return t;if(typeof e.empty!="function")throw new Error("WebGPU multi-pass plan requires a runtime with empty(dtype, shape)");for(let r of n.plan.scratches)t[r.id]=e.empty(r.dtype,r.shape,`webgpu-scratch-${r.id}`);return t}function kc(e,n,t,r){let a={};for(let s of n){if(s.buffer.type==="uniform"){let o=Va(e,s,r);a[s.name]=o??t[s.name];continue}a[s.name]=Va(e,s,r)}return a}function Va(e,n,t){return t[n.name]??t[n.role??""]??t[n.semantic??""]??or(n,e.request.resources)}function Xa(e,n,t){let r=null;for(let a of n){let s=xc(a);if(s===null)continue;let o=sr(t(a));if(o===null)continue;r===null&&(r=new Map);let i=r.get(o.buffer);if(i===void 0){r.set(o.buffer,{name:a.name,access:s,view:o});continue}if(i.access==="read"&&s==="read")continue;if(i.access==="read_write"&&s==="read_write"){if(!Ac(i.view.offset,i.view.end,o.offset,o.end))continue;throw new Error(`${e}: storage bindings "${i.name}" and "${a.name}" alias overlapping writable ranges of the same GPU buffer; overlapping storage aliases are unsafe when either binding is writable`)}let[u,l]=s==="read_write"?[i.name,a.name]:[a.name,i.name];throw new Error(`${e}: storage aliasing hazard \u2014 binding "${u}" (read-only-storage) and binding "${l}" (storage, read_write) resolve to the same GPU buffer. WebGPU usage scopes cover the whole buffer, so this poisons the entire command buffer and corrupts downstream results. Bind it once as storage (read_write) for intentional in-place, or use distinct buffers.`)}}function xc(e){if("buffer"in e&&e.buffer!==void 0)switch(e.buffer.type){case"read-only-storage":return"read";case"storage":return"read_write";default:return null}let n=e;return n.kind==="storage"?n.access:null}function Ec(e,n){let t=n.metadata?.viewAlias;if(t===void 0)return null;let r=t;if(r===null||typeof r!="object"||typeof r.input!="string"||typeof r.output!="string")throw new Error(`${e}: pass metadata.viewAlias must be an object naming two bindings, e.g. { "input": "\\"x\\"", "output": "\\"y\\"" } (values are expressions, so quote the binding names)`);return{input:r.input,output:r.output}}function Pc(e,n,t){let r=Ec(e,n);if(r===null)return!1;let a=n.bindingSpecs.find(u=>u.name===r.input),s=n.bindingSpecs.find(u=>u.name===r.output);if(!a||a.buffer.type!=="read-only-storage")throw new Error(`${e}: metadata.viewAlias.input "${r.input}" must name a read-only-storage binding of the pass`);if(!s||s.buffer.type!=="storage")throw new Error(`${e}: metadata.viewAlias.output "${r.output}" must name a storage (read_write) binding of the pass`);let o=sr(t[r.input]),i=sr(t[r.output]);return o===null||i===null?!1:o.buffer===i.buffer&&o.offset===i.offset&&o.end===i.end}function sr(e){if(e===null||typeof e!="object")return null;let n=e,t=n.buffer??e;if(t===null||typeof t!="object"&&typeof t!="function")return null;let r=typeof n.byteOffset=="number"?n.byteOffset:0,a=typeof n.byteLength=="number"?n.byteLength:typeof n.size=="number"?n.size:Number.POSITIVE_INFINITY;return{buffer:t,offset:r,end:r+a}}function Ac(e,n,t,r){return e{"use strict";An()});function Ya(e,n,t,r,a,s){return Object.freeze({id:e.id,name:e.name,source:e.source,entryPoint:e.entryPoint,cacheKey:t,bindings:e.bindings,bindingSpecs:e.bindingSpecs,dispatchWorkgroups:n.dispatchWorkgroups,uniforms:n.uniforms,constants:n.constants,...e.profile?{profile:e.profile}:{},...e.metadata?{metadata:e.metadata}:{},programKey:r,planKey:a,passIndex:s})}function lr(e,n,t,r){let a=dt(e);if(r.has(a))throw new Error(`Circular WebGPU template include: ${[...r,a].join(" -> ")}`);r.add(a);let s=n.replace(Gc,(o,i)=>{let u=Oc(a,i);return lr(u,t(u),t,r)});return r.delete(a),s}function Oc(e,n){if(n.startsWith(".")){let t=e.slice(0,Math.max(0,e.lastIndexOf("/")));return dt(`${t}/${n}`)}return dt(n)}function dt(e){let n=[];for(let t of e.replaceAll("\\","/").split("/"))if(!(t===""||t===".")){if(t===".."){if(n.length===0)throw new Error(`WebGPU template path escapes package root: ${e}`);n.pop();continue}n.push(t)}return n.join("/")}function Rc(e,n,t){if(n.kind==="tensor"){if(!it(t))throw new Error(`WebGPU arg ${e} must be a GPU tensor`);if(n.dtype&&t.dtype!==n.dtype)throw new Error(`WebGPU arg ${e} dtype ${t.dtype} does not match ${n.dtype}`);return}if(n.kind==="string"){if(typeof t!="string")throw new Error(`WebGPU arg ${e} must be a string`);if(n.oneOf&&!n.oneOf.includes(t))throw new Error(`WebGPU arg ${e} must be one of ${n.oneOf.join(", ")}`);return}if(n.kind==="bool"){if(typeof t!="boolean")throw new Error(`WebGPU arg ${e} must be a boolean`);return}if(typeof t!="number"||!Number.isFinite(t))throw new Error(`WebGPU arg ${e} must be a finite number`);if(n.kind==="u32"&&(!Number.isInteger(t)||t<0||t>4294967295))throw new Error(`WebGPU arg ${e} must be a u32`);if(n.kind==="i32"&&(!Number.isInteger(t)||t<-2147483648||t>2147483647))throw new Error(`WebGPU arg ${e} must be an i32`)}function Fc(e){return typeof e.readText=="function"?e:Je(e)}function Wc(e,n){return es(`WebGPU op ${e.program.op}`,e.program.passes,n)}function Mc(e,n,t){return es(`WebGPU op ${e} variant ${n.id}`,n.passes,t)}function es(e,n,t){if(t===void 0){if(n.length!==1)throw new Error(`${e} has ${n.length} passes; select a pass by id or index`);return 0}if(typeof t=="number"){if(!Number.isInteger(t)||t<0||t>=n.length)throw new Error(`${e} has no pass index ${t}`);return t}let r=n.findIndex(a=>a.id===t);if(r<0)throw new Error(`${e} has no pass ${t}`);return r}function Bc(e,n){if(!ns(e))throw new Error(`${n} must be a JSON object`);return ur(e,n)}function ur(e,n){if(e===null)return null;if(typeof e=="boolean"||typeof e=="string")return e;if(typeof e=="number"){if(!Number.isFinite(e))throw new Error(`${n} number must be finite`);return e}if(Array.isArray(e))return Object.freeze(e.map((t,r)=>ur(t,`${n}[${r}]`)));if(ns(e)){let t={};for(let[r,a]of Object.entries(e)){if(a===void 0)throw new Error(`${n}.${r} must be JSON; got undefined`);t[r]=ur(a,`${n}.${r}`)}return Object.freeze(t)}throw new Error(`${n} must be JSON-compatible`)}function ns(e){if(e===null||typeof e!="object"||Array.isArray(e))return!1;let n=Object.getPrototypeOf(e);return n===Object.prototype||n===null}function qc(e,n){if(e&&typeof e=="object"){let t=Ja.get(e);return t===void 0&&(t=Qe(kn(n)),Ja.set(e,t)),t}return Qe(kn(n))}function Ic(e,n,t){return Qe({v:t??null,d:qc(e,n.device),...ar(n),args:n.args,shapes:n.shapes,present:n.present,source:n.sourceContext})}function Dc(e){return e!==null&&typeof e=="object"&&typeof e.dtype=="string"&&Array.isArray(e.shape)}function Lc(e){let n=e.shape.reduce((t,r)=>t*r,1);return{dtype:e.dtype,shape:e.shape,size:n,byteLength:n*4,buffer:{},runtime:null}}var Mn,Gc,Ja,Uc,Bn=he(()=>{"use strict";An();Fn();$a();xn();tt();ot();Ha();nr();Mn=class{manifest;assets;programCache;planCache;prepareCache=new Map;constructor(n,t={}){this.manifest=tr(n),this.assets=Fc(t.assets??{}),this.programCache=t.programCache??new lt,this.planCache=t.planCache??new ct}explain(n,t,r={}){let a=ze(n.device),s=this.applyManifestDerive(this.buildBaseScope(a,t)),o=this.variantCandidates(r.variant).map(i=>{let u=this.checkVariant(i,s);return{id:i.id,ok:u.ok,...!u.ok&&u.reason?{reason:u.reason}:{}}});return{op:this.manifest.id,selected:o.find(i=>i.ok)?.id??null,candidates:o}}prepare(n,t,r={}){this.validateRequest(t);let a=ze(n.device),s=this.buildBaseScope(a,t),o=Ic(n.device,s,r.variant),i=this.prepareCache.get(o);if(i)return{program:i.program,plan:i.plan,request:t};let u=this.applyManifestDerive(s),{variant:l,scope:c}=this.selectVariantAndScope(u,t,r.variant),d=Na(this.manifest,l,c,this.programSpecialization(l,c)),p=this.programCache.getOrCreate(d,()=>this.buildProgram(d,l,c)),f=za(c),m=ja(d,f),_=this.planCache.getOrCreate(m,()=>this.buildPlan(m,d,f,l,c));return this.prepareCache.set(o,{program:p,plan:_}),{program:p,plan:_,request:t}}clearPreparedState(){this.prepareCache.clear(),this.programCache.clear(),this.planCache.clear()}inferOutputs(n,t={}){let r={};for(let[u,l]of Object.entries(n))l!==void 0&&(r[u]=Dc(l)?Lc(l):l);let a={resources:r,...t.args?{args:t.args}:{},...t.attrs?{attrs:t.attrs}:{}},s=this.applyManifestDerive(this.buildBaseScope(ze(void 0),a)),o=new Map;for(let[u,l]of Object.entries(this.manifest.args))l.kind==="tensor"&&(l.role==="output"||l.role==="inout")&&l.semantic&&o.set(l.semantic,u);let i={};for(let u of this.manifest.outputs){let l=o.get(u.role)??u.role;if(u.shape===void 0)throw new Error(`${this.manifest.id}: output "${u.role}" has no shape expression \u2014 add outputs[].shape to ops/${this.manifest.id}/manifest.json (docs/model-graph-builder.md).`);let c=typeof u.shape=="string"?Le(u.shape,s):u.shape.map(d=>je(d,s));if(!Array.isArray(c)||!c.every(d=>Number.isInteger(d)&&d>=0))throw new Error(`${this.manifest.id}: output "${u.role}" shape evaluated to ${JSON.stringify(c)} (expected non-negative integers)`);i[l]={role:u.role,shape:c,dtype:this.resolveOutputDtype(u,s)}}return i}resolveOutputDtype(n,t){if(!n.dtype)return"float32";if(Uc.has(n.dtype))return n.dtype;let r=t.dtypes[n.dtype];if(typeof r=="string")return On(r);let a=this.manifest.typeConstraints[n.dtype],s=t.tensorDtypes;for(let o of this.manifest.inputs){let i=s[o.role];if(typeof i=="string"&&(!Array.isArray(a)||a.includes(i)))return i}throw new Error(`${this.manifest.id}: output "${n.role}" dtype "${n.dtype}" is a constraint var with no bound input \u2014 pass a dtype override or bind an input sharing the var.`)}async run(n,t,r={}){let a=this.prepare(n,t,r),{executeWebGpuPlan:s}=await Promise.resolve().then(()=>(ir(),Za));return await s(n,a,r.runOptions??{}),a}prepareComputePassDescriptorTemplate(n,t,r={}){if(r.cacheKey!==void 0)return this.prepareDirectComputePassDescriptorTemplate(n,t,{...r,cacheKey:r.cacheKey});let a=this.prepare(n,t,r),s=Wc(a,r.pass),o=a.program.passes[s],i=a.plan.passes[s];if(!o||!i)throw new Error(`WebGPU op ${a.program.op} produced no compute pass descriptor template at index ${s}`);return Ya(o,i,`webgpu:${a.program.key}:pass=${o.id}`,a.program.key,a.plan.key,s)}prepareDirectComputePassDescriptorTemplate(n,t,r){this.validateRequest(t);let a=ze(n.device),s=this.applyManifestDerive(this.buildBaseScope(a,t)),{variant:o,scope:i}=this.selectVariantAndScope(s,t,r.variant),u=Mc(this.manifest.id,o,r.pass),l=o.passes[u],c=this.buildProgramPass(o,l,i),d=this.buildPlanPass(o,l,i,u);return Ya(c,d,r.cacheKey,r.cacheKey,r.cacheKey,u)}buildProgram(n,t,r){let a=t.passes.map(s=>this.buildProgramPass(t,s,r));return Object.freeze({key:n,op:this.manifest.id,variant:t.id,variantVersion:t.version,passes:Object.freeze(a)})}buildProgramPass(n,t,r){let a=this.passConstants(n,t,r),s={...r,variant:n,pass:t,constants:a},o=un(Da(t.bindings)),i=[Pa(o),Qt(o,a)].filter(Boolean).join(` -`),u=this.passSourceInputs(t.source,s),l={...s,sourceContext:u},c=this.buildTemplateSource(n,t,l,i),d=He(t.profile,l),p=He(t.metadata,l);return Object.freeze({id:t.id,name:t.name??`${this.manifest.id}.${n.id}.${t.id}`,source:c,entryPoint:t.entryPoint,bindings:o,bindingSpecs:t.bindings,constants:a,...Object.keys(d).length>0?{profile:d}:{},...Object.keys(p).length>0?{metadata:p}:{},reads:t.reads,writes:t.writes})}buildTemplateSource(n,t,r,a){let s=lr(t.source.shader,this.assets.readText(t.source.shader),u=>this.assets.readText(u),new Set),o=Jt(s,{...r,env:{device:Yt(r.device),wgsl:{resourceDeclarations:a}}}),i=er(o,r.device.features);if(i.length>0)throw new Error(`WebGPU op ${this.manifest.id} variant ${n.id} pass ${t.id} rendered WGSL enable directives the device does not support: ${i.join(", ")}. Gate the directive in the template (env.device.features) or declare the feature in the variant's requires.requiredFeatures.`);return o}programSpecialization(n,t){return{variant:He(n.constants,{...t,variant:n}),passes:n.passes.map(r=>({id:r.id,constants:He(r.constants,{...t,variant:n,pass:r}),source:this.passSourceSpecialization(n,r,t)}))}}passSourceSpecialization(n,t,r){let a=this.passConstants(n,t,r),s={...r,variant:n,pass:t,constants:a};return{kind:"template",shader:t.source.shader,sourceVersion:t.source.version??1,inputs:this.passSourceInputs(t.source,s)}}buildPlan(n,t,r,a,s){let o=Ka(a.intermediates,a.passes,s),i=a.passes.map((u,l)=>this.buildPlanPass(a,u,s,l));return Object.freeze({key:n,programKey:t,shapeKey:r,scratches:o,passes:Object.freeze(i)})}buildPlanPass(n,t,r,a){let s=this.passConstants(n,t,r),o={...r,variant:n,pass:t,constants:s},i={...o,sourceContext:this.passSourceInputs(t.source,o)},u=t.bindings.filter(l=>l.buffer.type==="uniform").reduce((l,c)=>(l[c.name]=this.uniformValues(c,t.uniforms[c.name],i),l),{});return Object.freeze({id:t.id,dispatchWorkgroups:this.passDispatchWorkgroups(t,i),uniforms:u,constants:{...s,passIndex:a}})}passDispatchWorkgroups(n,t){let r=t.device.limits.maxComputeWorkgroupsPerDimension;return[Le(n.dispatch.x,t),Le(n.dispatch.y??1,t),Le(n.dispatch.z??1,t)].map((a,s)=>{if(!Number.isInteger(a)||Number(a)<0)throw new Error(`WebGPU pass ${n.id} dispatch axis ${s} must resolve to a nonnegative integer, got ${String(a)}`);if(Number(a)>r)throw new Error(`WebGPU pass ${n.id} dispatch axis ${s} = ${a} exceeds maxComputeWorkgroupsPerDimension (${r}); clamp the dispatch (min(..., ${r})) and grid-stride over the remainder, or fold into 2D/3D.`);return Number(a)})}uniformValues(n,t,r){let a=n.struct;if(!a)throw new Error(`WebGPU uniform binding ${n.name} requires struct`);let s={};for(let o of a.fields){let i=t?.[o.name]??o.value??r.args[o.name]??o.default;if(i===void 0)continue;let u=Le(i,r);if(typeof u!="number"||!Number.isFinite(u))throw new Error(`WebGPU uniform ${n.name}.${o.name} must resolve to a finite number`);s[o.name]=u}return s}passConstants(n,t,r){return{...r.dtypes,...He(n.constants,{...r,variant:n,pass:t}),...He(t.constants,{...r,variant:n,pass:t})}}passSourceInputs(n,t){return Bc(He(n.inputs,t),`WebGPU template source ${n.shader} inputs`)}selectVariantAndScope(n,t,r){let a=this.selectVariant(n,r),s=this.applyVariantDerive(n,t,a,void 0);return{variant:a,scope:s}}selectVariant(n,t){let r=[];for(let a of this.variantCandidates(t)){let s=this.checkVariant(a,n);if(s.ok)return a;r.push(`${a.id}: ${s.reason}`)}throw new Error(`No supported WebGPU variant for ${this.manifest.id}; rejected ${r.join("; ")}`)}variantCandidates(n){if(n!==void 0){let r=this.manifest.variants.find(a=>a.id===n);if(!r)throw new Error(`WebGPU op ${this.manifest.id} has no variant ${n}`);return[r]}return[...this.manifest.variants].sort((r,a)=>r.default!==a.default?r.default?-1:1:a.priority-r.priority)}checkVariant(n,t){let r=Ct(n.requires,t.device);if(r)return{ok:!1,reason:r};let a={...t,variant:n},s=Array.isArray(n.when)?n.when:[n.when],o=s.length>1;for(let i of s){let u;try{u=Le(i,a)}catch(l){return{ok:!1,reason:`when eval error in \`${typeof i=="string"?i:String(i)}\`: ${l.message}`}}if(u!==!0){let l=typeof i=="string"?i:String(i);return{ok:!1,reason:o?`when clause failed: \`${l}\` \u2192 ${String(u)}`:`when guard resolved to ${String(u)}`}}}if(n.selectAbove!==null){let i;try{i=Le(n.selectAbove,a)}catch(u){return{ok:!1,reason:`selectAbove eval error in \`${n.selectAbove}\`: ${u.message}`}}if(i!==!0)return{ok:!1,reason:`below perf floor: \`${n.selectAbove}\` \u2192 ${String(i)}`}}return{ok:!0}}buildBaseScope(n,t){let r={...t.resources},a={...this.manifest.attributes,...t.attrs??{}},s={...t.args??{}},o={...t.sourceContext??{}};for(let[f,m]of Object.entries(r))!it(m)&&typeof m!="object"&&(s[f]=m);let i=Object.fromEntries(Object.keys({...this.manifest.args,...r}).map(f=>[f,r[f]!==void 0&&r[f]!==null])),u={},l={},c={},d={};for(let[f,m]of Object.entries(this.manifest.args)){let _=r[f];if(!it(_))continue;let E=[f,m.semantic,m.role].filter(b=>typeof b=="string"&&b.length>0);for(let b of E)u[b]=_.shape,l[b]=_.shape.length,c[b]=_.dtype}for(let f of[...this.manifest.inputs,...this.manifest.outputs]){if(!f.dtype)continue;let m=c[f.role];m!==void 0&&(d[f.dtype]=Zt(m))}return{op:this.manifest,device:n,attrs:a,args:s,sourceContext:o,resources:r,present:i,shapes:u,ranks:l,tensorDtypes:c,dtypes:d,derived:{},tunables:{...this.manifest.tunables,...t.tunables??{}},constants:{}}}applyManifestDerive(n){let t={};for(let[r,a]of Object.entries(this.manifest.derive))t[r]=je(a,{...n,derived:t});return{...n,derived:t}}applyVariantDerive(n,t,r,a){let s={...n,variant:r,tunables:{...this.manifest.tunables,...r.tunables,...a??{},...t.tunables??{}}},o={...n.derived};for(let[i,u]of Object.entries(r.derive))o[i]=je(u,{...s,derived:o});return{...s,derived:o}}validateRequest(n){for(let[t,r]of Object.entries(this.manifest.args)){let a=n.resources[t]??n.args?.[t];if(a==null){if(r.required!==!1)throw new Error(`WebGPU op ${this.manifest.id} missing required arg ${t}`);continue}Rc(t,r,a)}}};Gc=/{%\s*include\s+["']([^"']+)["']\s*%}/g;Ja=new WeakMap;Uc=new Set(["float32","float16","uint32","int32","uint8","int8"])});var ts,rs,as=he(()=>{ts=new Map([["ops/_shared/norm-row-stats.wgsl.jinja",`{% if source.usesF16 %} +If a string literal was intended, quote it (e.g. '"${a[0]}"' not '${a[0]}').`);if(t.statement===void 0)throw t.parseError??new Error(`Empty WebGPU expression: ${e}`);let s=new Ie;for(let[o,i]of Xl)s.set(o,i);for(let o of t.freeIdentifiers)s.set(o,r[o]);for(let o of t.probedIdentifiers)o in r&&s.set(o,r[o]);return Gn(new Mr(s).evaluate(t.statement,s))}function Jr(e,n={}){return Zl(e,qa(n))}function Zl(e,n){let r=Ra.get(e);r||(r=new Hn(e),Ra.set(e,r));let t=Jl(e),a=t?Yl(n,t):n;return r.render(a)}function Yl(e,n){let r={};for(let t of Object.keys(e))n.has(t)&&(r[t]=e[t]);return r}function Jl(e){let n=Fa.get(e);if(n!==void 0)return n;let r;try{let t=Kn($n(e,Ia)),a=new Set,s=o=>{if(!o||typeof o!="object")return;if(Array.isArray(o)){for(let u of o)s(u);return}if(o instanceof Map){for(let[u,l]of o)s(u),s(l);return}let i=o;i.type==="Identifier"&&typeof i.value=="string"&&a.add(i.value);for(let u of Object.keys(i))u!=="type"&&s(i[u])};s(t),r=a}catch{r=null}return Fa.set(e,r),r}function nc(e){let n=Ma.get(e);if(n!==void 0)return n;let r=new Set,t=new Set,a=i=>{if(!i||typeof i!="object")return;if(Array.isArray(i)){for(let l of i)a(l);return}if(i instanceof Map){for(let[l,c]of i)a(l),a(c);return}let u=i;switch(u.type){case"Identifier":ec.has(u.value)||r.add(u.value);return;case"MemberExpression":a(u.object),u.computed&&a(u.property);return;case"BinaryExpression":a(u.left),a(u.right);return;case"UnaryExpression":a(u.argument);return;case"FilterExpression":{a(u.operand);let l=u.filter;l?.type==="CallExpression"&&a(l.args);return}case"TestExpression":{let l=u.test,c=u.operand;(l?.value==="defined"||l?.value==="undefined")&&c?.type==="Identifier"?t.add(c.value):a(u.operand);return}case"CallExpression":a(u.callee),a(u.args);return;case"KeywordArgumentExpression":a(u.value);return;default:{for(let[l,c]of Object.entries(u))l!=="type"&&a(c);return}}},s,o;try{let i=Kn($n(`{{ ${e} }}`,Ia));s=i.body[0],a(i)}catch(i){o=i}for(let i of r)t.delete(i);return n=Object.freeze({statement:s,...o!==void 0?{parseError:o}:{},freeIdentifiers:Object.freeze([...r]),probedIdentifiers:Object.freeze([...t])}),Ma.set(e,n),n}function He(e,n){let r={};for(let[t,a]of Object.entries(e??{}))r[t]=je(a,n);return r}function je(e,n){return typeof e=="string"?Le(e,n):Array.isArray(e)?e.map(r=>je(r,n)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([r,t])=>[r,je(t,n)])):e}var Ra,Ba,Ql,Wa,Xl,Fa,Ma,Ia,ec,rr=he(()=>{"use strict";Br();kn();Ra=new Map;Ba=Object.freeze({ceil:de(e=>Math.ceil(e)),floor:de(e=>Math.floor(e)),min:de((...e)=>Math.min(...e)),max:de((...e)=>Math.max(...e)),pow:de((e,n)=>Math.pow(e,n)),ceilDiv:de((e,n)=>Math.ceil(e/n)),pow2ceil:de(e=>e<=1?1:2**Math.ceil(Math.log2(e))),numel:de(e=>e.reduce((n,r)=>n*r,1)),rank:de(e=>e.length),dim:de((e,n)=>{let r=(n%e.length+e.length)%e.length;return e[r]}),rows:de((e,n)=>{let r=(n%e.length+e.length)%e.length;return e.reduce((t,a,s)=>s===r?t:t*a,1)}),cols:de((e,n)=>{let r=(n%e.length+e.length)%e.length;return e[r]}),outer:de((e,n)=>{let r=(n%e.length+e.length)%e.length;return e.slice(0,r).reduce((t,a)=>t*a,1)}),inner:de((e,n)=>{let r=(n%e.length+e.length)%e.length;return e.slice(r+1).reduce((t,a)=>t*a,1)}),broadcastable:de((e,n)=>{if(e.length>n.length)return!1;let r=n.length-e.length;return e.every((t,a)=>t===1||t===n[a+r])}),sameShape:de((e,n)=>e.length===n.length&&e.every((r,t)=>r===n[t])),hasAxis:de((e,n,r)=>{let t=(n%r+r)%r;return e.some(a=>(a%r+r)%r===t)}),has:de((e,n)=>e instanceof Map?e.has(n):!!(e&&Object.prototype.hasOwnProperty.call(e,n))),dtypeBytes:de(e=>{if(e==="float16"||e==="f16")return 2;if(e==="float32"||e==="f32"||e==="uint32"||e==="u32"||e==="uint8"||e==="int32"||e==="i32"||e==="int8")return 4;throw new Error(`Unsupported dtype for dtypeBytes(): ${e}`)}),pick:de((e,n)=>{if(!Array.isArray(e))throw new Error("pick() expects a list of [condition, value] pairs as its first argument");for(let r of e){if(!Array.isArray(r)||r.length<2)throw new Error("pick() entries must be [condition, value] pairs");if(r[0])return r[1]}return n})});Ql=["f16Ok","f16Allowed"];Wa=new WeakMap;Xl=[["true",!0],["false",!1],["none",null],["True",!0],["False",!1],["None",null]];Fa=new Map;Ma=new Map,Ia=Object.freeze({lstrip_blocks:!0,trim_blocks:!0}),ec=new Set(["true","false","none","True","False","None"])});function et(e,n){let r=[];for(let t of e.split(` +`)){let a=rc.exec(t);if(a)for(let s of a[1].split(",")){let o=s.trim();if(o.length===0)continue;let i=Da[o];i&&!n.has(i)&&r.push(`enable ${o}; (requires device feature "${i}")`)}}return r}var Da,rc,nt=he(()=>{"use strict";Da=Object.freeze({f16:"shader-f16",subgroups:"subgroups",chromium_experimental_subgroup_matrix:"chromium-experimental-subgroup-matrix"}),rc=/^\s*enable\s+([^;]+);/});function Je(e){let n=e instanceof Map?new Map(e):new Map(Object.entries(e));return Object.freeze({readText(r){let t=n.get(r);if(t===void 0)throw new Error(`WebGPU template asset is missing: ${r}`);return t},has(r){return n.has(r)}})}function rt(e){sr(e,"WebGPU manifest");let n=e.schemaVersion??1;if(n!==1)throw new Error(`Unsupported WebGPU manifest schemaVersion: ${n}`);let r=e.domain??"ai.onnx";hc(r,"WebGPU manifest domain");let t=e.name;if(typeof t!="string"||t.length===0)throw new Error("WebGPU manifest requires a non-empty name");if(!Array.isArray(e.inputs))throw new Error(`WebGPU manifest ${r}.${t} requires inputs`);if(!Array.isArray(e.outputs))throw new Error(`WebGPU manifest ${r}.${t} requires outputs`);if(!tt(e.args)||Object.keys(e.args).length===0)throw new Error(`WebGPU manifest ${r}.${t} requires explicit args`);gc(e.args,`${r}.${t}.args`);let a=sc(e,`${r}.${t}`),s=oc(e,a);return Object.freeze({schemaVersion:1,domain:r,name:t,id:`${r}.${t}`,sinceVersion:e.sinceVersion,inputs:Object.freeze([...e.inputs]),outputs:Object.freeze([...e.outputs]),args:Object.freeze({...e.args}),attributes:Object.freeze({...e.attributes??{}}),derive:Object.freeze({...e.derive??{}}),typeConstraints:Object.freeze({...e.typeConstraints??{}}),tunables:Object.freeze({...e.tunables??{}}),staticShapes:Object.freeze([...e.staticShapes??[]]),variants:Object.freeze(s)})}function Ua(e){return e.map(n=>{if(n.buffer.type==="uniform"){if(!n.struct)throw new Error(`WebGPU uniform binding ${n.name} requires struct`);return Vr(n.name,Pn(n.struct.name,n.struct.fields.map(mc)),{semantic:n.semantic,binding:n.binding,group:n.group})}return Hr(n.name,{arg:n.arg,access:n.buffer.type==="storage"?"read_write":"read",elementType:n.elementType,semantic:n.semantic??n.role,role:n.role,binding:n.binding,group:n.group})})}function sc(e,n){let r=new Map;for(let[t,a]of Object.entries(e.bindingSets??{})){if(!Array.isArray(a)||a.length===0)throw new Error(`WebGPU manifest ${n} bindingSet "${t}" must be a non-empty binding array`);r.set(t,a)}return r}function La(e,n,r){if(Array.isArray(e))return e;if(typeof e=="string"){let t=n.get(e);if(!t)throw new Error(`WebGPU ${r} references unknown bindingSet "${e}"`);return t}if(e&&typeof e=="object"&&typeof e.set=="string"){let t=e,a=n.get(t.set);if(!a)throw new Error(`WebGPU ${r} references unknown bindingSet "${t.set}"`);let s=t.overrides??{};for(let o of Object.keys(s))if(!a.some(i=>i.name===o))throw new Error(`WebGPU ${r} bindingSet "${t.set}" has no binding "${o}" to override`);return a.map(o=>{let i=o.name!==void 0?s[o.name]:void 0;return i?{...o,...i}:o})}throw new Error(`WebGPU ${r} bindings must be an array, a bindingSet name, or { set, overrides }`)}function oc(e,n){let r=`${e.domain??"ai.onnx"}.${e.name}`,t=ac.filter(s=>e[s]!==void 0);if(t.length>0)throw new Error(`WebGPU manifest ${r} uses the retired flattened dialect: top-level ${t.join(", ")} is no longer accepted. Declare ${t.length===1?"it":"them"} on variants[].passes[] instead (docs/kernel-authoring-framework.md \xA74).`);let a=ar(e,r);if(a.length===0)throw new Error(`WebGPU manifest ${r} requires a non-empty variants list`);return a.map((s,o)=>uc(s,o,n))}function ar(e,n){let r=[...e.variants??[]];for(let t of e.variantFamilies??[]){let a=Object.keys(t.axes??{});if(a.length===0)throw new Error(`WebGPU manifest ${n}: a variantFamily requires at least one axis`);if(!Array.isArray(t.variants)||t.variants.length===0)throw new Error(`WebGPU manifest ${n}: a variantFamily requires at least one base variant`);for(let s of a){let o=t.axes[s];if(!Array.isArray(o)||o.length===0)throw new Error(`WebGPU manifest ${n}: variantFamily axis "${s}" must be a non-empty array`)}for(let s of ic(a,t.axes))for(let o of t.variants)r.push(tr(o,s))}return r}function ic(e,n){let r=[{}];for(let t of e)r=r.flatMap(a=>n[t].map(s=>({...a,[t]:s})));return r}function tr(e,n){if(typeof e=="string")return e.replace(/\{([A-Za-z_]\w*)\}/g,(r,t)=>t in n?String(n[t]):r);if(Array.isArray(e))return e.map(r=>tr(r,n));if(e!==null&&typeof e=="object"){let r={};for(let[t,a]of Object.entries(e))r[tr(t,n)]=tr(a,n);return r}return e}function uc(e,n,r){sr(e,"WebGPU variant");let t=e.id??e.name??`variant_${n}`;if(!/^[A-Za-z0-9][A-Za-z0-9_]*$/.test(t))throw new Error(`WebGPU variant id must be stable, got ${t}`);let a=e.passes;if(!Array.isArray(a)||a.length===0)throw new Error(`WebGPU variant ${t} requires passes`);let s=e.bindings!==void 0?La(e.bindings,r,`variant ${t}`):void 0,o=e.version??1;if(!Number.isInteger(o)||o<1)throw new Error(`WebGPU variant ${t} version must be an integer >= 1`);return Object.freeze({id:t,name:e.name??t,version:o,default:!!e.default,priority:e.priority??0,when:pc(e.when,t),selectAbove:typeof e.selectAbove=="string"&&e.selectAbove.length>0?e.selectAbove:null,requires:fc(e),tunables:Object.freeze({...e.tunables??{}}),derive:Object.freeze({...e.derive??{}}),constants:Object.freeze({...e.constants??{}}),intermediates:Object.freeze([...e.intermediates??[]]),passes:Object.freeze(a.map((i,u)=>lc(i,s,u,r)))})}function lc(e,n,r,t){let a=cc(e,r);if(!e.dispatch)throw new Error(`WebGPU pass ${e.id??r} requires dispatch`);let s=e.bindings!==void 0?La(e.bindings,t,`pass ${e.id??r}`):n;if(!Array.isArray(s)||s.length===0)throw new Error(`WebGPU pass ${e.id??r} requires bindings`);return Object.freeze({id:e.id??`pass_${r}`,...e.name?{name:e.name}:{},shader:a.shader,source:a,entryPoint:e.entryPoint??"main",bindings:Object.freeze(s.map(dc)),constants:Object.freeze({...e.constants??{}}),uniforms:Object.freeze({...e.uniforms??{}}),dispatch:e.dispatch,profile:Object.freeze({...e.profile??{}}),metadata:Object.freeze({...e.metadata??{}}),reads:Object.freeze([...e.reads??[]]),writes:Object.freeze([...e.writes??[]])})}function cc(e,n){let r=`WebGPU pass ${e.id??n}`,t=e.source;if(t!==void 0){if(sr(t,`${r}.source`),t.kind==="template"){let a=t.shader??e.shader;if(typeof a!="string"||a.length===0)throw new Error(`${r} template source requires shader`);if(e.shader!==void 0&&e.shader!==a)throw new Error(`${r} has conflicting shader and source.shader`);if(t.version!==void 0&&typeof t.version!="string"&&typeof t.version!="number")throw new Error(`${r} template source version must be a string or number`);if(t.inputs!==void 0&&!tt(t.inputs))throw new Error(`${r} template source inputs must be an object`);return Object.freeze({kind:"template",shader:a,...t.version!==void 0?{version:t.version}:{},inputs:Object.freeze({...t.inputs??{}})})}throw new Error(`${r} source has unsupported kind ${t.kind}`)}if(typeof e.shader!="string"||e.shader.length===0)throw new Error(`${r} requires shader or source`);return Object.freeze({kind:"template",shader:e.shader,inputs:Object.freeze({})})}function dc(e,n){if(sr(e,`WebGPU binding ${n}`),e.optional===!0)throw new Error(`WebGPU binding ${e.name??e.role??n} cannot be optional; use a separate variant`);let r=e.buffer?.type;if(!r||!tc.has(r))throw new Error(`WebGPU binding ${e.name??e.role??n} has invalid buffer type`);let t=e.name??e.role??e.semantic;if(typeof t!="string"||!/^[A-Za-z_][A-Za-z0-9_]*$/.test(t))throw new Error(`WebGPU binding requires a WGSL-compatible name, got ${String(t)}`);let a=Object.freeze({name:t,...e.role!==void 0?{role:e.role}:{},...e.semantic!==void 0?{semantic:e.semantic}:{},...e.arg!==void 0?{arg:e.arg}:{},buffer:{type:r},...e.elementType?{elementType:e.elementType}:{},...e.struct?{struct:e.struct}:{},...e.binding!==void 0?{binding:e.binding}:{},...e.group!==void 0?{group:e.group}:{}});if(r==="uniform"&&!a.struct)throw new Error(`WebGPU uniform binding ${t} requires struct`);if(r!=="uniform"&&!a.elementType)throw new Error(`WebGPU storage binding ${t} requires elementType`);return a}function pc(e,n){if(e===void 0)return!0;if(Array.isArray(e)){if(e.length===0)throw new Error(`WebGPU variant ${n} when[] must be a non-empty list of predicates`);for(let r of e)if(typeof r!="string"||r.length===0)throw new Error(`WebGPU variant ${n} when[] entries must be non-empty expression strings, got ${JSON.stringify(r)}`);return Object.freeze([...e])}if(typeof e!="string"&&typeof e!="boolean")throw new Error(`WebGPU variant ${n} when must be a string, boolean, or string[], got ${JSON.stringify(e)}`);return e}function fc(e){let n={...e.requiredFeatures?{requiredFeatures:e.requiredFeatures}:{},...e.requiredLimits?{requiredLimits:e.requiredLimits}:{},...e.requiredWGSLLanguageFeatures?{requiredWGSLLanguageFeatures:e.requiredWGSLLanguageFeatures}:{},...e.requiredSubgroupMinSize!==void 0?{requiredSubgroupMinSize:e.requiredSubgroupMinSize}:{}};if(n.requiredSubgroupMinSize!==void 0&&(!Number.isInteger(n.requiredSubgroupMinSize)||n.requiredSubgroupMinSize<1))throw new Error(`WebGPU variant ${e.id??e.name??"?"} requiredSubgroupMinSize must be a positive integer`);return Object.keys(n).length===0?null:n}function mc(e){if(e.type==="u32")return Nr(e.name,e);if(e.type==="i32")return zr(e.name,e);if(e.type==="f32")return jr(e.name,e);throw new Error(`Unsupported WebGPU uniform field type: ${e.type}`)}function gc(e,n){for(let[r,t]of Object.entries(e)){if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(r))throw new Error(`${n}.${r} is not a valid arg name`);if(!["tensor","u32","i32","f32","bool","string"].includes(t.kind))throw new Error(`${n}.${r} has unsupported kind ${String(t.kind)}`)}}function hc(e,n){if(!/^[a-z][a-z0-9]*(?:\.[A-Za-z][A-Za-z0-9_]*)*$/.test(e))throw new Error(`${n} must be a dotted canonical domain, got ${e}`)}function sr(e,n){if(!tt(e))throw new Error(`${n} must be an object`)}function tt(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}var tc,ac,or=he(()=>{"use strict";An();nr();tc=new Set(["read-only-storage","storage","uniform"]);ac=["shader","entryPoint","bindings","constants","uniforms","profile","metadata","dispatch"]});function Rn(e){if(e===ee.float16)return 2;if(e===ee.float32||e===ee.int8||e===ee.int32||e===ee.uint8||e===ee.uint32)return 4;throw new Error(`Unsupported dtype: ${e}`)}function Ve(e){if(!Array.isArray(e))throw new Error("shape must be an array");let n=1;for(let r of e){if(!Number.isInteger(r)||r<0)throw new Error(`invalid shape dimension: ${r}`);n*=r}return n}function Ca(e){let n=new Array(e.length),r=1;for(let t=e.length-1;t>=0;--t)n[t]=r,r*=e[t];return n}function ir(e){return e!==null&&typeof e=="object"&&typeof e.dtype=="string"&&Array.isArray(e.shape)&&typeof e.size=="number"&&typeof e.byteLength=="number"&&"buffer"in e&&"runtime"in e}var ee,Wn=he(()=>{"use strict";ee=Object.freeze({float16:"float16",float32:"float32",int8:"int8",int32:"int32",uint8:"uint8",uint32:"uint32"})});function at(e){return{attrs:e.attrs,dtypes:e.dtypes,tensorDtypes:e.tensorDtypes,ranks:e.ranks,tunables:e.tunables}}function Na(e,n,r,t=null){return Qe({op:e.id,sinceVersion:e.sinceVersion,variant:n.id,variantVersion:n.version,...at(r),staticShapes:bc(r,e.staticShapes),specialization:t,device:xn(r.device),bindings:n.passes.map(a=>a.bindings.map(s=>({name:s.name,binding:s.binding,group:s.group,type:s.buffer.type,elementType:s.elementType,struct:yc(s.struct)})))})}function yc(e){return e&&{name:e.name,fields:e.fields.map(n=>({name:n.name,type:n.type}))}}function za(e){return Qe({shapes:e.shapes,args:e.args})}function ja(e,n){return`${e}|shapes=${n}`}function Qe(e){return Array.isArray(e)?`[${e.map(Qe).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().map(n=>`${JSON.stringify(n)}:${Qe(e[n])}`).join(",")}}`:JSON.stringify(e)}function bc(e,n){let r={};for(let t of n){let[a,s]=t.split("."),o=e.shapes[a];if(!o)continue;if(s===void 0||s==="*"){r[t]=o;continue}let i=Number(s);Number.isInteger(i)&&(r[t]=o[i])}return r}var ur,lr,cr,$a=he(()=>{"use strict";kn();ur=class{entries=new Map;hits=0;misses=0;get(n){let r=this.entries.get(n);if(r===void 0){this.misses+=1;return}return this.hits+=1,r}getOrCreate(n,r){let t=this.get(n);if(t!==void 0)return t;let a=r();return this.entries.set(n,a),a}clear(){this.entries.clear(),this.hits=0,this.misses=0}},lr=class extends ur{},cr=class extends ur{}});function Ka(e,n,r){return e.map(t=>{let a=je(t.shape,r),s=_c(a,t.id),o=On(t.dtype),i=wc(t.id,n);return Object.freeze({id:t.id,dtype:o,shape:s,firstWrite:i.firstWrite,lastRead:i.lastRead,byteLength:Ve(s)*Rn(o)})})}function wc(e,n){let r=Number.POSITIVE_INFINITY,t=-1;for(let a=0;a{if(!Number.isInteger(t)||Number(t)<0)throw new Error(`WebGPU scratch ${n} shape dimension must be a nonnegative integer, got ${String(t)}`);return Number(t)}))}var Ha=he(()=>{"use strict";Wn();rr()});var Za={};Eo(Za,{executeWebGpuPlan:()=>vc,materializeComputePassDescriptorTemplate:()=>Qa,materializeWebGpuExecutionPlan:()=>Fn});async function vc(e,n,r={}){let t=Fn(e,n);try{if(t.programs.length===0)return;if(typeof e.runProgramSequence=="function")await e.runProgramSequence(t.programs,r);else for(let a of t.programs)await e.runProgram(a,r)}finally{t.cleanup()}}function Fn(e,n){let r=Tc(e,n),t=[],a=[];for(let s=0;sl[d.name]);let c=Aa(e,o.bindings,l,{labelPrefix:o.name});t.push(c.cleanup),a.push({name:o.name,source:o.source,entryPoint:o.entryPoint,cacheKey:`webgpu:${n.program.key}:pass=${o.id}`,bindings:c.bindings,dispatchWorkgroups:i.dispatchWorkgroups,...o.profile?{profile:o.profile}:{},...o.semantic!==void 0?{semantic:o.semantic}:{},...o.metadata?{metadata:o.metadata}:{},plan:{webgpuPlanKey:n.plan.key,pass:i.id,scratches:n.plan.scratches}})}return{programs:a,cleanup:()=>{for(let s of t)s();for(let s of Object.values(r))typeof s.destroy=="function"&&s.destroy()}}}function Qa(e,n){return Xa(`${e.name} (program ${e.programKey}, pass ${e.id})`,e.bindingSpecs,r=>ot(r,n)),{name:e.name,source:e.source,entryPoint:e.entryPoint,cacheKey:e.cacheKey,bindings:e.bindingSpecs.map((r,t)=>Sc(e,r,n,t)),dispatchWorkgroups:e.dispatchWorkgroups,...e.profile?{profile:e.profile}:{},...e.metadata?{metadata:e.metadata}:{},plan:{webgpuProgramKey:e.programKey,webgpuPlanKey:e.planKey,pass:e.id}}}function Sc(e,n,r,t){let a=ot(n,r);if(a==null)throw new Error(`Missing resource for compute pass descriptor template binding ${n.name}`);let s=n.binding??t;if(n.buffer.type==="uniform"){if(!Xr(a))throw new Error(`Compute pass descriptor template ${e.name} requires caller-owned uniform buffer for ${n.name}`);return{buffer:a,type:"uniform",binding:s,...n.group?{group:n.group}:{}}}let o=a,i=typeof o.byteOffset=="number"?o.byteOffset:0,u=typeof o.byteLength=="number"?o.byteLength:void 0;return{tensor:a,type:n.buffer.type,binding:s,...n.group?{group:n.group}:{},...i?{offset:i}:{},...u!==void 0?{size:u}:{}}}function ot(e,n){return n[e.arg??""]??n[e.name]??n[e.role??""]??n[e.semantic??""]}function Tc(e,n){let r={};if(n.plan.scratches.length===0)return r;if(typeof e.empty!="function")throw new Error("WebGPU multi-pass plan requires a runtime with empty(dtype, shape)");for(let t of n.plan.scratches)r[t.id]=e.empty(t.dtype,t.shape,`webgpu-scratch-${t.id}`);return r}function xc(e,n,r,t){let a={};for(let s of n){if(s.buffer.type==="uniform"){let o=Va(e,s,t);a[s.name]=o??r[s.name];continue}a[s.name]=Va(e,s,t)}return a}function Va(e,n,r){return r[n.name]??r[n.role??""]??r[n.semantic??""]??ot(n,e.request.resources)}function Xa(e,n,r){let t=null;for(let a of n){let s=kc(a);if(s===null)continue;let o=st(r(a));if(o===null)continue;t===null&&(t=new Map);let i=t.get(o.buffer);if(i===void 0){t.set(o.buffer,{name:a.name,access:s,view:o});continue}if(i.access==="read"&&s==="read")continue;if(i.access==="read_write"&&s==="read_write"){if(!Ac(i.view.offset,i.view.end,o.offset,o.end))continue;throw new Error(`${e}: storage bindings "${i.name}" and "${a.name}" alias overlapping writable ranges of the same GPU buffer; overlapping storage aliases are unsafe when either binding is writable`)}let[u,l]=s==="read_write"?[i.name,a.name]:[a.name,i.name];throw new Error(`${e}: storage aliasing hazard \u2014 binding "${u}" (read-only-storage) and binding "${l}" (storage, read_write) resolve to the same GPU buffer. WebGPU usage scopes cover the whole buffer, so this poisons the entire command buffer and corrupts downstream results. Bind it once as storage (read_write) for intentional in-place, or use distinct buffers.`)}}function kc(e){if("buffer"in e&&e.buffer!==void 0)switch(e.buffer.type){case"read-only-storage":return"read";case"storage":return"read_write";default:return null}let n=e;return n.kind==="storage"?n.access:null}function Ec(e,n){let r=n.metadata?.viewAlias;if(r===void 0)return null;let t=r;if(t===null||typeof t!="object"||typeof t.input!="string"||typeof t.output!="string")throw new Error(`${e}: pass metadata.viewAlias must be an object naming two bindings, e.g. { "input": "\\"x\\"", "output": "\\"y\\"" } (values are expressions, so quote the binding names)`);return{input:t.input,output:t.output}}function Pc(e,n,r){let t=Ec(e,n);if(t===null)return!1;let a=n.bindingSpecs.find(u=>u.name===t.input),s=n.bindingSpecs.find(u=>u.name===t.output);if(!a||a.buffer.type!=="read-only-storage")throw new Error(`${e}: metadata.viewAlias.input "${t.input}" must name a read-only-storage binding of the pass`);if(!s||s.buffer.type!=="storage")throw new Error(`${e}: metadata.viewAlias.output "${t.output}" must name a storage (read_write) binding of the pass`);let o=st(r[t.input]),i=st(r[t.output]);return o===null||i===null?!1:o.buffer===i.buffer&&o.offset===i.offset&&o.end===i.end}function st(e){if(e===null||typeof e!="object")return null;let n=e,r=n.buffer??e;if(r===null||typeof r!="object"&&typeof r!="function")return null;let t=typeof n.byteOffset=="number"?n.byteOffset:0,a=typeof n.byteLength=="number"?n.byteLength:typeof n.size=="number"?n.size:Number.POSITIVE_INFINITY;return{buffer:r,offset:t,end:t+a}}function Ac(e,n,r,t){return e{"use strict";An()});function Ya(e,n,r,t,a,s){return Object.freeze({id:e.id,name:e.name,source:e.source,entryPoint:e.entryPoint,cacheKey:r,bindings:e.bindings,bindingSpecs:e.bindingSpecs,dispatchWorkgroups:n.dispatchWorkgroups,uniforms:n.uniforms,constants:n.constants,...e.profile?{profile:e.profile}:{},...e.metadata?{metadata:e.metadata}:{},programKey:t,planKey:a,passIndex:s})}function lt(e,n,r,t){let a=dr(e);if(t.has(a))throw new Error(`Circular WebGPU template include: ${[...t,a].join(" -> ")}`);t.add(a);let s=n.replace(Gc,(o,i)=>{let u=Oc(a,i);return lt(u,r(u),r,t)});return t.delete(a),s}function Oc(e,n){if(n.startsWith(".")){let r=e.slice(0,Math.max(0,e.lastIndexOf("/")));return dr(`${r}/${n}`)}return dr(n)}function dr(e){let n=[];for(let r of e.replaceAll("\\","/").split("/"))if(!(r===""||r===".")){if(r===".."){if(n.length===0)throw new Error(`WebGPU template path escapes package root: ${e}`);n.pop();continue}n.push(r)}return n.join("/")}function Rc(e,n,r){if(n.kind==="tensor"){if(!ir(r))throw new Error(`WebGPU arg ${e} must be a GPU tensor`);if(n.dtype&&r.dtype!==n.dtype)throw new Error(`WebGPU arg ${e} dtype ${r.dtype} does not match ${n.dtype}`);return}if(n.kind==="string"){if(typeof r!="string")throw new Error(`WebGPU arg ${e} must be a string`);if(n.oneOf&&!n.oneOf.includes(r))throw new Error(`WebGPU arg ${e} must be one of ${n.oneOf.join(", ")}`);return}if(n.kind==="bool"){if(typeof r!="boolean")throw new Error(`WebGPU arg ${e} must be a boolean`);return}if(typeof r!="number"||!Number.isFinite(r))throw new Error(`WebGPU arg ${e} must be a finite number`);if(n.kind==="u32"&&(!Number.isInteger(r)||r<0||r>4294967295))throw new Error(`WebGPU arg ${e} must be a u32`);if(n.kind==="i32"&&(!Number.isInteger(r)||r<-2147483648||r>2147483647))throw new Error(`WebGPU arg ${e} must be an i32`)}function Wc(e){return typeof e.readText=="function"?e:Je(e)}function Fc(e,n){return es(`WebGPU op ${e.program.op}`,e.program.passes,n)}function Mc(e,n,r){return es(`WebGPU op ${e} variant ${n.id}`,n.passes,r)}function es(e,n,r){if(r===void 0){if(n.length!==1)throw new Error(`${e} has ${n.length} passes; select a pass by id or index`);return 0}if(typeof r=="number"){if(!Number.isInteger(r)||r<0||r>=n.length)throw new Error(`${e} has no pass index ${r}`);return r}let t=n.findIndex(a=>a.id===r);if(t<0)throw new Error(`${e} has no pass ${r}`);return t}function Bc(e,n){if(!ns(e))throw new Error(`${n} must be a JSON object`);return ut(e,n)}function ut(e,n){if(e===null)return null;if(typeof e=="boolean"||typeof e=="string")return e;if(typeof e=="number"){if(!Number.isFinite(e))throw new Error(`${n} number must be finite`);return e}if(Array.isArray(e))return Object.freeze(e.map((r,t)=>ut(r,`${n}[${t}]`)));if(ns(e)){let r={};for(let[t,a]of Object.entries(e)){if(a===void 0)throw new Error(`${n}.${t} must be JSON; got undefined`);r[t]=ut(a,`${n}.${t}`)}return Object.freeze(r)}throw new Error(`${n} must be JSON-compatible`)}function ns(e){if(e===null||typeof e!="object"||Array.isArray(e))return!1;let n=Object.getPrototypeOf(e);return n===Object.prototype||n===null}function qc(e,n){if(e&&typeof e=="object"){let r=Ja.get(e);return r===void 0&&(r=Qe(xn(n)),Ja.set(e,r)),r}return Qe(xn(n))}function Ic(e,n,r){return Qe({v:r??null,d:qc(e,n.device),...at(n),args:n.args,shapes:n.shapes,present:n.present,source:n.sourceContext})}function Uc(e){return e!==null&&typeof e=="object"&&typeof e.dtype=="string"&&Array.isArray(e.shape)}function Lc(e){let n=e.shape.reduce((r,t)=>r*t,1);return{dtype:e.dtype,shape:e.shape,size:n,byteLength:n*4,buffer:{},runtime:null}}var Mn,Gc,Ja,Dc,Bn=he(()=>{"use strict";An();Wn();$a();kn();rr();or();Ha();nt();Mn=class{manifest;assets;programCache;planCache;prepareCache=new Map;constructor(n,r={}){this.manifest=rt(n),this.assets=Wc(r.assets??{}),this.programCache=r.programCache??new lr,this.planCache=r.planCache??new cr}explain(n,r,t={}){let a=ze(n.device),s=this.applyManifestDerive(this.buildBaseScope(a,r)),o=this.variantCandidates(t.variant).map(i=>{let u=this.checkVariant(i,s);return{id:i.id,ok:u.ok,...!u.ok&&u.reason?{reason:u.reason}:{}}});return{op:this.manifest.id,selected:o.find(i=>i.ok)?.id??null,candidates:o}}prepare(n,r,t={}){this.validateRequest(r);let a=ze(n.device),s=this.buildBaseScope(a,r),o=Ic(n.device,s,t.variant),i=this.prepareCache.get(o);if(i)return{program:i.program,plan:i.plan,request:r};let u=this.applyManifestDerive(s),{variant:l,scope:c}=this.selectVariantAndScope(u,r,t.variant),d=Na(this.manifest,l,c,this.programSpecialization(l,c)),p=this.programCache.getOrCreate(d,()=>this.buildProgram(d,l,c)),f=za(c),m=ja(d,f),_=this.planCache.getOrCreate(m,()=>this.buildPlan(m,d,f,l,c));return this.prepareCache.set(o,{program:p,plan:_}),{program:p,plan:_,request:r}}clearPreparedState(){this.prepareCache.clear(),this.programCache.clear(),this.planCache.clear()}inferOutputs(n,r={}){let t={};for(let[u,l]of Object.entries(n))l!==void 0&&(t[u]=Uc(l)?Lc(l):l);let a={resources:t,...r.args?{args:r.args}:{},...r.attrs?{attrs:r.attrs}:{}},s=this.applyManifestDerive(this.buildBaseScope(ze(void 0),a)),o=new Map;for(let[u,l]of Object.entries(this.manifest.args))l.kind==="tensor"&&(l.role==="output"||l.role==="inout")&&l.semantic&&o.set(l.semantic,u);let i={};for(let u of this.manifest.outputs){let l=o.get(u.role)??u.role;if(u.shape===void 0)throw new Error(`${this.manifest.id}: output "${u.role}" has no shape expression \u2014 add outputs[].shape to ops/${this.manifest.id}/manifest.json (docs/model-graph-builder.md).`);let c=typeof u.shape=="string"?Le(u.shape,s):u.shape.map(d=>je(d,s));if(!Array.isArray(c)||!c.every(d=>Number.isInteger(d)&&d>=0))throw new Error(`${this.manifest.id}: output "${u.role}" shape evaluated to ${JSON.stringify(c)} (expected non-negative integers)`);i[l]={role:u.role,shape:c,dtype:this.resolveOutputDtype(u,s)}}return i}resolveOutputDtype(n,r){if(!n.dtype)return"float32";if(Dc.has(n.dtype))return n.dtype;let t=r.dtypes[n.dtype];if(typeof t=="string")return On(t);let a=this.manifest.typeConstraints[n.dtype],s=r.tensorDtypes;for(let o of this.manifest.inputs){let i=s[o.role];if(typeof i=="string"&&(!Array.isArray(a)||a.includes(i)))return i}throw new Error(`${this.manifest.id}: output "${n.role}" dtype "${n.dtype}" is a constraint var with no bound input \u2014 pass a dtype override or bind an input sharing the var.`)}async run(n,r,t={}){let a=this.prepare(n,r,t),{executeWebGpuPlan:s}=await Promise.resolve().then(()=>(it(),Za));return await s(n,a,t.runOptions??{}),a}prepareComputePassDescriptorTemplate(n,r,t={}){if(t.cacheKey!==void 0)return this.prepareDirectComputePassDescriptorTemplate(n,r,{...t,cacheKey:t.cacheKey});let a=this.prepare(n,r,t),s=Fc(a,t.pass),o=a.program.passes[s],i=a.plan.passes[s];if(!o||!i)throw new Error(`WebGPU op ${a.program.op} produced no compute pass descriptor template at index ${s}`);return Ya(o,i,`webgpu:${a.program.key}:pass=${o.id}`,a.program.key,a.plan.key,s)}prepareDirectComputePassDescriptorTemplate(n,r,t){this.validateRequest(r);let a=ze(n.device),s=this.applyManifestDerive(this.buildBaseScope(a,r)),{variant:o,scope:i}=this.selectVariantAndScope(s,r,t.variant),u=Mc(this.manifest.id,o,t.pass),l=o.passes[u],c=this.buildProgramPass(o,l,i),d=this.buildPlanPass(o,l,i,u);return Ya(c,d,t.cacheKey,t.cacheKey,t.cacheKey,u)}buildProgram(n,r,t){let a=r.passes.map(s=>this.buildProgramPass(r,s,t));return Object.freeze({key:n,op:this.manifest.id,variant:r.id,variantVersion:r.version,passes:Object.freeze(a)})}buildProgramPass(n,r,t){let a=this.passConstants(n,r,t),s={...t,variant:n,pass:r,constants:a},o=un(Ua(r.bindings)),i=[Pa(o),Qr(o,a)].filter(Boolean).join(` +`),u=this.passSourceInputs(r.source,s),l={...s,sourceContext:u},c=this.buildTemplateSource(n,r,l,i),d=He(r.profile,l),p=He(r.metadata,l);return Object.freeze({id:r.id,name:r.name??`${this.manifest.id}.${n.id}.${r.id}`,source:c,entryPoint:r.entryPoint,bindings:o,bindingSpecs:r.bindings,constants:a,...Object.keys(d).length>0?{profile:d}:{},...Object.keys(p).length>0?{metadata:p}:{},reads:r.reads,writes:r.writes})}buildTemplateSource(n,r,t,a){let s=lt(r.source.shader,this.assets.readText(r.source.shader),u=>this.assets.readText(u),new Set),o=Jr(s,{...t,env:{device:Yr(t.device),wgsl:{resourceDeclarations:a}}}),i=et(o,t.device.features);if(i.length>0)throw new Error(`WebGPU op ${this.manifest.id} variant ${n.id} pass ${r.id} rendered WGSL enable directives the device does not support: ${i.join(", ")}. Gate the directive in the template (env.device.features) or declare the feature in the variant's requires.requiredFeatures.`);return o}programSpecialization(n,r){return{variant:He(n.constants,{...r,variant:n}),passes:n.passes.map(t=>({id:t.id,constants:He(t.constants,{...r,variant:n,pass:t}),source:this.passSourceSpecialization(n,t,r)}))}}passSourceSpecialization(n,r,t){let a=this.passConstants(n,r,t),s={...t,variant:n,pass:r,constants:a};return{kind:"template",shader:r.source.shader,sourceVersion:r.source.version??1,inputs:this.passSourceInputs(r.source,s)}}buildPlan(n,r,t,a,s){let o=Ka(a.intermediates,a.passes,s),i=a.passes.map((u,l)=>this.buildPlanPass(a,u,s,l));return Object.freeze({key:n,programKey:r,shapeKey:t,scratches:o,passes:Object.freeze(i)})}buildPlanPass(n,r,t,a){let s=this.passConstants(n,r,t),o={...t,variant:n,pass:r,constants:s},i={...o,sourceContext:this.passSourceInputs(r.source,o)},u=r.bindings.filter(l=>l.buffer.type==="uniform").reduce((l,c)=>(l[c.name]=this.uniformValues(c,r.uniforms[c.name],i),l),{});return Object.freeze({id:r.id,dispatchWorkgroups:this.passDispatchWorkgroups(r,i),uniforms:u,constants:{...s,passIndex:a}})}passDispatchWorkgroups(n,r){let t=r.device.limits.maxComputeWorkgroupsPerDimension;return[Le(n.dispatch.x,r),Le(n.dispatch.y??1,r),Le(n.dispatch.z??1,r)].map((a,s)=>{if(!Number.isInteger(a)||Number(a)<0)throw new Error(`WebGPU pass ${n.id} dispatch axis ${s} must resolve to a nonnegative integer, got ${String(a)}`);if(Number(a)>t)throw new Error(`WebGPU pass ${n.id} dispatch axis ${s} = ${a} exceeds maxComputeWorkgroupsPerDimension (${t}); clamp the dispatch (min(..., ${t})) and grid-stride over the remainder, or fold into 2D/3D.`);return Number(a)})}uniformValues(n,r,t){let a=n.struct;if(!a)throw new Error(`WebGPU uniform binding ${n.name} requires struct`);let s={};for(let o of a.fields){let i=r?.[o.name]??o.value??t.args[o.name]??o.default;if(i===void 0)continue;let u=Le(i,t);if(typeof u!="number"||!Number.isFinite(u))throw new Error(`WebGPU uniform ${n.name}.${o.name} must resolve to a finite number`);s[o.name]=u}return s}passConstants(n,r,t){return{...t.dtypes,...He(n.constants,{...t,variant:n,pass:r}),...He(r.constants,{...t,variant:n,pass:r})}}passSourceInputs(n,r){return Bc(He(n.inputs,r),`WebGPU template source ${n.shader} inputs`)}selectVariantAndScope(n,r,t){let a=this.selectVariant(n,t),s=this.applyVariantDerive(n,r,a,void 0);return{variant:a,scope:s}}selectVariant(n,r){let t=[];for(let a of this.variantCandidates(r)){let s=this.checkVariant(a,n);if(s.ok)return a;t.push(`${a.id}: ${s.reason}`)}throw new Error(`No supported WebGPU variant for ${this.manifest.id}; rejected ${t.join("; ")}`)}variantCandidates(n){if(n!==void 0){let t=this.manifest.variants.find(a=>a.id===n);if(!t)throw new Error(`WebGPU op ${this.manifest.id} has no variant ${n}`);return[t]}return[...this.manifest.variants].sort((t,a)=>t.default!==a.default?t.default?-1:1:a.priority-t.priority)}checkVariant(n,r){let t=Cr(n.requires,r.device);if(t)return{ok:!1,reason:t};let a={...r,variant:n},s=Array.isArray(n.when)?n.when:[n.when],o=s.length>1;for(let i of s){let u;try{u=Le(i,a)}catch(l){return{ok:!1,reason:`when eval error in \`${typeof i=="string"?i:String(i)}\`: ${l.message}`}}if(u!==!0){let l=typeof i=="string"?i:String(i);return{ok:!1,reason:o?`when clause failed: \`${l}\` \u2192 ${String(u)}`:`when guard resolved to ${String(u)}`}}}if(n.selectAbove!==null){let i;try{i=Le(n.selectAbove,a)}catch(u){return{ok:!1,reason:`selectAbove eval error in \`${n.selectAbove}\`: ${u.message}`}}if(i!==!0)return{ok:!1,reason:`below perf floor: \`${n.selectAbove}\` \u2192 ${String(i)}`}}return{ok:!0}}buildBaseScope(n,r){let t={...r.resources},a={...this.manifest.attributes,...r.attrs??{}},s={...r.args??{}},o={...r.sourceContext??{}};for(let[f,m]of Object.entries(t))!ir(m)&&typeof m!="object"&&(s[f]=m);let i=Object.fromEntries(Object.keys({...this.manifest.args,...t}).map(f=>[f,t[f]!==void 0&&t[f]!==null])),u={},l={},c={},d={};for(let[f,m]of Object.entries(this.manifest.args)){let _=t[f];if(!ir(_))continue;let E=[f,m.semantic,m.role].filter(b=>typeof b=="string"&&b.length>0);for(let b of E)u[b]=_.shape,l[b]=_.shape.length,c[b]=_.dtype}for(let f of[...this.manifest.inputs,...this.manifest.outputs]){if(!f.dtype)continue;let m=c[f.role];m!==void 0&&(d[f.dtype]=Zr(m))}return{op:this.manifest,device:n,attrs:a,args:s,sourceContext:o,resources:t,present:i,shapes:u,ranks:l,tensorDtypes:c,dtypes:d,derived:{},tunables:{...this.manifest.tunables,...r.tunables??{}},constants:{}}}applyManifestDerive(n){let r={};for(let[t,a]of Object.entries(this.manifest.derive))r[t]=je(a,{...n,derived:r});return{...n,derived:r}}applyVariantDerive(n,r,t,a){let s={...n,variant:t,tunables:{...this.manifest.tunables,...t.tunables,...a??{},...r.tunables??{}}},o={...n.derived};for(let[i,u]of Object.entries(t.derive))o[i]=je(u,{...s,derived:o});return{...s,derived:o}}validateRequest(n){for(let[r,t]of Object.entries(this.manifest.args)){let a=n.resources[r]??n.args?.[r];if(a==null){if(t.required!==!1)throw new Error(`WebGPU op ${this.manifest.id} missing required arg ${r}`);continue}Rc(r,t,a)}}};Gc=/{%\s*include\s+["']([^"']+)["']\s*%}/g;Ja=new WeakMap;Dc=new Set(["float32","float16","uint32","int32","uint8","int8"])});var rs,ts,as=he(()=>{rs=new Map([["ops/_shared/norm-row-stats.wgsl.jinja",`{% if source.usesF16 %} enable f16; {% endif %} enable subgroups; @@ -264,7 +264,7 @@ fn main( } {% endif %} } -`]]),rs=new Map([["com.xenova.AddInPlace",{manifest:{schemaVersion:1,domain:"com.xenova",name:"AddInPlace",sinceVersion:1,inputs:[{role:"Y",dtype:"Y"},{role:"X",dtype:"X"}],outputs:[{role:"Y",dtype:"Y",shape:"shapes.yT"}],typeConstraints:{Y:["float32","float16"],X:["float32","float16"]},args:{yT:{kind:"tensor",semantic:"Y",role:"inout"},xT:{kind:"tensor",semantic:"X",role:"input"},count:{kind:"u32",semantic:"kernel.count"}},tunables:{WORKGROUP_SIZE:64,MAX_WORKGROUPS_X:1024},variants:[{id:"scalar",when:"args.count > 0 and numel(shapes.yT) >= args.count and numel(shapes.xT) >= args.count and (f16Ok(dtypes.Y) and f16Ok(dtypes.X))",passes:[{id:"main",name:"AddInPlace",shader:"add-in-place.wgsl.jinja",bindings:[{name:"y",arg:"yT",semantic:"Y",role:"inout",buffer:{type:"storage"},elementType:"$Y"},{name:"x",arg:"xT",semantic:"X",role:"input",buffer:{type:"read-only-storage"},elementType:"$X"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"count",type:"u32",value:"args.count"},{name:"wgY",type:"u32",value:"min(ceil(args.count / tunables.WORKGROUP_SIZE), tunables.MAX_WORKGROUPS_X)"}]}}],dispatch:{x:"min(ceil(args.count / tunables.WORKGROUP_SIZE), tunables.MAX_WORKGROUPS_X)",y:"ceil(ceil(args.count / tunables.WORKGROUP_SIZE) / min(ceil(args.count / tunables.WORKGROUP_SIZE), tunables.MAX_WORKGROUPS_X))",z:1},reads:["Y","X"],writes:["Y"]}]}]},assets:[["add-in-place.wgsl.jinja",`{% if Y == "f16" or X == "f16" %} +`]]),ts=new Map([["com.xenova.AddInPlace",{manifest:{schemaVersion:1,domain:"com.xenova",name:"AddInPlace",sinceVersion:1,inputs:[{role:"Y",dtype:"Y"},{role:"X",dtype:"X"}],outputs:[{role:"Y",dtype:"Y",shape:"shapes.yT"}],typeConstraints:{Y:["float32","float16"],X:["float32","float16"]},args:{yT:{kind:"tensor",semantic:"Y",role:"inout"},xT:{kind:"tensor",semantic:"X",role:"input"},count:{kind:"u32",semantic:"kernel.count"}},tunables:{WORKGROUP_SIZE:64,MAX_WORKGROUPS_X:1024},variants:[{id:"scalar",when:"args.count > 0 and numel(shapes.yT) >= args.count and numel(shapes.xT) >= args.count and (f16Ok(dtypes.Y) and f16Ok(dtypes.X))",passes:[{id:"main",name:"AddInPlace",shader:"add-in-place.wgsl.jinja",bindings:[{name:"y",arg:"yT",semantic:"Y",role:"inout",buffer:{type:"storage"},elementType:"$Y"},{name:"x",arg:"xT",semantic:"X",role:"input",buffer:{type:"read-only-storage"},elementType:"$X"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"count",type:"u32",value:"args.count"},{name:"wgY",type:"u32",value:"min(ceil(args.count / tunables.WORKGROUP_SIZE), tunables.MAX_WORKGROUPS_X)"}]}}],dispatch:{x:"min(ceil(args.count / tunables.WORKGROUP_SIZE), tunables.MAX_WORKGROUPS_X)",y:"ceil(ceil(args.count / tunables.WORKGROUP_SIZE) / min(ceil(args.count / tunables.WORKGROUP_SIZE), tunables.MAX_WORKGROUPS_X))",z:1},reads:["Y","X"],writes:["Y"]}]}]},assets:[["add-in-place.wgsl.jinja",`{% if Y == "f16" or X == "f16" %} enable f16; {% endif %} {{ env.wgsl.resourceDeclarations }} @@ -455,7 +455,7 @@ fn main(@builtin(local_invocation_id) lid: vec3) { out[0] = wgIdx[0]; } } -`]]}],["com.xenova.gemma4.Attention",{manifest:{schemaVersion:1,domain:"com.xenova.gemma4",name:"Attention",sinceVersion:1,inputs:[{role:"Q",dtype:"T"},{role:"K",dtype:"T"},{role:"V",dtype:"T"}],outputs:[{role:"Out",dtype:"U",shape:["args.seqQ","args.qHeads * args.headDim"]}],typeConstraints:{T:["float32","float16"],U:["float32","float16"]},args:{qT:{kind:"tensor",semantic:"Q",role:"input"},kT:{kind:"tensor",semantic:"K",role:"input"},vT:{kind:"tensor",semantic:"V",role:"input"},outT:{kind:"tensor",semantic:"Out",role:"output"},seqQ:{kind:"u32",semantic:"seq_q"},keyLen:{kind:"u32",semantic:"key_len"},qOffset:{kind:"u32",semantic:"q_offset"},qHeads:{kind:"u32",semantic:"q_heads"},kvHeads:{kind:"u32",semantic:"kv_heads"},headDim:{kind:"u32",semantic:"head_dim"},scale:{kind:"f32",semantic:"scale",required:!1},window:{kind:"u32",semantic:"window",required:!1},exact:{kind:"u32",semantic:"exact_reference_order",required:!1},maxKeyLen:{kind:"u32",semantic:"max_key_len",required:!1}},variants:[{id:"tiled",priority:5,when:["(not args.exact)",'(args.seqQ > 0 and args.keyLen > 0 and args.qHeads > 0 and args.kvHeads > 0 and args.headDim > 0 and args.qHeads % args.kvHeads == 0 and tensorDtypes.qT == tensorDtypes.kT and tensorDtypes.qT == tensorDtypes.vT and (tensorDtypes.qT == "float32" or tensorDtypes.qT == "float16") and (tensorDtypes.outT == "float32" or tensorDtypes.outT == "float16") and ((tensorDtypes.qT != "float16" and tensorDtypes.outT != "float16") or device.features.has("shader-f16")) and numel(shapes.qT) >= args.seqQ * args.qHeads * args.headDim and numel(shapes.kT) >= args.keyLen * args.kvHeads * args.headDim and numel(shapes.vT) >= args.keyLen * args.kvHeads * args.headDim and numel(shapes.outT) >= args.seqQ * args.qHeads * args.headDim)',"args.seqQ >= 32","args.headDim % 32 == 0",'device.features.has("subgroups")','has(device.adapterInfo, "subgroupMinSize")',"device.adapterInfo.subgroupMinSize == 32","device.adapterInfo.subgroupMaxSize == 32"],constants:{inputScalar:"dtypes.T",outputScalar:"dtypes.U",outputVec4:'"vec4" if dtypes.U == "f16" else "vec4"',inputVec4:'"vec4" if dtypes.T == "f16" else "vec4"',headDim:"args.headDim",TILE_Q:"32 if args.headDim >= 512 else 16",TILE_K:8,scale:"args.scale if args.scale else 1.0",usesF16:'tensorDtypes.qT == "float16" or tensorDtypes.outT == "float16"',stageF16:'args.headDim >= 512 and device.features.has("shader-f16")'},passes:[{id:"main",name:"Gemma4Attention",shader:"gemma4-attention-tiled.wgsl.jinja",bindings:[{name:"q",arg:"qT",semantic:"Q",role:"input",buffer:{type:"read-only-storage"},elementType:"$inputVec4"},{name:"k",arg:"kT",semantic:"K",role:"input",buffer:{type:"read-only-storage"},elementType:"$inputVec4"},{name:"v",arg:"vT",semantic:"V",role:"input",buffer:{type:"read-only-storage"},elementType:"$inputVec4"},{name:"out",arg:"outT",semantic:"Out",role:"output",buffer:{type:"storage"},elementType:"$outputVec4"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"seqQ",type:"u32",value:"args.seqQ"},{name:"keyLen",type:"u32",value:"args.keyLen"},{name:"qOffset",type:"u32",value:"args.qOffset"},{name:"qHeads",type:"u32",value:"args.qHeads"},{name:"kvHeads",type:"u32",value:"args.kvHeads"},{name:"window",type:"u32",value:"args.window if args.window else 0"}]}}],dispatch:{x:"ceil(args.seqQ / (32 if args.headDim >= 512 else 16))",y:"args.qHeads",z:1},reads:["Q","K","V"],writes:["Out"]}]},{id:"scalar",priority:0,when:["(not args.exact)",'(args.seqQ > 0 and args.keyLen > 0 and args.qHeads > 0 and args.kvHeads > 0 and args.headDim > 0 and args.qHeads % args.kvHeads == 0 and tensorDtypes.qT == tensorDtypes.kT and tensorDtypes.qT == tensorDtypes.vT and (tensorDtypes.qT == "float32" or tensorDtypes.qT == "float16") and (tensorDtypes.outT == "float32" or tensorDtypes.outT == "float16") and ((tensorDtypes.qT != "float16" and tensorDtypes.outT != "float16") or device.features.has("shader-f16")) and numel(shapes.qT) >= args.seqQ * args.qHeads * args.headDim and numel(shapes.kT) >= args.keyLen * args.kvHeads * args.headDim and numel(shapes.vT) >= args.keyLen * args.kvHeads * args.headDim and numel(shapes.outT) >= args.seqQ * args.qHeads * args.headDim)'],constants:{usesF16:'tensorDtypes.qT == "float16" or tensorDtypes.outT == "float16"',inputScalar:"dtypes.T",outputScalar:"dtypes.U",headDim:"args.headDim",workgroupSize:128,scale:"args.scale if args.scale else 1.0"},passes:[{id:"main",name:"Gemma4Attention",shader:"gemma4-attention.wgsl.jinja",bindings:[{name:"q",arg:"qT",semantic:"Q",role:"input",buffer:{type:"read-only-storage"},elementType:"$inputScalar"},{name:"k",arg:"kT",semantic:"K",role:"input",buffer:{type:"read-only-storage"},elementType:"$inputScalar"},{name:"v",arg:"vT",semantic:"V",role:"input",buffer:{type:"read-only-storage"},elementType:"$inputScalar"},{name:"out",arg:"outT",semantic:"Out",role:"output",buffer:{type:"storage"},elementType:"$outputScalar"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"seqQ",type:"u32",value:"args.seqQ"},{name:"keyLen",type:"u32",value:"args.keyLen"},{name:"qOffset",type:"u32",value:"args.qOffset"},{name:"qHeads",type:"u32",value:"args.qHeads"},{name:"kvHeads",type:"u32",value:"args.kvHeads"},{name:"window",type:"u32",value:"args.window if args.window else 0"}]}}],dispatch:{x:"args.seqQ",y:"args.qHeads",z:1},reads:["Q","K","V"],writes:["Out"]}]}]},assets:[["gemma4-attention-tiled.wgsl.jinja",`{% if usesF16 or stageF16 %} +`]]}],["com.xenova.gemma4.Attention",{manifest:{schemaVersion:1,domain:"com.xenova.gemma4",name:"Attention",sinceVersion:1,inputs:[{role:"Q",dtype:"T"},{role:"K",dtype:"T"},{role:"V",dtype:"T"}],outputs:[{role:"Out",dtype:"U",shape:["args.seqQ","args.qHeads * args.headDim"]}],typeConstraints:{T:["float32","float16"],U:["float32","float16"]},args:{qT:{kind:"tensor",semantic:"Q",role:"input"},kT:{kind:"tensor",semantic:"K",role:"input"},vT:{kind:"tensor",semantic:"V",role:"input"},outT:{kind:"tensor",semantic:"Out",role:"output"},seqQ:{kind:"u32",semantic:"seq_q"},keyLen:{kind:"u32",semantic:"key_len"},qOffset:{kind:"u32",semantic:"q_offset"},qHeads:{kind:"u32",semantic:"q_heads"},kvHeads:{kind:"u32",semantic:"kv_heads"},headDim:{kind:"u32",semantic:"head_dim"},scale:{kind:"f32",semantic:"scale",required:!1},window:{kind:"u32",semantic:"window",required:!1},exact:{kind:"u32",semantic:"exact_reference_order",required:!1},maxKeyLen:{kind:"u32",semantic:"max_key_len",required:!1}},variants:[{id:"tiled",priority:5,when:["(not args.exact)",'(args.seqQ > 0 and args.keyLen > 0 and args.qHeads > 0 and args.kvHeads > 0 and args.headDim > 0 and args.qHeads % args.kvHeads == 0 and tensorDtypes.qT == tensorDtypes.kT and tensorDtypes.qT == tensorDtypes.vT and (tensorDtypes.qT == "float32" or tensorDtypes.qT == "float16") and (tensorDtypes.outT == "float32" or tensorDtypes.outT == "float16") and ((tensorDtypes.qT != "float16" and tensorDtypes.outT != "float16") or device.features.has("shader-f16")) and numel(shapes.qT) >= args.seqQ * args.qHeads * args.headDim and numel(shapes.kT) >= args.keyLen * args.kvHeads * args.headDim and numel(shapes.vT) >= args.keyLen * args.kvHeads * args.headDim and numel(shapes.outT) >= args.seqQ * args.qHeads * args.headDim)',"args.seqQ >= 32","args.headDim % 32 == 0",'device.features.has("subgroups")','has(device.adapterInfo, "subgroupMinSize")',"device.adapterInfo.subgroupMinSize >= 32"],constants:{inputScalar:"dtypes.T",outputScalar:"dtypes.U",outputVec4:'"vec4" if dtypes.U == "f16" else "vec4"',inputVec4:'"vec4" if dtypes.T == "f16" else "vec4"',headDim:"args.headDim",TILE_Q:"32 if args.headDim >= 512 else 16",TILE_K:8,scale:"args.scale if args.scale else 1.0",usesF16:'tensorDtypes.qT == "float16" or tensorDtypes.outT == "float16"',stageF16:'args.headDim >= 512 and device.features.has("shader-f16")'},passes:[{id:"main",name:"Gemma4Attention",shader:"gemma4-attention-tiled.wgsl.jinja",bindings:[{name:"q",arg:"qT",semantic:"Q",role:"input",buffer:{type:"read-only-storage"},elementType:"$inputVec4"},{name:"k",arg:"kT",semantic:"K",role:"input",buffer:{type:"read-only-storage"},elementType:"$inputVec4"},{name:"v",arg:"vT",semantic:"V",role:"input",buffer:{type:"read-only-storage"},elementType:"$inputVec4"},{name:"out",arg:"outT",semantic:"Out",role:"output",buffer:{type:"storage"},elementType:"$outputVec4"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"seqQ",type:"u32",value:"args.seqQ"},{name:"keyLen",type:"u32",value:"args.keyLen"},{name:"qOffset",type:"u32",value:"args.qOffset"},{name:"qHeads",type:"u32",value:"args.qHeads"},{name:"kvHeads",type:"u32",value:"args.kvHeads"},{name:"window",type:"u32",value:"args.window if args.window else 0"}]}}],dispatch:{x:"ceil(args.seqQ / (32 if args.headDim >= 512 else 16))",y:"args.qHeads",z:1},reads:["Q","K","V"],writes:["Out"]}]},{id:"scalar",priority:0,when:["(not args.exact)",'(args.seqQ > 0 and args.keyLen > 0 and args.qHeads > 0 and args.kvHeads > 0 and args.headDim > 0 and args.qHeads % args.kvHeads == 0 and tensorDtypes.qT == tensorDtypes.kT and tensorDtypes.qT == tensorDtypes.vT and (tensorDtypes.qT == "float32" or tensorDtypes.qT == "float16") and (tensorDtypes.outT == "float32" or tensorDtypes.outT == "float16") and ((tensorDtypes.qT != "float16" and tensorDtypes.outT != "float16") or device.features.has("shader-f16")) and numel(shapes.qT) >= args.seqQ * args.qHeads * args.headDim and numel(shapes.kT) >= args.keyLen * args.kvHeads * args.headDim and numel(shapes.vT) >= args.keyLen * args.kvHeads * args.headDim and numel(shapes.outT) >= args.seqQ * args.qHeads * args.headDim)'],constants:{usesF16:'tensorDtypes.qT == "float16" or tensorDtypes.outT == "float16"',inputScalar:"dtypes.T",outputScalar:"dtypes.U",headDim:"args.headDim",workgroupSize:128,scale:"args.scale if args.scale else 1.0"},passes:[{id:"main",name:"Gemma4Attention",shader:"gemma4-attention.wgsl.jinja",bindings:[{name:"q",arg:"qT",semantic:"Q",role:"input",buffer:{type:"read-only-storage"},elementType:"$inputScalar"},{name:"k",arg:"kT",semantic:"K",role:"input",buffer:{type:"read-only-storage"},elementType:"$inputScalar"},{name:"v",arg:"vT",semantic:"V",role:"input",buffer:{type:"read-only-storage"},elementType:"$inputScalar"},{name:"out",arg:"outT",semantic:"Out",role:"output",buffer:{type:"storage"},elementType:"$outputScalar"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"seqQ",type:"u32",value:"args.seqQ"},{name:"keyLen",type:"u32",value:"args.keyLen"},{name:"qOffset",type:"u32",value:"args.qOffset"},{name:"qHeads",type:"u32",value:"args.qHeads"},{name:"kvHeads",type:"u32",value:"args.kvHeads"},{name:"window",type:"u32",value:"args.window if args.window else 0"}]}}],dispatch:{x:"args.seqQ",y:"args.qHeads",z:1},reads:["Q","K","V"],writes:["Out"]}]}]},assets:[["gemma4-attention-tiled.wgsl.jinja",`{% if usesF16 or stageF16 %} enable f16; {% endif %} enable subgroups; @@ -748,7 +748,7 @@ fn main( out[outBase + d] = {{ outputScalar }}(out_acc[d] * inv); } } -`]]}],["com.xenova.gemma4.DecodeAttention",{manifest:{schemaVersion:1,domain:"com.xenova.gemma4",name:"DecodeAttention",sinceVersion:1,inputs:[{role:"Q",dtype:"T"},{role:"W",dtype:"float32",rank:1},{role:"Cos",dtype:"float32"},{role:"Sin",dtype:"float32"},{role:"K",dtype:"T"},{role:"V",dtype:"T"}],outputs:[{role:"Out",dtype:"U"}],typeConstraints:{T:["float32","float16"],U:["float32","float16"]},args:{qT:{kind:"tensor",semantic:"Q",role:"input"},wT:{kind:"tensor",semantic:"W",role:"weights"},cosT:{kind:"tensor",semantic:"Cos",role:"input"},sinT:{kind:"tensor",semantic:"Sin",role:"input"},kT:{kind:"tensor",semantic:"K",role:"input"},vT:{kind:"tensor",semantic:"V",role:"input"},outT:{kind:"tensor",semantic:"Out",role:"output"},seqQ:{kind:"u32",semantic:"seq_q"},keyLen:{kind:"u32",semantic:"key_len"},qOffset:{kind:"u32",semantic:"q_offset"},qHeads:{kind:"u32",semantic:"q_heads"},kvHeads:{kind:"u32",semantic:"kv_heads"},headDim:{kind:"u32",semantic:"head_dim"},eps:{kind:"f32",semantic:"eps",required:!1},scale:{kind:"f32",semantic:"scale",required:!1},window:{kind:"u32",semantic:"window",required:!1},outQuantScale:{kind:"f32",semantic:"out_quant_scale",required:!1}},variants:[{id:"split8_fused",priority:5,when:'args.seqQ == 1 and args.keyLen > 0 and args.qHeads > 0 and args.kvHeads > 0 and args.headDim > 0 and args.headDim % 2 == 0 and args.qHeads % args.kvHeads == 0 and tensorDtypes.qT == tensorDtypes.kT and tensorDtypes.qT == tensorDtypes.vT and (tensorDtypes.qT == "float32" or tensorDtypes.qT == "float16") and (tensorDtypes.outT == "float32" or tensorDtypes.outT == "float16") and ((tensorDtypes.qT != "float16" and tensorDtypes.outT != "float16") or device.features.has("shader-f16")) and numel(shapes.qT) >= args.qHeads * args.headDim and dim(shapes.wT, 0) == args.headDim and numel(shapes.cosT) >= args.headDim / 2 and numel(shapes.sinT) >= args.headDim / 2 and numel(shapes.kT) >= args.keyLen * args.kvHeads * args.headDim and numel(shapes.vT) >= args.keyLen * args.kvHeads * args.headDim and numel(shapes.outT) >= args.qHeads * args.headDim and args.headDim % 4 == 0',constants:{usesF16:'tensorDtypes.qT == "float16" or tensorDtypes.outT == "float16"',inputScalar:"dtypes.T",outputScalar:"dtypes.U",HEAD_DIM:"args.headDim",HALF_DIM:"args.headDim / 2",NCHUNK:32,WG:256,EPS:"args.eps if args.eps else 0.000001",scale:"args.scale if args.scale else 1.0",useSubgroups:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32',MERGE_WG:128,OUT_Q:"args.outQuantScale if args.outQuantScale else 0.0",qHeadsConst:"args.qHeads"},intermediates:[{id:"attn_partials",dtype:"uint32",shape:"[args.qHeads * 32 * (args.headDim + 2) + args.qHeads]"}],passes:[{id:"partial",name:"Gemma4DecodeAttentionPartial",shader:"decode-attention-partial.wgsl.jinja",bindings:[{name:"q",arg:"qT",semantic:"Q",role:"input",buffer:{type:"read-only-storage"},elementType:"$inputScalar"},{name:"w",arg:"wT",semantic:"W",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"cosTbl",arg:"cosT",semantic:"Cos",role:"input",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"sinTbl",arg:"sinT",semantic:"Sin",role:"input",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"k",arg:"kT",semantic:"K",role:"input",buffer:{type:"read-only-storage"},elementType:"vec4"},{name:"v",arg:"vT",semantic:"V",role:"input",buffer:{type:"read-only-storage"},elementType:"vec4"},{name:"partials",semantic:"attn_partials",role:"scratch",buffer:{type:"storage"},elementType:"atomic"},{name:"out",arg:"outT",semantic:"Out",role:"output",buffer:{type:"storage"},elementType:"$outputScalar"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"seqQ",type:"u32",value:"args.seqQ"},{name:"keyLen",type:"u32",value:"args.keyLen"},{name:"qOffset",type:"u32",value:"args.qOffset"},{name:"qHeads",type:"u32",value:"args.qHeads"},{name:"kvHeads",type:"u32",value:"args.kvHeads"},{name:"window",type:"u32",value:"args.window if args.window else 0"}]}}],dispatch:{x:"args.qHeads",y:32,z:1},reads:["Q","W","Cos","Sin","K","V"],writes:["attn_partials","Out"]}]}]},assets:[["decode-attention-partial.wgsl.jinja",`{% if useSubgroups %} +`]]}],["com.xenova.gemma4.DecodeAttention",{manifest:{schemaVersion:1,domain:"com.xenova.gemma4",name:"DecodeAttention",sinceVersion:1,inputs:[{role:"Q",dtype:"T"},{role:"W",dtype:"float32",rank:1},{role:"Cos",dtype:"float32"},{role:"Sin",dtype:"float32"},{role:"K",dtype:"T"},{role:"V",dtype:"T"}],outputs:[{role:"Out",dtype:"U"}],typeConstraints:{T:["float32","float16"],U:["float32","float16"]},args:{qT:{kind:"tensor",semantic:"Q",role:"input"},wT:{kind:"tensor",semantic:"W",role:"weights"},cosT:{kind:"tensor",semantic:"Cos",role:"input"},sinT:{kind:"tensor",semantic:"Sin",role:"input"},kT:{kind:"tensor",semantic:"K",role:"input"},vT:{kind:"tensor",semantic:"V",role:"input"},outT:{kind:"tensor",semantic:"Out",role:"output"},seqQ:{kind:"u32",semantic:"seq_q"},keyLen:{kind:"u32",semantic:"key_len"},qOffset:{kind:"u32",semantic:"q_offset"},qHeads:{kind:"u32",semantic:"q_heads"},kvHeads:{kind:"u32",semantic:"kv_heads"},headDim:{kind:"u32",semantic:"head_dim"},eps:{kind:"f32",semantic:"eps",required:!1},scale:{kind:"f32",semantic:"scale",required:!1},window:{kind:"u32",semantic:"window",required:!1},outQuantScale:{kind:"f32",semantic:"out_quant_scale",required:!1}},variants:[{id:"split8_fused",priority:5,when:'args.seqQ == 1 and args.keyLen > 0 and args.qHeads > 0 and args.kvHeads > 0 and args.headDim > 0 and args.headDim % 2 == 0 and args.qHeads % args.kvHeads == 0 and tensorDtypes.qT == tensorDtypes.kT and tensorDtypes.qT == tensorDtypes.vT and (tensorDtypes.qT == "float32" or tensorDtypes.qT == "float16") and (tensorDtypes.outT == "float32" or tensorDtypes.outT == "float16") and ((tensorDtypes.qT != "float16" and tensorDtypes.outT != "float16") or device.features.has("shader-f16")) and numel(shapes.qT) >= args.qHeads * args.headDim and dim(shapes.wT, 0) == args.headDim and numel(shapes.cosT) >= args.headDim / 2 and numel(shapes.sinT) >= args.headDim / 2 and numel(shapes.kT) >= args.keyLen * args.kvHeads * args.headDim and numel(shapes.vT) >= args.keyLen * args.kvHeads * args.headDim and numel(shapes.outT) >= args.qHeads * args.headDim and args.headDim % 4 == 0',constants:{usesF16:'tensorDtypes.qT == "float16" or tensorDtypes.outT == "float16"',inputScalar:"dtypes.T",outputScalar:"dtypes.U",HEAD_DIM:"args.headDim",HALF_DIM:"args.headDim / 2",NCHUNK:32,WG:256,EPS:"args.eps if args.eps else 0.000001",scale:"args.scale if args.scale else 1.0",useSubgroups:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize >= 32',sgExact32:"device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32",MERGE_WG:128,OUT_Q:"args.outQuantScale if args.outQuantScale else 0.0",qHeadsConst:"args.qHeads"},intermediates:[{id:"attn_partials",dtype:"uint32",shape:"[args.qHeads * 32 * (args.headDim + 2) + args.qHeads]"}],passes:[{id:"partial",name:"Gemma4DecodeAttentionPartial",shader:"decode-attention-partial.wgsl.jinja",bindings:[{name:"q",arg:"qT",semantic:"Q",role:"input",buffer:{type:"read-only-storage"},elementType:"$inputScalar"},{name:"w",arg:"wT",semantic:"W",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"cosTbl",arg:"cosT",semantic:"Cos",role:"input",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"sinTbl",arg:"sinT",semantic:"Sin",role:"input",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"k",arg:"kT",semantic:"K",role:"input",buffer:{type:"read-only-storage"},elementType:"vec4"},{name:"v",arg:"vT",semantic:"V",role:"input",buffer:{type:"read-only-storage"},elementType:"vec4"},{name:"partials",semantic:"attn_partials",role:"scratch",buffer:{type:"storage"},elementType:"atomic"},{name:"out",arg:"outT",semantic:"Out",role:"output",buffer:{type:"storage"},elementType:"$outputScalar"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"seqQ",type:"u32",value:"args.seqQ"},{name:"keyLen",type:"u32",value:"args.keyLen"},{name:"qOffset",type:"u32",value:"args.qOffset"},{name:"qHeads",type:"u32",value:"args.qHeads"},{name:"kvHeads",type:"u32",value:"args.kvHeads"},{name:"window",type:"u32",value:"args.window if args.window else 0"}]}}],dispatch:{x:"args.qHeads",y:32,z:1},reads:["Q","W","Cos","Sin","K","V"],writes:["attn_partials","Out"]}]}]},assets:[["decode-attention-partial.wgsl.jinja",`{% if useSubgroups %} enable subgroups; {% endif %} {{ env.wgsl.resourceDeclarations }} @@ -801,10 +801,40 @@ var running_max: f32; var running_denom: f32; {% if useSubgroups %} -// Hybrid 2-barrier reductions: subgroup op within each subgroup, followed by a -// cross-subgroup combine. +// Reductions over each logical 32-lane block. sgExact32 (fixed 32-wide adapter) -> hardware +// subgroup ops; otherwise a 32-lane subgroupShuffleXor butterfly that reduces each block +// independently \u2014 correct for any subgroup width >= 32 (NVIDIA D3D12 [32,128], AMD [32,64]) +// where a plain subgroup op would span multiple 32-blocks. +fn sg_sum(value: f32) -> f32 { +{% if sgExact32 %} + return subgroupAdd(value); +{% else %} + var x = value; + x = x + subgroupShuffleXor(x, 1u); + x = x + subgroupShuffleXor(x, 2u); + x = x + subgroupShuffleXor(x, 4u); + x = x + subgroupShuffleXor(x, 8u); + x = x + subgroupShuffleXor(x, 16u); + return x; +{% endif %} +} +fn sg_max(value: f32) -> f32 { +{% if sgExact32 %} + return subgroupMax(value); +{% else %} + var x = value; + x = max(x, subgroupShuffleXor(x, 1u)); + x = max(x, subgroupShuffleXor(x, 2u)); + x = max(x, subgroupShuffleXor(x, 4u)); + x = max(x, subgroupShuffleXor(x, 8u)); + x = max(x, subgroupShuffleXor(x, 16u)); + return x; +{% endif %} +} + +// Hybrid 2-barrier reductions: 32-block reduce, followed by a cross-block combine. fn reduce_max(value: f32, tid: u32) -> f32 { - let s = subgroupMax(value); + let s = sg_max(value); if ((tid & 31u) == 0u) { red[tid >> 5u] = s; } workgroupBarrier(); var total: f32 = NEG_INF; @@ -814,7 +844,7 @@ fn reduce_max(value: f32, tid: u32) -> f32 { } fn reduce_sum(value: f32, tid: u32) -> f32 { - let s = subgroupAdd(value); + let s = sg_sum(value); if ((tid & 31u) == 0u) { red[tid >> 5u] = s; } workgroupBarrier(); var total: f32 = 0.0; @@ -935,7 +965,7 @@ fn main(@builtin(workgroup_id) wg: vec3, @builtin(local_invocation_id) lid: accS = accS + dot(vec4(qn_sh[d4 * 4u], qn_sh[d4 * 4u + 1u], qn_sh[d4 * 4u + 2u], qn_sh[d4 * 4u + 3u]), kv4); } } - let sj = subgroupAdd(accS); + let sj = sg_sum(accS); if ((tid & 31u) == 0u && j < tileCountS) { sval_sh[j] = sj * SCALE; } } workgroupBarrier(); @@ -1051,10 +1081,12 @@ fn main(@builtin(workgroup_id) wg: vec3, @builtin(local_invocation_id) lid: out[h * HEAD_DIM + d] = {{ outputScalar }}(srq(acc * inv, OUT_Q)); } } -`]]}],["com.xenova.gemma4.DecodeDownNormAdd",{manifest:{schemaVersion:1,domain:"com.xenova.gemma4",name:"DecodeDownNormAdd",sinceVersion:1,inputs:[{role:"A",dtype:"T"},{role:"Bits",dtype:"uint32"},{role:"Scale",dtype:"float32"},{role:"Hidden",dtype:"H"},{role:"W",dtype:"float32",rank:1}],outputs:[{role:"Hidden",dtype:"H"}],typeConstraints:{T:["float32","float16"],H:["float32","float16"]},args:{aT:{kind:"tensor",semantic:"A",role:"input"},bitsT:{kind:"tensor",semantic:"Bits",role:"weights"},scaleT:{kind:"tensor",semantic:"Scale",role:"weights"},hiddenT:{kind:"tensor",semantic:"Hidden",role:"inout"},wT:{kind:"tensor",semantic:"W",role:"weights"},M:{kind:"u32",semantic:"M"},inFeatures:{kind:"u32",semantic:"in_features"},outFeatures:{kind:"u32",semantic:"out_features"},bits:{kind:"u32",semantic:"bits"},zeroPoint:{kind:"u32",semantic:"zero_point"},mask:{kind:"u32",semantic:"mask"},inputScale:{kind:"f32",semantic:"input_activation_scale",required:!1},outputScale:{kind:"f32",semantic:"output_activation_scale",required:!1},eps:{kind:"f32",semantic:"eps",required:!1},codes:{kind:"u32",semantic:"input_is_codes",required:!1}},variants:[{id:"fused",priority:5,when:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32 and (args.bits == 2 or args.bits == 4) and args.M == 1 and args.inFeatures > 0 and args.outFeatures > 0 and args.outFeatures <= 4096 and (args.inFeatures * args.bits / 32) % 4 == 0 and args.zeroPoint > 0 and args.mask > 0 and numel(shapes.aT) >= args.inFeatures and numel(shapes.bitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.scaleT) >= args.outFeatures and numel(shapes.hiddenT) >= args.outFeatures and dim(shapes.wT, 0) == args.outFeatures and (tensorDtypes.aT == "float32" or tensorDtypes.aT == "float16") and (tensorDtypes.hiddenT == "float32" or tensorDtypes.hiddenT == "float16") and ((tensorDtypes.aT != "float16" and tensorDtypes.hiddenT != "float16") or device.features.has("shader-f16"))',constants:{usesF16:'tensorDtypes.aT == "float16" or tensorDtypes.hiddenT == "float16"',inputScalar:"dtypes.T",xScalar:"dtypes.H",IN_FEATURES:"args.inFeatures",OUT_FEATURES:"args.outFeatures",BITS:"args.bits",VALS_PER_WORD:"32 / args.bits",CHUNKS:"8 / args.bits",WORDS_PER_ROW:"args.inFeatures * args.bits / 32",MASK:"args.mask",ZP:"args.zeroPoint",N_ROWS:4,TOTAL_WGS:"ceil(args.outFeatures / 4)",EPS:"args.eps if args.eps else 0.000001",WG:256,CODES:"1 if args.codes else 0",aVec4:'"vec4" if dtypes.T == "f16" else "vec4"'},intermediates:[{id:"pp",dtype:"uint32",shape:"[args.outFeatures + 1]"}],passes:[{id:"main",name:"DecodeDownNormAddFused",shader:"down-fused.wgsl.jinja",bindings:[{name:"a",arg:"aT",semantic:"A",role:"input",buffer:{type:"read-only-storage"},elementType:"$aVec4"},{name:"bits_buf",arg:"bitsT",semantic:"Bits",role:"weights",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"pp",semantic:"pp",role:"scratch",buffer:{type:"storage"},elementType:"atomic"},{name:"scale",arg:"scaleT",semantic:"Scale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"hidden",arg:"hiddenT",semantic:"Hidden",role:"inout",buffer:{type:"storage"},elementType:"$xScalar"},{name:"nw",arg:"wT",semantic:"W",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"inScale",type:"f32",value:"args.inputScale if args.inputScale else 0.0"},{name:"outScale",type:"f32",value:"args.outputScale if args.outputScale else 0.0"}]}}],dispatch:{x:"ceil(args.outFeatures / 4)",y:1,z:1},reads:["A","Bits","Scale","Hidden","W"],writes:["pp","Hidden"]}]},{id:"splitk",priority:0,when:'(not args.codes) and ((args.bits == 2 or args.bits == 4) and args.M == 1 and args.inFeatures > 0 and args.outFeatures > 0 and args.outFeatures <= 4096 and (args.inFeatures * args.bits / 32) % 4 == 0 and args.zeroPoint > 0 and args.mask > 0 and numel(shapes.aT) >= args.inFeatures and numel(shapes.bitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.scaleT) >= args.outFeatures and numel(shapes.hiddenT) >= args.outFeatures and dim(shapes.wT, 0) == args.outFeatures and (tensorDtypes.aT == "float32" or tensorDtypes.aT == "float16") and (tensorDtypes.hiddenT == "float32" or tensorDtypes.hiddenT == "float16") and ((tensorDtypes.aT != "float16" and tensorDtypes.hiddenT != "float16") or device.features.has("shader-f16")))',constants:{usesF16:'tensorDtypes.aT == "float16" or tensorDtypes.hiddenT == "float16"',inputScalar:"dtypes.T",xScalar:"dtypes.H",IN_FEATURES:"args.inFeatures",OUT_FEATURES:"args.outFeatures",BITS:"args.bits",VALS_PER_WORD:"32 / args.bits",CHUNKS:"8 / args.bits",WORDS_PER_ROW:"args.inFeatures * args.bits / 32",MASK:"args.mask",ZP:"args.zeroPoint",SPLIT:4,WG:32,N_ROWS:2,MERGE_WG:128,EPS:"args.eps if args.eps else 0.000001",useSubgroups:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32',GRID_X:"min(ceil(args.outFeatures / 2), 65535)"},intermediates:[{id:"partial_qa",dtype:"float32",shape:"[args.outFeatures * 4]"},{id:"partial_a",dtype:"float32",shape:"[4]"}],passes:[{id:"partial",name:"DecodeDownNormAddPartial",shader:"down-partial.wgsl.jinja",bindings:[{name:"a",arg:"aT",semantic:"A",role:"input",buffer:{type:"read-only-storage"},elementType:"$inputScalar"},{name:"bits_buf",arg:"bitsT",semantic:"Bits",role:"weights",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"partial_qa",semantic:"partial_qa",role:"scratch",buffer:{type:"storage"},elementType:"f32"},{name:"partial_a",semantic:"partial_a",role:"scratch",buffer:{type:"storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"inScale",type:"f32",value:"args.inputScale if args.inputScale else 0.0"}]}}],dispatch:{x:"min(ceil(args.outFeatures / 2), 65535)",y:"ceil(ceil(args.outFeatures / 2) / min(ceil(args.outFeatures / 2), 65535))",z:4},reads:["A","Bits"],writes:["partial_qa","partial_a"]},{id:"merge",name:"DecodeDownNormAddMerge",shader:"down-merge-norm-add.wgsl.jinja",bindings:[{name:"partial_qa",semantic:"partial_qa",role:"scratch",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"partial_a",semantic:"partial_a",role:"scratch",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"scale",arg:"scaleT",semantic:"Scale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"hidden",arg:"hiddenT",semantic:"Hidden",role:"inout",buffer:{type:"storage"},elementType:"$xScalar"},{name:"w",arg:"wT",semantic:"W",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"outScale",type:"f32",value:"args.outputScale if args.outputScale else 0.0"}]}}],dispatch:{x:1,y:1,z:1},reads:["partial_qa","partial_a","Scale","Hidden","W"],writes:["Hidden"]}]}]},assets:[["down-fused.wgsl.jinja",`{% if usesF16 %} +`]]}],["com.xenova.gemma4.DecodeDownNormAdd",{manifest:{schemaVersion:1,domain:"com.xenova.gemma4",name:"DecodeDownNormAdd",sinceVersion:1,inputs:[{role:"A",dtype:"T"},{role:"Bits",dtype:"uint32"},{role:"Scale",dtype:"float32"},{role:"Hidden",dtype:"H"},{role:"W",dtype:"float32",rank:1}],outputs:[{role:"Hidden",dtype:"H"}],typeConstraints:{T:["float32","float16"],H:["float32","float16"]},args:{aT:{kind:"tensor",semantic:"A",role:"input"},bitsT:{kind:"tensor",semantic:"Bits",role:"weights"},scaleT:{kind:"tensor",semantic:"Scale",role:"weights"},hiddenT:{kind:"tensor",semantic:"Hidden",role:"inout"},wT:{kind:"tensor",semantic:"W",role:"weights"},M:{kind:"u32",semantic:"M"},inFeatures:{kind:"u32",semantic:"in_features"},outFeatures:{kind:"u32",semantic:"out_features"},bits:{kind:"u32",semantic:"bits"},zeroPoint:{kind:"u32",semantic:"zero_point"},mask:{kind:"u32",semantic:"mask"},inputScale:{kind:"f32",semantic:"input_activation_scale",required:!1},outputScale:{kind:"f32",semantic:"output_activation_scale",required:!1},eps:{kind:"f32",semantic:"eps",required:!1},codes:{kind:"u32",semantic:"input_is_codes",required:!1}},variants:[{id:"fused",priority:5,when:'(device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize >= 32 or args.codes) and (args.bits == 2 or args.bits == 4) and args.M == 1 and args.inFeatures > 0 and args.outFeatures > 0 and args.outFeatures <= 4096 and (args.inFeatures * args.bits / 32) % 4 == 0 and args.zeroPoint > 0 and args.mask > 0 and numel(shapes.aT) >= args.inFeatures and numel(shapes.bitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.scaleT) >= args.outFeatures and numel(shapes.hiddenT) >= args.outFeatures and dim(shapes.wT, 0) == args.outFeatures and (tensorDtypes.aT == "float32" or tensorDtypes.aT == "float16") and (tensorDtypes.hiddenT == "float32" or tensorDtypes.hiddenT == "float16") and ((tensorDtypes.aT != "float16" and tensorDtypes.hiddenT != "float16") or device.features.has("shader-f16"))',constants:{usesF16:'tensorDtypes.aT == "float16" or tensorDtypes.hiddenT == "float16"',inputScalar:"dtypes.T",xScalar:"dtypes.H",IN_FEATURES:"args.inFeatures",OUT_FEATURES:"args.outFeatures",BITS:"args.bits",VALS_PER_WORD:"32 / args.bits",CHUNKS:"8 / args.bits",WORDS_PER_ROW:"args.inFeatures * args.bits / 32",MASK:"args.mask",ZP:"args.zeroPoint",useSubgroups:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize >= 32',sgExact32:"device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32",N_ROWS:4,TOTAL_WGS:"ceil(args.outFeatures / 4)",EPS:"args.eps if args.eps else 0.000001",WG:256,CODES:"1 if args.codes else 0",aVec4:'"vec4" if dtypes.T == "f16" else "vec4"'},intermediates:[{id:"pp",dtype:"uint32",shape:"[args.outFeatures + 1]"}],passes:[{id:"main",name:"DecodeDownNormAddFused",shader:"down-fused.wgsl.jinja",bindings:[{name:"a",arg:"aT",semantic:"A",role:"input",buffer:{type:"read-only-storage"},elementType:"$aVec4"},{name:"bits_buf",arg:"bitsT",semantic:"Bits",role:"weights",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"pp",semantic:"pp",role:"scratch",buffer:{type:"storage"},elementType:"atomic"},{name:"scale",arg:"scaleT",semantic:"Scale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"hidden",arg:"hiddenT",semantic:"Hidden",role:"inout",buffer:{type:"storage"},elementType:"$xScalar"},{name:"nw",arg:"wT",semantic:"W",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"inScale",type:"f32",value:"args.inputScale if args.inputScale else 0.0"},{name:"outScale",type:"f32",value:"args.outputScale if args.outputScale else 0.0"}]}}],dispatch:{x:"ceil(args.outFeatures / 4)",y:1,z:1},reads:["A","Bits","Scale","Hidden","W"],writes:["pp","Hidden"]}]},{id:"splitk",priority:0,when:'(not args.codes) and ((args.bits == 2 or args.bits == 4) and args.M == 1 and args.inFeatures > 0 and args.outFeatures > 0 and args.outFeatures <= 4096 and (args.inFeatures * args.bits / 32) % 4 == 0 and args.zeroPoint > 0 and args.mask > 0 and numel(shapes.aT) >= args.inFeatures and numel(shapes.bitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.scaleT) >= args.outFeatures and numel(shapes.hiddenT) >= args.outFeatures and dim(shapes.wT, 0) == args.outFeatures and (tensorDtypes.aT == "float32" or tensorDtypes.aT == "float16") and (tensorDtypes.hiddenT == "float32" or tensorDtypes.hiddenT == "float16") and ((tensorDtypes.aT != "float16" and tensorDtypes.hiddenT != "float16") or device.features.has("shader-f16")))',constants:{usesF16:'tensorDtypes.aT == "float16" or tensorDtypes.hiddenT == "float16"',inputScalar:"dtypes.T",xScalar:"dtypes.H",IN_FEATURES:"args.inFeatures",OUT_FEATURES:"args.outFeatures",BITS:"args.bits",VALS_PER_WORD:"32 / args.bits",CHUNKS:"8 / args.bits",WORDS_PER_ROW:"args.inFeatures * args.bits / 32",MASK:"args.mask",ZP:"args.zeroPoint",SPLIT:4,WG:32,N_ROWS:2,MERGE_WG:128,EPS:"args.eps if args.eps else 0.000001",useSubgroups:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32',GRID_X:"min(ceil(args.outFeatures / 2), 65535)"},intermediates:[{id:"partial_qa",dtype:"float32",shape:"[args.outFeatures * 4]"},{id:"partial_a",dtype:"float32",shape:"[4]"}],passes:[{id:"partial",name:"DecodeDownNormAddPartial",shader:"down-partial.wgsl.jinja",bindings:[{name:"a",arg:"aT",semantic:"A",role:"input",buffer:{type:"read-only-storage"},elementType:"$inputScalar"},{name:"bits_buf",arg:"bitsT",semantic:"Bits",role:"weights",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"partial_qa",semantic:"partial_qa",role:"scratch",buffer:{type:"storage"},elementType:"f32"},{name:"partial_a",semantic:"partial_a",role:"scratch",buffer:{type:"storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"inScale",type:"f32",value:"args.inputScale if args.inputScale else 0.0"}]}}],dispatch:{x:"min(ceil(args.outFeatures / 2), 65535)",y:"ceil(ceil(args.outFeatures / 2) / min(ceil(args.outFeatures / 2), 65535))",z:4},reads:["A","Bits"],writes:["partial_qa","partial_a"]},{id:"merge",name:"DecodeDownNormAddMerge",shader:"down-merge-norm-add.wgsl.jinja",bindings:[{name:"partial_qa",semantic:"partial_qa",role:"scratch",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"partial_a",semantic:"partial_a",role:"scratch",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"scale",arg:"scaleT",semantic:"Scale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"hidden",arg:"hiddenT",semantic:"Hidden",role:"inout",buffer:{type:"storage"},elementType:"$xScalar"},{name:"w",arg:"wT",semantic:"W",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"outScale",type:"f32",value:"args.outputScale if args.outputScale else 0.0"}]}}],dispatch:{x:1,y:1,z:1},reads:["partial_qa","partial_a","Scale","Hidden","W"],writes:["Hidden"]}]}]},assets:[["down-fused.wgsl.jinja",`{% if usesF16 %} enable f16; {% endif %} +{% if useSubgroups %} enable subgroups; +{% endif %} {{ env.wgsl.resourceDeclarations }} // Single-dispatch fused down-projection + post-FFN residual norm-add (M=1 decode). @@ -1080,8 +1112,17 @@ const EPS: f32 = {{ EPS }}; const COUNTER_IDX: u32 = OUT_F; var dsh: array; +{% if useSubgroups %} var sgq: array, WG / 32u>; var sgs: array; +{% else %} +// Subgroup-free fallback (device lacks subgroups or has a non-32 subgroup width): +// every thread parks its partial, the combine sums the full workgroup. Slower combine +// (a serial/tree pass over WG instead of WG/32), but correct on any subgroup size and +// only on the off-critical-path final-row epilogue. +var sgq: array, WG>; +var sgs: array; +{% endif %} var lastFlag: u32; fn srq(x: f32, s: f32) -> f32 { @@ -1094,15 +1135,60 @@ fn srq4(x: vec4, s: f32) -> vec4 { return clamp(round(x / s), vec4(-128.0), vec4(127.0)) * s; } -// Hybrid 2-barrier reduction for the merge tail (subgroupAdd + cross-subgroup combine). +{% if useSubgroups %} +// Sum over each logical 32-lane block. sgExact32 (fixed 32-wide adapter) -> hardware +// subgroupAdd; otherwise a 32-lane subgroupShuffleXor butterfly that reduces each block +// independently, correct for any subgroup width >= 32 (NVIDIA D3D12 [32,128], AMD [32,64]). +fn sg_sum(value: f32) -> f32 { +{% if sgExact32 %} + return subgroupAdd(value); +{% else %} + var x = value; + x = x + subgroupShuffleXor(x, 1u); + x = x + subgroupShuffleXor(x, 2u); + x = x + subgroupShuffleXor(x, 4u); + x = x + subgroupShuffleXor(x, 8u); + x = x + subgroupShuffleXor(x, 16u); + return x; +{% endif %} +} +fn sg_sum_v4(value: vec4) -> vec4 { +{% if sgExact32 %} + return subgroupAdd(value); +{% else %} + var x = value; + x = x + subgroupShuffleXor(x, 1u); + x = x + subgroupShuffleXor(x, 2u); + x = x + subgroupShuffleXor(x, 4u); + x = x + subgroupShuffleXor(x, 8u); + x = x + subgroupShuffleXor(x, 16u); + return x; +{% endif %} +} +{% endif %} + fn reduce_sum(value: f32, tid: u32) -> f32 { - let s = subgroupAdd(value); +{% if useSubgroups %} + // Hybrid 2-barrier reduction (sg_sum within each 32-block + cross-block combine). + let s = sg_sum(value); if ((tid & 31u) == 0u) { sgs[tid >> 5u] = s; } workgroupBarrier(); var total: f32 = 0.0; for (var i: u32 = 0u; i < WG / 32u; i = i + 1u) { total = total + sgs[i]; } workgroupBarrier(); return total; +{% else %} + // Workgroup-memory tree reduction; total broadcast to every thread via sgs[0]. + sgs[tid] = value; + workgroupBarrier(); + for (var s: u32 = WG / 2u; s > 0u; s = s >> 1u) { + if (tid < s) { sgs[tid] = sgs[tid] + sgs[tid + s]; } + workgroupBarrier(); + } + let total = sgs[0]; + workgroupBarrier(); + return total; +{% endif %} } @compute @workgroup_size(WG, 1, 1) @@ -1161,7 +1247,8 @@ fn main(@builtin(workgroup_id) wg: vec3, @builtin(local_invocation_id) lid: } {% if N_ROWS == 2 %} - let red = subgroupAdd(vec4(q0, q1, sumA, 0.0)); +{% if useSubgroups %} + let red = sg_sum_v4(vec4(q0, q1, sumA, 0.0)); if ((tid & 31u) == 0u) { sgq[tid >> 5u] = red; } workgroupBarrier(); if (tid == 0u) { @@ -1169,14 +1256,41 @@ fn main(@builtin(workgroup_id) wg: vec3, @builtin(local_invocation_id) lid: for (var i: u32 = 0u; i < WG / 32u; i = i + 1u) { tot = tot + sgq[i]; } let aSum = tot.z; {% else %} - let red = subgroupAdd(vec4(q0, q1, q2, q3)); - let redA = subgroupAdd(sumA); + // Parallel workgroup tree (shared barriers): O(log WG) instead of a serial sum by tid 0. + sgq[tid] = vec4(q0, q1, sumA, 0.0); + workgroupBarrier(); + for (var s: u32 = WG / 2u; s > 0u; s = s >> 1u) { + if (tid < s) { sgq[tid] = sgq[tid] + sgq[tid + s]; } + workgroupBarrier(); + } + if (tid == 0u) { + let tot = sgq[0]; + let aSum = tot.z; +{% endif %} +{% else %} +{% if useSubgroups %} + let red = sg_sum_v4(vec4(q0, q1, q2, q3)); + let redA = sg_sum(sumA); if ((tid & 31u) == 0u) { sgq[tid >> 5u] = red; sgs[tid >> 5u] = redA; } workgroupBarrier(); if (tid == 0u) { var tot = vec4(0.0); var aSum: f32 = 0.0; for (var i: u32 = 0u; i < WG / 32u; i = i + 1u) { tot = tot + sgq[i]; aSum = aSum + sgs[i]; } +{% else %} + // Parallel workgroup tree (shared barriers): the q-vec and sumA reduce together, sharing + // one barrier chain \u2014 O(log WG) vs a serial sum by tid 0 over all WG partials. + sgq[tid] = vec4(q0, q1, q2, q3); + sgs[tid] = sumA; + workgroupBarrier(); + for (var s: u32 = WG / 2u; s > 0u; s = s >> 1u) { + if (tid < s) { sgq[tid] = sgq[tid] + sgq[tid + s]; sgs[tid] = sgs[tid] + sgs[tid + s]; } + workgroupBarrier(); + } + if (tid == 0u) { + let tot = sgq[0]; + let aSum = sgs[0]; +{% endif %} {% endif %} let outScale = params.outScale; let zpA = ZP * aSum; @@ -1430,7 +1544,7 @@ fn main(@builtin(workgroup_id) wg: vec3, @builtin(local_invocation_id) lid: partial_a[chunk] = rA; } } -`]]}],["com.xenova.gemma4.DecodeGateUpNorm",{manifest:{schemaVersion:1,domain:"com.xenova.gemma4",name:"DecodeGateUpNorm",sinceVersion:1,inputs:[{role:"Hidden",dtype:"T"},{role:"GateBits",dtype:"uint32"},{role:"GateScale",dtype:"float32"},{role:"UpBits",dtype:"uint32"},{role:"UpScale",dtype:"float32"},{role:"SumA",dtype:"float32",optional:!0},{role:"GeluLut",dtype:"float32"}],outputs:[{role:"Out",dtype:"O",shape:["args.M","args.outFeatures"]}],typeConstraints:{T:["float32","float16"],O:["float32","float16"]},args:{hiddenT:{kind:"tensor",semantic:"Hidden",role:"input"},gateBitsT:{kind:"tensor",semantic:"GateBits",role:"weights"},gateScaleT:{kind:"tensor",semantic:"GateScale",role:"weights"},upBitsT:{kind:"tensor",semantic:"UpBits",role:"weights"},upScaleT:{kind:"tensor",semantic:"UpScale",role:"weights"},sumAT:{kind:"tensor",semantic:"SumA",role:"input",required:!1},outT:{kind:"tensor",semantic:"Out",role:"output"},M:{kind:"u32",semantic:"M"},inFeatures:{kind:"u32",semantic:"in_features"},outFeatures:{kind:"u32",semantic:"out_features"},bits:{kind:"u32",semantic:"bits"},zeroPoint:{kind:"u32",semantic:"zero_point"},mask:{kind:"u32",semantic:"mask"},inScale:{kind:"f32",semantic:"input_activation_scale",required:!1},gateOutScale:{kind:"f32",semantic:"gate_output_activation_scale",required:!1},upOutScale:{kind:"f32",semantic:"up_output_activation_scale",required:!1},outQuantScale:{kind:"f32",semantic:"out_quant_scale",required:!1},emitCodes:{kind:"u32",semantic:"emit_codes",required:!1},geluLutT:{kind:"tensor",semantic:"GeluLut",role:"weights"},exact:{kind:"u32",semantic:"exact_reference_order",required:!1}},bindingSets:{default:[{name:"hidden",arg:"hiddenT",semantic:"Hidden",role:"input",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"gate_bits",arg:"gateBitsT",semantic:"GateBits",role:"weights",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"gate_scale",arg:"gateScaleT",semantic:"GateScale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"up_bits",arg:"upBitsT",semantic:"UpBits",role:"weights",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"up_scale",arg:"upScaleT",semantic:"UpScale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"out",arg:"outT",semantic:"Out",role:"output",buffer:{type:"storage"},elementType:"f32"},{name:"gelu_lut",arg:"geluLutT",semantic:"GeluLut",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"inScale",type:"f32",value:"args.inScale if args.inScale else 0.0"},{name:"invInScale",type:"f32",value:"(1.0 / args.inScale) if args.inScale else 0.0"},{name:"gateOutScale",type:"f32",value:"args.gateOutScale if args.gateOutScale else 0.0"},{name:"invGateOutScale",type:"f32",value:"(1.0 / args.gateOutScale) if args.gateOutScale else 0.0"},{name:"upOutScale",type:"f32",value:"args.upOutScale if args.upOutScale else 0.0"},{name:"invUpOutScale",type:"f32",value:"(1.0 / args.upOutScale) if args.upOutScale else 0.0"}]}}],set1:[{name:"hidden",arg:"hiddenT",semantic:"Hidden",role:"input",buffer:{type:"read-only-storage"},elementType:"$hiddenVec4"},{name:"gate_bits",arg:"gateBitsT",semantic:"GateBits",role:"weights",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"gate_scale",arg:"gateScaleT",semantic:"GateScale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"up_bits",arg:"upBitsT",semantic:"UpBits",role:"weights",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"up_scale",arg:"upScaleT",semantic:"UpScale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"sum_a",arg:"sumAT",semantic:"SumA",role:"input",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"out",arg:"outT",semantic:"Out",role:"output",buffer:{type:"storage"},elementType:"$outScalar"},{name:"gelu_lut",arg:"geluLutT",semantic:"GeluLut",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"gateOutScale",type:"f32",value:"args.gateOutScale if args.gateOutScale else 0.0"},{name:"upOutScale",type:"f32",value:"args.upOutScale if args.upOutScale else 0.0"},{name:"outQuantScale",type:"f32",value:"args.outQuantScale if args.outQuantScale else 0.0"}]}}],set2:[{name:"hidden",arg:"hiddenT",semantic:"Hidden",role:"input",buffer:{type:"read-only-storage"},elementType:"$scalar"},{name:"gate_bits",arg:"gateBitsT",semantic:"GateBits",role:"weights",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"gate_scale",arg:"gateScaleT",semantic:"GateScale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"up_bits",arg:"upBitsT",semantic:"UpBits",role:"weights",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"up_scale",arg:"upScaleT",semantic:"UpScale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"out",arg:"outT",semantic:"Out",role:"output",buffer:{type:"storage"},elementType:"$outScalar"},{name:"gelu_lut",arg:"geluLutT",semantic:"GeluLut",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"inScale",type:"f32",value:"args.inScale if args.inScale else 0.0"},{name:"gateOutScale",type:"f32",value:"args.gateOutScale if args.gateOutScale else 0.0"},{name:"upOutScale",type:"f32",value:"args.upOutScale if args.upOutScale else 0.0"}]}}],set3:[{name:"hidden",arg:"hiddenT",semantic:"Hidden",role:"input",buffer:{type:"read-only-storage"},elementType:"$hiddenVec4"},{name:"gate_bits",arg:"gateBitsT",semantic:"GateBits",role:"weights",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"gate_scale",arg:"gateScaleT",semantic:"GateScale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"up_bits",arg:"upBitsT",semantic:"UpBits",role:"weights",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"up_scale",arg:"upScaleT",semantic:"UpScale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"out",arg:"outT",semantic:"Out",role:"output",buffer:{type:"storage"},elementType:"$outScalar"},{name:"gelu_lut",arg:"geluLutT",semantic:"GeluLut",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"inScale",type:"f32",value:"args.inScale if args.inScale else 0.0"},{name:"gateOutScale",type:"f32",value:"args.gateOutScale if args.gateOutScale else 0.0"},{name:"upOutScale",type:"f32",value:"args.upOutScale if args.upOutScale else 0.0"}]}}]},variants:[{id:"gemm",priority:12,when:"(not args.exact) and (present.sumAT and (args.bits == 2 or args.bits == 4) and args.M > 0 and args.inFeatures > 0 and args.inFeatures <= 4096 and args.outFeatures > 0 and (args.inFeatures * args.bits) % 32 == 0 and args.zeroPoint > 0 and args.mask > 0 and numel(shapes.hiddenT) >= args.M * args.inFeatures and numel(shapes.sumAT) >= args.M and numel(shapes.gateBitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.gateScaleT) >= args.outFeatures and numel(shapes.upBitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.upScaleT) >= args.outFeatures and numel(shapes.outT) >= args.M * args.outFeatures and (f16Ok(dtypes.T)) and numel(shapes.geluLutT) >= 256) and args.M >= 16",constants:{usesF16:'dtypes.T == "f16"',scalar:"dtypes.T",M:"args.M",H:"args.inFeatures",INTER:"args.outFeatures",BITS:"args.bits",VPW:"32 / args.bits",CHUNKS:"8 / args.bits",WPR:"args.inFeatures * args.bits / 32",MASK:"args.mask",ZP:"args.zeroPoint",WG:64,N_ROWS:"2 if args.bits == 2 else 4",useSubgroups:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32',GRID_X:"min(ceil(args.outFeatures / (32 if args.bits == 4 else 16)), 65535)",M_TILE:"2 if args.M > 2 else args.M",outScalar:"dtypes.O",SG_COUNT:2,hiddenVec4:'"vec4" if dtypes.T == "f16" else "vec4"',EMIT_CODES:"1 if args.emitCodes else 0",GEMM:1,THREADS_N:16,THREADS_M:16,N_PT:"2 if args.bits == 4 else 1",M_PT:2,PRESRQ:1},passes:[{id:"main",name:"DecodeGateUpNormPresrq",shader:"decode-gate-up-norm-presrq.wgsl.jinja",bindings:"set1",dispatch:{x:"min(ceil(args.outFeatures / (32 if args.bits == 4 else 16)), 65535)",y:"ceil(ceil(args.outFeatures / (32 if args.bits == 4 else 16)) / min(ceil(args.outFeatures / (32 if args.bits == 4 else 16)), 65535))",z:"ceil(args.M / 32)"},reads:["Hidden","GateBits","GateScale","UpBits","UpScale","SumA","GeluLut"],writes:["Out"]}]},{id:"presrq",priority:10,when:"(not args.exact) and (present.sumAT and (args.bits == 2 or args.bits == 4) and args.M > 0 and args.inFeatures > 0 and args.inFeatures <= 4096 and args.outFeatures > 0 and (args.inFeatures * args.bits) % 32 == 0 and args.zeroPoint > 0 and args.mask > 0 and numel(shapes.hiddenT) >= args.M * args.inFeatures and numel(shapes.sumAT) >= args.M and numel(shapes.gateBitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.gateScaleT) >= args.outFeatures and numel(shapes.upBitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.upScaleT) >= args.outFeatures and numel(shapes.outT) >= args.M * args.outFeatures and (f16Ok(dtypes.T)) and numel(shapes.geluLutT) >= 256)",constants:{usesF16:'dtypes.T == "f16"',scalar:"dtypes.T",M:"args.M",H:"args.inFeatures",INTER:"args.outFeatures",BITS:"args.bits",VPW:"32 / args.bits",CHUNKS:"8 / args.bits",WPR:"args.inFeatures * args.bits / 32",MASK:"args.mask",ZP:"args.zeroPoint",WG:64,N_ROWS:"2 if args.bits == 2 else 4",useSubgroups:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32',GRID_X:"min(ceil(args.outFeatures / ((2 if args.bits == 2 else 4) * 2)), 65535)",M_TILE:"2 if args.M > 2 else args.M",outScalar:"dtypes.O",SG_COUNT:2,hiddenVec4:'"vec4" if dtypes.T == "f16" else "vec4"',EMIT_CODES:"1 if args.emitCodes else 0",GEMM:0,PRESRQ:1},passes:[{id:"main",name:"DecodeGateUpNormPresrq",shader:"decode-gate-up-norm-presrq.wgsl.jinja",bindings:"set1",dispatch:{x:"min(ceil(args.outFeatures / ((2 if args.bits == 2 else 4) * 2)), 65535)",y:"ceil(ceil(args.outFeatures / ((2 if args.bits == 2 else 4) * 2)) / min(ceil(args.outFeatures / ((2 if args.bits == 2 else 4) * 2)), 65535))",z:"ceil(args.M / (2 if args.M > 2 else args.M))"},reads:["Hidden","GateBits","GateScale","UpBits","UpScale","SumA","GeluLut"],writes:["Out"]}]},{id:"gemm_sgmat",priority:13,when:'(not args.exact) and ((not args.emitCodes) and ((args.bits == 2 or args.bits == 4) and args.M > 0 and args.inFeatures > 0 and args.inFeatures <= 4096 and args.outFeatures > 0 and (args.inFeatures * args.bits) % 32 == 0 and args.zeroPoint > 0 and args.mask > 0 and numel(shapes.hiddenT) >= args.M * args.inFeatures and numel(shapes.gateBitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.gateScaleT) >= args.outFeatures and numel(shapes.upBitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.upScaleT) >= args.outFeatures and numel(shapes.outT) >= args.M * args.outFeatures and (f16Ok(dtypes.T))) and numel(shapes.geluLutT) >= 256) and args.M >= 16 and args.M >= 64 and args.inFeatures % 32 == 0 and args.outFeatures % 64 == 0 and args.inScale > 0 and device.features.has("shader-f16") and device.features.has("chromium-experimental-subgroup-matrix")',constants:{usesF16:'dtypes.T == "f16"',scalar:"dtypes.T",M:"args.M",H:"args.inFeatures",INTER:"args.outFeatures",BITS:"args.bits",CHUNKS:"8 / args.bits",WPR:"args.inFeatures * args.bits / 32",ZP:"args.zeroPoint",outScalar:"dtypes.O"},passes:[{id:"main",name:"DecodeGateUpNorm",shader:"decode-gate-up-norm-sgmat.wgsl.jinja",bindings:"set2",dispatch:{x:"ceil(args.outFeatures / 64)",y:"ceil(args.M / 32)",z:1},reads:["Hidden","GateBits","GateScale","UpBits","UpScale","GeluLut"],writes:["Out"]}]},{id:"gemm_staged",priority:8,when:"(not args.exact) and ((not args.emitCodes) and ((args.bits == 2 or args.bits == 4) and args.M > 0 and args.inFeatures > 0 and args.inFeatures <= 4096 and args.outFeatures > 0 and (args.inFeatures * args.bits) % 32 == 0 and args.zeroPoint > 0 and args.mask > 0 and numel(shapes.hiddenT) >= args.M * args.inFeatures and numel(shapes.gateBitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.gateScaleT) >= args.outFeatures and numel(shapes.upBitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.upScaleT) >= args.outFeatures and numel(shapes.outT) >= args.M * args.outFeatures and (f16Ok(dtypes.T))) and numel(shapes.geluLutT) >= 256) and args.M >= 16",constants:{usesF16:'dtypes.T == "f16"',scalar:"dtypes.T",M:"args.M",H:"args.inFeatures",INTER:"args.outFeatures",BITS:"args.bits",VPW:"32 / args.bits",CHUNKS:"8 / args.bits",WPR:"args.inFeatures * args.bits / 32",MASK:"args.mask",ZP:"args.zeroPoint",WG:32,N_ROWS:2,useSubgroups:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize >= 32',GRID_X:"min(ceil(args.outFeatures / (32 if args.bits == 4 else 16)), 65535)",M_TILE:"2 if args.M > 2 else args.M",outScalar:"dtypes.O",hiddenVec4:'"vec4" if dtypes.T == "f16" else "vec4"',GEMM:1,PRESRQ:0,EMIT_CODES:0,THREADS_N:16,THREADS_M:16,N_PT:"2 if args.bits == 4 else 1",M_PT:2,SG_COUNT:1},passes:[{id:"main",name:"DecodeGateUpNorm",shader:"decode-gate-up-norm-presrq.wgsl.jinja",bindings:"set3",dispatch:{x:"min(ceil(args.outFeatures / (32 if args.bits == 4 else 16)), 65535)",y:"ceil(ceil(args.outFeatures / (32 if args.bits == 4 else 16)) / min(ceil(args.outFeatures / (32 if args.bits == 4 else 16)), 65535))",z:"ceil(args.M / 32)"},reads:["Hidden","GateBits","GateScale","UpBits","UpScale","GeluLut"],writes:["Out"]}]},{id:"staged",priority:0,when:"(not args.exact) and ((not args.emitCodes) and ((args.bits == 2 or args.bits == 4) and args.M > 0 and args.inFeatures > 0 and args.inFeatures <= 4096 and args.outFeatures > 0 and (args.inFeatures * args.bits) % 32 == 0 and args.zeroPoint > 0 and args.mask > 0 and numel(shapes.hiddenT) >= args.M * args.inFeatures and numel(shapes.gateBitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.gateScaleT) >= args.outFeatures and numel(shapes.upBitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.upScaleT) >= args.outFeatures and numel(shapes.outT) >= args.M * args.outFeatures and (f16Ok(dtypes.T))) and numel(shapes.geluLutT) >= 256)",constants:{usesF16:'dtypes.T == "f16"',scalar:"dtypes.T",M:"args.M",H:"args.inFeatures",INTER:"args.outFeatures",BITS:"args.bits",VPW:"32 / args.bits",CHUNKS:"8 / args.bits",WPR:"args.inFeatures * args.bits / 32",MASK:"args.mask",ZP:"args.zeroPoint",WG:32,N_ROWS:2,useSubgroups:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize >= 32',GRID_X:"min(ceil(args.outFeatures / 2), 65535)",M_TILE:"2 if args.M > 2 else args.M",outScalar:"dtypes.O",hiddenVec4:'"vec4" if dtypes.T == "f16" else "vec4"',GEMM:0,PRESRQ:0},passes:[{id:"main",name:"DecodeGateUpNorm",shader:"decode-gate-up-norm.wgsl.jinja",bindings:"set3",dispatch:{x:"min(ceil(args.outFeatures / 2), 65535)",y:"ceil(ceil(args.outFeatures / 2) / min(ceil(args.outFeatures / 2), 65535))",z:"ceil(args.M / (2 if args.M > 2 else args.M))"},reads:["Hidden","GateBits","GateScale","UpBits","UpScale","GeluLut"],writes:["Out"]}]}]},assets:[["decode-gate-up-norm-presrq.wgsl.jinja",`{% if usesF16 %} +`]]}],["com.xenova.gemma4.DecodeGateUpNorm",{manifest:{schemaVersion:1,domain:"com.xenova.gemma4",name:"DecodeGateUpNorm",sinceVersion:1,inputs:[{role:"Hidden",dtype:"T"},{role:"GateBits",dtype:"uint32"},{role:"GateScale",dtype:"float32"},{role:"UpBits",dtype:"uint32"},{role:"UpScale",dtype:"float32"},{role:"SumA",dtype:"float32",optional:!0},{role:"GeluLut",dtype:"float32"}],outputs:[{role:"Out",dtype:"O",shape:["args.M","args.outFeatures"]}],typeConstraints:{T:["float32","float16"],O:["float32","float16"]},args:{hiddenT:{kind:"tensor",semantic:"Hidden",role:"input"},gateBitsT:{kind:"tensor",semantic:"GateBits",role:"weights"},gateScaleT:{kind:"tensor",semantic:"GateScale",role:"weights"},upBitsT:{kind:"tensor",semantic:"UpBits",role:"weights"},upScaleT:{kind:"tensor",semantic:"UpScale",role:"weights"},sumAT:{kind:"tensor",semantic:"SumA",role:"input",required:!1},outT:{kind:"tensor",semantic:"Out",role:"output"},M:{kind:"u32",semantic:"M"},inFeatures:{kind:"u32",semantic:"in_features"},outFeatures:{kind:"u32",semantic:"out_features"},bits:{kind:"u32",semantic:"bits"},zeroPoint:{kind:"u32",semantic:"zero_point"},mask:{kind:"u32",semantic:"mask"},inScale:{kind:"f32",semantic:"input_activation_scale",required:!1},gateOutScale:{kind:"f32",semantic:"gate_output_activation_scale",required:!1},upOutScale:{kind:"f32",semantic:"up_output_activation_scale",required:!1},outQuantScale:{kind:"f32",semantic:"out_quant_scale",required:!1},emitCodes:{kind:"u32",semantic:"emit_codes",required:!1},geluLutT:{kind:"tensor",semantic:"GeluLut",role:"weights"},exact:{kind:"u32",semantic:"exact_reference_order",required:!1}},bindingSets:{default:[{name:"hidden",arg:"hiddenT",semantic:"Hidden",role:"input",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"gate_bits",arg:"gateBitsT",semantic:"GateBits",role:"weights",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"gate_scale",arg:"gateScaleT",semantic:"GateScale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"up_bits",arg:"upBitsT",semantic:"UpBits",role:"weights",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"up_scale",arg:"upScaleT",semantic:"UpScale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"out",arg:"outT",semantic:"Out",role:"output",buffer:{type:"storage"},elementType:"f32"},{name:"gelu_lut",arg:"geluLutT",semantic:"GeluLut",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"inScale",type:"f32",value:"args.inScale if args.inScale else 0.0"},{name:"invInScale",type:"f32",value:"(1.0 / args.inScale) if args.inScale else 0.0"},{name:"gateOutScale",type:"f32",value:"args.gateOutScale if args.gateOutScale else 0.0"},{name:"invGateOutScale",type:"f32",value:"(1.0 / args.gateOutScale) if args.gateOutScale else 0.0"},{name:"upOutScale",type:"f32",value:"args.upOutScale if args.upOutScale else 0.0"},{name:"invUpOutScale",type:"f32",value:"(1.0 / args.upOutScale) if args.upOutScale else 0.0"}]}}],set1:[{name:"hidden",arg:"hiddenT",semantic:"Hidden",role:"input",buffer:{type:"read-only-storage"},elementType:"$hiddenVec4"},{name:"gate_bits",arg:"gateBitsT",semantic:"GateBits",role:"weights",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"gate_scale",arg:"gateScaleT",semantic:"GateScale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"up_bits",arg:"upBitsT",semantic:"UpBits",role:"weights",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"up_scale",arg:"upScaleT",semantic:"UpScale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"sum_a",arg:"sumAT",semantic:"SumA",role:"input",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"out",arg:"outT",semantic:"Out",role:"output",buffer:{type:"storage"},elementType:"$outScalar"},{name:"gelu_lut",arg:"geluLutT",semantic:"GeluLut",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"gateOutScale",type:"f32",value:"args.gateOutScale if args.gateOutScale else 0.0"},{name:"upOutScale",type:"f32",value:"args.upOutScale if args.upOutScale else 0.0"},{name:"outQuantScale",type:"f32",value:"args.outQuantScale if args.outQuantScale else 0.0"}]}}],set2:[{name:"hidden",arg:"hiddenT",semantic:"Hidden",role:"input",buffer:{type:"read-only-storage"},elementType:"$scalar"},{name:"gate_bits",arg:"gateBitsT",semantic:"GateBits",role:"weights",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"gate_scale",arg:"gateScaleT",semantic:"GateScale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"up_bits",arg:"upBitsT",semantic:"UpBits",role:"weights",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"up_scale",arg:"upScaleT",semantic:"UpScale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"out",arg:"outT",semantic:"Out",role:"output",buffer:{type:"storage"},elementType:"$outScalar"},{name:"gelu_lut",arg:"geluLutT",semantic:"GeluLut",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"inScale",type:"f32",value:"args.inScale if args.inScale else 0.0"},{name:"gateOutScale",type:"f32",value:"args.gateOutScale if args.gateOutScale else 0.0"},{name:"upOutScale",type:"f32",value:"args.upOutScale if args.upOutScale else 0.0"}]}}],set3:[{name:"hidden",arg:"hiddenT",semantic:"Hidden",role:"input",buffer:{type:"read-only-storage"},elementType:"$hiddenVec4"},{name:"gate_bits",arg:"gateBitsT",semantic:"GateBits",role:"weights",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"gate_scale",arg:"gateScaleT",semantic:"GateScale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"up_bits",arg:"upBitsT",semantic:"UpBits",role:"weights",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"up_scale",arg:"upScaleT",semantic:"UpScale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"out",arg:"outT",semantic:"Out",role:"output",buffer:{type:"storage"},elementType:"$outScalar"},{name:"gelu_lut",arg:"geluLutT",semantic:"GeluLut",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"inScale",type:"f32",value:"args.inScale if args.inScale else 0.0"},{name:"gateOutScale",type:"f32",value:"args.gateOutScale if args.gateOutScale else 0.0"},{name:"upOutScale",type:"f32",value:"args.upOutScale if args.upOutScale else 0.0"}]}}]},variants:[{id:"gemm",priority:12,when:"(not args.exact) and (present.sumAT and (args.bits == 2 or args.bits == 4) and args.M > 0 and args.inFeatures > 0 and args.inFeatures <= 4096 and args.outFeatures > 0 and (args.inFeatures * args.bits) % 32 == 0 and args.zeroPoint > 0 and args.mask > 0 and numel(shapes.hiddenT) >= args.M * args.inFeatures and numel(shapes.sumAT) >= args.M and numel(shapes.gateBitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.gateScaleT) >= args.outFeatures and numel(shapes.upBitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.upScaleT) >= args.outFeatures and numel(shapes.outT) >= args.M * args.outFeatures and (f16Ok(dtypes.T)) and numel(shapes.geluLutT) >= 256) and args.M >= 16",constants:{usesF16:'dtypes.T == "f16"',scalar:"dtypes.T",M:"args.M",H:"args.inFeatures",INTER:"args.outFeatures",BITS:"args.bits",VPW:"32 / args.bits",CHUNKS:"8 / args.bits",WPR:"args.inFeatures * args.bits / 32",MASK:"args.mask",ZP:"args.zeroPoint",WG:64,N_ROWS:"2 if args.bits == 2 else 4",useSubgroups:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32',GRID_X:"min(ceil(args.outFeatures / (32 if args.bits == 4 else 16)), 65535)",M_TILE:"2 if args.M > 2 else args.M",outScalar:"dtypes.O",SG_COUNT:2,hiddenVec4:'"vec4" if dtypes.T == "f16" else "vec4"',EMIT_CODES:"1 if args.emitCodes else 0",GEMM:1,THREADS_N:16,THREADS_M:16,N_PT:"2 if args.bits == 4 else 1",M_PT:2,PRESRQ:1},passes:[{id:"main",name:"DecodeGateUpNormPresrq",shader:"decode-gate-up-norm-presrq.wgsl.jinja",bindings:"set1",dispatch:{x:"min(ceil(args.outFeatures / (32 if args.bits == 4 else 16)), 65535)",y:"ceil(ceil(args.outFeatures / (32 if args.bits == 4 else 16)) / min(ceil(args.outFeatures / (32 if args.bits == 4 else 16)), 65535))",z:"ceil(args.M / 32)"},reads:["Hidden","GateBits","GateScale","UpBits","UpScale","SumA","GeluLut"],writes:["Out"]}]},{id:"presrq",priority:10,when:"(not args.exact) and (present.sumAT and (args.bits == 2 or args.bits == 4) and args.M > 0 and args.inFeatures > 0 and args.inFeatures <= 4096 and args.outFeatures > 0 and (args.inFeatures * args.bits) % 32 == 0 and args.zeroPoint > 0 and args.mask > 0 and numel(shapes.hiddenT) >= args.M * args.inFeatures and numel(shapes.sumAT) >= args.M and numel(shapes.gateBitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.gateScaleT) >= args.outFeatures and numel(shapes.upBitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.upScaleT) >= args.outFeatures and numel(shapes.outT) >= args.M * args.outFeatures and (f16Ok(dtypes.T)) and numel(shapes.geluLutT) >= 256)",constants:{usesF16:'dtypes.T == "f16"',scalar:"dtypes.T",M:"args.M",H:"args.inFeatures",INTER:"args.outFeatures",BITS:"args.bits",VPW:"32 / args.bits",CHUNKS:"8 / args.bits",WPR:"args.inFeatures * args.bits / 32",MASK:"args.mask",ZP:"args.zeroPoint",WG:64,N_ROWS:"2 if args.bits == 2 else 4",useSubgroups:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize >= 32',sgExact32:"device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32",GRID_X:"min(ceil(args.outFeatures / ((2 if args.bits == 2 else 4) * 2)), 65535)",M_TILE:"2 if args.M > 2 else args.M",outScalar:"dtypes.O",SG_COUNT:2,hiddenVec4:'"vec4" if dtypes.T == "f16" else "vec4"',EMIT_CODES:"1 if args.emitCodes else 0",GEMM:0,PRESRQ:1},passes:[{id:"main",name:"DecodeGateUpNormPresrq",shader:"decode-gate-up-norm-presrq.wgsl.jinja",bindings:"set1",dispatch:{x:"min(ceil(args.outFeatures / ((2 if args.bits == 2 else 4) * 2)), 65535)",y:"ceil(ceil(args.outFeatures / ((2 if args.bits == 2 else 4) * 2)) / min(ceil(args.outFeatures / ((2 if args.bits == 2 else 4) * 2)), 65535))",z:"ceil(args.M / (2 if args.M > 2 else args.M))"},reads:["Hidden","GateBits","GateScale","UpBits","UpScale","SumA","GeluLut"],writes:["Out"]}]},{id:"gemm_sgmat",priority:13,when:'(not args.exact) and ((not args.emitCodes) and ((args.bits == 2 or args.bits == 4) and args.M > 0 and args.inFeatures > 0 and args.inFeatures <= 4096 and args.outFeatures > 0 and (args.inFeatures * args.bits) % 32 == 0 and args.zeroPoint > 0 and args.mask > 0 and numel(shapes.hiddenT) >= args.M * args.inFeatures and numel(shapes.gateBitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.gateScaleT) >= args.outFeatures and numel(shapes.upBitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.upScaleT) >= args.outFeatures and numel(shapes.outT) >= args.M * args.outFeatures and (f16Ok(dtypes.T))) and numel(shapes.geluLutT) >= 256) and args.M >= 16 and args.M >= 64 and args.inFeatures % 32 == 0 and args.outFeatures % 64 == 0 and args.inScale > 0 and device.features.has("shader-f16") and device.features.has("subgroups") and device.features.has("chromium-experimental-subgroup-matrix")',constants:{usesF16:'dtypes.T == "f16"',scalar:"dtypes.T",M:"args.M",H:"args.inFeatures",INTER:"args.outFeatures",BITS:"args.bits",CHUNKS:"8 / args.bits",WPR:"args.inFeatures * args.bits / 32",ZP:"args.zeroPoint",outScalar:"dtypes.O"},passes:[{id:"main",name:"DecodeGateUpNorm",shader:"decode-gate-up-norm-sgmat.wgsl.jinja",bindings:"set2",dispatch:{x:"ceil(args.outFeatures / 64)",y:"ceil(args.M / 32)",z:1},reads:["Hidden","GateBits","GateScale","UpBits","UpScale","GeluLut"],writes:["Out"]}]},{id:"gemm_staged",priority:8,when:"(not args.exact) and ((not args.emitCodes) and ((args.bits == 2 or args.bits == 4) and args.M > 0 and args.inFeatures > 0 and args.inFeatures <= 4096 and args.outFeatures > 0 and (args.inFeatures * args.bits) % 32 == 0 and args.zeroPoint > 0 and args.mask > 0 and numel(shapes.hiddenT) >= args.M * args.inFeatures and numel(shapes.gateBitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.gateScaleT) >= args.outFeatures and numel(shapes.upBitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.upScaleT) >= args.outFeatures and numel(shapes.outT) >= args.M * args.outFeatures and (f16Ok(dtypes.T))) and numel(shapes.geluLutT) >= 256) and args.M >= 16",constants:{usesF16:'dtypes.T == "f16"',scalar:"dtypes.T",M:"args.M",H:"args.inFeatures",INTER:"args.outFeatures",BITS:"args.bits",VPW:"32 / args.bits",CHUNKS:"8 / args.bits",WPR:"args.inFeatures * args.bits / 32",MASK:"args.mask",ZP:"args.zeroPoint",WG:32,N_ROWS:2,useSubgroups:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize >= 32',GRID_X:"min(ceil(args.outFeatures / (32 if args.bits == 4 else 16)), 65535)",M_TILE:"2 if args.M > 2 else args.M",outScalar:"dtypes.O",hiddenVec4:'"vec4" if dtypes.T == "f16" else "vec4"',GEMM:1,PRESRQ:0,EMIT_CODES:0,THREADS_N:16,THREADS_M:16,N_PT:"2 if args.bits == 4 else 1",M_PT:2,SG_COUNT:1},passes:[{id:"main",name:"DecodeGateUpNorm",shader:"decode-gate-up-norm-presrq.wgsl.jinja",bindings:"set3",dispatch:{x:"min(ceil(args.outFeatures / (32 if args.bits == 4 else 16)), 65535)",y:"ceil(ceil(args.outFeatures / (32 if args.bits == 4 else 16)) / min(ceil(args.outFeatures / (32 if args.bits == 4 else 16)), 65535))",z:"ceil(args.M / 32)"},reads:["Hidden","GateBits","GateScale","UpBits","UpScale","GeluLut"],writes:["Out"]}]},{id:"staged",priority:0,when:"(not args.exact) and ((not args.emitCodes) and ((args.bits == 2 or args.bits == 4) and args.M > 0 and args.inFeatures > 0 and args.inFeatures <= 4096 and args.outFeatures > 0 and (args.inFeatures * args.bits) % 32 == 0 and args.zeroPoint > 0 and args.mask > 0 and numel(shapes.hiddenT) >= args.M * args.inFeatures and numel(shapes.gateBitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.gateScaleT) >= args.outFeatures and numel(shapes.upBitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.upScaleT) >= args.outFeatures and numel(shapes.outT) >= args.M * args.outFeatures and (f16Ok(dtypes.T))) and numel(shapes.geluLutT) >= 256)",constants:{usesF16:'dtypes.T == "f16"',scalar:"dtypes.T",M:"args.M",H:"args.inFeatures",INTER:"args.outFeatures",BITS:"args.bits",VPW:"32 / args.bits",CHUNKS:"8 / args.bits",WPR:"args.inFeatures * args.bits / 32",MASK:"args.mask",ZP:"args.zeroPoint",WG:32,N_ROWS:2,useSubgroups:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize >= 32',GRID_X:"min(ceil(args.outFeatures / 2), 65535)",M_TILE:"2 if args.M > 2 else args.M",outScalar:"dtypes.O",hiddenVec4:'"vec4" if dtypes.T == "f16" else "vec4"',GEMM:0,PRESRQ:0},passes:[{id:"main",name:"DecodeGateUpNorm",shader:"decode-gate-up-norm.wgsl.jinja",bindings:"set3",dispatch:{x:"min(ceil(args.outFeatures / 2), 65535)",y:"ceil(ceil(args.outFeatures / 2) / min(ceil(args.outFeatures / 2), 65535))",z:"ceil(args.M / (2 if args.M > 2 else args.M))"},reads:["Hidden","GateBits","GateScale","UpBits","UpScale","GeluLut"],writes:["Out"]}]}]},assets:[["decode-gate-up-norm-presrq.wgsl.jinja",`{% if usesF16 %} enable f16; {% endif %} {% if useSubgroups %} @@ -1464,9 +1578,29 @@ const GRID_X: u32 = {{ GRID_X }}u; var partial: array; {% endif %} -fn reduce_sum(value: f32, lidx: u32) -> f32 { {% if useSubgroups %} +// Sum over each logical 32-lane virtual subgroup. sgExact32 (fixed 32-wide adapter) -> +// hardware subgroupAdd; otherwise a 32-lane subgroupShuffleXor butterfly that reduces each +// 32-block independently \u2014 correct for any subgroup width >= 32 (NVIDIA D3D12 [32,128], +// AMD [32,64]) where a plain subgroupAdd over the WG would merge the virtual units. +fn sg_sum(value: f32) -> f32 { +{% if sgExact32 %} return subgroupAdd(value); +{% else %} + var x = value; + x = x + subgroupShuffleXor(x, 1u); + x = x + subgroupShuffleXor(x, 2u); + x = x + subgroupShuffleXor(x, 4u); + x = x + subgroupShuffleXor(x, 8u); + x = x + subgroupShuffleXor(x, 16u); + return x; +{% endif %} +} +{% endif %} + +fn reduce_sum(value: f32, lidx: u32) -> f32 { +{% if useSubgroups %} + return sg_sum(value); {% else %} // Segment-local tree matching the virtual-subgroup layout: each 32-lane // unit reduces its own partial[base..base+31] slots. A whole-workgroup tree @@ -2192,7 +2326,7 @@ fn main(@builtin(workgroup_id) wg: vec3, @builtin(local_invocation_id) lid: } } {% endif %} -`]]}],["com.xenova.gemma4.DecodeNormAdd",{manifest:{schemaVersion:1,domain:"com.xenova.gemma4",name:"DecodeNormAdd",sinceVersion:1,inputs:[{role:"Hidden",dtype:"T"},{role:"Src",dtype:"T"},{role:"W",dtype:"W",rank:1},{role:"Scale",dtype:"float32",rank:1}],outputs:[{role:"Hidden",dtype:"T",shape:"shapes.hiddenT"}],typeConstraints:{T:["float32","float16"],W:["float32","float16"]},args:{hiddenT:{kind:"tensor",semantic:"Hidden",role:"inout"},srcT:{kind:"tensor",semantic:"Src",role:"input"},wT:{kind:"tensor",semantic:"W",role:"weights"},scaleT:{kind:"tensor",semantic:"Scale",role:"weights"},rows:{kind:"u32",semantic:"rows"},dim:{kind:"u32",semantic:"dim"},eps:{kind:"f32",semantic:"eps",required:!1}},variants:[{id:"scalar",priority:0,when:'args.rows > 0 and args.dim > 0 and numel(shapes.hiddenT) >= args.rows * args.dim and numel(shapes.srcT) >= args.rows * args.dim and dim(shapes.wT, 0) == args.dim and numel(shapes.scaleT) >= 1 and ((dtypes.T != "f16" and dtypes.W != "f16") or device.features.has("shader-f16"))',constants:{usesF16:'dtypes.T == "f16" or dtypes.W == "f16"',useSubgroups:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32',WG:256,xScalar:"dtypes.T",wScalar:"dtypes.W",DIM:"args.dim",EPS:"args.eps if args.eps else 0.000001"},passes:[{id:"main",name:"DecodeNormAdd",shader:"decode-norm-add.wgsl.jinja",bindings:[{name:"hidden",arg:"hiddenT",semantic:"Hidden",role:"inout",buffer:{type:"storage"},elementType:"$xScalar"},{name:"src",arg:"srcT",semantic:"Src",role:"input",buffer:{type:"read-only-storage"},elementType:"$xScalar"},{name:"w",arg:"wT",semantic:"W",role:"weights",buffer:{type:"read-only-storage"},elementType:"$wScalar"},{name:"sc",arg:"scaleT",semantic:"Scale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"rows",type:"u32",value:"args.rows"},{name:"rowStride",type:"u32",value:"min(args.rows, 65535)"}]}}],dispatch:{x:"min(args.rows, 65535)",y:"ceil(args.rows / min(args.rows, 65535))",z:1},reads:["Hidden","Src","W","Scale"],writes:["Hidden"]}]}]},assets:[["decode-norm-add.wgsl.jinja",`{% if usesF16 %} +`]]}],["com.xenova.gemma4.DecodeNormAdd",{manifest:{schemaVersion:1,domain:"com.xenova.gemma4",name:"DecodeNormAdd",sinceVersion:1,inputs:[{role:"Hidden",dtype:"T"},{role:"Src",dtype:"T"},{role:"W",dtype:"W",rank:1},{role:"Scale",dtype:"float32",rank:1}],outputs:[{role:"Hidden",dtype:"T",shape:"shapes.hiddenT"}],typeConstraints:{T:["float32","float16"],W:["float32","float16"]},args:{hiddenT:{kind:"tensor",semantic:"Hidden",role:"inout"},srcT:{kind:"tensor",semantic:"Src",role:"input"},wT:{kind:"tensor",semantic:"W",role:"weights"},scaleT:{kind:"tensor",semantic:"Scale",role:"weights"},rows:{kind:"u32",semantic:"rows"},dim:{kind:"u32",semantic:"dim"},eps:{kind:"f32",semantic:"eps",required:!1}},variants:[{id:"scalar",priority:0,when:'args.rows > 0 and args.dim > 0 and numel(shapes.hiddenT) >= args.rows * args.dim and numel(shapes.srcT) >= args.rows * args.dim and dim(shapes.wT, 0) == args.dim and numel(shapes.scaleT) >= 1 and ((dtypes.T != "f16" and dtypes.W != "f16") or device.features.has("shader-f16"))',constants:{usesF16:'dtypes.T == "f16" or dtypes.W == "f16"',useSubgroups:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize >= 32',sgExact32:"device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32",WG:256,xScalar:"dtypes.T",wScalar:"dtypes.W",DIM:"args.dim",EPS:"args.eps if args.eps else 0.000001"},passes:[{id:"main",name:"DecodeNormAdd",shader:"decode-norm-add.wgsl.jinja",bindings:[{name:"hidden",arg:"hiddenT",semantic:"Hidden",role:"inout",buffer:{type:"storage"},elementType:"$xScalar"},{name:"src",arg:"srcT",semantic:"Src",role:"input",buffer:{type:"read-only-storage"},elementType:"$xScalar"},{name:"w",arg:"wT",semantic:"W",role:"weights",buffer:{type:"read-only-storage"},elementType:"$wScalar"},{name:"sc",arg:"scaleT",semantic:"Scale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"rows",type:"u32",value:"args.rows"},{name:"rowStride",type:"u32",value:"min(args.rows, 65535)"}]}}],dispatch:{x:"min(args.rows, 65535)",y:"ceil(args.rows / min(args.rows, 65535))",z:1},reads:["Hidden","Src","W","Scale"],writes:["Hidden"]}]}]},assets:[["decode-norm-add.wgsl.jinja",`{% if usesF16 %} enable f16; {% endif %} {% if useSubgroups %} @@ -2216,8 +2350,25 @@ const WG: u32 = {{ WG }}u; // Hybrid 2-barrier reduction: subgroupAdd per subgroup + cross-subgroup combine via shared. var sgp: array; +// Sum over each logical 32-lane block. sgExact32 (fixed 32-wide adapter) -> hardware +// subgroupAdd; otherwise a 32-lane subgroupShuffleXor butterfly that reduces each block +// independently, correct for any subgroup width >= 32 (NVIDIA D3D12 [32,128], AMD [32,64]). +fn sg_sum(value: f32) -> f32 { +{% if sgExact32 %} + return subgroupAdd(value); +{% else %} + var x = value; + x = x + subgroupShuffleXor(x, 1u); + x = x + subgroupShuffleXor(x, 2u); + x = x + subgroupShuffleXor(x, 4u); + x = x + subgroupShuffleXor(x, 8u); + x = x + subgroupShuffleXor(x, 16u); + return x; +{% endif %} +} + fn reduce_sum(value: f32, tid: u32) -> f32 { - let s = subgroupAdd(value); + let s = sg_sum(value); if ((tid & 31u) == 0u) { sgp[tid >> 5u] = s; } workgroupBarrier(); var total: f32 = 0.0; @@ -2279,7 +2430,7 @@ fn main(@builtin(workgroup_id) wg: vec3, @builtin(local_invocation_id) lid: j = j + WG; } } -`]]}],["com.xenova.gemma4.DecodeNormAddNorm",{manifest:{schemaVersion:1,domain:"com.xenova.gemma4",name:"DecodeNormAddNorm",sinceVersion:1,inputs:[{role:"Hidden",dtype:"T"},{role:"Src",dtype:"T"},{role:"W1",dtype:"float32",rank:1},{role:"Scale",dtype:"float32",rank:1},{role:"W2",dtype:"float32",rank:1}],outputs:[{role:"Hidden",dtype:"T"},{role:"Y2",dtype:"Y"},{role:"Sum2",dtype:"float32"}],typeConstraints:{T:["float32","float16"],Y:["float32","float16"]},args:{hiddenT:{kind:"tensor",semantic:"Hidden",role:"inout"},srcT:{kind:"tensor",semantic:"Src",role:"input"},w1T:{kind:"tensor",semantic:"W1",role:"weights"},scaleT:{kind:"tensor",semantic:"Scale",role:"weights"},w2T:{kind:"tensor",semantic:"W2",role:"weights"},y2T:{kind:"tensor",semantic:"Y2",role:"output"},sum2T:{kind:"tensor",semantic:"Sum2",role:"output"},rows:{kind:"u32",semantic:"rows"},dim:{kind:"u32",semantic:"dim"},eps:{kind:"f32",semantic:"eps",required:!1},inScale:{kind:"f32",semantic:"input_activation_scale",required:!1}},variants:[{id:"main",priority:0,when:'args.rows > 0 and args.dim > 0 and args.dim <= 8192 and numel(shapes.hiddenT) >= args.rows * args.dim and numel(shapes.srcT) >= args.rows * args.dim and dim(shapes.w1T, 0) == args.dim and numel(shapes.scaleT) >= 1 and dim(shapes.w2T, 0) == args.dim and numel(shapes.y2T) >= args.rows * args.dim and numel(shapes.sum2T) >= args.rows and ((dtypes.T != "f16" and dtypes.Y != "f16") or device.features.has("shader-f16"))',constants:{xScalar:"dtypes.T",yScalar:"dtypes.Y",usesF16:'dtypes.T == "f16" or dtypes.Y == "f16"',useSubgroups:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32',WG:256,DIM:"args.dim",ELEMS:"ceil(args.dim / 256)",EPS:"args.eps if args.eps else 0.000001"},passes:[{id:"main",name:"DecodeNormAddNorm",shader:"decode-norm-add-norm.wgsl.jinja",bindings:[{name:"hidden",arg:"hiddenT",semantic:"Hidden",role:"inout",buffer:{type:"storage"},elementType:"$xScalar"},{name:"src",arg:"srcT",semantic:"Src",role:"input",buffer:{type:"read-only-storage"},elementType:"$xScalar"},{name:"w1",arg:"w1T",semantic:"W1",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"sc",arg:"scaleT",semantic:"Scale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"w2",arg:"w2T",semantic:"W2",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"y2",arg:"y2T",semantic:"Y2",role:"output",buffer:{type:"storage"},elementType:"$yScalar"},{name:"sum2",arg:"sum2T",semantic:"Sum2",role:"output",buffer:{type:"storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"rows",type:"u32",value:"args.rows"},{name:"rowStride",type:"u32",value:"min(args.rows, 65535)"},{name:"inScale",type:"f32",value:"args.inScale if args.inScale else 0.0"}]}}],dispatch:{x:"min(args.rows, 65535)",y:"ceil(args.rows / min(args.rows, 65535))",z:1},reads:["Hidden","Src","W1","Scale","W2"],writes:["Hidden","Y2","Sum2"]}]}]},assets:[["decode-norm-add-norm.wgsl.jinja",`{% if usesF16 %} +`]]}],["com.xenova.gemma4.DecodeNormAddNorm",{manifest:{schemaVersion:1,domain:"com.xenova.gemma4",name:"DecodeNormAddNorm",sinceVersion:1,inputs:[{role:"Hidden",dtype:"T"},{role:"Src",dtype:"T"},{role:"W1",dtype:"float32",rank:1},{role:"Scale",dtype:"float32",rank:1},{role:"W2",dtype:"float32",rank:1}],outputs:[{role:"Hidden",dtype:"T"},{role:"Y2",dtype:"Y"},{role:"Sum2",dtype:"float32"}],typeConstraints:{T:["float32","float16"],Y:["float32","float16"]},args:{hiddenT:{kind:"tensor",semantic:"Hidden",role:"inout"},srcT:{kind:"tensor",semantic:"Src",role:"input"},w1T:{kind:"tensor",semantic:"W1",role:"weights"},scaleT:{kind:"tensor",semantic:"Scale",role:"weights"},w2T:{kind:"tensor",semantic:"W2",role:"weights"},y2T:{kind:"tensor",semantic:"Y2",role:"output"},sum2T:{kind:"tensor",semantic:"Sum2",role:"output"},rows:{kind:"u32",semantic:"rows"},dim:{kind:"u32",semantic:"dim"},eps:{kind:"f32",semantic:"eps",required:!1},inScale:{kind:"f32",semantic:"input_activation_scale",required:!1}},variants:[{id:"main",priority:0,when:'args.rows > 0 and args.dim > 0 and args.dim <= 8192 and numel(shapes.hiddenT) >= args.rows * args.dim and numel(shapes.srcT) >= args.rows * args.dim and dim(shapes.w1T, 0) == args.dim and numel(shapes.scaleT) >= 1 and dim(shapes.w2T, 0) == args.dim and numel(shapes.y2T) >= args.rows * args.dim and numel(shapes.sum2T) >= args.rows and ((dtypes.T != "f16" and dtypes.Y != "f16") or device.features.has("shader-f16"))',constants:{xScalar:"dtypes.T",yScalar:"dtypes.Y",usesF16:'dtypes.T == "f16" or dtypes.Y == "f16"',useSubgroups:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize >= 32',sgExact32:"device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32",WG:256,DIM:"args.dim",ELEMS:"ceil(args.dim / 256)",EPS:"args.eps if args.eps else 0.000001"},passes:[{id:"main",name:"DecodeNormAddNorm",shader:"decode-norm-add-norm.wgsl.jinja",bindings:[{name:"hidden",arg:"hiddenT",semantic:"Hidden",role:"inout",buffer:{type:"storage"},elementType:"$xScalar"},{name:"src",arg:"srcT",semantic:"Src",role:"input",buffer:{type:"read-only-storage"},elementType:"$xScalar"},{name:"w1",arg:"w1T",semantic:"W1",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"sc",arg:"scaleT",semantic:"Scale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"w2",arg:"w2T",semantic:"W2",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"y2",arg:"y2T",semantic:"Y2",role:"output",buffer:{type:"storage"},elementType:"$yScalar"},{name:"sum2",arg:"sum2T",semantic:"Sum2",role:"output",buffer:{type:"storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"rows",type:"u32",value:"args.rows"},{name:"rowStride",type:"u32",value:"min(args.rows, 65535)"},{name:"inScale",type:"f32",value:"args.inScale if args.inScale else 0.0"}]}}],dispatch:{x:"min(args.rows, 65535)",y:"ceil(args.rows / min(args.rows, 65535))",z:1},reads:["Hidden","Src","W1","Scale","W2"],writes:["Hidden","Y2","Sum2"]}]}]},assets:[["decode-norm-add-norm.wgsl.jinja",`{% if usesF16 %} enable f16; {% endif %} {% if useSubgroups %} @@ -2305,8 +2456,25 @@ const ELEMS: u32 = {{ ELEMS }}u; // sums through shared slots. var sgp: array; +// Sum over each logical 32-lane block. sgExact32 (fixed 32-wide adapter) -> hardware +// subgroupAdd; otherwise a 32-lane subgroupShuffleXor butterfly that reduces each block +// independently, correct for any subgroup width >= 32 (NVIDIA D3D12 [32,128], AMD [32,64]). +fn sg_sum(value: f32) -> f32 { +{% if sgExact32 %} + return subgroupAdd(value); +{% else %} + var x = value; + x = x + subgroupShuffleXor(x, 1u); + x = x + subgroupShuffleXor(x, 2u); + x = x + subgroupShuffleXor(x, 4u); + x = x + subgroupShuffleXor(x, 8u); + x = x + subgroupShuffleXor(x, 16u); + return x; +{% endif %} +} + fn reduce_sum(value: f32, tid: u32) -> f32 { - let s = subgroupAdd(value); + let s = sg_sum(value); if ((tid & 31u) == 0u) { sgp[tid >> 5u] = s; } workgroupBarrier(); var total: f32 = 0.0; @@ -2408,10 +2576,12 @@ fn main(@builtin(workgroup_id) wg: vec3, @builtin(local_invocation_id) lid: sum2[row] = qSum; } } -`]]}],["com.xenova.gemma4.DecodeOprojNorm",{manifest:{schemaVersion:1,domain:"com.xenova.gemma4",name:"DecodeOprojNorm",sinceVersion:1,inputs:[{role:"A",dtype:"T"},{role:"Bits",dtype:"uint32"},{role:"Scale",dtype:"float32"},{role:"Hidden",dtype:"H"},{role:"W12",dtype:"float32"}],outputs:[{role:"Hidden",dtype:"H"},{role:"Y2",dtype:"Y"},{role:"Sum2",dtype:"float32"}],typeConstraints:{T:["float32"],H:["float32","float16"],Y:["float32","float16"]},args:{aT:{kind:"tensor",semantic:"A",role:"input"},bitsT:{kind:"tensor",semantic:"Bits",role:"weights"},scaleT:{kind:"tensor",semantic:"Scale",role:"weights"},hiddenT:{kind:"tensor",semantic:"Hidden",role:"inout"},w12T:{kind:"tensor",semantic:"W12",role:"weights"},y2T:{kind:"tensor",semantic:"Y2",role:"output"},sum2T:{kind:"tensor",semantic:"Sum2",role:"output"},inFeatures:{kind:"u32",semantic:"in_features"},outFeatures:{kind:"u32",semantic:"out_features"},bits:{kind:"u32",semantic:"bits"},zeroPoint:{kind:"u32",semantic:"zero_point"},mask:{kind:"u32",semantic:"mask"},outputScale:{kind:"f32",semantic:"output_activation_scale",required:!1},eps:{kind:"f32",semantic:"eps",required:!1},inScale2:{kind:"f32",semantic:"next_input_activation_scale",required:!1},rows:{kind:"u32",semantic:"row_cooperative",required:!1}},bindingSets:{default:[{name:"a",arg:"aT",semantic:"A",role:"input",buffer:{type:"read-only-storage"},elementType:"vec4"},{name:"bits_buf",arg:"bitsT",semantic:"Bits",role:"weights",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"scale",arg:"scaleT",semantic:"Scale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"pp",semantic:"pp",role:"scratch",buffer:{type:"storage"},elementType:"atomic"},{name:"hidden",arg:"hiddenT",semantic:"Hidden",role:"inout",buffer:{type:"storage"},elementType:"$xScalar"},{name:"w12",arg:"w12T",semantic:"W12",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"y2",arg:"y2T",semantic:"Y2",role:"output",buffer:{type:"storage"},elementType:"$yScalar"},{name:"sum2",arg:"sum2T",semantic:"Sum2",role:"output",buffer:{type:"storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"outScale",type:"f32",value:"args.outputScale if args.outputScale else 0.0"},{name:"inScale2",type:"f32",value:"args.inScale2 if args.inScale2 else 0.0"}]}}]},variants:[{id:"fused_rows",priority:10,when:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32 and (args.bits == 2 or args.bits == 4) and args.inFeatures > 0 and args.inFeatures % (32 / args.bits) == 0 and args.inFeatures % 4 == 0 and args.outFeatures > 0 and args.outFeatures <= 8192 and args.zeroPoint > 0 and args.mask > 0 and numel(shapes.aT) >= args.inFeatures and numel(shapes.bitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.scaleT) >= args.outFeatures and numel(shapes.hiddenT) >= args.outFeatures and numel(shapes.w12T) >= 2 * args.outFeatures and numel(shapes.y2T) >= args.outFeatures and numel(shapes.sum2T) >= 1 and ((dtypes.H != "f16" and dtypes.Y != "f16") or device.features.has("shader-f16")) and args.rows == 1 and args.bits == 4 and args.outFeatures % 8 == 0',constants:{usesF16:'dtypes.H == "f16" or dtypes.Y == "f16"',xScalar:"dtypes.H",yScalar:"dtypes.Y",IN_FEATURES:"args.inFeatures",OUT_FEATURES:"args.outFeatures",BITS:"args.bits",VALS_PER_WORD:"32 / args.bits",CHUNKS:"8 / args.bits",WORDS_PER_ROW:"args.inFeatures * args.bits / 32",MASK:"args.mask",ZP:"args.zeroPoint",WG:256,SG_ROWS:1,ROWS_PER_WG:8,ROWS_MODE:1,N_ROWS:8,TOTAL_WGS:"ceil(args.outFeatures / 8)",ELEMS:"ceil(args.outFeatures / 256)",EPS:"args.eps if args.eps else 0.000001"},intermediates:[{id:"pp",dtype:"uint32",shape:"[args.outFeatures + 1]"}],passes:[{id:"main",name:"DecodeOprojNorm",shader:"oproj-norm.wgsl.jinja",bindings:"default",dispatch:{x:"ceil(args.outFeatures / 8)",y:1,z:1},reads:["A","Bits","Scale","Hidden","W12"],writes:["pp","Hidden","Y2","Sum2"]}]},{id:"fused",priority:0,when:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32 and (args.bits == 2 or args.bits == 4) and args.inFeatures > 0 and args.inFeatures % (32 / args.bits) == 0 and args.inFeatures % 4 == 0 and args.outFeatures > 0 and args.outFeatures <= 8192 and args.zeroPoint > 0 and args.mask > 0 and numel(shapes.aT) >= args.inFeatures and numel(shapes.bitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.scaleT) >= args.outFeatures and numel(shapes.hiddenT) >= args.outFeatures and numel(shapes.w12T) >= 2 * args.outFeatures and numel(shapes.y2T) >= args.outFeatures and numel(shapes.sum2T) >= 1 and ((dtypes.H != "f16" and dtypes.Y != "f16") or device.features.has("shader-f16"))',constants:{usesF16:'dtypes.H == "f16" or dtypes.Y == "f16"',xScalar:"dtypes.H",yScalar:"dtypes.Y",IN_FEATURES:"args.inFeatures",OUT_FEATURES:"args.outFeatures",BITS:"args.bits",VALS_PER_WORD:"32 / args.bits",CHUNKS:"8 / args.bits",WORDS_PER_ROW:"args.inFeatures * args.bits / 32",MASK:"args.mask",ZP:"args.zeroPoint",WG:256,SG_ROWS:1,ROWS_PER_WG:8,ROWS_MODE:0,N_ROWS:1,TOTAL_WGS:"ceil(args.outFeatures / 8)",ELEMS:"ceil(args.outFeatures / 256)",EPS:"args.eps if args.eps else 0.000001"},intermediates:[{id:"pp",dtype:"uint32",shape:"[args.outFeatures + 1]"}],passes:[{id:"main",name:"DecodeOprojNorm",shader:"oproj-norm.wgsl.jinja",bindings:"default",dispatch:{x:"ceil(args.outFeatures / 8)",y:1,z:1},reads:["A","Bits","Scale","Hidden","W12"],writes:["pp","Hidden","Y2","Sum2"]}]}]},assets:[["oproj-norm.wgsl.jinja",`{% if usesF16 %} +`]]}],["com.xenova.gemma4.DecodeOprojNorm",{manifest:{schemaVersion:1,domain:"com.xenova.gemma4",name:"DecodeOprojNorm",sinceVersion:1,inputs:[{role:"A",dtype:"T"},{role:"Bits",dtype:"uint32"},{role:"Scale",dtype:"float32"},{role:"Hidden",dtype:"H"},{role:"W12",dtype:"float32"}],outputs:[{role:"Hidden",dtype:"H"},{role:"Y2",dtype:"Y"},{role:"Sum2",dtype:"float32"}],typeConstraints:{T:["float32"],H:["float32","float16"],Y:["float32","float16"]},args:{aT:{kind:"tensor",semantic:"A",role:"input"},bitsT:{kind:"tensor",semantic:"Bits",role:"weights"},scaleT:{kind:"tensor",semantic:"Scale",role:"weights"},hiddenT:{kind:"tensor",semantic:"Hidden",role:"inout"},w12T:{kind:"tensor",semantic:"W12",role:"weights"},y2T:{kind:"tensor",semantic:"Y2",role:"output"},sum2T:{kind:"tensor",semantic:"Sum2",role:"output"},inFeatures:{kind:"u32",semantic:"in_features"},outFeatures:{kind:"u32",semantic:"out_features"},bits:{kind:"u32",semantic:"bits"},zeroPoint:{kind:"u32",semantic:"zero_point"},mask:{kind:"u32",semantic:"mask"},outputScale:{kind:"f32",semantic:"output_activation_scale",required:!1},eps:{kind:"f32",semantic:"eps",required:!1},inScale2:{kind:"f32",semantic:"next_input_activation_scale",required:!1},rows:{kind:"u32",semantic:"row_cooperative",required:!1}},bindingSets:{default:[{name:"a",arg:"aT",semantic:"A",role:"input",buffer:{type:"read-only-storage"},elementType:"vec4"},{name:"bits_buf",arg:"bitsT",semantic:"Bits",role:"weights",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"scale",arg:"scaleT",semantic:"Scale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"pp",semantic:"pp",role:"scratch",buffer:{type:"storage"},elementType:"atomic"},{name:"hidden",arg:"hiddenT",semantic:"Hidden",role:"inout",buffer:{type:"storage"},elementType:"$xScalar"},{name:"w12",arg:"w12T",semantic:"W12",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"y2",arg:"y2T",semantic:"Y2",role:"output",buffer:{type:"storage"},elementType:"$yScalar"},{name:"sum2",arg:"sum2T",semantic:"Sum2",role:"output",buffer:{type:"storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"outScale",type:"f32",value:"args.outputScale if args.outputScale else 0.0"},{name:"inScale2",type:"f32",value:"args.inScale2 if args.inScale2 else 0.0"}]}}]},variants:[{id:"fused_rows",priority:10,when:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize >= 32 and (args.bits == 2 or args.bits == 4) and args.inFeatures > 0 and args.inFeatures % (32 / args.bits) == 0 and args.inFeatures % 4 == 0 and args.outFeatures > 0 and args.outFeatures <= 8192 and args.zeroPoint > 0 and args.mask > 0 and numel(shapes.aT) >= args.inFeatures and numel(shapes.bitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.scaleT) >= args.outFeatures and numel(shapes.hiddenT) >= args.outFeatures and numel(shapes.w12T) >= 2 * args.outFeatures and numel(shapes.y2T) >= args.outFeatures and numel(shapes.sum2T) >= 1 and ((dtypes.H != "f16" and dtypes.Y != "f16") or device.features.has("shader-f16")) and args.rows == 1 and args.bits == 4 and args.outFeatures % 8 == 0',constants:{usesF16:'dtypes.H == "f16" or dtypes.Y == "f16"',xScalar:"dtypes.H",yScalar:"dtypes.Y",IN_FEATURES:"args.inFeatures",OUT_FEATURES:"args.outFeatures",BITS:"args.bits",VALS_PER_WORD:"32 / args.bits",CHUNKS:"8 / args.bits",WORDS_PER_ROW:"args.inFeatures * args.bits / 32",MASK:"args.mask",ZP:"args.zeroPoint",WG:256,SG_ROWS:1,ROWS_PER_WG:8,ROWS_MODE:1,useSubgroups:!0,sgExact32:"device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32",N_ROWS:8,TOTAL_WGS:"ceil(args.outFeatures / 8)",ELEMS:"ceil(args.outFeatures / 256)",EPS:"args.eps if args.eps else 0.000001"},intermediates:[{id:"pp",dtype:"uint32",shape:"[args.outFeatures + 1]"}],passes:[{id:"main",name:"DecodeOprojNorm",shader:"oproj-norm.wgsl.jinja",bindings:"default",dispatch:{x:"ceil(args.outFeatures / 8)",y:1,z:1},reads:["A","Bits","Scale","Hidden","W12"],writes:["pp","Hidden","Y2","Sum2"]}]},{id:"fused",priority:0,when:'(args.bits == 2 or args.bits == 4) and args.inFeatures > 0 and args.inFeatures % (32 / args.bits) == 0 and args.inFeatures % 4 == 0 and args.outFeatures > 0 and args.outFeatures <= 8192 and args.zeroPoint > 0 and args.mask > 0 and numel(shapes.aT) >= args.inFeatures and numel(shapes.bitsT) >= args.outFeatures * (args.inFeatures * args.bits / 32) and numel(shapes.scaleT) >= args.outFeatures and numel(shapes.hiddenT) >= args.outFeatures and numel(shapes.w12T) >= 2 * args.outFeatures and numel(shapes.y2T) >= args.outFeatures and numel(shapes.sum2T) >= 1 and ((dtypes.H != "f16" and dtypes.Y != "f16") or device.features.has("shader-f16"))',constants:{usesF16:'dtypes.H == "f16" or dtypes.Y == "f16"',xScalar:"dtypes.H",yScalar:"dtypes.Y",IN_FEATURES:"args.inFeatures",OUT_FEATURES:"args.outFeatures",BITS:"args.bits",VALS_PER_WORD:"32 / args.bits",CHUNKS:"8 / args.bits",WORDS_PER_ROW:"args.inFeatures * args.bits / 32",MASK:"args.mask",ZP:"args.zeroPoint",WG:256,SG_ROWS:1,ROWS_PER_WG:8,ROWS_MODE:0,useSubgroups:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize >= 32',sgExact32:"device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32",N_ROWS:1,TOTAL_WGS:"ceil(args.outFeatures / 8)",ELEMS:"ceil(args.outFeatures / 256)",EPS:"args.eps if args.eps else 0.000001"},intermediates:[{id:"pp",dtype:"uint32",shape:"[args.outFeatures + 1]"}],passes:[{id:"main",name:"DecodeOprojNorm",shader:"oproj-norm.wgsl.jinja",bindings:"default",dispatch:{x:"ceil(args.outFeatures / 8)",y:1,z:1},reads:["A","Bits","Scale","Hidden","W12"],writes:["pp","Hidden","Y2","Sum2"]}]}]},assets:[["oproj-norm.wgsl.jinja",`{% if usesF16 %} enable f16; {% endif %} +{% if useSubgroups %} enable subgroups; +{% endif %} {{ env.wgsl.resourceDeclarations }} // Single-dispatch fused o-projection (QAT GEMV) + post-attention residual norm-add + pre-FFN @@ -2441,7 +2611,12 @@ const EPS: f32 = {{ EPS }}; const ELEMS: u32 = {{ ELEMS }}u; var lastFlag: u32; +{% if useSubgroups %} var sgp: array; +{% else %} +var wred: array; +var wred4: array, WG>; +{% endif %} {% if ROWS_MODE %} const N_ROWS: u32 = {{ N_ROWS }}u; var sgq: array, WG / 32u>; @@ -2449,14 +2624,81 @@ var sgq2: array, WG / 32u>; var sgpA: array; {% endif %} +{% if not useSubgroups %} +// Subgroup-free fallback (device lacks subgroups or has a non-32 subgroup width). +// Segmented reduction within each 32-lane logical block: role-equivalent to subgroupAdd +// over a 32-wide subgroup, but driven entirely by workgroup memory so it is correct on any +// hardware subgroup size. Reduces a vec4 so the activation sum + up to 3 row dot-sums share +// ONE barrier chain (vs one chain each). All WG threads must call it uniformly. +fn block_reduce32_v4(value: vec4, tid: u32) -> vec4 { + wred4[tid] = value; + workgroupBarrier(); + for (var s: u32 = 16u; s > 0u; s = s >> 1u) { + if ((tid & 31u) < s) { wred4[tid] = wred4[tid] + wred4[tid + s]; } + workgroupBarrier(); + } + let r = wred4[(tid >> 5u) << 5u]; + workgroupBarrier(); + return r; +} +{% endif %} + +{% if useSubgroups %} +// Sum over each logical 32-lane block. On a fixed 32-wide adapter (sgExact32) this is the +// hardware subgroupAdd. On adapters reporting a wider/ranged subgroup (NVIDIA D3D12 [32,128], +// AMD [32,64]/[64,64]) a plain subgroupAdd would span multiple 32-blocks, so we use a 32-lane +// subgroupShuffleXor butterfly (deltas 1,2,4,8,16) that reduces each block independently \u2014 +// correct for ANY hardware subgroup width >= 32, which is exactly what the >=32 gate ensures. +fn sg_sum(value: f32) -> f32 { +{% if sgExact32 %} + return subgroupAdd(value); +{% else %} + var x = value; + x = x + subgroupShuffleXor(x, 1u); + x = x + subgroupShuffleXor(x, 2u); + x = x + subgroupShuffleXor(x, 4u); + x = x + subgroupShuffleXor(x, 8u); + x = x + subgroupShuffleXor(x, 16u); + return x; +{% endif %} +} +{% if ROWS_MODE %} +fn sg_sum_v4(value: vec4) -> vec4 { +{% if sgExact32 %} + return subgroupAdd(value); +{% else %} + var x = value; + x = x + subgroupShuffleXor(x, 1u); + x = x + subgroupShuffleXor(x, 2u); + x = x + subgroupShuffleXor(x, 4u); + x = x + subgroupShuffleXor(x, 8u); + x = x + subgroupShuffleXor(x, 16u); + return x; +{% endif %} +} +{% endif %} +{% endif %} + fn reduce_sum(value: f32, tid: u32) -> f32 { - let s = subgroupAdd(value); +{% if useSubgroups %} + let s = sg_sum(value); if ((tid & 31u) == 0u) { sgp[tid >> 5u] = s; } workgroupBarrier(); var total: f32 = 0.0; for (var i: u32 = 0u; i < WG / 32u; i = i + 1u) { total = total + sgp[i]; } workgroupBarrier(); return total; +{% else %} + wred[tid] = value; + workgroupBarrier(); + for (var s: u32 = WG / 2u; s > 0u; s = s >> 1u) { + if (tid < s) { wred[tid] = wred[tid] + wred[tid + s]; } + workgroupBarrier(); + } + let total = wred[0]; + workgroupBarrier(); + return total; +{% endif %} } fn srq(x: f32, s: f32) -> f32 { @@ -2499,9 +2741,9 @@ fn main(@builtin(workgroup_id) wg: vec3, @builtin(local_invocation_id) lid: {% endfor %} w = w + WG; } - let red = subgroupAdd(vec4(q0, q1, q2, q3)); - let red2 = subgroupAdd(vec4(q4, q5, q6, q7)); - let redA = subgroupAdd(sumA); + let red = sg_sum_v4(vec4(q0, q1, q2, q3)); + let red2 = sg_sum_v4(vec4(q4, q5, q6, q7)); + let redA = sg_sum(sumA); if ((tid & 31u) == 0u) { sgq[tid >> 5u] = red; sgq2[tid >> 5u] = red2; sgpA[tid >> 5u] = redA; } workgroupBarrier(); if (tid == 0u) { @@ -2555,14 +2797,29 @@ fn main(@builtin(workgroup_id) wg: vec3, @builtin(local_invocation_id) lid: w = w + 32u; } - let rA = subgroupAdd(sumA); +{% if useSubgroups %} + let rA = sg_sum(sumA); for (var r: u32 = 0u; r < SG_ROWS; r = r + 1u) { - let rQA = subgroupAdd(sumQA[r]); + let rQA = sg_sum(sumQA[r]); let o = rowBase + r; if (lane == 0u && o < OUT_F) { atomicStore(&pp[o], bitcast(srq(scale[o] * (rQA - ZP * rA), outScale))); } } +{% else %} + // Batch the activation sum + the SG_ROWS row dot-sums into one segmented reduce + // (SG_ROWS <= 3 here, so all fit a single vec4 -> one barrier chain instead of SG_ROWS+1). + let red = block_reduce32_v4(vec4(sumA{% for r in range(SG_ROWS) %}, sumQA[{{ r }}u]{% endfor %}{% for _ in range(3 - SG_ROWS) %}, 0.0{% endfor %}), tid); + let rA = red.x; +{% for r in range(SG_ROWS) %} + { + let o = rowBase + {{ r }}u; + if (lane == 0u && o < OUT_F) { + atomicStore(&pp[o], bitcast(srq(scale[o] * (red[{{ r + 1 }}u] - ZP * rA), outScale))); + } + } +{% endfor %} +{% endif %} {% endif %} storageBarrier(); @@ -2835,10 +3092,12 @@ fn main(@builtin(workgroup_id) wg: vec3, @builtin(local_invocation_id) lid: } } } -`]]}],["com.xenova.gemma4.DecodePleProjNorm",{manifest:{schemaVersion:1,domain:"com.xenova.gemma4",name:"DecodePleProjNorm",sinceVersion:1,inputs:[{role:"A",dtype:"T"},{role:"Wt",dtype:"Wt",optional:!0},{role:"Codes",dtype:"uint32",optional:!0},{role:"RowScale",dtype:"float32",optional:!0},{role:"Hidden",dtype:"H"},{role:"W12S",dtype:"float32"}],outputs:[{role:"Hidden",dtype:"H"},{role:"Y2",dtype:"Y"},{role:"Sum2",dtype:"float32"}],typeConstraints:{T:["float32","float16"],Wt:["float32","float16"],H:["float32","float16"],Y:["float32","float16"]},args:{aT:{kind:"tensor",semantic:"A",role:"input"},wT:{kind:"tensor",semantic:"Wt",role:"weights",required:!1},codesT:{kind:"tensor",semantic:"Codes",role:"weights",required:!1},rowScaleT:{kind:"tensor",semantic:"RowScale",role:"weights",required:!1},codes:{kind:"u32",semantic:"codes_mode",required:!1},hiddenT:{kind:"tensor",semantic:"Hidden",role:"inout"},w12sT:{kind:"tensor",semantic:"W12S",role:"weights"},y2T:{kind:"tensor",semantic:"Y2",role:"output"},sum2T:{kind:"tensor",semantic:"Sum2",role:"output"},inFeatures:{kind:"u32",semantic:"in_features"},outFeatures:{kind:"u32",semantic:"out_features"},eps:{kind:"f32",semantic:"eps",required:!1},inScale:{kind:"f32",semantic:"input_activation_scale",required:!1},projInScale:{kind:"f32",semantic:"proj_input_activation_scale",required:!1},projOutScale:{kind:"f32",semantic:"proj_output_activation_scale",required:!1},codesCatT:{kind:"tensor",semantic:"CodesCat",role:"weights",required:!1},scaleCatT:{kind:"tensor",semantic:"ScaleCat",role:"weights",required:!1},pleT:{kind:"tensor",semantic:"Ple",role:"input",required:!1},gateInFeatures:{kind:"u32",semantic:"gate_in_features",required:!1},gateInScale:{kind:"f32",semantic:"gate_input_activation_scale",required:!1},gateOutScale:{kind:"f32",semantic:"gate_output_activation_scale",required:!1},pleOffset:{kind:"u32",semantic:"ple_offset",required:!1}},variants:[{id:"fused_codes",priority:1,when:'args.codes and present.codesT and present.rowScaleT and device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32 and args.inFeatures > 0 and args.inFeatures % 4 == 0 and args.inFeatures <= 1024 and args.outFeatures > 0 and args.outFeatures <= 8192 and dtypes.T == "f32" and numel(shapes.aT) >= args.inFeatures and numel(shapes.codesT) >= args.outFeatures * args.inFeatures / 4 and numel(shapes.rowScaleT) >= args.outFeatures and numel(shapes.hiddenT) >= args.outFeatures and numel(shapes.w12sT) >= 2 * args.outFeatures + 1 and numel(shapes.y2T) >= args.outFeatures and numel(shapes.sum2T) >= 1 and ((dtypes.H != "f16" and dtypes.Y != "f16") or device.features.has("shader-f16"))',constants:{usesF16:'dtypes.H == "f16" or dtypes.Y == "f16"',xScalar:"dtypes.H",yScalar:"dtypes.Y",IN_FEATURES:"args.inFeatures",OUT_FEATURES:"args.outFeatures",K_ITER:"ceil(args.inFeatures / 128)",WG:256,SG_ROWS:2,ROWS_PER_WG:16,TOTAL_WGS:"ceil(args.outFeatures / 16)",ELEMS:"ceil(args.outFeatures / 256)",EPS:"args.eps if args.eps else 0.000001"},intermediates:[{id:"pp",dtype:"uint32",shape:"[args.outFeatures + 1]"}],passes:[{id:"main",name:"DecodePleProjNormCodes",shader:"ple-proj-norm-codes.wgsl.jinja",bindings:[{name:"a",arg:"aT",semantic:"A",role:"input",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"codes",arg:"codesT",semantic:"Codes",role:"weights",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"row_scale",arg:"rowScaleT",semantic:"RowScale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"pp",semantic:"pp",role:"scratch",buffer:{type:"storage"},elementType:"atomic"},{name:"hidden",arg:"hiddenT",semantic:"Hidden",role:"inout",buffer:{type:"storage"},elementType:"$xScalar"},{name:"w12s",arg:"w12sT",semantic:"W12S",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"y2",arg:"y2T",semantic:"Y2",role:"output",buffer:{type:"storage"},elementType:"$yScalar"},{name:"sum2",arg:"sum2T",semantic:"Sum2",role:"output",buffer:{type:"storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"inScale",type:"f32",value:"args.inScale if args.inScale else 0.0"},{name:"projInScale",type:"f32",value:"args.projInScale if args.projInScale else 0.0"},{name:"projOutScale",type:"f32",value:"args.projOutScale if args.projOutScale else 0.0"}]}}],dispatch:{x:"ceil(args.outFeatures / 16)",y:1,z:1},reads:["A","Codes","RowScale","Hidden","W12S"],writes:["pp","Hidden","Y2","Sum2"]}]},{id:"fused",priority:0,when:'(not args.codes) and present.wT and device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32 and args.inFeatures > 0 and args.inFeatures % 4 == 0 and args.outFeatures > 0 and args.outFeatures <= 8192 and numel(shapes.aT) >= args.inFeatures and numel(shapes.wT) >= args.outFeatures * args.inFeatures and numel(shapes.hiddenT) >= args.outFeatures and numel(shapes.w12sT) >= 2 * args.outFeatures + 1 and numel(shapes.y2T) >= args.outFeatures and numel(shapes.sum2T) >= 1 and ((dtypes.T != "f16" and dtypes.Wt != "f16" and dtypes.H != "f16" and dtypes.Y != "f16") or device.features.has("shader-f16"))',constants:{usesF16:'dtypes.T == "f16" or dtypes.Wt == "f16" or dtypes.H == "f16" or dtypes.Y == "f16"',aScalar:"dtypes.T",wScalar:"dtypes.Wt",xScalar:"dtypes.H",yScalar:"dtypes.Y",IN_FEATURES:"args.inFeatures",OUT_FEATURES:"args.outFeatures",WG:256,SG_ROWS:2,ROWS_PER_WG:16,TOTAL_WGS:"ceil(args.outFeatures / 16)",ELEMS:"ceil(args.outFeatures / 256)",EPS:"args.eps if args.eps else 0.000001"},intermediates:[{id:"pp",dtype:"uint32",shape:"[args.outFeatures + 1]"}],passes:[{id:"main",name:"DecodePleProjNorm",shader:"ple-proj-norm.wgsl.jinja",bindings:[{name:"a",arg:"aT",semantic:"A",role:"input",buffer:{type:"read-only-storage"},elementType:"$aScalar"},{name:"wt",arg:"wT",semantic:"Wt",role:"weights",buffer:{type:"read-only-storage"},elementType:"$wScalar"},{name:"pp",semantic:"pp",role:"scratch",buffer:{type:"storage"},elementType:"atomic"},{name:"hidden",arg:"hiddenT",semantic:"Hidden",role:"inout",buffer:{type:"storage"},elementType:"$xScalar"},{name:"w12s",arg:"w12sT",semantic:"W12S",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"y2",arg:"y2T",semantic:"Y2",role:"output",buffer:{type:"storage"},elementType:"$yScalar"},{name:"sum2",arg:"sum2T",semantic:"Sum2",role:"output",buffer:{type:"storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"inScale",type:"f32",value:"args.inScale if args.inScale else 0.0"},{name:"projInScale",type:"f32",value:"args.projInScale if args.projInScale else 0.0"},{name:"projOutScale",type:"f32",value:"args.projOutScale if args.projOutScale else 0.0"}]}}],dispatch:{x:"ceil(args.outFeatures / 16)",y:1,z:1},reads:["A","Wt","Hidden","W12S"],writes:["pp","Hidden","Y2","Sum2"]}]}]},assets:[["ple-proj-norm-codes.wgsl.jinja",`{% if usesF16 %} +`]]}],["com.xenova.gemma4.DecodePleProjNorm",{manifest:{schemaVersion:1,domain:"com.xenova.gemma4",name:"DecodePleProjNorm",sinceVersion:1,inputs:[{role:"A",dtype:"T"},{role:"Wt",dtype:"Wt",optional:!0},{role:"Codes",dtype:"uint32",optional:!0},{role:"RowScale",dtype:"float32",optional:!0},{role:"Hidden",dtype:"H"},{role:"W12S",dtype:"float32"}],outputs:[{role:"Hidden",dtype:"H"},{role:"Y2",dtype:"Y"},{role:"Sum2",dtype:"float32"}],typeConstraints:{T:["float32","float16"],Wt:["float32","float16"],H:["float32","float16"],Y:["float32","float16"]},args:{aT:{kind:"tensor",semantic:"A",role:"input"},wT:{kind:"tensor",semantic:"Wt",role:"weights",required:!1},codesT:{kind:"tensor",semantic:"Codes",role:"weights",required:!1},rowScaleT:{kind:"tensor",semantic:"RowScale",role:"weights",required:!1},codes:{kind:"u32",semantic:"codes_mode",required:!1},hiddenT:{kind:"tensor",semantic:"Hidden",role:"inout"},w12sT:{kind:"tensor",semantic:"W12S",role:"weights"},y2T:{kind:"tensor",semantic:"Y2",role:"output"},sum2T:{kind:"tensor",semantic:"Sum2",role:"output"},inFeatures:{kind:"u32",semantic:"in_features"},outFeatures:{kind:"u32",semantic:"out_features"},eps:{kind:"f32",semantic:"eps",required:!1},inScale:{kind:"f32",semantic:"input_activation_scale",required:!1},projInScale:{kind:"f32",semantic:"proj_input_activation_scale",required:!1},projOutScale:{kind:"f32",semantic:"proj_output_activation_scale",required:!1},codesCatT:{kind:"tensor",semantic:"CodesCat",role:"weights",required:!1},scaleCatT:{kind:"tensor",semantic:"ScaleCat",role:"weights",required:!1},pleT:{kind:"tensor",semantic:"Ple",role:"input",required:!1},gateInFeatures:{kind:"u32",semantic:"gate_in_features",required:!1},gateInScale:{kind:"f32",semantic:"gate_input_activation_scale",required:!1},gateOutScale:{kind:"f32",semantic:"gate_output_activation_scale",required:!1},pleOffset:{kind:"u32",semantic:"ple_offset",required:!1}},variants:[{id:"fused_codes",priority:1,when:'args.codes and present.codesT and present.rowScaleT and args.inFeatures > 0 and args.inFeatures % 4 == 0 and args.inFeatures <= 1024 and args.outFeatures > 0 and args.outFeatures <= 8192 and dtypes.T == "f32" and numel(shapes.aT) >= args.inFeatures and numel(shapes.codesT) >= args.outFeatures * args.inFeatures / 4 and numel(shapes.rowScaleT) >= args.outFeatures and numel(shapes.hiddenT) >= args.outFeatures and numel(shapes.w12sT) >= 2 * args.outFeatures + 1 and numel(shapes.y2T) >= args.outFeatures and numel(shapes.sum2T) >= 1 and ((dtypes.H != "f16" and dtypes.Y != "f16") or device.features.has("shader-f16"))',constants:{usesF16:'dtypes.H == "f16" or dtypes.Y == "f16"',xScalar:"dtypes.H",yScalar:"dtypes.Y",IN_FEATURES:"args.inFeatures",OUT_FEATURES:"args.outFeatures",K_ITER:"ceil(args.inFeatures / 128)",useSubgroups:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize >= 32',sgExact32:"device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32",WG:256,SG_ROWS:2,ROWS_PER_WG:16,TOTAL_WGS:"ceil(args.outFeatures / 16)",ELEMS:"ceil(args.outFeatures / 256)",EPS:"args.eps if args.eps else 0.000001"},intermediates:[{id:"pp",dtype:"uint32",shape:"[args.outFeatures + 1]"}],passes:[{id:"main",name:"DecodePleProjNormCodes",shader:"ple-proj-norm-codes.wgsl.jinja",bindings:[{name:"a",arg:"aT",semantic:"A",role:"input",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"codes",arg:"codesT",semantic:"Codes",role:"weights",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"row_scale",arg:"rowScaleT",semantic:"RowScale",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"pp",semantic:"pp",role:"scratch",buffer:{type:"storage"},elementType:"atomic"},{name:"hidden",arg:"hiddenT",semantic:"Hidden",role:"inout",buffer:{type:"storage"},elementType:"$xScalar"},{name:"w12s",arg:"w12sT",semantic:"W12S",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"y2",arg:"y2T",semantic:"Y2",role:"output",buffer:{type:"storage"},elementType:"$yScalar"},{name:"sum2",arg:"sum2T",semantic:"Sum2",role:"output",buffer:{type:"storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"inScale",type:"f32",value:"args.inScale if args.inScale else 0.0"},{name:"projInScale",type:"f32",value:"args.projInScale if args.projInScale else 0.0"},{name:"projOutScale",type:"f32",value:"args.projOutScale if args.projOutScale else 0.0"}]}}],dispatch:{x:"ceil(args.outFeatures / 16)",y:1,z:1},reads:["A","Codes","RowScale","Hidden","W12S"],writes:["pp","Hidden","Y2","Sum2"]}]},{id:"fused",priority:0,when:'(not args.codes) and present.wT and args.inFeatures > 0 and args.inFeatures % 4 == 0 and args.outFeatures > 0 and args.outFeatures <= 8192 and numel(shapes.aT) >= args.inFeatures and numel(shapes.wT) >= args.outFeatures * args.inFeatures and numel(shapes.hiddenT) >= args.outFeatures and numel(shapes.w12sT) >= 2 * args.outFeatures + 1 and numel(shapes.y2T) >= args.outFeatures and numel(shapes.sum2T) >= 1 and ((dtypes.T != "f16" and dtypes.Wt != "f16" and dtypes.H != "f16" and dtypes.Y != "f16") or device.features.has("shader-f16"))',constants:{usesF16:'dtypes.T == "f16" or dtypes.Wt == "f16" or dtypes.H == "f16" or dtypes.Y == "f16"',aScalar:"dtypes.T",wScalar:"dtypes.Wt",xScalar:"dtypes.H",yScalar:"dtypes.Y",IN_FEATURES:"args.inFeatures",OUT_FEATURES:"args.outFeatures",useSubgroups:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize >= 32',sgExact32:"device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32",WG:256,SG_ROWS:2,ROWS_PER_WG:16,TOTAL_WGS:"ceil(args.outFeatures / 16)",ELEMS:"ceil(args.outFeatures / 256)",EPS:"args.eps if args.eps else 0.000001"},intermediates:[{id:"pp",dtype:"uint32",shape:"[args.outFeatures + 1]"}],passes:[{id:"main",name:"DecodePleProjNorm",shader:"ple-proj-norm.wgsl.jinja",bindings:[{name:"a",arg:"aT",semantic:"A",role:"input",buffer:{type:"read-only-storage"},elementType:"$aScalar"},{name:"wt",arg:"wT",semantic:"Wt",role:"weights",buffer:{type:"read-only-storage"},elementType:"$wScalar"},{name:"pp",semantic:"pp",role:"scratch",buffer:{type:"storage"},elementType:"atomic"},{name:"hidden",arg:"hiddenT",semantic:"Hidden",role:"inout",buffer:{type:"storage"},elementType:"$xScalar"},{name:"w12s",arg:"w12sT",semantic:"W12S",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"y2",arg:"y2T",semantic:"Y2",role:"output",buffer:{type:"storage"},elementType:"$yScalar"},{name:"sum2",arg:"sum2T",semantic:"Sum2",role:"output",buffer:{type:"storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"inScale",type:"f32",value:"args.inScale if args.inScale else 0.0"},{name:"projInScale",type:"f32",value:"args.projInScale if args.projInScale else 0.0"},{name:"projOutScale",type:"f32",value:"args.projOutScale if args.projOutScale else 0.0"}]}}],dispatch:{x:"ceil(args.outFeatures / 16)",y:1,z:1},reads:["A","Wt","Hidden","W12S"],writes:["pp","Hidden","Y2","Sum2"]}]}]},assets:[["ple-proj-norm-codes.wgsl.jinja",`{% if usesF16 %} enable f16; {% endif %} +{% if useSubgroups %} enable subgroups; +{% endif %} {{ env.wgsl.resourceDeclarations }} // Codes path for the single-dispatch fused PLE projection + post-PLE residual @@ -2862,16 +3121,69 @@ const EPS: f32 = {{ EPS }}; const ELEMS: u32 = {{ ELEMS }}u; var lastFlag: u32; +{% if useSubgroups %} var sgp: array; +// Sum over each logical 32-lane block. sgExact32 (fixed 32-wide adapter) -> hardware +// subgroupAdd; otherwise a 32-lane subgroupShuffleXor butterfly that reduces each block +// independently, correct for any subgroup width >= 32 (NVIDIA D3D12 [32,128], AMD [32,64]). +fn sg_sum(value: f32) -> f32 { +{% if sgExact32 %} + return subgroupAdd(value); +{% else %} + var x = value; + x = x + subgroupShuffleXor(x, 1u); + x = x + subgroupShuffleXor(x, 2u); + x = x + subgroupShuffleXor(x, 4u); + x = x + subgroupShuffleXor(x, 8u); + x = x + subgroupShuffleXor(x, 16u); + return x; +{% endif %} +} +{% else %} +var wred: array; +var wred4: array, WG>; +{% endif %} + +{% if not useSubgroups %} +// Subgroup-free fallback (device lacks subgroups or has a non-32 subgroup width). +// Segmented reduction within each 32-lane logical block: role-equivalent to subgroupAdd +// over a 32-wide subgroup, but driven entirely by workgroup memory so it is correct on any +// hardware subgroup size. Reduces a vec4 so the activation sum + up to 3 row dot-sums share +// ONE barrier chain. All WG threads must call it uniformly. +fn block_reduce32_v4(value: vec4, tid: u32) -> vec4 { + wred4[tid] = value; + workgroupBarrier(); + for (var s: u32 = 16u; s > 0u; s = s >> 1u) { + if ((tid & 31u) < s) { wred4[tid] = wred4[tid] + wred4[tid + s]; } + workgroupBarrier(); + } + let r = wred4[(tid >> 5u) << 5u]; + workgroupBarrier(); + return r; +} +{% endif %} + fn reduce_sum(value: f32, tid: u32) -> f32 { - let s = subgroupAdd(value); +{% if useSubgroups %} + let s = sg_sum(value); if ((tid & 31u) == 0u) { sgp[tid >> 5u] = s; } workgroupBarrier(); var total: f32 = 0.0; for (var i: u32 = 0u; i < WG / 32u; i = i + 1u) { total = total + sgp[i]; } workgroupBarrier(); return total; +{% else %} + wred[tid] = value; + workgroupBarrier(); + for (var s: u32 = WG / 2u; s > 0u; s = s >> 1u) { + if (tid < s) { wred[tid] = wred[tid] + wred[tid + s]; } + workgroupBarrier(); + } + let total = wred[0]; + workgroupBarrier(); + return total; +{% endif %} } fn srq(x: f32, s: f32) -> f32 { @@ -2905,7 +3217,7 @@ fn main(@builtin(workgroup_id) wg: vec3, @builtin(local_invocation_id) lid: aAcc = aAcc + (av[ki].x + av[ki].y) + (av[ki].z + av[ki].w); } } - let aSum = subgroupAdd(aAcc); + var accs: array; for (var r: u32 = 0u; r < SG_ROWS; r = r + 1u) { let o = rowBase + r; var acc: f32 = 0.0; @@ -2917,12 +3229,33 @@ fn main(@builtin(workgroup_id) wg: vec3, @builtin(local_invocation_id) lid: } } } - let s = subgroupAdd(acc); + accs[r] = acc; + } +{% if useSubgroups %} + let aSum = sg_sum(aAcc); + for (var r: u32 = 0u; r < SG_ROWS; r = r + 1u) { + let s = sg_sum(accs[r]); + let o = rowBase + r; if (lane == 0u && o < OUT_F) { // fma(s, 255, -128*aSum) undoes the unorm 1/255 decode and the +128 code bias. atomicStore(&pp[o], bitcast(srq(row_scale[o] * fma(s, 255.0, -128.0 * aSum), params.projOutScale))); } } +{% else %} + // Batch the activation sum + the SG_ROWS row dot-sums into one segmented reduce + // (SG_ROWS <= 3 here, so all fit a single vec4 -> one barrier chain). + let red = block_reduce32_v4(vec4(aAcc{% for r in range(SG_ROWS) %}, accs[{{ r }}u]{% endfor %}{% for _ in range(3 - SG_ROWS) %}, 0.0{% endfor %}), tid); + let aSum = red.x; +{% for r in range(SG_ROWS) %} + { + let o = rowBase + {{ r }}u; + if (lane == 0u && o < OUT_F) { + // fma(s, 255, -128*aSum) undoes the unorm 1/255 decode and the +128 code bias. + atomicStore(&pp[o], bitcast(srq(row_scale[o] * fma(red[{{ r + 1 }}u], 255.0, -128.0 * aSum), params.projOutScale))); + } + } +{% endfor %} +{% endif %} storageBarrier(); // --- last-arriver norm tail (all WG threads of the final workgroup) --- @@ -2985,7 +3318,9 @@ fn main(@builtin(workgroup_id) wg: vec3, @builtin(local_invocation_id) lid: `],["ple-proj-norm.wgsl.jinja",`{% if usesF16 %} enable f16; {% endif %} +{% if useSubgroups %} enable subgroups; +{% endif %} {{ env.wgsl.resourceDeclarations }} // Single-dispatch fused PLE projection + post-PLE residual norm-add + next-layer norm (M=1): @@ -3009,16 +3344,69 @@ const EPS: f32 = {{ EPS }}; const ELEMS: u32 = {{ ELEMS }}u; var lastFlag: u32; +{% if useSubgroups %} var sgp: array; +// Sum over each logical 32-lane block. sgExact32 (fixed 32-wide adapter) -> hardware +// subgroupAdd; otherwise a 32-lane subgroupShuffleXor butterfly that reduces each block +// independently, correct for any subgroup width >= 32 (NVIDIA D3D12 [32,128], AMD [32,64]). +fn sg_sum(value: f32) -> f32 { +{% if sgExact32 %} + return subgroupAdd(value); +{% else %} + var x = value; + x = x + subgroupShuffleXor(x, 1u); + x = x + subgroupShuffleXor(x, 2u); + x = x + subgroupShuffleXor(x, 4u); + x = x + subgroupShuffleXor(x, 8u); + x = x + subgroupShuffleXor(x, 16u); + return x; +{% endif %} +} +{% else %} +var wred: array; +var wred4: array, WG>; +{% endif %} + +{% if not useSubgroups %} +// Subgroup-free fallback (device lacks subgroups or has a non-32 subgroup width). +// Segmented reduction within each 32-lane logical block: role-equivalent to subgroupAdd +// over a 32-wide subgroup, but driven entirely by workgroup memory so it is correct on any +// hardware subgroup size. Reduces a vec4 so up to 4 row dot-sums share ONE barrier chain. +// All WG threads must call it uniformly. +fn block_reduce32_v4(value: vec4, tid: u32) -> vec4 { + wred4[tid] = value; + workgroupBarrier(); + for (var s: u32 = 16u; s > 0u; s = s >> 1u) { + if ((tid & 31u) < s) { wred4[tid] = wred4[tid] + wred4[tid + s]; } + workgroupBarrier(); + } + let r = wred4[(tid >> 5u) << 5u]; + workgroupBarrier(); + return r; +} +{% endif %} + fn reduce_sum(value: f32, tid: u32) -> f32 { - let s = subgroupAdd(value); +{% if useSubgroups %} + let s = sg_sum(value); if ((tid & 31u) == 0u) { sgp[tid >> 5u] = s; } workgroupBarrier(); var total: f32 = 0.0; for (var i: u32 = 0u; i < WG / 32u; i = i + 1u) { total = total + sgp[i]; } workgroupBarrier(); return total; +{% else %} + wred[tid] = value; + workgroupBarrier(); + for (var s: u32 = WG / 2u; s > 0u; s = s >> 1u) { + if (tid < s) { wred[tid] = wred[tid] + wred[tid + s]; } + workgroupBarrier(); + } + let total = wred[0]; + workgroupBarrier(); + return total; +{% endif %} } fn srq(x: f32, s: f32) -> f32 { @@ -3039,6 +3427,7 @@ fn main(@builtin(workgroup_id) wg: vec3, @builtin(local_invocation_id) lid: let rowBase = wg.x * ROWS_PER_WG + sgId * SG_ROWS; // --- dense GEMV phase (per virtual subgroup; mirrors DenseGemv's vec4 K-split) --- + var accs: array; for (var r: u32 = 0u; r < SG_ROWS; r = r + 1u) { let o = rowBase + r; var acc: f32 = 0.0; @@ -3055,11 +3444,28 @@ fn main(@builtin(workgroup_id) wg: vec3, @builtin(local_invocation_id) lid: k4 = k4 + 32u; } } - let s = subgroupAdd(acc); + accs[r] = acc; + } +{% if useSubgroups %} + for (var r: u32 = 0u; r < SG_ROWS; r = r + 1u) { + let s = sg_sum(accs[r]); + let o = rowBase + r; if (lane == 0u && o < OUT_F) { atomicStore(&pp[o], bitcast(srq(s, params.projOutScale))); } } +{% else %} + // Batch the SG_ROWS row dot-sums into one segmented reduce (SG_ROWS <= 4 -> one vec4). + let red = block_reduce32_v4(vec4({% for r in range(SG_ROWS) %}{% if r > 0 %}, {% endif %}accs[{{ r }}u]{% endfor %}{% for _ in range(4 - SG_ROWS) %}, 0.0{% endfor %}), tid); +{% for r in range(SG_ROWS) %} + { + let o = rowBase + {{ r }}u; + if (lane == 0u && o < OUT_F) { + atomicStore(&pp[o], bitcast(srq(red[{{ r }}u], params.projOutScale))); + } + } +{% endfor %} +{% endif %} storageBarrier(); // --- last-arriver norm tail (all WG threads of the final workgroup) --- @@ -3308,7 +3714,7 @@ fn main(@builtin(workgroup_id) wg: vec3, @builtin(local_invocation_id) lid: {{ gemv("v_bits", "out_v", "KV_OUT", "Q_OUT + KV_OUT", "params.vOutScale") }} } } -`]]}],["com.xenova.gemma4.DecodeRmsSrq",{manifest:{schemaVersion:1,domain:"com.xenova.gemma4",name:"DecodeRmsSrq",sinceVersion:1,inputs:[{role:"X",dtype:"X"},{role:"W",dtype:"float32",rank:1}],outputs:[{role:"Y",dtype:"Y",shape:"shapes.xT"},{role:"SumA",dtype:"float32",shape:["args.rows"]}],typeConstraints:{X:["float32","float16"],Y:["float32","float16"]},args:{xT:{kind:"tensor",semantic:"X",role:"input"},wT:{kind:"tensor",semantic:"W",role:"weights"},yT:{kind:"tensor",semantic:"Y",role:"output"},sumAT:{kind:"tensor",semantic:"SumA",role:"output"},rows:{kind:"u32",semantic:"rows"},dim:{kind:"u32",semantic:"dim"},eps:{kind:"f32",semantic:"eps",required:!1},inScale:{kind:"f32",semantic:"input_activation_scale",required:!1}},variants:[{id:"main",priority:0,when:'args.rows > 0 and args.dim > 0 and numel(shapes.xT) >= args.rows * args.dim and dim(shapes.wT, 0) == args.dim and numel(shapes.yT) >= args.rows * args.dim and numel(shapes.sumAT) >= args.rows and ((dtypes.X != "f16" and dtypes.Y != "f16") or device.features.has("shader-f16"))',constants:{xScalar:"dtypes.X",yScalar:"dtypes.Y",usesF16:'dtypes.X == "f16" or dtypes.Y == "f16"',useSubgroups:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32',WG:256,dim:"args.dim",eps:"args.eps if args.eps else 0.000001"},passes:[{id:"main",name:"DecodeRmsSrq",shader:"decode-rms-srq.wgsl.jinja",bindings:[{name:"x",arg:"xT",semantic:"X",role:"input",buffer:{type:"read-only-storage"},elementType:"$xScalar"},{name:"w",arg:"wT",semantic:"W",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"y",arg:"yT",semantic:"Y",role:"output",buffer:{type:"storage"},elementType:"$yScalar"},{name:"sum_a",arg:"sumAT",semantic:"SumA",role:"output",buffer:{type:"storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"rows",type:"u32",value:"args.rows"},{name:"rowStride",type:"u32",value:"min(args.rows, 65535)"},{name:"inScale",type:"f32",value:"args.inScale if args.inScale else 0.0"}]}}],dispatch:{x:"min(args.rows, 65535)",y:"ceil(args.rows / min(args.rows, 65535))",z:1},reads:["X","W"],writes:["Y","SumA"]}]}]},assets:[["decode-rms-srq.wgsl.jinja",`{% if usesF16 %} +`]]}],["com.xenova.gemma4.DecodeRmsSrq",{manifest:{schemaVersion:1,domain:"com.xenova.gemma4",name:"DecodeRmsSrq",sinceVersion:1,inputs:[{role:"X",dtype:"X"},{role:"W",dtype:"float32",rank:1}],outputs:[{role:"Y",dtype:"Y",shape:"shapes.xT"},{role:"SumA",dtype:"float32",shape:["args.rows"]}],typeConstraints:{X:["float32","float16"],Y:["float32","float16"]},args:{xT:{kind:"tensor",semantic:"X",role:"input"},wT:{kind:"tensor",semantic:"W",role:"weights"},yT:{kind:"tensor",semantic:"Y",role:"output"},sumAT:{kind:"tensor",semantic:"SumA",role:"output"},rows:{kind:"u32",semantic:"rows"},dim:{kind:"u32",semantic:"dim"},eps:{kind:"f32",semantic:"eps",required:!1},inScale:{kind:"f32",semantic:"input_activation_scale",required:!1}},variants:[{id:"main",priority:0,when:'args.rows > 0 and args.dim > 0 and numel(shapes.xT) >= args.rows * args.dim and dim(shapes.wT, 0) == args.dim and numel(shapes.yT) >= args.rows * args.dim and numel(shapes.sumAT) >= args.rows and ((dtypes.X != "f16" and dtypes.Y != "f16") or device.features.has("shader-f16"))',constants:{xScalar:"dtypes.X",yScalar:"dtypes.Y",usesF16:'dtypes.X == "f16" or dtypes.Y == "f16"',useSubgroups:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize >= 32',sgExact32:"device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32",WG:256,dim:"args.dim",eps:"args.eps if args.eps else 0.000001"},passes:[{id:"main",name:"DecodeRmsSrq",shader:"decode-rms-srq.wgsl.jinja",bindings:[{name:"x",arg:"xT",semantic:"X",role:"input",buffer:{type:"read-only-storage"},elementType:"$xScalar"},{name:"w",arg:"wT",semantic:"W",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"y",arg:"yT",semantic:"Y",role:"output",buffer:{type:"storage"},elementType:"$yScalar"},{name:"sum_a",arg:"sumAT",semantic:"SumA",role:"output",buffer:{type:"storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"rows",type:"u32",value:"args.rows"},{name:"rowStride",type:"u32",value:"min(args.rows, 65535)"},{name:"inScale",type:"f32",value:"args.inScale if args.inScale else 0.0"}]}}],dispatch:{x:"min(args.rows, 65535)",y:"ceil(args.rows / min(args.rows, 65535))",z:1},reads:["X","W"],writes:["Y","SumA"]}]}]},assets:[["decode-rms-srq.wgsl.jinja",`{% if usesF16 %} enable f16; {% endif %} {% if useSubgroups %} @@ -3334,8 +3740,25 @@ const WG: u32 = {{ WG }}u; // Hybrid 2-barrier reduction: subgroupAdd per subgroup + cross-subgroup combine via shared. var sgp: array; +// Sum over each logical 32-lane block. sgExact32 (fixed 32-wide adapter) -> hardware +// subgroupAdd; otherwise a 32-lane subgroupShuffleXor butterfly that reduces each block +// independently, correct for any subgroup width >= 32 (NVIDIA D3D12 [32,128], AMD [32,64]). +fn sg_sum(value: f32) -> f32 { +{% if sgExact32 %} + return subgroupAdd(value); +{% else %} + var x = value; + x = x + subgroupShuffleXor(x, 1u); + x = x + subgroupShuffleXor(x, 2u); + x = x + subgroupShuffleXor(x, 4u); + x = x + subgroupShuffleXor(x, 8u); + x = x + subgroupShuffleXor(x, 16u); + return x; +{% endif %} +} + fn reduce_sum(value: f32, tid: u32) -> f32 { - let s = subgroupAdd(value); + let s = sg_sum(value); if ((tid & 31u) == 0u) { sgp[tid >> 5u] = s; } workgroupBarrier(); var total: f32 = 0.0; @@ -3776,7 +4199,7 @@ fn main(@builtin(workgroup_id) wg: vec3, @builtin(local_invocation_id) lid: // slice of pleNorm. y[i] = {{ scalar }}(gelu_grid(f32(a[i]), params.gridScale) * f32(b[params.bOffset + i])); } -`]]}],["com.xenova.gemma4.QatEmbedGather",{manifest:{schemaVersion:1,domain:"com.xenova.gemma4",name:"QatEmbedGather",sinceVersion:1,inputs:[{role:"Ids",dtype:"uint32"},{role:"Bits",dtype:"uint32"},{role:"Scale",dtype:"float32"},{role:"W",dtype:"float32",optional:!0}],outputs:[{role:"Out",dtype:"O",shape:["args.seq","args.hidden"]},{role:"Y2",dtype:"float32",optional:!0,shape:["args.seq","args.hidden"]},{role:"SumA",dtype:"float32",optional:!0,shape:["args.seq"]}],typeConstraints:{O:["float16","float32"]},args:{idsT:{kind:"tensor",semantic:"Ids",role:"input"},bitsT:{kind:"tensor",semantic:"Bits",role:"input"},scaleT:{kind:"tensor",semantic:"Scale",role:"input"},yT:{kind:"tensor",semantic:"Out",role:"output"},seq:{kind:"u32",semantic:"seq"},hidden:{kind:"u32",semantic:"hidden"},vocab:{kind:"u32",semantic:"vocab"},bits:{kind:"u32",semantic:"bits"},groupSize:{kind:"u32",semantic:"groupSize"},zeroPoint:{kind:"u32",semantic:"zero_point"},embedScale:{kind:"f32",semantic:"embed_scale"},wT:{kind:"tensor",semantic:"W",role:"weights",required:!1},y2T:{kind:"tensor",semantic:"Y2",role:"output",required:!1},sumAT:{kind:"tensor",semantic:"SumA",role:"output",required:!1},normSrq:{kind:"u32",semantic:"norm_srq_mode",required:!1},eps:{kind:"f32",semantic:"eps",required:!1},inScale:{kind:"f32",semantic:"input_activation_scale",required:!1}},variants:[{id:"norm_srq",priority:1,when:'args.normSrq and present.wT and present.y2T and present.sumAT and args.seq == 1 and (args.bits == 2 or args.bits == 4) and args.hidden > 0 and args.groupSize > 0 and args.hidden % args.groupSize == 0 and (args.hidden * args.bits) % 32 == 0 and args.zeroPoint > 0 and dtypes.O == "f32" and numel(shapes.wT) >= args.hidden and numel(shapes.y2T) >= args.hidden and numel(shapes.sumAT) >= 1',constants:{outputScalar:"dtypes.O",HIDDEN:"args.hidden",VOCAB:"args.vocab",GROUP_SIZE:"args.groupSize",NUM_GROUPS:"args.hidden / args.groupSize",WORDS_PER_ROW:"args.hidden * args.bits / 32",VALS_PER_WORD:"32 / args.bits",BITS:"args.bits",MASK:"15 if args.bits == 4 else 3",ZP:"args.zeroPoint",EMBED_SCALE:"args.embedScale",EPS:"args.eps if args.eps else 0.000001",useSubgroups:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize >= 32'},passes:[{id:"main",name:"QatEmbedGatherNormSrq",shader:"qat-embed-gather-norm.wgsl.jinja",bindings:[{name:"ids",arg:"idsT",semantic:"Ids",role:"input",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"bits_buf",arg:"bitsT",semantic:"Bits",role:"input",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"scale",arg:"scaleT",semantic:"Scale",role:"input",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"wt",arg:"wT",semantic:"W",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"y",arg:"yT",semantic:"Out",role:"output",buffer:{type:"storage"},elementType:"$O"},{name:"y2",arg:"y2T",semantic:"Y2",role:"output",buffer:{type:"storage"},elementType:"f32"},{name:"sum_a",arg:"sumAT",semantic:"SumA",role:"output",buffer:{type:"storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"inScale",type:"f32",value:"args.inScale if args.inScale else 0.0"}]}}],dispatch:{x:1,y:1,z:1},reads:["Ids","Bits","Scale","W"],writes:["Out","Y2","SumA"]}]},{id:"main",when:"(not args.normSrq) and ((args.bits == 2 or args.bits == 4) and args.seq > 0 and args.hidden > 0 and args.groupSize > 0 and args.hidden % args.groupSize == 0 and (args.hidden * args.bits) % 32 == 0 and args.zeroPoint > 0 and (f16Ok(dtypes.O)))",constants:{usesF16:'dtypes.O == "f16"',outputScalar:"dtypes.O",HIDDEN:"args.hidden",VOCAB:"args.vocab",GROUP_SIZE:"args.groupSize",NUM_GROUPS:"args.hidden / args.groupSize",WORDS_PER_ROW:"args.hidden * args.bits / 32",VALS_PER_WORD:"32 / args.bits",BITS:"args.bits",MASK:"15 if args.bits == 4 else 3",ZP:"args.zeroPoint",EMBED_SCALE:"args.embedScale"},passes:[{id:"main",name:"QatEmbedGather",shader:"qat-embed-gather.wgsl.jinja",bindings:[{name:"ids",arg:"idsT",semantic:"Ids",role:"input",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"bits_buf",arg:"bitsT",semantic:"Bits",role:"input",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"scale",arg:"scaleT",semantic:"Scale",role:"input",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"y",arg:"yT",semantic:"Out",role:"output",buffer:{type:"storage"},elementType:"$O"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"seq",type:"u32",value:"args.seq"}]}}],dispatch:{x:"args.seq",y:1,z:1},reads:["Ids","Bits","Scale"],writes:["Out"]}]}]},assets:[["qat-embed-gather-norm.wgsl.jinja",`{% if useSubgroups %} +`]]}],["com.xenova.gemma4.QatEmbedGather",{manifest:{schemaVersion:1,domain:"com.xenova.gemma4",name:"QatEmbedGather",sinceVersion:1,inputs:[{role:"Ids",dtype:"uint32"},{role:"Bits",dtype:"uint32"},{role:"Scale",dtype:"float32"},{role:"W",dtype:"float32",optional:!0}],outputs:[{role:"Out",dtype:"O",shape:["args.seq","args.hidden"]},{role:"Y2",dtype:"float32",optional:!0,shape:["args.seq","args.hidden"]},{role:"SumA",dtype:"float32",optional:!0,shape:["args.seq"]}],typeConstraints:{O:["float16","float32"]},args:{idsT:{kind:"tensor",semantic:"Ids",role:"input"},bitsT:{kind:"tensor",semantic:"Bits",role:"input"},scaleT:{kind:"tensor",semantic:"Scale",role:"input"},yT:{kind:"tensor",semantic:"Out",role:"output"},seq:{kind:"u32",semantic:"seq"},hidden:{kind:"u32",semantic:"hidden"},vocab:{kind:"u32",semantic:"vocab"},bits:{kind:"u32",semantic:"bits"},groupSize:{kind:"u32",semantic:"groupSize"},zeroPoint:{kind:"u32",semantic:"zero_point"},embedScale:{kind:"f32",semantic:"embed_scale"},wT:{kind:"tensor",semantic:"W",role:"weights",required:!1},y2T:{kind:"tensor",semantic:"Y2",role:"output",required:!1},sumAT:{kind:"tensor",semantic:"SumA",role:"output",required:!1},normSrq:{kind:"u32",semantic:"norm_srq_mode",required:!1},eps:{kind:"f32",semantic:"eps",required:!1},inScale:{kind:"f32",semantic:"input_activation_scale",required:!1}},variants:[{id:"norm_srq",priority:1,when:'args.normSrq and present.wT and present.y2T and present.sumAT and args.seq == 1 and (args.bits == 2 or args.bits == 4) and args.hidden > 0 and args.groupSize > 0 and args.hidden % args.groupSize == 0 and (args.hidden * args.bits) % 32 == 0 and args.zeroPoint > 0 and dtypes.O == "f32" and numel(shapes.wT) >= args.hidden and numel(shapes.y2T) >= args.hidden and numel(shapes.sumAT) >= 1',constants:{outputScalar:"dtypes.O",HIDDEN:"args.hidden",VOCAB:"args.vocab",GROUP_SIZE:"args.groupSize",NUM_GROUPS:"args.hidden / args.groupSize",WORDS_PER_ROW:"args.hidden * args.bits / 32",VALS_PER_WORD:"32 / args.bits",BITS:"args.bits",MASK:"15 if args.bits == 4 else 3",ZP:"args.zeroPoint",EMBED_SCALE:"args.embedScale",EPS:"args.eps if args.eps else 0.000001",useSubgroups:'device.features.has("subgroups") and has(device.adapterInfo, "subgroupMinSize") and device.adapterInfo.subgroupMinSize >= 32',sgExact32:"device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32"},passes:[{id:"main",name:"QatEmbedGatherNormSrq",shader:"qat-embed-gather-norm.wgsl.jinja",bindings:[{name:"ids",arg:"idsT",semantic:"Ids",role:"input",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"bits_buf",arg:"bitsT",semantic:"Bits",role:"input",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"scale",arg:"scaleT",semantic:"Scale",role:"input",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"wt",arg:"wT",semantic:"W",role:"weights",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"y",arg:"yT",semantic:"Out",role:"output",buffer:{type:"storage"},elementType:"$O"},{name:"y2",arg:"y2T",semantic:"Y2",role:"output",buffer:{type:"storage"},elementType:"f32"},{name:"sum_a",arg:"sumAT",semantic:"SumA",role:"output",buffer:{type:"storage"},elementType:"f32"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"inScale",type:"f32",value:"args.inScale if args.inScale else 0.0"}]}}],dispatch:{x:1,y:1,z:1},reads:["Ids","Bits","Scale","W"],writes:["Out","Y2","SumA"]}]},{id:"main",when:"(not args.normSrq) and ((args.bits == 2 or args.bits == 4) and args.seq > 0 and args.hidden > 0 and args.groupSize > 0 and args.hidden % args.groupSize == 0 and (args.hidden * args.bits) % 32 == 0 and args.zeroPoint > 0 and (f16Ok(dtypes.O)))",constants:{usesF16:'dtypes.O == "f16"',outputScalar:"dtypes.O",HIDDEN:"args.hidden",VOCAB:"args.vocab",GROUP_SIZE:"args.groupSize",NUM_GROUPS:"args.hidden / args.groupSize",WORDS_PER_ROW:"args.hidden * args.bits / 32",VALS_PER_WORD:"32 / args.bits",BITS:"args.bits",MASK:"15 if args.bits == 4 else 3",ZP:"args.zeroPoint",EMBED_SCALE:"args.embedScale"},passes:[{id:"main",name:"QatEmbedGather",shader:"qat-embed-gather.wgsl.jinja",bindings:[{name:"ids",arg:"idsT",semantic:"Ids",role:"input",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"bits_buf",arg:"bitsT",semantic:"Bits",role:"input",buffer:{type:"read-only-storage"},elementType:"u32"},{name:"scale",arg:"scaleT",semantic:"Scale",role:"input",buffer:{type:"read-only-storage"},elementType:"f32"},{name:"y",arg:"yT",semantic:"Out",role:"output",buffer:{type:"storage"},elementType:"$O"},{name:"params",semantic:"kernel.params",buffer:{type:"uniform"},struct:{name:"Params",fields:[{name:"seq",type:"u32",value:"args.seq"}]}}],dispatch:{x:"args.seq",y:1,z:1},reads:["Ids","Bits","Scale"],writes:["Out"]}]}]},assets:[["qat-embed-gather-norm.wgsl.jinja",`{% if useSubgroups %} enable subgroups; {% endif %} {{ env.wgsl.resourceDeclarations }} @@ -3808,8 +4231,27 @@ const ELEMS: u32 = KW * VALS_PER_WORD; {% if useSubgroups %} var sgp: array; +// Sum over each logical 32-lane block. sgExact32 (fixed 32-wide adapter) -> hardware +// subgroupAdd; otherwise a 32-lane subgroupShuffleXor butterfly that reduces each block +// independently, correct for any subgroup width >= 32 (NVIDIA D3D12 [32,128], AMD [32,64]). +// A bare subgroupAdd here would span multiple 32-blocks on a wider subgroup, and this +// WG=256 hybrid then stores that spanning sum into every sgp slot -> 2x/4x overcount. +fn sg_sum(value: f32) -> f32 { +{% if sgExact32 %} + return subgroupAdd(value); +{% else %} + var x = value; + x = x + subgroupShuffleXor(x, 1u); + x = x + subgroupShuffleXor(x, 2u); + x = x + subgroupShuffleXor(x, 4u); + x = x + subgroupShuffleXor(x, 8u); + x = x + subgroupShuffleXor(x, 16u); + return x; +{% endif %} +} + fn reduce_sum(value: f32, tid: u32) -> f32 { - let s = subgroupAdd(value); + let s = sg_sum(value); if ((tid & 31u) == 0u) { sgp[tid >> 5u] = s; } workgroupBarrier(); var total: f32 = 0.0; @@ -5157,5 +5599,5 @@ fn main(@builtin(workgroup_id) wg: vec3, @builtin(local_invocation_id) lid: i = i + 64u; } } -`]]}]])});function ae(e,n={}){let t=ss(e);return new Mn(t.manifest,{...n,assets:t.assets})}function ss(e){let n=Nc.get(e);if(n){let r=new Map(Cc);for(let[a,s]of n.assets)r.set(a,s);return{manifest:n.manifest,assets:Je(r)}}let t=rs.get(e);if(t){let r=new Map(ts);for(let[a,s]of t.assets)r.set(a,s);return{manifest:t.manifest,assets:Je(r)}}return jc(e)}function os(e){let n=new Set;for(let t of at(e,""))for(let r of is(t))n.add(r);return n}function is(e){let n=new Set;for(let t of e.passes??[])zc(n,t);return n}function zc(e,n){if(n.source!==void 0){n.source.kind==="template"&&n.source.shader&&e.add(n.source.shader);return}n.shader&&e.add(n.shader)}function jc(e){throw new Error(`WebGPU op package ${e} is not embedded in this runtime`)}function cr(e,n){let t=[],r=a=>{let s=new URL(a,e);for(let o of n(s,{withFileTypes:!0})){let i=`${a}${o.name}`;o.isDirectory()?r(`${i}/`):o.isFile()&&$c(i)&&t.push(i)}};return r(""),t.sort((a,s)=>a.localeCompare(s))}function us(e,n){let t=new URL(pt,e);return cr(t,n).map(r=>`${pt}${r}`)}function ls(e){return e.replaceAll("\\","/").startsWith(pt)}function $c(e){return e.endsWith(".wgsl")||e.endsWith(".wgsl.jinja")}var pt,Cc,Nc,cs=he(()=>{"use strict";ot();Bn();as();pt="ops/_shared/",Cc=new Map,Nc=new Map});var ds=he(()=>{"use strict";Bn()});var ft=he(()=>{"use strict";xn();An();nt();tt();nr();ot();cs();ds();Bn();Bn();ir()});function ps(e,n=[]){let t=new Set(Hc(n));return Kc.filter(r=>e.features.has(r)&&!t.has(r)).map(r=>r)}function Hc(e){return typeof e=="string"?e.split(",").map(n=>n.trim()).filter(Boolean):Array.isArray(e)?[...e]:e instanceof Set?[...e]:[]}function fs(e,n,t){let r=n.info,a=t?.wgslLanguageFeatures??globalThis.navigator?.gpu?.wgslLanguageFeatures;return{adapterInfo:{vendor:r.vendor,architecture:r.architecture,device:r.device,description:r.description,isFallbackAdapter:r.isFallbackAdapter===!0,...typeof r.subgroupMinSize=="number"?{subgroupMinSize:r.subgroupMinSize}:{},...typeof r.subgroupMaxSize=="number"?{subgroupMaxSize:r.subgroupMaxSize}:{}},features:Yn(e.features),wgslLanguageFeatures:Jn(a),limits:et(e.limits)}}function ms(e){return{maxBufferSize:Number(e.limits.maxBufferSize),maxStorageBufferBindingSize:Number(e.limits.maxStorageBufferBindingSize),maxStorageBuffersPerShaderStage:Number(e.limits.maxStorageBuffersPerShaderStage),maxComputeWorkgroupStorageSize:Number(e.limits.maxComputeWorkgroupStorageSize)}}function gs({adapter:e,device:n,deviceInfo:t,destroy:r,gpu:a,syncPipelineCreation:s}){return{gpu:a,adapter:e,device:n,deviceInfo:t,createShaderModule:(i,u)=>n.createShaderModule({code:i,label:u}),createComputePipeline:s?async i=>{n.pushErrorScope("validation");let u=n.createComputePipeline(i),l=await n.popErrorScope();if(l)throw new Error(`createComputePipeline failed: ${l.message}`);return u}:i=>n.createComputePipelineAsync(i),createBuffer:i=>n.createBuffer(i),writeBuffer:(i,u,l)=>n.queue.writeBuffer(i,u,l),submit:async(i,u)=>{n.queue.submit(i),u.wait&&await n.queue.onSubmittedWorkDone()},mapRead:async(i,u,l)=>{await i.mapAsync(GPUMapMode.READ,u,l);let c=i.getMappedRange(u,l).slice(0);return i.unmap(),c},pushErrorScope:i=>n.pushErrorScope(i),popErrorScope:()=>n.popErrorScope(),destroy:r}}var Kc,hs=he(()=>{"use strict";ft();Kc=["shader-f16","subgroups","chromium-experimental-subgroup-matrix","timestamp-query","texture-formats-tier1","texture-formats-tier2"]});Bt();var Ti=class{constructor(e){this.trie=this._build_trie(e)}_build_trie(e){let n=Object.create(null);for(let t of e){let r=n;for(let a=0;ar&&n.push(e.slice(r,a)),n.push(o),a+=o.length,r=a):++a}return r{let e=[...Array.from({length:94},(a,s)=>s+33),...Array.from({length:12},(a,s)=>s+161),...Array.from({length:82},(a,s)=>s+174)],n=e.slice(),t=0;for(let a=0;a<256;++a)e.includes(a)||(e.push(a),n.push(256+t),t+=1);let r=n.map(a=>String.fromCharCode(a));return Object.fromEntries(e.map((a,s)=>[a,r[s]]))})(),xi=e=>Object.fromEntries(Object.entries(e).map(([n,t])=>[t,n])),Ei=xi(sa),Jr=".,!?\u2026\u3002\uFF0C\u3001\u0964\u06D4\u060C",Pi=new Map([["(?i:'s|'t|'re|'ve|'m|'ll|'d)","(?:'([sS]|[tT]|[rR][eE]|[vV][eE]|[mM]|[lL][lL]|[dD]))"],["(?i:[sdmt]|ll|ve|re)","(?:[sS]|[dD]|[mM]|[tT]|[lL][lL]|[vV][eE]|[rR][eE])"],["[^\\r\\n\\p{L}\\p{N}]?+","[^\\r\\n\\p{L}\\p{N}]?"],["[^\\s\\p{L}\\p{N}]++","[^\\s\\p{L}\\p{N}]+"],["(?>\\p{Nd}{510})","(?:\\p{Nd}{510})"],["\\p{Nd}{3}+","(?:\\p{Nd}{3})+"],["\\G",""],[` ?[^(\\s|[${Jr}])]+`,` ?[^\\s${Jr}]+`]]),Vn="\\p{P}\\u0021-\\u002F\\u003A-\\u0040\\u005B-\\u0060\\u007B-\\u007E",It=e=>e.replace(/ \./g,".").replace(/ \?/g,"?").replace(/ \!/g,"!").replace(/ ,/g,",").replace(/ \' /g,"'").replace(/ n't/g,"n't").replace(/ 'm/g,"'m").replace(/ 's/g,"'s").replace(/ 've/g,"'ve").replace(/ 're/g,"'re"),Qn=(e,n=!0)=>{if(e.Regex!==void 0){let t=e.Regex.replace(/\\([#&~])/g,"$1");t=t.replace(/\\A/g,"^").replace(/\\z/g,"$").replace(/\\Z/g,"(?=\\r?\\n?$)");for(let[r,a]of Pi)t=t.replaceAll(r,a);try{return new RegExp(t,"gu")}catch(r){if(!(r instanceof SyntaxError)||!r.message.toLowerCase().includes("invalid property name"))throw r;let a=!1,s=t.replace(/(\\[pP])\{([^}=]+)\}/g,(o,i,u)=>{try{return new RegExp(`\\p{${u}}`,"u"),`${i}{${u}}`}catch{return a=!0,`${i}{Script=${u}}`}});if(!a)throw r;try{return new RegExp(s,"gu")}catch{throw r}}}else if(e.String!==void 0){let t=Ai(e.String);return new RegExp(n?t:`(${t})`,"gu")}else return console.warn("Unknown pattern type:",e),null},Ai=e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),Gi=(e,n,t)=>{let r=[],a=0;for(;ae>=19968&&e<=40959||e>=13312&&e<=19903||e>=131072&&e<=173791||e>=173824&&e<=177983||e>=177984&&e<=178207||e>=178208&&e<=183983||e>=63744&&e<=64255||e>=194560&&e<=195103,Ri=e=>Number.isInteger(e)||typeof e=="bigint",Fi=e=>{let n=0;for(let t of e)++n;return n},Wi=e=>oa(e.toLowerCase()),Fe=(...e)=>Array.prototype.concat.apply([],e),Ut=e=>new Map(Object.entries(e)),Mi=(e,n)=>{let t=[],r=0;for(let a of e.matchAll(n)){let s=a[0];r0&&t.push(s),r=a.index+s.length}return re.replace(/\p{M}/gu,""),ea=(e,n,t=[])=>{if(!e||Array.isArray(e)||typeof e!="object")return`${n} must be a valid object`;for(let r of t)if(!(r in e))return`${n} must contain a "${r}" property`;return null},Bi=e=>e.match(/\S+/g)||[],qi=class{constructor(){let e=function(...n){return e._call(...n)};return Object.setPrototypeOf(e,new.target.prototype)}},Tn=qi,Ii=class extends Tn{constructor(e){super(),this.config=e}_call(e){return this.normalize(e)}},Ne=Ii,Ui=class extends Ne{tokenize_chinese_chars(e){let n=[];for(let t=0;tt.normalize("NFKC")).join("\uFF5E"):e=e.normalize("NFKC"),e}},Ci=Li,Ni=class extends Ne{constructor(e){super(e),this.normalizers=(e.normalizers??[]).map(n=>ia(n))}normalize(e){return this.normalizers.reduce((n,t)=>t?t.normalize(n):n,e)}},zi=Ni,ji=class extends Ne{normalize(e){let n=Qn(this.config.pattern??{});return n===null?e:e.replaceAll(n,this.config.content??"")}},$i=ji,Ki=class extends Ne{constructor(){super(...arguments),this.form="NFC"}normalize(e){return e=e.normalize(this.form),e}},Xn=Ki,Hi=class extends Xn{constructor(){super(...arguments),this.form="NFC"}},Vi=Hi,Qi=class extends Xn{constructor(){super(...arguments),this.form="NFD"}},Xi=Qi,Zi=class extends Xn{constructor(){super(...arguments),this.form="NFKC"}},Yi=Zi,Ji=class extends Xn{constructor(){super(...arguments),this.form="NFKD"}},eu=Ji,nu=class extends Ne{normalize(e){return this.config.strip_left&&this.config.strip_right?e=e.trim():(this.config.strip_left&&(e=e.trimStart()),this.config.strip_right&&(e=e.trimEnd())),e}},tu=nu,ru=class extends Ne{normalize(e){return oa(e)}},au=ru,su=class extends Ne{normalize(e){return e.toLowerCase()}},ou=su,iu=class extends Ne{normalize(e){return e=this.config.prepend+e,e}},uu=iu;function lu(e){if(e===null)return null;switch(e.type){case"BertNormalizer":return new Di(e);case"Precompiled":return new Ci(e);case"Sequence":return new zi(e);case"Replace":return new $i(e);case"NFC":return new Vi(e);case"NFD":return new Xi(e);case"NFKC":return new Yi(e);case"NFKD":return new eu(e);case"Strip":return new tu(e);case"StripAccents":return new au(e);case"Lowercase":return new ou(e);case"Prepend":return new uu(e);default:throw new Error(`Unknown Normalizer type: ${e.type}`)}}var ia=lu,cu=class extends Tn{pre_tokenize(e,n){return(Array.isArray(e)?e.map(t=>this.pre_tokenize_text(t,n)):this.pre_tokenize_text(e,n)).flat()}_call(e,n){return this.pre_tokenize(e,n)}},We=cu,du=class extends We{constructor(e){super(),this.config=e,this.add_prefix_space=this.config.add_prefix_space??!1,this.trim_offsets=this.config.trim_offsets??!1,this.use_regex=this.config.use_regex??!0,this.pattern=/'s|'t|'re|'ve|'m|'ll|'d| ?\p{L}+| ?\p{N}+| ?[^\s\p{L}\p{N}]+|\s+(?!\S)|\s+/gu,this.byte_encoder=sa,this.text_encoder=new TextEncoder}pre_tokenize_text(e,n){return this.add_prefix_space&&!e.startsWith(" ")&&(e=" "+e),(this.use_regex?e.match(this.pattern)||[]:[e]).map(r=>Array.from(this.text_encoder.encode(r),a=>this.byte_encoder[a]).join(""))}},pu=du,fu=class extends We{pre_tokenize_text(e,n){return e.match(/\w+|[^\w\s]+/g)||[]}},mu=fu,gu=class extends We{constructor(e){super(),this.replacement=e.replacement??"\u2581",this.str_rep=e.str_rep||this.replacement,this.prepend_scheme=e.prepend_scheme??"always"}pre_tokenize_text(e,n){let{section_index:t=void 0}=n??{},r=e.replaceAll(" ",this.str_rep);return!r.startsWith(this.replacement)&&(this.prepend_scheme==="always"||this.prepend_scheme==="first"&&t===0)&&(r=this.str_rep+r),[r]}},hu=gu,yu=class extends We{constructor(e){super(),this.config=e,this.pattern=Qn(this.config.pattern??{},this.config.invert??!0)}pre_tokenize_text(e){return this.pattern===null?[]:this.config.invert?e.match(this.pattern)||[]:this.config.behavior?.toLowerCase()==="removed"?e.split(this.pattern).filter(n=>n):Mi(e,this.pattern)}},bu=yu,wu=class extends We{constructor(e){super(),this.config=e,this.pattern=new RegExp(`[^${Vn}]+|[${Vn}]+`,"gu")}pre_tokenize_text(e){return e.match(this.pattern)||[]}},_u=wu,vu=class extends We{constructor(e){super(),this.config=e;let n=`[^\\d]+|\\d${this.config.individual_digits?"":"+"}`;this.pattern=new RegExp(n,"gu")}pre_tokenize_text(e){return e.match(this.pattern)||[]}},Tu=vu,Su=class extends We{constructor(){super(),this.pattern=new RegExp(`[^\\s${Vn}]+|[${Vn}]`,"gu")}pre_tokenize_text(e,n){return e.trim().match(this.pattern)||[]}},ku=Su,xu=class extends We{constructor(e){super(),this.config=e,this.pattern=Qn(this.config.pattern??{}),this.content=this.config.content??""}pre_tokenize_text(e){return this.pattern===null?[e]:[e.replaceAll(this.pattern,this.config.content??"")]}},Eu=xu,Pu=class extends We{constructor(e){super(),this.tokenizers=(e.pretokenizers??[]).map(n=>ua(n))}pre_tokenize_text(e,n){return this.tokenizers.reduce((t,r)=>r?r.pre_tokenize(t,n):t,[e])}},Au=Pu,Gu=class extends We{pre_tokenize_text(e){return Bi(e)}},Ou=Gu,Ru=class extends We{constructor(e){super(),this.config=e,this._length=e.length}pre_tokenize_text(e){let n=[];for(let t=0;tthis.max_input_chars_per_word){n.push(this.unk_token);continue}let a=!1,s=0,o=[];for(;s0&&(l=this.config.continuing_subword_prefix+l),this.tokens_to_ids.has(l)){u=l;break}--i}if(u===null){a=!0;break}o.push(u),s=i}a?n.push(this.unk_token):n.push(...o)}return n}},na=Bu,ta=class la{constructor(n,t){this.is_leaf=n,this.children=t}static default(){return new la(!1,new Map)}},qu=class{constructor(){this.root=ta.default()}extend(e){for(let n of e)this.push(n)}push(e){let n=this.root;for(let t of e){let r=n.children.get(t);r===void 0&&(r=ta.default(),n.children.set(t,r)),n=r}n.is_leaf=!0}*common_prefix_search(e){let n=this.root;if(n===void 0)return;let t="";for(let r of e){if(t+=r,n=n.children.get(r),n===void 0)return;n.is_leaf&&(yield t)}}},Iu=qu,qt=class ca{constructor(n,t,r,a,s){this.token_id=n,this.node_id=t,this.pos=r,this.length=a,this.score=s,this.prev=null,this.backtrace_score=0}clone(){let n=new ca(this.token_id,this.node_id,this.pos,this.length,this.score);return n.prev=this.prev,n.backtrace_score=this.backtrace_score,n}},Uu=class{constructor(e,n,t){this.chars=Array.from(e),this.len=this.chars.length,this.bos_token_id=n,this.eos_token_id=t,this.nodes=[],this.begin_nodes=Array.from({length:this.len+1},()=>[]),this.end_nodes=Array.from({length:this.len+1},()=>[]);let r=new qt(this.bos_token_id??0,0,0,0,0),a=new qt(this.eos_token_id??0,1,this.len,0,0);this.nodes.push(r.clone()),this.nodes.push(a.clone()),this.begin_nodes[this.len].push(a),this.end_nodes[0].push(r)}insert(e,n,t,r){let a=this.nodes.length,s=new qt(r,a,e,n,t);this.begin_nodes[e].push(s),this.end_nodes[e+n].push(s),this.nodes.push(s)}viterbi(){let e=this.len,n=0;for(;n<=e;){if(this.begin_nodes[n].length==0)return[];for(let o of this.begin_nodes[n]){o.prev=null;let i=0,u=null;for(let l of this.end_nodes[n]){let c=l.backtrace_score+o.score;(u===null||c>i)&&(u=l.clone(),i=c)}if(u!==null)o.prev=u,o.backtrace_score=i;else return[]}++n}let t=[],a=this.begin_nodes[e][0].prev;if(a===null)return[];let s=a.clone();for(;s.prev!==null;)t.push(s.clone()),s=s.clone().prev.clone();return t.reverse(),t}piece(e){return this.chars.slice(e.pos,e.pos+e.length).join("")}tokens(){return this.viterbi().map(n=>this.piece(n))}token_ids(){return this.viterbi().map(n=>n.token_id)}},Du=Uu;function Lu(e){if(e.length===0)throw new Error("Array must not be empty");let n=e[0],t=0;for(let r=1;r[r,a])),this.bos_token=" ",this.bos_token_id=this.tokens_to_ids.get(this.bos_token),this.eos_token=n,this.eos_token_id=this.tokens_to_ids.get(this.eos_token),this.unk_token=this.vocab[this.unk_token_id],this.min_score=Lu(this.scores)[0],this.unk_score=this.min_score-10,this.scores[this.unk_token_id]=this.unk_score,this.trie=new Iu,this.trie.extend(this.vocab),this.fuse_unk=!0}populate_nodes(e){let n=e.chars,t=1,r=0;for(;rt>r,n=1/0){this._heap=[],this._comparator=e,this._max_size=n}get size(){return this._heap.length}is_empty(){return this.size===0}peek(){return this._heap[0]}push(...e){return this.extend(e)}extend(e){for(let n of e)if(this.size0&&this._swap(0,n),this._heap.pop(),this._sift_down(),e}replace(e){let n=this.peek();return this._heap[0]=e,this._sift_down(),n}_parent(e){return(e+1>>>1)-1}_left(e){return(e<<1)+1}_right(e){return e+1<<1}_greater(e,n){return this._comparator(this._heap[e],this._heap[n])}_swap(e,n){let t=this._heap[e];this._heap[e]=this._heap[n],this._heap[n]=t}_sift_up(){this._sift_up_from(this.size-1)}_sift_up_from(e){for(;e>0&&this._greater(e,this._parent(e));)this._swap(e,this._parent(e)),e=this._parent(e)}_sift_down(){let e=0;for(;this._left(e)this.capacity&&this.cache.delete(this.cache.keys().next().value)}clear(){this.cache.clear()}},$u=ju,Ku=class extends Zn{constructor(e){super(e),this.tokens_to_ids=Ut(e.vocab),this.unk_token_id=this.tokens_to_ids.get(e.unk_token),this.unk_token=e.unk_token,this.vocab=new Array(this.tokens_to_ids.size);for(let[t,r]of this.tokens_to_ids)this.vocab[r]=t;let n=Array.isArray(e.merges[0]);this.merges=n?e.merges:e.merges.map(t=>t.split(" ",2)),this.bpe_ranks=new Map(this.merges.map((t,r)=>[JSON.stringify(t),r])),this.end_of_word_suffix=e.end_of_word_suffix,this.continuing_subword_suffix=e.continuing_subword_suffix??null,this.byte_fallback=this.config.byte_fallback??!1,this.byte_fallback&&(this.text_encoder=new TextEncoder),this.ignore_merges=this.config.ignore_merges??!1,this.max_length_to_cache=256,this.cache_capacity=1e4,this.cache=new $u(this.cache_capacity)}clear_cache(){this.cache.clear()}bpe(e){if(e.length===0)return[];let n=this.cache.get(e);if(n!==void 0)return n;let t=Array.from(e);this.end_of_word_suffix&&(t[t.length-1]+=this.end_of_word_suffix);let r=[];if(t.length>1){let a=new zu((i,u)=>i.score`<0x${o.toString(16).toUpperCase().padStart(2,"0")}>`);s.every(o=>this.tokens_to_ids.has(o))?n.push(...s):this.unk_token!=null&&n.push(this.unk_token)}else this.unk_token!=null&&n.push(this.unk_token)}return n}},aa=Ku,Hu=class extends Zn{constructor(e,n){super(e);let t=e.vocab;this.tokens_to_ids=Ut(n.target_lang?t[n.target_lang]:t),this.bos_token=n.bos_token,this.bos_token_id=this.tokens_to_ids.get(this.bos_token),this.eos_token=n.eos_token,this.eos_token_id=this.tokens_to_ids.get(this.eos_token),this.pad_token=n.pad_token,this.pad_token_id=this.tokens_to_ids.get(this.pad_token),this.unk_token=n.unk_token,this.unk_token_id=this.tokens_to_ids.get(this.unk_token),this.vocab=new Array(this.tokens_to_ids.size);for(let[r,a]of this.tokens_to_ids)this.vocab[a]=r}encode(e){return e}},Vu=Hu;function Qu(e,n){switch(e.type){case"WordPiece":return new na(e);case"Unigram":return new ra(e,n.eos_token);case"BPE":return new aa(e);default:if(e.vocab)return Array.isArray(e.vocab)?new ra(e,n.eos_token):Object.hasOwn(e,"continuing_subword_prefix")&&Object.hasOwn(e,"unk_token")?Object.hasOwn(e,"merges")?new aa(e):new na(e):new Vu(e,{target_lang:n.target_lang,bos_token:n.bos_token,eos_token:n.eos_token,pad_token:n.pad_token,unk_token:n.unk_token});throw new Error(`Unknown TokenizerModel type: ${e?.type}`)}}var Xu=Qu,Zu=class extends Tn{constructor(e){super(),this.config=e}_call(e,...n){return this.post_process(e,...n)}},Sn=Zu,Yu=class extends Sn{post_process(e,n=null,t=!0){let r=n===null?this.config.single:this.config.pair,a=[],s=[];for(let o of r)"SpecialToken"in o?t&&(a.push(o.SpecialToken.id),s.push(o.SpecialToken.type_id)):"Sequence"in o&&(o.Sequence.id==="A"?(a=Fe(a,e),s=Fe(s,new Array(e.length).fill(o.Sequence.type_id))):o.Sequence.id==="B"&&(a=Fe(a,n),s=Fe(s,new Array(n.length).fill(o.Sequence.type_id))));return{tokens:a,token_type_ids:s}}},Ju=Yu,el=class extends Sn{post_process(e,n=null){return{tokens:e,tokens_pair:n}}},nl=el,tl=class extends Sn{constructor(e){super(e),this.sep=e.sep,this.cls=e.cls}post_process(e,n=null,t=!0){t&&(e=Fe([this.cls[0]],e,[this.sep[0]]));let r=new Array(e.length).fill(0);if(n){let a=[],s=t?[this.sep[0]]:[];e=Fe(e,a,n,s),r=Fe(r,new Array(n.length+a.length+s.length).fill(1))}return{tokens:e,token_type_ids:r}}},rl=tl,al=class extends Sn{constructor(e){super(e),this.sep=e.sep,this.cls=e.cls}post_process(e,n,t=!0){t&&(e=Fe([this.cls[0]],e,[this.sep[0]]));let r=new Array(e.length).fill(0);if(n){let a=t?[this.sep[0]]:[],s=t?[this.sep[0]]:[];e=Fe(e,a,n,s),r=Fe(r,new Array(n.length+a.length+s.length).fill(1))}return{tokens:e,token_type_ids:r}}},sl=al,ol=class extends Sn{constructor(e){super(e),this.processors=(e.processors??[]).map(n=>da(n))}post_process(e,n=null,t=!0){let r={tokens:e,tokens_pair:n};for(let a of this.processors)r=a.post_process(r.tokens,r.tokens_pair,t);return r}},il=ol;function ul(e){if(e===null)return null;switch(e.type){case"TemplateProcessing":return new Ju(e);case"ByteLevel":return new nl(e);case"BertProcessing":return new rl(e);case"RobertaProcessing":return new sl(e);case"Sequence":return new il(e);default:throw new Error(`Unknown PostProcessor type: ${e.type}`)}}var da=ul,ll=class extends Tn{constructor(e){super(),this.config=e,this.added_tokens=[],this.end_of_word_suffix=null,this.trim_offsets="trim_offsets"in e?e.trim_offsets:!1}_call(e){return this.decode(e)}decode(e){return this.decode_chain(e).join("")}},De=ll,cl=class extends De{constructor(e){super(e),this.byte_decoder=Ei,this.text_decoder=new TextDecoder("utf-8",{fatal:!1,ignoreBOM:!0}),this.end_of_word_suffix=null}convert_tokens_to_string(e){let n=e.join(""),t=new Uint8Array([...n].map(r=>this.byte_decoder[r]));return this.text_decoder.decode(t)}decode_chain(e){let n=[],t=[];for(let r of e)this.added_tokens.find(a=>a.content===r)!==void 0?(t.length>0&&(n.push(this.convert_tokens_to_string(t)),t=[]),n.push(r)):t.push(r);return t.length>0&&n.push(this.convert_tokens_to_string(t)),n}},dl=cl,pl=class extends De{constructor(e){super(e),this.cleanup=e.cleanup}decode_chain(e){return e.map((n,t)=>{if(t!==0){let r=this.config.prefix;r&&n.startsWith(r)?n=n.replace(r,""):n=" "+n}return this.cleanup&&(n=It(n)),n})}},fl=pl,ml=class extends De{constructor(e){super(e),this.replacement=e.replacement??"\u2581"}decode_chain(e){let n=[];for(let t=0;tn.replaceAll(this.suffix,t===e.length-1?"":" "))}},yl=hl,bl=class extends De{constructor(e){super(e),this.pad_token=e.pad_token??"",this.word_delimiter_token=e.word_delimiter_token??"",this.cleanup=e.cleanup}convert_tokens_to_string(e){if(e.length===0)return"";let n=[e[0]];for(let a=1;aa!==this.pad_token).join("");return this.cleanup&&(r=It(r).replaceAll(this.word_delimiter_token," ").trim()),r}decode_chain(e){return[this.convert_tokens_to_string(e)]}},wl=bl,_l=class extends De{constructor(e){super(e),this.decoders=(e.decoders??[]).map(n=>pa(n))}decode_chain(e){return this.decoders.reduce((n,t)=>t.decode_chain(n),e)}},vl=_l,Tl=class extends De{decode_chain(e){let n=Qn(this.config.pattern),t=this.config.content??"";return n===null?e:e.map(r=>r.replaceAll(n,t))}},Sl=Tl,kl=class extends De{decode_chain(e){return[e.join("")]}},xl=kl,El=class extends De{constructor(e){super(e),this.content=e.content??"",this.start=e.start??0,this.stop=e.stop??0}decode_chain(e){return e.map(n=>{let t=0;for(let a=0;a")){let s=parseInt(r.slice(3,5),16);isNaN(s)||(a=s)}if(a!==null)t.push(a);else{if(t.length>0){let s=this.text_decoder.decode(Uint8Array.from(t));n.push(s),t=[]}n.push(r)}}if(t.length>0){let r=this.text_decoder.decode(Uint8Array.from(t));n.push(r),t=[]}return n}},Gl=Al;function Ol(e){if(e===null)return null;switch(e.type){case"ByteLevel":return new dl(e);case"WordPiece":return new fl(e);case"Metaspace":return new gl(e);case"BPEDecoder":return new yl(e);case"CTC":return new wl(e);case"Sequence":return new vl(e);case"Replace":return new Sl(e);case"Fuse":return new xl(e);case"Strip":return new Pl(e);case"ByteFallback":return new Gl(e);default:throw new Error(`Unknown Decoder type: ${e.type}`)}}var pa=Ol,Rl=class{constructor(e,n){let t=ea(e,"Tokenizer",["model","decoder","post_processor","pre_tokenizer","normalizer"]);if(t)throw new Error(t);let r=ea(n,"Config");if(r)throw new Error(r);this.tokenizer=e,this.config=n,this.normalizer=ia(this.tokenizer.normalizer),this.pre_tokenizer=ua(this.tokenizer.pre_tokenizer),this.model=Xu(this.tokenizer.model,this.config),this.post_processor=da(this.tokenizer.post_processor),this.decoder=pa(this.tokenizer.decoder),this.special_tokens=[],this.all_special_ids=[],this.added_tokens=[];let a=[],s=[];this.added_tokens_map=new Map;for(let o of this.tokenizer.added_tokens){let i=new ki(o);if(this.added_tokens.push(i),this.model.tokens_to_ids.set(i.content,i.id),this.model.vocab[i.id]=i.content,i.special&&(this.special_tokens.push(i.content),this.all_special_ids.push(i.id)),this.added_tokens_map.set(i.content,i),i.normalized&&this.normalizer!==null){let u=this.normalizer(i.content);s.push(u),this.added_tokens_map.set(u,i)}else a.push(i.content)}(this.config.additional_special_tokens??[]).forEach(o=>{this.special_tokens.includes(o)||this.special_tokens.push(o)}),this.decoder&&(this.decoder.added_tokens=this.added_tokens,this.decoder.end_of_word_suffix=this.model.end_of_word_suffix),this.splitter_unnormalized=new Yr(a),this.splitter_normalized=new Yr(s),this.remove_space=this.config.remove_space,this.clean_up_tokenization_spaces=this.config.clean_up_tokenization_spaces??!0,this.do_lowercase_and_remove_accent=this.config.do_lowercase_and_remove_accent??!1}encode(e,{text_pair:n=null,add_special_tokens:t=!0,return_token_type_ids:r=null}={}){let{tokens:a,token_type_ids:s}=this.tokenize_helper(e,{text_pair:n,add_special_tokens:t}),o=a.map(u=>this.added_tokens_map.get(u)?.id??this.model.tokens_to_ids.get(u)??this.model.unk_token_id),i={ids:o,tokens:a,attention_mask:new Array(o.length).fill(1)};return r&&s&&(i.token_type_ids=s),i}decode(e,n={}){if(!Array.isArray(e)||e.length===0||!Ri(e[0]))throw Error("token_ids must be a non-empty array of integers.");let t=e.map(a=>this.model.vocab[Number(a)]??this.model.unk_token);n.skip_special_tokens&&(t=t.filter(a=>!this.special_tokens.includes(a)));let r=this.decoder?this.decoder(t):t.join(" ");return this.decoder&&this.decoder.end_of_word_suffix&&(r=r.replaceAll(this.decoder.end_of_word_suffix," "),n.skip_special_tokens&&(r=r.trim())),(n.clean_up_tokenization_spaces??this.clean_up_tokenization_spaces)&&(r=It(r)),r}tokenize(e,{text_pair:n=null,add_special_tokens:t=!1}={}){return this.tokenize_helper(e,{text_pair:n,add_special_tokens:t}).tokens}encode_text(e){if(e===null)return null;let n=this.splitter_unnormalized.split(e);return n.forEach((t,r)=>{let a=this.added_tokens_map.get(t);a&&(a.lstrip&&r>0&&(n[r-1]=n[r-1].trimEnd()),a.rstrip&&r{if(t.length===0)return[];if(this.added_tokens_map.has(t))return[t];if(this.remove_space===!0&&(t=t.trim().split(/\s+/).join(" ")),this.do_lowercase_and_remove_accent&&(t=Wi(t)),this.normalizer!==null&&(t=this.normalizer(t)),t.length===0)return[];let a=this.splitter_normalized.split(t);return a.forEach((s,o)=>{let i=this.added_tokens_map.get(s);i&&(i.lstrip&&o>0&&(a[o-1]=a[o-1].trimEnd()),i.rstrip&&o{if(s.length===0)return[];if(this.added_tokens_map.has(s))return[s];let o=this.pre_tokenizer!==null?this.pre_tokenizer(s,{section_index:r}):[s];return this.model(o)})})}tokenize_helper(e,{text_pair:n=null,add_special_tokens:t=!0}){let r=this.encode_text(e),a=this.encode_text(n||null);return this.post_processor?this.post_processor(r,a,t):{tokens:Fe(r??[],a??[])}}token_to_id(e){return this.model.tokens_to_ids.get(e)}id_to_token(e){return this.model.vocab[e]}get_added_tokens_decoder(){let e=new Map;for(let n of this.added_tokens)e.set(n.id,n);return e}get_vocab(e=!0){let n=new Map;for(let t=0;t{console.error("WebGPU uncaptured error:",a.error)}),gs({gpu:n,adapter:t,device:r,deviceInfo:fs(r,t,n),destroy:()=>r.destroy()})}Fn();var Vc=Object.freeze(["embed","qkv","qk_norm","rope_cache","attention","o_proj","conv","rms_norm","mlp","lm_head","other"]),Qc=new Set(Vc);function bs({label:e="profile",events:n=[],timestampUnit:t="ns"}={}){let r=n.map((i,u)=>Xc(i,u)),a=r.reduce((i,u)=>i+u.durationMs,0),s=ys(r,i=>i.group,a),o=ys(r.filter(i=>i.layer!==void 0),i=>`layer.${i.layer}`,a);return{label:e,timestampUnit:t,totalGpuMs:a,dispatchCount:r.length,groups:s,layers:o,events:r}}function pr({name:e="",cacheKey:n="",profile:t=null}={}){let r=Zc(n),a={model:t?.model??r.config?.model_type,phase:t?.phase??Yc(e,r),layer:t?.layer??r.layer,part:t?.part??r.part??Jc(e),...t};return a.group=nd(a.group??ed(a.part,e)),Object.fromEntries(Object.entries(a).filter(([,s])=>s!==void 0))}function Xc(e,n){let t=pr(e);return{index:n,name:e.name,cacheKey:e.cacheKey,dispatchWorkgroups:e.dispatchWorkgroups,startTimestamp:e.startTimestamp,endTimestamp:e.endTimestamp,durationMs:e.durationMs??0,model:t.model,phase:t.phase,layer:t.layer,part:t.part,group:t.group}}function ys(e,n,t){let r=new Map;for(let a of e){let s=n(a),o=r.get(s)??{group:s,dispatches:0,totalGpuMs:0};o.dispatches+=1,o.totalGpuMs+=a.durationMs,r.set(s,o)}return Array.from(r.values()).map(a=>({...a,meanGpuMs:a.dispatches>0?a.totalGpuMs/a.dispatches:0,percent:t>0?a.totalGpuMs/t*100:0})).sort((a,s)=>s.totalGpuMs-a.totalGpuMs)}function Zc(e){if(typeof e!="string")return{};let n=e.split("|weights:")[0],t=n.indexOf("{"),r=n.lastIndexOf("}"),a=t>=0&&r>t?n.slice(t,r+1):n;try{return JSON.parse(a)}catch{return{}}}function Yc(e,n){if(n.kind?.includes("decode")||e.includes("decode"))return"decode";if(n.kind?.includes("megakernel")||e.includes("causal_lm"))return"forward"}function Jc(e){return e.replace(/^llama_decode_/,"").replace(/^lfm2_decode_/,"").replace(/^llama_/,"")}function ed(e="",n=""){let t=`${e} ${n}`.toLowerCase();return t.includes("embed")?"embed":t.includes("qkv")?"qkv":t.includes("qk_head_norm")||t.includes("qk_norm")?"qk_norm":t.includes("rope_cache")?"rope_cache":t.includes("attention")?"attention":t.includes("o_proj")||t.includes("out_proj")?"o_proj":t.includes("conv")?"conv":t.includes("lm_head")||t.includes("argmax")||t.includes("final")?"lm_head":t.includes("gate")||t.includes("up")||t.includes("down_proj")?"mlp":t.includes("norm")?"rms_norm":"other"}function nd(e){return typeof e=="string"&&Qc.has(e)?e:"other"}var ln=class{runtime;dtype;shape;strides;byteOffset;layout;encoding;components;storage;buffer;size;byteLength;destroyed;constructor({runtime:n,dtype:t,shape:r,buffer:a,strides:s=Ca(r),byteOffset:o=0,layout:i,encoding:u,components:l,storage:c="buffer"}){this.runtime=n,this.dtype=t,this.shape=r,this.strides=s,this.byteOffset=o,this.layout=i,this.encoding=u,this.components=l,this.storage=c,this.buffer=a,this.size=Ve(r),this.byteLength=this.size*Rn(t),this.destroyed=!1}destroy(){this.destroyed||(this.buffer.destroy(),this.destroyed=!0)}},gt=class{host;pipelineCache;bindGroupCache;maxBindGroupCacheEntries;bufferIds;nextBufferId;profileSession;readbackPool;readbackPoolBytes;maxReadbackPoolBytes;destroyed;captureShaders;capturedShaders;constructor({host:n}){this.host=n,this.captureShaders=!1,this.capturedShaders=new Map,this.pipelineCache=new Map,this.bindGroupCache=new Map,this.maxBindGroupCacheEntries=4096,this.bufferIds=new WeakMap,this.nextBufferId=1,this.profileSession=null,this.readbackPool=new Map,this.readbackPoolBytes=0,this.maxReadbackPoolBytes=64*1024*1024,this.destroyed=!1}get device(){return this.host.deviceInfo}getRenderedShaders(){return[...this.capturedShaders].map(([n,t])=>({name:n,source:t}))}async destroy(){this.destroyed||(this.destroyed=!0,this.clearTransientCaches(),this.clearReadbackPool(),await this.host.destroy())}clearReadbackPool(){let n=0;for(let t of this.readbackPool.values())for(let r of t)r.destroy(),n++;return this.readbackPool.clear(),this.readbackPoolBytes=0,n}clearTransientCaches(){return{bindGroups:this.clearBindGroupCache()}}clearBindGroupCache(){let n=this.bindGroupCache.size;return this.bindGroupCache.clear(),n}startProfiling(n={}){if(this.profileSession!==null)throw new Error("A profiling session is already active");if(!this.device.features.has("timestamp-query"))throw new Error("Kernel profiling requires the WebGPU timestamp-query feature");this.profileSession={label:n.label??"kernel-profile",events:[]}}async stopProfiling(){if(this.profileSession===null)throw new Error("No profiling session is active");let n=this.profileSession;return this.profileSession=null,bs({label:n.label,events:n.events,timestampUnit:"ns"})}tensorFromTypedArray(n,t,r){if(!td(n,r))throw new Error("Only float16/Uint16Array, float32/Float32Array and uint32/Uint32Array tensors are supported");let a=Ve(t);if(r.length!==a)throw new Error(`tensor data length ${r.length} does not match shape element count ${a}`);let s=this.host.createBuffer({label:"tensor",size:fr(r.byteLength),usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST|GPUBufferUsage.COPY_SRC,mappedAtCreation:!0}),o=s.getMappedRange();return r instanceof Float32Array?new Float32Array(o).set(r):r instanceof Uint16Array?new Uint16Array(o).set(r):r instanceof Int32Array?new Int32Array(o).set(r):new Uint32Array(o).set(r),s.unmap(),new ln({runtime:this,dtype:n,shape:t,buffer:s})}allocateWeightsBuffer({byteLength:n,dtype:t,shape:r,label:a="weights"}){if(!ws(t))throw new Error(`Unsupported dtype: ${t}`);if(!Number.isInteger(n)||n<0)throw new Error(`byteLength must be a nonnegative integer, got ${n}`);let s=this.host.createBuffer({label:a,size:n,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST|GPUBufferUsage.COPY_SRC});return new ln({runtime:this,dtype:t,shape:r,buffer:s})}writeWeightsRange(n,t,r){if(!(n instanceof ln))throw new Error("writeWeightsRange expects a WebGpuTensor");if(!Number.isInteger(t)||t<0)throw new Error(`byteOffset must be a nonnegative integer, got ${t}`);if(t+r.byteLength>n.byteLength)throw new Error(`write range [${t}, ${t+r.byteLength}] exceeds tensor byteLength ${n.byteLength}`);this.host.writeBuffer(n.buffer,t,r)}async copyBufferToBuffer({src:n,dst:t,srcOffset:r=0,dstOffset:a=0,byteLength:s,wait:o=!1}){if(s===0)return;let i=cn(n),u=cn(t),l=this.host.device.createCommandEncoder({label:"copyBufferToBuffer"});l.copyBufferToBuffer(i,r,u,a,s),await this.host.submit([l.finish()],{wait:o})}async queueIdle(){await this.host.device.queue.onSubmittedWorkDone()}empty(n,t,r="tensor-output"){if(!ws(n))throw new Error(`Unsupported dtype: ${n}`);let a=Ve(t)*Rn(n),s=this.host.createBuffer({label:r,size:fr(a),usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC|GPUBufferUsage.COPY_DST});return new ln({runtime:this,dtype:n,shape:t,buffer:s})}readTensor(n){if(n.byteLength===0)return n.dtype===ee.float32?Promise.resolve(new Float32Array(0)):n.dtype===ee.float16?Promise.resolve(new Uint16Array(0)):n.dtype===ee.int8?Promise.resolve(new Int32Array(0)):n.dtype===ee.int32?Promise.resolve(new Int32Array(0)):n.dtype===ee.uint8?Promise.resolve(new Uint32Array(0)):n.dtype===ee.uint32?Promise.resolve(new Uint32Array(0)):Promise.reject(new Error(`Unsupported dtype: ${n.dtype}`));let t=fr(n.byteLength),r=this.#e(t),a=this.host.device.createCommandEncoder({label:"readTensor"});a.copyBufferToBuffer(n.buffer,0,r,0,t),this.host.device.queue.submit([a.finish()]);let{dtype:s,byteLength:o}=n;return(async()=>{let i;try{i=await this.host.mapRead(r,0,t)}catch(u){throw this.#t(t,r),u}if(this.#t(t,r),t!==o&&(i=i.slice(0,o)),s===ee.float32)return new Float32Array(i);if(s===ee.float16)return new Uint16Array(i);if(s===ee.int8)return new Int32Array(i);if(s===ee.int32)return new Int32Array(i);if(s===ee.uint8)return new Uint32Array(i);if(s===ee.uint32)return new Uint32Array(i);throw new Error(`Unsupported dtype: ${s}`)})()}#e(n){let t=this.readbackPool.get(n);return t&&t.length>0?(this.readbackPoolBytes-=n,t.pop()):this.host.createBuffer({label:"tensor-readback",size:n,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ})}#t(n,t){if(this.readbackPoolBytes+n>this.maxReadbackPoolBytes){t.destroy();return}let r=this.readbackPool.get(n);r||(r=[],this.readbackPool.set(n,r)),r.push(t),this.readbackPoolBytes+=n}async runProgram(n,t={}){await this.runProgramSequence([n],t)}async runProgramSequence(n,t={}){let r=await this.prepareProgramSequence(n);await this.executePreparedProgramSequence(r,t)}async prepareProgramSequence(n){if(!Array.isArray(n)||n.length===0)throw new Error("prepareProgramSequence requires at least one program");let t=[];for(let r of n){if(rd(r)){t.push(ad(r));continue}let{name:a,source:s,entryPoint:o="main",cacheKey:i=a,bindings:u,dispatchWorkgroups:l,profile:c}=r;if(typeof s!="string"||s.length===0)throw new Error("program requires WGSL source");if(!Array.isArray(u)||u.length===0)throw new Error("program requires bindings");if(!Array.isArray(l)||l.length!==3)throw new Error("program requires a 3D dispatchWorkgroups array");let d=await this.programPipeline({name:a,source:s,entryPoint:o,cacheKey:i,layoutFactory:()=>this.pipelineLayout(a,u)}),{bindGroup:p,extraBindGroups:f}=this.cachedBindGroups({name:a,cacheKey:i,pipeline:d,bindings:u});t.push({pipeline:d,bindGroup:p,...f?{extraBindGroups:f}:{},dispatchWorkgroups:l,name:a,cacheKey:i,profile:c})}return t}async executePreparedProgramSequence(n,t={}){if(!Array.isArray(n)||n.length===0)throw new Error("executePreparedProgramSequence requires at least one prepared step");let r=t.wait??!1;await this._runSteps(n,{wait:r,mergePass:!this.profileSession})}enqueuePreparedProgramSequence(n){if(!Array.isArray(n)||n.length===0)throw new Error("enqueuePreparedProgramSequence requires at least one prepared step");if(this.profileSession)throw new Error("enqueuePreparedProgramSequence cannot be used while profiling");let t=this.host.device.createCommandEncoder({label:"compute-dispatch"});_s(t,n),this.host.device.queue.submit([t.finish()])}async measurePreparedSequenceGpuMs(n){if(!this.host.device.features.has("timestamp-query"))return null;let t=this.createTimestampResources(2);try{let r=this.host.device.createCommandEncoder({label:"gpu-time-measure"});for(let l of n)l.kind==="copy"&&l.byteLength>0&&r.copyBufferToBuffer(l.src,l.srcOffset,l.dst,l.dstOffset,l.byteLength);let a=r.beginComputePass({label:"gpu-time-pass",timestampWrites:{querySet:t.querySet,beginningOfPassWriteIndex:0,endOfPassWriteIndex:1}}),s=!1,o=null,i=null;for(let l of n)if(!(l.kind==="copy"||mt(l.dispatchWorkgroups))){if(l.pipeline!==o&&(a.setPipeline(l.pipeline),o=l.pipeline),l.bindGroup!==i&&(a.setBindGroup(0,l.bindGroup),i=l.bindGroup),l.extraBindGroups)for(let c of l.extraBindGroups)a.setBindGroup(c.group,c.bindGroup),c.group===0&&(i=c.bindGroup);a.dispatchWorkgroups(l.dispatchWorkgroups[0],l.dispatchWorkgroups[1],l.dispatchWorkgroups[2]),s=!0}if(a.end(),!s)return null;r.resolveQuerySet(t.querySet,0,2,t.resolveBuffer,0),r.copyBufferToBuffer(t.resolveBuffer,0,t.readbackBuffer,0,16),await this.host.submit([r.finish()],{wait:!0});let u=await this.readTimestampBuffer(t.readbackBuffer,2);return Number(u[1]-u[0])/1e6}finally{t.querySet.destroy(),t.resolveBuffer.destroy(),t.readbackBuffer.destroy()}}createUniformU32(n,t){let r=new Uint32Array(n),a=this.host.createBuffer({label:t,size:r.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});return this.host.writeBuffer(a,0,r),a}async _runSteps(n,{wait:t=!1,mergePass:r}){let a=!!this.profileSession,s=this.host.device.createCommandEncoder({label:a?"profiled-compute-dispatch":"compute-dispatch"});if(!a&&r){_s(s,n),await this.host.submit([s.finish()],{wait:t});return}let o=n.map((c,d)=>c.kind==="copy"||mt(c.dispatchWorkgroups)?-1:d).filter(c=>c>=0),i=a?o.length*2:0,u=a&&i>0?this.createTimestampResources(i):void 0,l=0;for(let c of n){if(c.kind==="copy"){c.byteLength>0&&s.copyBufferToBuffer(c.src,c.srcOffset,c.dst,c.dstOffset,c.byteLength);continue}if(mt(c.dispatchWorkgroups))continue;let d=s.beginComputePass({label:a?`${c.name??"compute"}-profile-pass`:"compute-pass",...a?{timestampWrites:{querySet:u.querySet,beginningOfPassWriteIndex:l*2,endOfPassWriteIndex:l*2+1}}:{}});if(d.setPipeline(c.pipeline),d.setBindGroup(0,c.bindGroup),c.extraBindGroups)for(let p of c.extraBindGroups)d.setBindGroup(p.group,p.bindGroup);d.dispatchWorkgroups(c.dispatchWorkgroups[0],c.dispatchWorkgroups[1],c.dispatchWorkgroups[2]),d.end(),l+=1}if(!a||u===void 0){await this.host.submit([s.finish()],{wait:t});return}try{s.resolveQuerySet(u.querySet,0,i,u.resolveBuffer,0),s.copyBufferToBuffer(u.resolveBuffer,0,u.readbackBuffer,0,i*8),await this.host.submit([s.finish()],{wait:t});let c=await this.readTimestampBuffer(u.readbackBuffer,i);for(let d=0;dt})}async _buildPipeline({cacheKey:n,name:t,entryPoint:r,layoutFactory:a,sourceFactory:s}){let o=this.pipelineCache.get(n);if(o)return o;let i=await s();this.captureShaders&&!this.capturedShaders.has(t)&&this.capturedShaders.set(t,i);let u=this.host.createShaderModule(i,t),l=await this.host.createComputePipeline({label:t,layout:a(),compute:{module:u,entryPoint:r}});return this.pipelineCache.set(n,l),l}cachedBindGroups({name:n,cacheKey:t,pipeline:r,bindings:a}){let s=new Map;for(let l of a){let c=l.group??0,d=s.get(c);d?d.push(l):s.set(c,[l])}let o=[...s.keys()].sort((l,c)=>l-c),i=this.buildGroupBindGroup(n,t,r,0,s.get(0)??[]),u=o.filter(l=>l!==0).map(l=>({group:l,bindGroup:this.buildGroupBindGroup(n,t,r,l,s.get(l))}));return u.length>0?{bindGroup:i,extraBindGroups:u}:{bindGroup:i}}buildGroupBindGroup(n,t,r,a,s){let o=s.map((l,c)=>{let d=sd(l),p={buffer:d,offset:l.offset??0};return l.size!==void 0&&l.size>0&&(p.size=l.size),{binding:l.binding??c,resource:p,cachePart:`${l.binding??c}:${this.bufferId(d)}:${p.offset}:${p.size??""}`}}),i=`${t}|g${a}|${o.map(l=>l.cachePart).join("|")}`,u=this.bindGroupCache.get(i);if(u===void 0&&(u=this.host.device.createBindGroup({label:`${n}-bind-group-${a}`,layout:r.getBindGroupLayout(a),entries:o.map(({binding:l,resource:c})=>({binding:l,resource:c}))}),this.bindGroupCache.set(i,u),this.bindGroupCache.size>this.maxBindGroupCacheEntries)){let l=this.bindGroupCache.keys().next().value;l!==void 0&&this.bindGroupCache.delete(l)}return u}bufferId(n){let t=this.bufferIds.get(n);return t===void 0&&(t=this.nextBufferId++,this.bufferIds.set(n,t)),t}pipelineLayout(n,t){let r=t.map((i,u)=>typeof i=="string"?{group:0,binding:u,type:i}:{group:i.group??0,binding:i.binding??u,type:i.type}),a=new Set,s=0;for(let i of r){if(!Number.isInteger(i.binding)||i.binding<0)throw new Error(`pipeline layout ${n} has invalid binding index ${i.binding}`);if(!Number.isInteger(i.group)||i.group<0)throw new Error(`pipeline layout ${n} has invalid bind group index ${i.group}`);let u=`${i.group}:${i.binding}`;if(a.has(u))throw new Error(`pipeline layout ${n} has duplicate binding index ${i.binding} in @group(${i.group})`);if(typeof i.type!="string"||i.type.length===0)throw new Error(`pipeline layout ${n} binding ${i.binding} is missing a buffer type`);a.add(u),s=Math.max(s,i.group)}let o=[];for(let i=0;i<=s;++i)o.push(this.host.device.createBindGroupLayout({label:`${n}-bgl${i}`,entries:r.filter(u=>u.group===i).map(u=>({binding:u.binding,visibility:GPUShaderStage.COMPUTE,buffer:{type:u.type}}))}));return this.host.device.createPipelineLayout({label:`${n}-layout`,bindGroupLayouts:o})}createTimestampResources(n){let t=n*8,r=this.host.device.createQuerySet({type:"timestamp",count:n}),a=this.host.createBuffer({label:"kernel-profile-timestamp-resolve",size:t,usage:GPUBufferUsage.QUERY_RESOLVE|GPUBufferUsage.COPY_SRC}),s=this.host.createBuffer({label:"kernel-profile-timestamp-readback",size:t,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ});return{querySet:r,resolveBuffer:a,readbackBuffer:s}}async readTimestampBuffer(n,t){let r=await this.host.mapRead(n,0,t*8),a=new BigUint64Array(r);return Array.from(a,s=>s)}recordProfileEvent(n,t,r){if(!this.profileSession)return;let a=r>t?r-t:0n,s=pr(n);this.profileSession.events.push({name:n.name,cacheKey:n.cacheKey,dispatchWorkgroups:n.dispatchWorkgroups,profile:n.profile,...s,startTimestamp:t.toString(),endTimestamp:r.toString(),durationMs:Number(a)/1e6})}};function td(e,n){return e===ee.float16&&n instanceof Uint16Array||e===ee.float32&&n instanceof Float32Array||(e===ee.int8||e===ee.int32)&&n instanceof Int32Array||(e===ee.uint8||e===ee.uint32)&&n instanceof Uint32Array}function ws(e){return Object.values(ee).includes(e)}function fr(e){return Math.max(4,Math.ceil(e/4)*4)}function rd(e){return e.kind==="copy"}function ad(e){if(!e.src||!e.dst)throw new Error("copy step requires src and dst (buffer or tensor)");let n=cn(e.src),t=cn(e.dst),r=e.srcOffset??0,a=e.dstOffset??0,s=e.byteLength;if(!Number.isInteger(s)||s<=0)throw new Error("copy step requires positive integer byteLength");return{kind:"copy",src:n,dst:t,srcOffset:r,dstOffset:a,byteLength:s,name:e.name??"copy"}}function sd(e){if(e.tensor!==void 0&&e.tensor!==null)return cn(e.tensor);if(e.buffer!==void 0&&e.buffer!==null)return cn(e.buffer);throw new Error(`binding ${e.binding??"?"} is missing tensor or buffer`)}function cn(e){return od(e)?e:e.buffer}function od(e){return e===null||typeof e!="object"?!1:"destroy"in e&&"mapAsync"in e&&"getMappedRange"in e&&!("buffer"in e)}function _s(e,n){let t=null,r=null,a=null,s=()=>{t!==null&&(t.end(),t=null),r=null,a=null};for(let o of n){if(o.kind==="copy"){s(),o.byteLength>0&&e.copyBufferToBuffer(o.src,o.srcOffset,o.dst,o.dstOffset,o.byteLength);continue}if(!mt(o.dispatchWorkgroups)){if(t===null&&(t=e.beginComputePass({label:"compute-sequence-pass"})),o.pipeline!==r&&(t.setPipeline(o.pipeline),r=o.pipeline),o.bindGroup!==a&&(t.setBindGroup(0,o.bindGroup),a=o.bindGroup),o.extraBindGroups)for(let i of o.extraBindGroups)t.setBindGroup(i.group,i.bindGroup),i.group===0&&(a=i.bindGroup);t.dispatchWorkgroups(o.dispatchWorkgroups[0],o.dispatchWorkgroups[1],o.dispatchWorkgroups[2])}}s()}function mt(e){return e[0]===0||e[1]===0||e[2]===0}async function vs(e={}){let n=e.host??await dr(e);return new gt({host:n})}var id=BigInt(1e8),ud=new TextDecoder("utf-8",{fatal:!0}),Ts=Object.freeze({BOOL:8,F4:4,F6_E2M3:6,F6_E3M2:6,U8:8,I8:8,F8_E5M2:8,F8_E4M3:8,F8_E8M0:8,F8_E4M3FNUZ:8,F8_E5M2FNUZ:8,I16:16,U16:16,F16:16,BF16:16,I32:32,U32:32,F32:32,F64:64,I64:64,U64:64,C64:64}),ld=Object.freeze({U8:Uint8Array,I8:Int8Array,I16:Int16Array,U16:Uint16Array,I32:Int32Array,U32:Uint32Array,F32:Float32Array,F64:Float64Array,I64:BigInt64Array,U64:BigUint64Array});function cd(e){let n=Ts[e];if(!n)throw new B(`Unknown dtype: ${e}`);return n}function Ss(e){return ld[e]??null}function ks(e,n){let t=n.BYTES_PER_ELEMENT;if(e.byteLength%t!==0)throw new B(`Byte length ${e.byteLength} not divisible by ${n.name} element size`);if(e.byteOffset%t===0)return new n(e.buffer,e.byteOffset,e.byteLength/t);let r=new ArrayBuffer(e.byteLength);return new Uint8Array(r).set(e),new n(r)}var B=class extends Error{constructor(n){super(n),this.name="SafeTensorsError"}};function xs(e){if(e.byteLength<8)throw new B(`File too small: ${e.byteLength} bytes < 8 byte header prefix`);let t=new DataView(e.buffer,e.byteOffset,e.byteLength).getBigUint64(0,!0);if(t>id)throw new B(`Header length ${t} exceeds maximum 100000000`);let r=Number(t),a=8+r;if(a>e.byteLength)throw new B(`Header length ${r} exceeds buffer size`);let s=e.subarray(8,a),o;try{o=ud.decode(s)}catch{throw new B("Header is not valid UTF-8")}let i;try{i=JSON.parse(o)}catch(u){let l=u instanceof Error?u.message:String(u);throw new B(`Header is not valid JSON: ${l}`)}if(i===null||typeof i!="object"||Array.isArray(i))throw new B("Header must be a JSON object");return{headerByteLength:r,dataStart:a,header:i}}function mr(e,n){let t=e.__metadata__;if(t!==void 0&&!pd(t))throw new B("__metadata__ must be a {string: string} map");let r=[];for(let[s,o]of Object.entries(e))s!=="__metadata__"&&r.push([s,dd(s,o)]);r.sort((s,o)=>s[1].dataOffsets[0]-o[1].dataOffsets[0]);let a=0;for(let[s,o]of r){let[i,u]=o.dataOffsets;if(i!==a)throw new B(`Invalid offset for tensor ${s}: expected ${a}, got ${i}`);let l=o.elementCount*cd(o.dtype);if(l%8!==0)throw new B(`Tensor ${s} has subbyte size ${l} bits not divisible by 8`);if(u-i!==l/8)throw new B(`Tensor ${s} byte length ${u-i} does not match shape*dtype ${l/8}`);a=u}if(n!==null&&a!==n)throw new B(`Data length mismatch: header expects ${a} bytes, got ${n}`);return{metadata:t??null,tensors:new Map(r),dataByteLength:a}}function dd(e,n){if(n===null||typeof n!="object"||Array.isArray(n))throw new B(`Tensor ${e}: info must be an object`);let{dtype:t,shape:r,data_offsets:a}=n;if(typeof t!="string"||!(t in Ts))throw new B(`Tensor ${e}: unknown dtype ${t}`);if(!Array.isArray(r)||!r.every(u=>Number.isInteger(u)&&u>=0))throw new B(`Tensor ${e}: shape must be an array of nonnegative integers`);if(!Array.isArray(a)||a.length!==2||!a.every(u=>Number.isInteger(u)&&u>=0))throw new B(`Tensor ${e}: data_offsets must be a 2-element array of nonnegative integers`);let[s,o]=a;if(o0){let c=new Uint8Array(n),d=[];for(;;){let{done:p,value:f}=await o.read();if(p)break;f&&(u+f.byteLength<=c.byteLength&&d.length===0?c.set(f,u):(d.length===0&&d.push(c.subarray(0,u)),d.push(f)),u+=f.byteLength,hr({onByteProgress:t,onProgress:r,loaded:u,delta:f.byteLength,total:i,fromCache:s}))}return d.length===0?u===n?c:c.subarray(0,u):Es(d,u)}let l=[];for(;;){let{done:c,value:d}=await o.read();if(c)break;d&&(l.push(d),u+=d.byteLength,hr({onByteProgress:t,onProgress:r,loaded:u,delta:d.byteLength,total:i,fromCache:s}))}return Es(l,u)}function hr({onByteProgress:e,onProgress:n,loaded:t,delta:r,total:a,fromCache:s}){e?.(r),n?.({loaded:t,total:a??null,fromCache:s})}function Es(e,n){if(e.length===0)return new Uint8Array(0);if(e.length===1&&e[0].byteLength===n)return e[0];let t=new Uint8Array(n),r=0;for(let a of e)t.set(a,r),r+=a.byteLength;return t}var md=128<<20,gd=1<<20,hd=4,qn=class{#e;#t;#n;metadata;url;totalSize;headerByteLength;dataByteLength;constructor({source:n,dataStart:t,metadata:r,tensors:a,headerByteLength:s,dataLength:o}){this.#e=n,this.#t=t,this.#n=a,this.metadata=r,this.url=n.url,this.totalSize=n.size,this.headerByteLength=s,this.dataByteLength=o??(n.size==null?null:n.size-t)}names(){return[...this.#n.keys()]}has(n){return this.#n.has(n)}info(n){let t=this.#r(n);return{dtype:t.dtype,shape:[...t.shape],dataOffsets:[...t.dataOffsets]}}byteLength(n){let t=this.#r(n);return t.dataOffsets[1]-t.dataOffsets[0]}async tensorBytes(n,t){let r=this.#r(n),[a,s]=r.dataOffsets,o=this.#t+a,i=this.#t+s,u=await this.#e.readTensor(o,i);if(u)return u;let l=await this.#e.readRange(o,i,t);return await this.#e.writeTensor(o,i,l),l}async tensorAs(n,t){let r=this.#r(n),a=Ss(r.dtype);if(!a)throw new B(`No native typed-array for dtype ${r.dtype}; use tensorBytes()`);return ks(await this.tensorBytes(n,t),a)}async batchBytes(n,t){if(n.length===0)return new Map;let r=n.map(u=>[u,this.#r(u)]),a=1/0,s=0;for(let[,u]of r)u.dataOffsets[0]s&&(s=u.dataOffsets[1]);let o=await this.#e.readRange(this.#t+a,this.#t+s,t),i=new Map;for(let[u,l]of r)i.set(u,o.subarray(l.dataOffsets[0]-a,l.dataOffsets[1]-a));return i}async streamAll(n,{concurrency:t=hd,chunkMaxBytes:r=md,chunkMaxGap:a=gd,names:s=null,onProgress:o,signal:i}={}){let u=this.#a(s);if(u.length===0)return;let l=yd(u,{maxBytes:r,maxGap:a}),c=l.reduce((G,C)=>G+(C.end-C.begin),0),d=0,p=new Map,f=(G={})=>{if(!o)return;let C=d;for(let T of p.values())C+=T;o({loaded:C,total:c,...G})},m=this.#t,_=this.#e,E=0,b=async G=>{let{begin:C,end:T,tensors:U}=l[G],P=m+C,N=m+T,R=T-C,V,z=!0,j=await Promise.all(U.map(g=>_.readTensor(m+g.begin,m+g.end)));for(let g of j)if(!g){z=!1;break}if(z){V=new Uint8Array(R);for(let g=0;g{p.set(G,(p.get(G)??0)+g),f({fromCache:!1,range:[P,N],inFlight:!0})}});let ne=z,Q=U.map(g=>({name:g.name,offset:g.begin-C,length:g.end-g.begin})),ve=Promise.resolve(n({begin:P,end:N,bytes:V,tensors:Q})),Z=ne?Promise.resolve():Promise.all(U.map((g,w)=>{if(j[w])return null;let S=V.subarray(g.begin-C,g.end-C);return _.writeTensor(m+g.begin,m+g.end,S).catch(()=>{})})).catch(()=>{});await Promise.all([ve,Z]),p.delete(G),d+=R,f({fromCache:ne,range:[P,N]})},F=async()=>{for(;;){if(i?.aborted)throw i.reason??new Error("aborted");let G=E++;if(G>=l.length)return;await b(G)}},q=[];for(let G=0;Go&&r.push({name:a,begin:o,end:i})}return r.sort((a,s)=>a.begin-s.begin),r}#r(n){let t=this.#n.get(n);if(!t)throw new B(`Unknown tensor: ${n}`);return t}};function yd(e,{maxBytes:n,maxGap:t}){let r=[],a=null;for(let s of e){if(!a){a={begin:s.begin,end:s.end,tensors:[s]};continue}let o=s.begin-a.end,i=s.end-a.begin;o<=t&&i<=n?(a.end=s.end,a.tensors.push(s)):(r.push(a),a={begin:s.begin,end:s.end,tensors:[s]})}return a&&r.push(a),r}async function Gs(e,{headerProbeBytes:n}){let t=e.size==null?n:Math.min(n,e.size),r=await e.readRange(0,t);if(r.byteLength<8)throw new B(`Probe returned ${r.byteLength} bytes; need at least ${8}`);let a=new DataView(r.buffer,r.byteOffset,r.byteLength).getBigUint64(0,!0);if(a>BigInt(1e8))throw new B(`Header length ${a} exceeds maximum ${1e8}`);let s=Number(a),o=8+s,i;if(r.byteLength>=o)i=r.subarray(0,o);else{let l=await e.readRange(r.byteLength,o);i=new Uint8Array(o),i.set(r),i.set(l,r.byteLength)}let{header:u}=xs(i);return{header:u,headerByteLength:s,dataStart:o,dataLength:e.size==null?null:e.size-o}}function dn(e){return e instanceof Error?e.message:String(e)}function Os(e){return e.byteOffset===0&&e.byteLength===e.buffer.byteLength&&e.buffer instanceof ArrayBuffer?e.buffer:e.slice().buffer}var bd=262144,wd="safetensors-cache-v1",pn="chunks",fn="meta";async function Fs(e,n={},t){let r=n.cacheKey??(typeof e=="string"?e:e.toString()),a=n.cache===!1,s=!!n.force,o=a||n.source?null:n.chunkCache??_d(n.cacheName??wd);if(o&&!s)try{let m=await o.getMeta(r);if(m&&m.header&&Number.isFinite(m.size)&&Number.isFinite(m.dataStart)){let _=await t(e,{...n,chunkCache:o,knownSize:m.size,knownAcceptsRanges:m.acceptsRanges??!0}),E=m.size-m.dataStart,{metadata:b,tensors:F}=mr(m.header,E);return new qn({source:_,dataStart:m.dataStart,metadata:b,tensors:F,headerByteLength:m.dataStart-8,dataLength:E})}}catch(m){typeof console<"u"&&console.warn(`safetensors meta cache read failed: ${dn(m)}`)}let i=await t(e,{...n,chunkCache:o}),{header:u,headerByteLength:l,dataStart:c,dataLength:d}=await Gs(i,{headerProbeBytes:n.headerProbeBytes??bd}),{metadata:p,tensors:f}=mr(u,d);return o&&!s&&i.size!=null&&o.putMeta(r,{size:i.size,dataStart:c,header:u,acceptsRanges:i.acceptsRanges}).catch(()=>{}),new qn({source:i,dataStart:c,metadata:p,tensors:f,headerByteLength:l,dataLength:d})}function Ws(e){return{requireRangeRequests:!!(e.requireRangeRequests??e.requireRanges??!1),knownSize:e.knownSize,knownAcceptsRanges:e.knownAcceptsRanges}}function Ms(e,n){let{chunkCache:t}=n,r=n.cacheKey??e.url,a=!!n.force;return{...e,async readTensor(s,o){if(a)return null;try{return await t.get(r,s,o)}catch(i){return typeof console<"u"&&console.warn(`safetensors cache read failed: ${dn(i)}`),null}},async writeTensor(s,o,i){try{let u=i.byteOffset===0&&i.byteLength===i.buffer.byteLength?i:new Uint8Array(i);await t.put(r,s,o,u)}catch(u){typeof console<"u"&&console.warn(`safetensors cache write failed: ${dn(u)}`)}}}}var Rs=new Map;function _d(e){return typeof indexedDB>"u"?null:{async get(n,t,r){let a=await ht(e);return new Promise((s,o)=>{let u=a.transaction(pn,"readonly").objectStore(pn).get([n,t,r]);u.onsuccess=async()=>{let l=u.result;if(!l)return s(null);s(new Uint8Array(await l.arrayBuffer()))},u.onerror=()=>o(u.error)})},async put(n,t,r,a){let s=await ht(e);return new Promise((o,i)=>{let l=s.transaction(pn,"readwrite").objectStore(pn).put(new Blob([Os(a)]),[n,t,r]);l.onsuccess=()=>o(),l.onerror=()=>i(l.error)})},async getMeta(n){let t=await ht(e);return new Promise((r,a)=>{let o=t.transaction(fn,"readonly").objectStore(fn).get(n);o.onsuccess=()=>r(o.result??null),o.onerror=()=>a(o.error)})},async putMeta(n,t){let r=await ht(e);return new Promise((a,s)=>{let i=r.transaction(fn,"readwrite").objectStore(fn).put(t,n);i.onsuccess=()=>a(),i.onerror=()=>s(i.error)})}}}function ht(e){let n=Rs.get(e);if(n)return n;let t=new Promise((r,a)=>{let s=indexedDB.open(e,2);s.onupgradeneeded=()=>{let o=s.result;o.objectStoreNames.contains(pn)||o.createObjectStore(pn),o.objectStoreNames.contains(fn)||o.createObjectStore(fn)},s.onsuccess=()=>r(s.result),s.onerror=()=>a(s.error),s.onblocked=()=>a(new Error("indexedDB open blocked"))});return Rs.set(e,t),t}var Bs=(e,n={})=>Fs(e,n,vd);async function vd(e,n){let t=await Ps(e,n,Ws(n));return n.chunkCache?Ms(t,{...n,chunkCache:n.chunkCache}):t}function Is({readTextResource:e,openSafeTensorsResource:n}){async function t(s,o,i){return JSON.parse(await e(s,o,i))}async function r(s,o,i){return qs(()=>t(s,o,i))}async function a(s,o,i){return qs(()=>e(s,o,i))}return Object.freeze({readJsonResource:t,readJsonResourceOptional:r,readTextResource:e,readTextResourceOptional:a,openSafeTensorsResource:n})}var yr=class extends Error{url;status;statusText;constructor(n,t){super(`GET ${n} failed: ${t.status} ${t.statusText}`),this.name="ResourceFetchError",this.url=n,this.status=t.status,this.statusText=t.statusText}};function br(e,n){let t=e instanceof URL?e.toString():String(e),r=new URL(Td(t),globalThis.location?.href);return new URL(n,r).toString()}async function Us(e,n={}){let t=n.fetch??globalThis.fetch;if(typeof t!="function")throw new Error("No fetch implementation available");let r=await kd(n);if(r&&!n.force){let s=await r.match(e);if(s)return s.text()}let a=await t(e,{signal:n.signal});if(!a.ok)throw new yr(e,a);if(r)try{await r.put(e,a.clone())}catch(s){typeof console<"u"&&console.warn(`resource cache write failed: ${dn(s)}`)}return a.text()}function Td(e){return e.endsWith("/")?e:`${e}/`}async function qs(e){try{return await e()}catch(n){if(!Sd(n))throw n;return null}}function Sd(e){return typeof e=="object"&&e!==null&&(e.code==="ENOENT"||e.status===404)}async function kd(e={}){if(e.cache===!1)return null;let n=e.cacheStorage??globalThis.caches;return n?.open?n.open(e.cacheName??"bonsai-pipeline-v1"):null}var mn=Is({readTextResource:xd,openSafeTensorsResource:Ed});async function xd(e,n,t={}){return Us(br(e,n),t)}async function Ed(e,n,t={}){return Bs(br(e,n),t)}var Pd={tensor:e=>e.destroy(),buffer:e=>e.destroy(),map:e=>e.clear(),set:e=>e.clear()};function en(e,n=new Set){yt(e,n,Pd)}function yt(e,n,t){if(!(e==null||typeof e!="object")&&!n.has(e)&&(n.add(e),!(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))){if(Ad(e)){t.tensor(e);return}if(Gd(e)){t.buffer(e);return}if(e instanceof Map){for(let r of e.values())yt(r,n,t);t.map(e);return}if(e instanceof Set){for(let r of e.values())yt(r,n,t);t.set(e);return}for(let r of Object.keys(e))yt(e[r],n,t)}}function Ad(e){let n=e;return Array.isArray(n.shape)&&typeof n.dtype=="string"&&typeof n.destroy=="function"&&n.buffer!=null&&typeof n.buffer.destroy=="function"}function Gd(e){let n=e;return typeof n.destroy=="function"&&typeof n.mapAsync=="function"&&typeof n.getMappedRange=="function"}var wr="sliding_attention",_r="full_attention";function Od(e){return e&&typeof e=="object"&&e.text_config&&typeof e.text_config=="object"?{...e.text_config}:e??{}}function Ae(e,n,t){let r=e[n];if(r==null){if(t!==void 0)return t;throw new Error(`Gemma4Config: missing required integer field "${n}"`)}let a=Number(r);if(!Number.isInteger(a))throw new Error(`Gemma4Config: field "${n}" must be an integer, got ${r}`);return a}var Un=class{model_type="gemma4_text";vocab_size;vocab_size_per_layer_input;hidden_size;intermediate_size;num_hidden_layers;num_attention_heads;num_key_value_heads;head_dim;global_head_dim;hidden_size_per_layer_input;num_kv_shared_layers;sliding_window;rms_norm_eps;final_logit_softcapping;use_double_wide_mlp;tie_word_embeddings;max_position_embeddings;layer_types;firstKvSharedLayer;layers;slidingRopeTheta;fullRopeTheta;fullPartialRotaryFactor;embedScale;perLayerEmbedScale;constructor(n={}){let t=Od(n);this.vocab_size=Ae(t,"vocab_size"),this.vocab_size_per_layer_input=Ae(t,"vocab_size_per_layer_input",this.vocab_size),this.hidden_size=Ae(t,"hidden_size"),this.intermediate_size=Ae(t,"intermediate_size"),this.num_hidden_layers=Ae(t,"num_hidden_layers"),this.num_attention_heads=Ae(t,"num_attention_heads"),this.num_key_value_heads=Ae(t,"num_key_value_heads"),this.head_dim=Ae(t,"head_dim"),this.global_head_dim=Ae(t,"global_head_dim",this.head_dim),this.hidden_size_per_layer_input=Ae(t,"hidden_size_per_layer_input"),this.num_kv_shared_layers=Ae(t,"num_kv_shared_layers",0),this.sliding_window=Ae(t,"sliding_window"),this.rms_norm_eps=Number(t.rms_norm_eps??1e-6),this.final_logit_softcapping=Number(t.final_logit_softcapping??0)||0,this.use_double_wide_mlp=!!t.use_double_wide_mlp,this.tie_word_embeddings=!!(t.tie_word_embeddings??!1),this.max_position_embeddings=Ae(t,"max_position_embeddings",131072);let r=t.rope_parameters??{};this.slidingRopeTheta=Number(r?.[wr]?.rope_theta??1e4),this.fullRopeTheta=Number(r?.[_r]?.rope_theta??1e6),this.fullPartialRotaryFactor=Number(r?.[_r]?.partial_rotary_factor??.25);let a=Array.isArray(t.layer_types)?t.layer_types:null;if(this.layer_types=a?a.slice():Array.from({length:this.num_hidden_layers},(o,i)=>(i+1)%5===0?_r:wr),this.layer_types.length!==this.num_hidden_layers)throw new Error(`Gemma4Config: layer_types length ${this.layer_types.length} != num_hidden_layers ${this.num_hidden_layers}`);this.firstKvSharedLayer=this.num_hidden_layers-this.num_kv_shared_layers;let s={};for(let o=0;o{let u=o===wr,l=u?this.head_dim:this.global_head_dim,c=i>=this.firstKvSharedLayer&&this.firstKvSharedLayer>=0,d=this.use_double_wide_mlp&&c;return{index:i,layerType:o,isSliding:u,headDim:l,qOut:this.num_attention_heads*l,kvOut:this.num_key_value_heads*l,attnBits:4,mlpBits:c?2:4,intermediate:d?this.intermediate_size*2:this.intermediate_size,slidingWindow:u?this.sliding_window:0,ropeTheta:u?this.slidingRopeTheta:this.fullRopeTheta,partialRotaryFactor:u?1:this.fullPartialRotaryFactor,isKvShared:c,kvSourceLayer:c?s[o]:i}}),this.embedScale=Math.sqrt(this.hidden_size),this.perLayerEmbedScale=Math.sqrt(this.hidden_size_per_layer_input),this.validate()}validate(){if(this.num_attention_heads%this.num_key_value_heads!==0)throw new Error("Gemma4Config: num_attention_heads must be divisible by num_key_value_heads");for(let n of this.layers)if(n.isKvShared&&(n.kvSourceLayer===void 0||n.kvSourceLayer<0))throw new Error(`Gemma4Config: no KV source layer for shared layer ${n.index} (${n.layerType})`)}};var Ds=8192,Dn=class e{batchSize=1;maxLength;seqLength=0;keys;values;constructor(n,t,r){this.maxLength=n,this.keys=t,this.values=r}static defaultCapacity(n){return Math.max(1,Math.min(Ds,n.max_position_embeddings))}static allocate(n,t,r){let a=Math.max(1,Math.min(r??Ds,t.max_position_embeddings)),s=new Array(t.num_hidden_layers).fill(null),o=new Array(t.num_hidden_layers).fill(null);for(let i of t.layers)i.isKvShared||(s[i.index]=n.empty("float32",[a,i.kvOut],`gemma4-cache-k-${i.index}`),o[i.index]=n.empty("float32",[a,i.kvOut],`gemma4-cache-v-${i.index}`));return new e(a,s,o)}keyT(n){let t=this.keys[n];if(!t)throw new Error(`Gemma4DynamicCache: layer ${n} has no KV storage (is it a shared layer?)`);return t}valueT(n){let t=this.values[n];if(!t)throw new Error(`Gemma4DynamicCache: layer ${n} has no KV storage (is it a shared layer?)`);return t}get_seq_length(){return this.seqLength}advance(n){if(!Number.isInteger(n)||n<0)throw new Error(`advance(${n}) invalid`);if(this.seqLength+n>this.maxLength)throw new Error(`KV cache overflow: ${this.seqLength}+${n} > ${this.maxLength}`);this.seqLength+=n}truncate(n){if(!Number.isInteger(n)||n<0||n>this.maxLength)throw new Error(`truncate(${n}) invalid`);this.seqLength=n}dispose(){for(let n of this.keys)en(n);for(let n of this.values)en(n);this.keys.fill(null),this.values.fill(null)}};function Ls(e){let n=e&32768?-1:1,t=e>>>10&31,r=e&1023;return t===31?r===0?n*(1/0):NaN:t===0?n*2**-14*(r/1024):n*2**(t-15)*(1+r/1024)}function vr(e){let n=new Uint16Array(e.length);for(let t=0;t>>16&32768,r=n>>>23&255,a=n&8388607;if(r===255)return a!==0?t|32256:t|31744;let s=r-127+15;if(s>=31)return t|31743;if(s<=0){if(s<-10)return t;let c=a|8388608,d=14-s,p=1<>>d;return(f>p||f===p&&(m&1)===1)&&(m+=1),t|m}let o=4096,i=a&8191,u=a>>>13,l=s;return(i>o||i===o&&(u&1)===1)&&(u+=1,u===1024&&(u=0,l+=1)),l>=31?t|31743:t|l<<10|u}var Fd=new Set(["F32","BF16","F16"]),Wd=new Set(["float32","float16"]);function zs(e,n,t){Id(e,n);let r=Ud(e);if(t.byteLength%r!==0)throw new Error(`source byte length ${t.byteLength} not divisible by ${r}`);return e==="F32"&&n==="float32"?Ns(t,Float32Array,4):e==="F16"&&n==="float16"?Ns(t,Uint16Array,2):Dd(e,n)(t)}function Md(e){return typeof e=="string"&&Fd.has(e)}function Bd(e){return typeof e=="string"&&Wd.has(e)}function kr(e){if(!Md(e))throw new Error(`Unsupported source dtype: ${e}`)}function qd(e){if(!Bd(e))throw new Error(`Unsupported target dtype: ${e}`)}function Id(e,n){kr(e),qd(n)}function Ud(e){if(e==="F32")return 4;if(e==="BF16"||e==="F16")return 2;throw new Error(`Unsupported source dtype: ${e}`)}function Dd(e,n){if(e==="BF16"&&n==="float32")return Ld;if(e==="BF16"&&n==="float16")return Cd;if(e==="F16"&&n==="float32")return jd;if(e==="F32"&&n==="float16")return zd;throw new Error(`No converter for ${e} -> ${n}`)}function Ns(e,n,t){let r=new n(e.byteLength/t);return new Uint8Array(r.buffer).set(e),r}function Ld(e){let n=e.byteLength/2,t=new Float32Array(n),r=new Uint32Array(t.buffer);if(e.byteOffset%2===0){let a=new Uint16Array(e.buffer,e.byteOffset,n);for(let s=0;s>>0,Tr($d[0])}var Sr=null;function Hd(){if(Sr)return Sr;let e=new Uint16Array(65536);for(let n=0;n<65536;++n)e[n]=Kd(n);return Sr=e,e}var bt=class{specs;handlers;pending;constructor(n=[]){this.specs=n.map(wt),this.handlers=new Map,this.pending=new Set}add(n){return this.specs.push(wt(n)),this}tensor(n){return this.add(Qs(n))}group(n){return this.add(Ln(n))}prepare({reader:n,context:t={}}){this.handlers.clear(),this.pending.clear();for(let r of this.specs)if(r.type==="tensor")this.#e(r,n,t);else if(r.type==="group")this.#t(r,n,t);else throw new Error(`Unsupported weight plan spec type: ${r.type}`);return this}names(){return[...this.handlers.keys()]}async onChunk({bytes:n,tensors:t},r={}){let a=[];for(let s of t){let o=this.handlers.get(s.name);if(!o)continue;let i=n.subarray(s.offset,s.offset+s.length);a.push($s(o,i,r))}a.length&&await Promise.all(a)}async readSequential(n,t={}){for(let r of this.names()){let a=await n.read(r),s=this.handlers.get(r);s&&await $s(s,a,t)}}assertComplete(){if(this.pending.size>0){let n=[...this.pending].slice(0,5).join(", ");throw new Error(`WeightPlan incomplete - ${this.pending.size} tensor(s) never arrived (first: ${n})`)}}#e(n,t,r){let a=Ks(t,n.name);if(!a){Vs(n,r);return}Hs(n,a),this.#n(n.name,async(s,o)=>{this.pending.delete(n.name),await Xd(n,s,{...r,...o,description:a})},n.progressLabel??n.name)}#t(n,t,r){let a={},s=n.names.filter(u=>{let l=Ks(t,u);return l&&(a[u]=l),!l});if(s.length>0){Vs(n,r,s);return}for(let u of n.names)Hs(n,a[u],u);let o={},i=n.names.length;for(let u of n.names)this.#n(u,async(l,c)=>{if(this.pending.delete(u),o[u]=l,--i===0)try{await Zd(n,o,{...r,...c,descriptions:a})}finally{for(let d of n.names)delete o[d]}},n.progressLabel??u)}#n(n,t,r=n){if(this.handlers.has(n))throw new Error(`Duplicate WeightPlan handler for tensor: ${n}`);this.handlers.set(n,{name:n,progressLabel:r,receive:t}),this.pending.add(n)}};function Qs(e){return wt({type:"tensor",required:!0,...e})}function Ln(e){return wt({type:"group",required:!0,...e})}function Xs({name:e,required:n=!0,sourceDtype:t=null,targetDtype:r,shape:a=null,label:s=e,progressLabel:o=e,assign:i=null,missing:u=null,transform:l=null,upload:c=null,cleanup:d=null}){return Qs({name:e,required:n,sourceDtype:t,targetDtype:r,shape:a,label:s,progressLabel:o,transform:l??((p,{description:f})=>{if(!f)throw new Error(`WeightPlan tensor ${e} is missing a description`);let m=t??f.dtype;return kr(m),zs(m,r,p)}),upload:c??((p,{rt:f,description:m})=>{if(!f)throw new Error(`WeightPlan tensor ${e} upload requires context.rt`);if(!m)throw new Error(`WeightPlan tensor ${e} is missing a description`);let _=Ys(a,p.length,m);return f.tensorFromTypedArray(r,_,p)}),assign:i,missing:u,cleanup:d})}async function Zs(e,{source:n=null,reader:t,context:r={},concurrency:a,chunkMaxBytes:s,onProgress:o=null,signal:i}={}){let u=e instanceof bt?e:new bt(e);if(!t)throw new Error("WeightPlan execution requires a reader");try{u.prepare({reader:t,context:r});let l={...r,onTensorProgress:Vd(u,o)};return n?await n.streamAll(c=>u.onChunk(c,l),{concurrency:a,chunkMaxBytes:s,names:u.names(),onProgress:o,signal:i}):await u.readSequential(t,l),u.assertComplete(),u}finally{await Qd(n,t)}}async function $s(e,n,t){await e.receive(n,t),t.onTensorProgress?.({name:e.name,label:e.progressLabel})}function Vd(e,n){if(!n)return null;let t=0,r=e.names().length;return({name:a,label:s})=>{n({phase:"tensor",processed:++t,total:r,name:a,label:s})}}async function Qd(e,n){let t=new Set,r=e?[n,e]:[n];for(let a of r){let s=a.closeTarget??a;t.has(s)||(t.add(s),await a.close())}}function wt(e){if(!e||typeof e!="object")throw new Error("WeightPlan spec must be an object");if(e.type==="tensor"){if(typeof e.name!="string"||e.name.length===0)throw new Error("WeightPlan tensor spec requires a name");return{required:!0,...e}}if(e.type==="group"){if(!Array.isArray(e.names)||e.names.length===0)throw new Error("WeightPlan group spec requires a non-empty names array");for(let n of e.names)if(typeof n!="string"||n.length===0)throw new Error("WeightPlan group tensor names must be non-empty strings");return{required:!0,...e}}throw new Error(`Unknown WeightPlan spec type: ${e.type}`)}async function Xd(e,n,t){let r=e.transform?await e.transform(n,t):n,a=e.upload?await e.upload(r,t):r;e.run&&await e.run(a,t),e.assign?.(a,t),await e.cleanup?.(a,t)}async function Zd(e,n,t){let r=e.transform?await e.transform(n,t):n,a=e.upload?await e.upload(r,t):r;e.run&&await e.run(a,t),e.assign?.(a,t),await e.cleanup?.(a,t)}function Ks(e,n){return e.has(n)?e.describe(n):null}function Hs(e,n,t=e.type==="tensor"?e.name:"group"){if(e.sourceDtype&&n.dtype!==e.sourceDtype)throw new Error(`${t} has dtype ${n.dtype}; expected ${e.sourceDtype}`);if(e.shape){let r=Ys(e.shape,n.elementCount,n);if(r.length!==n.shape.length||r.some((a,s)=>a!==n.shape[s]))throw new Error(`${t} has shape [${n.shape}]; expected [${r}]`)}}function Vs(e,n,t=e.type==="tensor"?[e.name]:[...e.names]){if(e.required===!1){e.missing?.(t,n);return}throw new Error(`Missing required tensor${t.length===1?"":"s"}: ${t.join(", ")}`)}function Ys(e,n,t){return typeof e=="function"?e({valueLength:n,description:t}):Array.isArray(e)?e:t.shape?t.shape:[n]}Fn();function Js(e){return{has:t=>e.has(t),describe(t){let r=e.info(t),a=[...r.shape];return{dtype:r.dtype,shape:a,elementCount:Ve(a)}},async read(t){return e.tensorBytes(t)},async close(){await e.close()},closeTarget:e}}var v=Math.fround,Yd=v(1.4426950408889634),Jd=v(-.693145751953125),ep=v(-1428606765330187e-21),np=v(.0001980960224),tp=v(.001394256484),rp=v(.008333456703),ap=v(.04166637361),eo=v(.16666665941423425),sp=v(8.664339742),Me=(e,n,t)=>v(e*n+t),Cn=(e,n,t)=>v(e*n-t),_t=(e,n,t)=>v(t-e*n);function op(e){let n=Math.floor(e),t=e-n;return t>.5?n+1:t<.5||(n&1)===0?n:n+1}function no(e,n){let t=n>>1;return v(v(e*2**t)*2**(n-t))}function ip(e){let n=Math.abs(e);if(!(n<=sp))return e<0?-1:1;let t=op(v(n*Yd)),r=t,a=v(r*Jd),s=v(n+a),o=v(s-n),i=v(v(v(n-v(s-o))+v(a-o))+0);a=v(r*ep);let u=v(s+a);o=v(u-s);let l=v(v(v(s-v(u-o))+v(a-o))+i);s=u,i=l;let c=np;c=Me(c,s,tp),c=Me(c,s,rp),c=Me(c,s,ap);let d=v(s*c),p=Me(i,c,Cn(s,c,d)),f=v(d+eo);o=v(f-d),p=v(v(v(d-v(f-o))+v(eo-o))+p),d=f;let m=v(s*d),_=Me(s,p,Me(i,d,Cn(s,d,m)));f=v(m+.5),o=v(f-m),p=v(v(v(m-v(f-o))+v(.5-o))+_),d=f;let E=v(s*s),b=Me(v(s+s),i,Cn(s,s,E));m=v(E*d),_=Me(E,p,Me(b,d,Cn(E,d,m))),f=v(s+m),o=v(f-s),p=v(v(v(s-v(f-o))+v(m-o))+v(i+_)),d=f,f=v(1+d),p=v(v(v(1-f)+d)+p),d=f,d=no(d,t),p=no(p,t);let F=v(1/d),q=v(F*_t(p,F,_t(d,F,1))),G=v(d-F),C=v(v(v(v(d-G)-F)+p)-q),T=v(d+F),U=v(v(v(v(d-T)+F)+p)+q),P=v(1/T),N=v(G*P),R=Cn(P,G,N),V=_t(U,P,_t(T,P,1)),z=Me(N,V,Me(C,P,R)),j=v(N+z);return e<0?-j:j}function xr(e){let n=v(.7978845608028654),t=v(.044715),r=v(e),a=new Float32Array(256);for(let s=-128;s<128;++s){let o=v(s*r),i=v(v(o*o)*o),u=v(n*v(o+v(t*i))),l=ip(u);a[s+128]=v(v(.5*o)*v(1+l))}return a}function $e(e){let n=e.slice();return new Float32Array(n.buffer,n.byteOffset,n.byteLength>>>2)}var gn="model.language_model";async function to(e,n,t,r={}){let a=[],s=(c,d,p,f,m,_=!1)=>{a.push(Ln({names:[`${c}.weight`,`${c}.weight_scale`,`${c}.input_activation_scale`,`${c}.output_activation_scale`],progressLabel:c,run:async E=>{let b=E[`${c}.weight`],F=E[`${c}.weight_scale`];if(!b||!F)throw new Error(`Missing tensors for ${c}`);let q=b.byteLength*8/(d*p);if(q!==2&&q!==4&&q!==8)throw new Error(`${c}: derived ${q}-bit from ${b.byteLength} bytes for [${d}, ${p}]`);if(_){let P=p*q/32,N=new Uint32Array(b.buffer.slice(b.byteOffset,b.byteOffset+b.byteLength)),R=new Uint32Array(N.length),V=P/4;for(let z=0;z{a.push(Ln({names:[`${c}.embedding_quantized`,`${c}.embedding_scale`],progressLabel:c,run:async E=>{let b=E[`${c}.embedding_quantized`],F=E[`${c}.embedding_scale`];if(!b||!F)throw new Error(`Missing tensors for ${c}`);let q=b.byteLength*8/(d*p);if(q!==2&&q!==4&&q!==8)throw new Error(`${c}: derived ${q}-bit from ${b.byteLength} bytes for [${d}, ${p}]`);let G=e.allocateWeightsBuffer({byteLength:b.byteLength,dtype:"uint32",shape:[d,p*q/32],label:`${c}.bits`});e.writeWeightsRange(G,0,b);let C=e.tensorFromTypedArray("float32",[d,m],$e(F));_({bitsT:G,scaleT:C,bits:q})}}))},i=(c,d,p,f)=>{a.push(Ln({names:[`${c}.weight`,`${c}.weight_scale`,`${c}.input_activation_scale`,`${c}.output_activation_scale`],progressLabel:c,run:async m=>{let _=m[`${c}.weight`],E=m[`${c}.weight_scale`];if(!_||!E)throw new Error(`Missing tensors for ${c}`);let b=new Int8Array(_.buffer,_.byteOffset,_.byteLength),F=$e(E),q=new Float32Array(d*p);for(let U=0;U{a.push(Xs({name:c,sourceDtype:"BF16",targetDtype:f,shape:d??void 0,assign:m=>p(m)}))},l={layers:n.layers.map(()=>({}))};o(`${gn}.embed_tokens`,n.vocab_size,n.hidden_size,2,1,c=>{l.embedTokens=c}),o(`${gn}.embed_tokens_per_layer`,n.vocab_size_per_layer_input,n.num_hidden_layers*n.hidden_size_per_layer_input,4,n.num_hidden_layers,c=>{l.embedTokensPerLayer=c}),u(`${gn}.per_layer_model_projection.weight`,[n.num_hidden_layers*n.hidden_size_per_layer_input,n.hidden_size],c=>{l.perLayerModelProjection=c},"float16"),u(`${gn}.per_layer_projection_norm.weight`,[n.hidden_size_per_layer_input],c=>{l.perLayerProjectionNorm=c}),u(`${gn}.norm.weight`,[n.hidden_size],c=>{l.finalNorm=c}),s("lm_head",n.vocab_size,n.hidden_size,2,c=>{l.lmHead=c},!0);for(let c of n.layers){let d=c.index,p=`${gn}.layers.${d}`,f=l.layers[d];u(`${p}.input_layernorm.weight`,[n.hidden_size],m=>{f.inputLn=m}),u(`${p}.post_attention_layernorm.weight`,[n.hidden_size],m=>{f.postAttnLn=m}),u(`${p}.pre_feedforward_layernorm.weight`,[n.hidden_size],m=>{f.preFfLn=m}),u(`${p}.post_feedforward_layernorm.weight`,[n.hidden_size],m=>{f.postFfLn=m}),u(`${p}.post_per_layer_input_norm.weight`,[n.hidden_size],m=>{f.postPleLn=m}),u(`${p}.layer_scalar`,[1],m=>{f.layerScalarT=m}),s(`${p}.self_attn.q_proj`,c.qOut,n.hidden_size,c.attnBits,m=>{f.qProj=m}),u(`${p}.self_attn.q_norm.weight`,[c.headDim],m=>{f.qNorm=m}),c.isKvShared?(f.kProj=null,f.vProj=null,f.kNorm=null):(s(`${p}.self_attn.k_proj`,c.kvOut,n.hidden_size,c.attnBits,m=>{f.kProj=m}),s(`${p}.self_attn.v_proj`,c.kvOut,n.hidden_size,c.attnBits,m=>{f.vProj=m}),u(`${p}.self_attn.k_norm.weight`,[c.headDim],m=>{f.kNorm=m})),s(`${p}.self_attn.o_proj`,n.hidden_size,c.qOut,c.attnBits,m=>{f.oProj=m}),s(`${p}.mlp.gate_proj`,c.intermediate,n.hidden_size,c.mlpBits,m=>{f.gateProj=m}),s(`${p}.mlp.up_proj`,c.intermediate,n.hidden_size,c.mlpBits,m=>{f.upProj=m}),s(`${p}.mlp.down_proj`,n.hidden_size,c.intermediate,c.mlpBits,m=>{f.downProj=m}),i(`${p}.per_layer_input_gate`,n.hidden_size_per_layer_input,n.hidden_size,m=>{f.perLayerInputGate=m}),i(`${p}.per_layer_projection`,n.hidden_size,n.hidden_size_per_layer_input,m=>{f.perLayerProjection=m})}await Zs(a,{source:t,reader:Js(t),context:{rt:e},concurrency:r.concurrency,chunkMaxBytes:r.chunkMaxBytes,onProgress:r.onProgress??null,signal:r.signal});for(let c of l.layers)c.gateGeluLutT=e.tensorFromTypedArray("float32",[256],xr(c.gateProj.outScale)),c.pleGeluLutT=e.tensorFromTypedArray("float32",[256],xr(c.perLayerInputGate.outScale));return l}var y=Math.fround,Y=(e,n,t)=>y(e*n+t);function vt(e,n){let t=y(e+n),r=y(t-e);return{x:t,y:y(y(e-y(t-r))+y(n-r))}}function Tt(e,n){let t=y(e.x+n),r=y(t-e.x);return{x:t,y:y(y(y(e.x-y(t-r))+y(n-r))+e.y)}}function up(e,n){let t=y(e.x+n.x),r=y(t-e.x),a=y(y(e.x-y(t-r))+y(n.x-r));return{x:t,y:y(a+y(e.y+n.y))}}function ro(e,n){let t=y(e+n);return{x:t,y:y(y(e-t)+n)}}function Ar(e,n){let t=y(e+n.x);return{x:t,y:y(y(y(e-t)+n.x)+n.y)}}function lp(e,n){let t=y(e.x+n);return{x:t,y:y(y(y(e.x-t)+n)+e.y)}}function Er(e,n){let t=y(e.x+n.x);return{x:t,y:y(y(y(y(e.x-t)+n.x)+e.y)+n.y)}}function St(e,n){let t=y(e.x*n);return{x:t,y:Y(e.y,n,Y(e.x,n,-t))}}function kt(e,n){let t=y(e.x*n.x);return{x:t,y:Y(e.x,n.y,Y(e.y,n.x,Y(e.x,n.x,-t)))}}function ao(e,n){return Y(e.x,n.x,Y(e.y,n.x,y(e.x*n.y)))}function Et(e){let n=y(e.x*e.x);return{x:n,y:Y(y(e.x+e.x),e.y,Y(e.x,e.x,-n))}}function cp(e,n){let t=y(1/n.x),r=y(e.x*t),a=Y(t,e.x,-r),s=Y(-n.y,t,Y(-n.x,t,1));return{x:r,y:Y(r,s,Y(e.y,t,a))}}function dp(e){let n=y(e.x+e.y);return{x:n,y:y(y(e.x-n)+e.y)}}function pp(e,n){return{x:y(e.x*n),y:y(e.y*n)}}var Gr=new Float32Array(1),so=new Uint32Array(Gr.buffer);function oo(e){return Gr[0]=e,so[0]}function Pr(e){return so[0]=e>>>0,Gr[0]}function fp(e){let n=oo(e);return n=n>>>23&255,n-127}function mp(e,n){return Pr(oo(e)+(n<<23)|0)}function gp(e,n){let t=n>>31;t=(t+n>>6)-t<<4,n=n-(t<<2),t+=127,t=t>0?t:0,t=t>255?255:t;let r=Pr(t<<23>>>0);return e=y(y(y(y(e*r)*r)*r)*r),r=Pr(n+127<<23>>>0),y(e*r)}function xt(e){let n=Math.floor(e),t=e-n;return t>.5?n+1:t<.5||n%2===0?n:n+1}var hp=y(1.4426950408889634),yp=y(.693145751953125),bp=y(1428606765330187e-21),io=y(.3183098861837907),uo=y(3.1414794921875),lo=y(.0001131594181060791),co=y(1984187258941006e-24),wp=11754943508222875e-54;function _p(e){let n=el.type==="uniform");u?.buffer&&(o==="attn"?this.attnUniforms:this.cacheUniforms).push(u.buffer)}this.cleanups.push(s.cleanup),this.timing&&(this.collectMs+=performance.now()-r)}async buildSteps(){return this.rt.prepareProgramSequence(this.programs)}prependCopies(n){this.programs.unshift(...n.map(t=>({kind:"copy",src:t.src,dst:t.dst,srcOffset:t.srcOffset,dstOffset:0,byteLength:t.byteLength})))}enqueue(n){this.rt.enqueuePreparedProgramSequence(n)}disposeBuild(){for(let n of this.cleanups)n();this.programs=[],this.cleanups=[]}async flush(n=!0){if(this.programs.length===0)return;let t=this.timing?performance.now():0;await this.rt.runProgramSequence(this.programs,{wait:n}),this.timing&&(this.flushMs+=performance.now()-t);for(let r of this.cleanups)r();this.programs=[],this.cleanups=[]}};var oe={rms:ae("com.xenova.RMSNorm"),rope:ae("com.xenova.Rope1d"),mul:ae("com.xenova.MulBroadcast"),strided:ae("com.xenova.StridedCopy"),add:ae("com.xenova.AddInPlace"),qatMatmul:ae("com.xenova.gemma4.QatMatMul"),qatEmbed:ae("com.xenova.gemma4.QatEmbedGather"),attn:ae("com.xenova.gemma4.Attention"),argmax:ae("com.xenova.gemma4.ArgMax"),srq:ae("com.xenova.gemma4.SrqQuantize"),normAdd:ae("com.xenova.gemma4.DecodeNormAdd"),pleGate:ae("com.xenova.gemma4.PleGate"),gateUpNorm:ae("com.xenova.gemma4.DecodeGateUpNorm"),denseGemv:ae("com.xenova.gemma4.DenseGemv"),qkNormRope:ae("com.xenova.gemma4.DecodeQkNormRope"),pleGateFused:ae("com.xenova.gemma4.DecodePleGate"),rmsSrq:ae("com.xenova.gemma4.DecodeRmsSrq"),normAddNorm:ae("com.xenova.gemma4.DecodeNormAddNorm"),decodeAttn:ae("com.xenova.gemma4.DecodeAttention"),downNormAdd:ae("com.xenova.gemma4.DecodeDownNormAdd"),pleProjNorm:ae("com.xenova.gemma4.DecodePleProjNorm"),oprojNorm:ae("com.xenova.gemma4.DecodeOprojNorm"),qkvProj:ae("com.xenova.gemma4.DecodeQkvProj")},hn=e=>1<(1<>1,i=new Float32Array(n*o),u=new Float32Array(n*o),l=new Float32Array(o);for(let c=0;c>1,i=n.global_head_dim>>1;return{cosSlidingT:e.tensorFromTypedArray("float32",[t,o],a.cos),sinSlidingT:e.tensorFromTypedArray("float32",[t,o],a.sin),cosFullT:e.tensorFromTypedArray("float32",[t,i],s.cos),sinFullT:e.tensorFromTypedArray("float32",[t,i],s.sin)}},write(e,n,t,r,a){let{sliding:s,full:o}=ho(n,r,a);e.writeBuffer(t.cosSlidingT.buffer,0,s.cos),e.writeBuffer(t.sinSlidingT.buffer,0,s.sin),e.writeBuffer(t.cosFullT.buffer,0,o.cos),e.writeBuffer(t.sinFullT.buffer,0,o.sin)}};function ho(e,n,t){let r=e.head_dim>>1,a=Math.trunc(e.fullPartialRotaryFactor*e.global_head_dim/2);return{sliding:go(n,t,e.head_dim,e.slidingRopeTheta,r),full:go(n,t,e.global_head_dim,e.fullRopeTheta,a)}}async function nn(e,n){let t=await e.readTensor(n);return t instanceof Float32Array?new Float32Array(t):Float32Array.from(t)}async function Or(e,n,t,r,a=!1,s,o=!0){let{rt:i,config:u,weights:l}=e,c=n.length,d=u.hidden_size,p=u.num_hidden_layers,f=u.hidden_size_per_layer_input,m=p*f,_=u.rms_norm_eps,E=u.num_attention_heads,b=u.vocab_size,F=E*u.global_head_dim,q=u.num_key_value_heads,G=q*u.global_head_dim,C=u.intermediate_size*2,T=new Xe(i),U=[],P=(z,j)=>{let ne=i.empty("float32",z,j);return U.push(ne),ne},N=(z,j)=>{let ne=i.tensorFromTypedArray(j instanceof Uint32Array?"uint32":"float32",z,j);return U.push(ne),ne},R=a?{hiddenStates:[],perLayerInputs:new Float32Array(0),lastHidden:new Float32Array(0),allLogits:new Float32Array(0)}:void 0,V=s?async(z,j)=>{await T.flush(),s.set(z,await nn(i,j))}:null;try{let z=N([1],new Float32Array([1/Math.sqrt(d)])),j=N([1],new Float32Array([Math.SQRT1_2])),ne=N([c],n),Q=P([c,d],"g4-hidden"),ve=P([c,m],"g4-ple"),Z=P([c,d],"g4-normed"),g=P([c,F],"g4-q"),w=P([c,F],"g4-qn"),S=P([c,G],"g4-k"),X=P([c,G],"g4-kn"),Be=P([c,G],"g4-v"),Se=P([c,G],"g4-vn"),Te=P([c,F],"g4-attn"),Ke=P([c,d],"g4-oproj"),Ze=P([c,d],"g4-ffnormed"),ke=P([c,C],"g4-gelu"),$=P([c,d],"g4-down"),K=P([c,f],"g4-ple-slice"),M=P([c,f],"g4-ple-gate"),J=P([c,f],"g4-ple-gelu"),xe=P([c,d],"g4-ple-projout"),k=P([c,d],"g4-aqH"),fe=P([c,F],"g4-aqQ"),pe=P([c,C],"g4-aqI"),ue=P([c,d],"g4-nrm-tail");T.qatEmbed({idsT:ne,bitsT:l.embedTokens.bitsT,scaleT:l.embedTokens.scaleT,yT:Q,seq:c,hidden:d,vocab:b,bits:l.embedTokens.bits,groupSize:d,embedScale:u.embedScale}),R&&(await T.flush(),R.hiddenStates.push(await nn(i,Q)));{let we=P([c,m],"g4-ple-id"),H=P([c,m],"g4-ple-proj");T.qatEmbed({idsT:ne,bitsT:l.embedTokensPerLayer.bitsT,scaleT:l.embedTokensPerLayer.scaleT,yT:we,seq:c,hidden:m,vocab:u.vocab_size_per_layer_input,bits:l.embedTokensPerLayer.bits,groupSize:f,embedScale:u.perLayerEmbedScale}),T.denseGemv({aT:Q,wT:l.perLayerModelProjection,outT:H,M:c,inFeatures:d,outFeatures:m,exact:o}),T.mul({xT:H,factorT:z,count:c*m,period:1}),T.rms({xT:H,wT:l.perLayerProjectionNorm,yT:ve,rows:c*p,dim:f,eps:_,exact:o}),T.addInPlace({yT:ve,xT:we,count:c*m}),T.mul({xT:ve,factorT:j,count:c*m,period:1})}R&&(await T.flush(),R.perLayerInputs=await nn(i,ve));let me=tn.create(i,u,c,t);U.push(me.cosSlidingT,me.sinSlidingT,me.cosFullT,me.sinFullT);for(let we=0;wet-r);return n[n.length>>1]}var Gt=class extends yn{model;cache;idsT;rope;attnUni=new Map;cacheUni=new Map;constructor(n,t){super(new Xe(n.rt)),this.model=n,this.cache=t}async build(n){let{rt:t,config:r,weights:a}=this.model,s=this.col,o=r.hidden_size,i=r.num_hidden_layers,u=r.hidden_size_per_layer_input,l=i*u,c=r.rms_norm_eps,d=r.num_attention_heads,p=r.vocab_size,f=d*r.global_head_dim,m=r.num_key_value_heads,_=m*r.global_head_dim,E=r.intermediate_size*2,b=1,F=this.uploadOwned([1],new Float32Array([1/Math.sqrt(o)])),q=this.uploadOwned([1],new Float32Array([Math.SQRT1_2]));this.idsT=this.uploadOwned([b],new Uint32Array([0])),this.rope=tn.create(t,r,b,n),this.owned.push(this.rope.cosSlidingT,this.rope.sinSlidingT,this.rope.cosFullT,this.rope.sinFullT);let G=this.allocOwned([b,o],"g4d-hidden"),C=this.allocOwned([b,l],"g4d-ple"),T=this.allocOwned([b,o],"g4d-normed"),U=this.allocOwned([b,f],"g4d-q"),P=this.allocOwned([b,_],"g4d-k"),N=this.allocOwned([b,_],"g4d-kn"),R=this.allocOwned([b,_],"g4d-v"),V=this.allocOwned([b,_],"g4d-vn"),z=this.allocOwned([b,f],"g4d-attn"),j=this.allocOwned([b,o],"g4d-ffnormed","float16"),ne=this.allocOwned([b,E],"g4d-gelu","float16"),Q=this.allocOwned([b,u],"g4d-ple-gelu"),ve=this.allocOwned([b],"g4d-ff-suma"),Z=this.allocOwned([b],"g4d-n-suma"),g=this.allocOwned([b,o],"g4d-final-norm"),w=this.allocOwned([b,l],"g4d-ple-id"),S=this.allocOwned([b,l],"g4d-ple-proj"),X=this.allocOwned([1,p],"g4d-logits"),Be=($,K,M)=>{let J=$.get(K);return J||(J=t.createUniformU32(new Uint32Array(8),`${M}-${K}`),$.set(K,J)),J},Se=($,K,M,J,xe,k,fe=b,pe)=>{s.qatMatmul({aT:$,bitsT:M.bitsT,scaleT:M.scaleT,sumAT:pe,outT:xe,M:fe,inFeatures:K,outFeatures:J,bits:k,inputScale:M.inScale,outputScale:M.outScale,blockMajor:M.blockMajor})},Te=r.layers.map(($,K)=>{let M=a.layers[K];return!$.isKvShared&&!!M.kProj&&!!M.vProj&&M.kProj.bits===M.qProj.bits&&M.vProj.bits===M.qProj.bits&&!M.qProj.blockMajor&&!_e.has("qproj")&&!_e.has("kv")}),Ke=[],Ze=[],ke=[];{let $=[],K=(M,J,xe,k)=>$.push({kind:"copy",name:"g4d-weight-pack",src:M,dst:J,srcOffset:0,dstOffset:xe,byteLength:k});for(let M=0;Mr[0])}async step(n,t){let{rt:r}=this.model;if(this.writeStepInputs(n,t),yo){let s=performance.now();this.col.enqueue(this.steps);let o=performance.now();await r.queueIdle();let i=performance.now(),u=await r.readTensor(this.idsT),l=performance.now();return At.push(o-s),Rr.push(i-o),Fr.push(l-i),u[0]}return this.col.enqueue(this.steps),(await r.readTensor(this.idsT))[0]}get _diagnostics(){return{rt:this.model.rt,idsT:this.idsT,steps:this.steps,writeStepInputs:(n,t)=>this.writeStepInputs(n,t),enqueue:()=>this.col.enqueue(this.steps),measureGpuMs:()=>this.model.rt.measurePreparedSequenceGpuMs?this.model.rt.measurePreparedSequenceGpuMs(this.steps):Promise.resolve(null)}}reportTiming(){if(!yo||At.length===0)return;let n=At.slice(2),t=Rr.slice(2),r=Fr.slice(2);console.error(`[g4d] per-token median: cpu-encode=${Wr(n).toFixed(2)}ms gpu-compute=${Wr(t).toFixed(2)}ms readback=${Wr(r).toFixed(2)}ms (n=${n.length})`),At.length=0,Rr.length=0,Fr.length=0}dispose(){this.reportTiming(),super.dispose();for(let n of[...this.attnUni.values(),...this.cacheUni.values()])n.destroy?.();this.attnUni.clear(),this.cacheUni.clear()}};var Sp=()=>!1,ie=new Set("".split(",").filter(Boolean)),Ot=class extends yn{model;cache;blockLen;idsT;tokenIdT;lastRowUniform=null;rope;attn=[];cacheWrites=[];hiddenSize;constructor(n,t,r){super(new Xe(n.rt)),this.model=n,this.cache=t,this.blockLen=r,this.hiddenSize=n.config.hidden_size}async build(){let n=Sp(),{rt:t,config:r,weights:a}=this.model,s=this.col,o=this.cache,i=this.blockLen,u=0,l=r.hidden_size,c=r.num_hidden_layers,d=r.hidden_size_per_layer_input,p=c*d,f=r.rms_norm_eps,m=r.num_attention_heads,_=r.vocab_size,E=m*r.global_head_dim,b=r.num_key_value_heads,F=b*r.global_head_dim,q=r.intermediate_size*2,G=this.uploadOwned([1],new Float32Array([1/Math.sqrt(l)])),C=this.uploadOwned([1],new Float32Array([Math.SQRT1_2]));this.idsT=this.uploadOwned([i],new Uint32Array(i)),this.tokenIdT=this.uploadOwned([1],new Uint32Array(1));let T=this.allocOwned([i,l],"g4p-hidden"),U=this.allocOwned([i,p],"g4p-ple"),P=this.allocOwned([i,l],"g4p-normed"),N=this.allocOwned([i,E],"g4p-q"),R=this.allocOwned([i,E],"g4p-qn"),V=this.allocOwned([i,F],"g4p-k"),z=this.allocOwned([i,F],"g4p-kn"),j=this.allocOwned([i,F],"g4p-v"),ne=this.allocOwned([i,F],"g4p-vn"),Q=this.allocOwned([i,E],"g4p-attn"),ve=this.allocOwned([i,l],"g4p-oproj"),Z=this.allocOwned([i,l],"g4p-ffnormed"),g=this.allocOwned([i,q],"g4p-gelu"),w=this.allocOwned([i,l],"g4p-down"),S=this.allocOwned([i,d],"g4p-ple-slice"),X=this.allocOwned([i,d],"g4p-ple-gate"),Be=this.allocOwned([i,d],"g4p-ple-gelu"),Se=this.allocOwned([i,l],"g4p-ple-projout"),Te=this.allocOwned([i,l],"g4p-aqH"),Ke=this.allocOwned([i,E],"g4p-aqQ"),Ze=this.allocOwned([i,q],"g4p-aqI"),ke=this.allocOwned([i,l],"g4p-nrm-tail"),$=this.allocOwned([1,_],"g4p-logits");s.qatEmbed({idsT:this.idsT,bitsT:a.embedTokens.bitsT,scaleT:a.embedTokens.scaleT,yT:T,seq:i,hidden:l,vocab:_,bits:a.embedTokens.bits,groupSize:l,embedScale:r.embedScale});let K=this.allocOwned([i,p],"g4p-ple-id"),M=this.allocOwned([i,p],"g4p-ple-proj");s.qatEmbed({idsT:this.idsT,bitsT:a.embedTokensPerLayer.bitsT,scaleT:a.embedTokensPerLayer.scaleT,yT:K,seq:i,hidden:p,vocab:r.vocab_size_per_layer_input,bits:a.embedTokensPerLayer.bits,groupSize:d,embedScale:r.perLayerEmbedScale}),ie.has("ple")||s.denseGemv({aT:T,wT:a.perLayerModelProjection,outT:M,M:i,inFeatures:l,outFeatures:p,exact:n}),s.mul({xT:M,factorT:G,count:i*p,period:1}),ie.has("rms")||s.rms({xT:M,wT:a.perLayerProjectionNorm,yT:U,rows:i*c,dim:d,eps:f,exact:n}),s.addInPlace({yT:U,xT:K,count:i*p}),s.mul({xT:U,factorT:C,count:i*p,period:1}),this.rope=tn.create(t,r,i,u),this.owned.push(this.rope.cosSlidingT,this.rope.sinSlidingT,this.rope.cosFullT,this.rope.sinFullT);for(let fe=0;fethis.blockLen)throw new Error(`prefill block ${this.blockLen} cannot run ${n.length} tokens`);let{rt:r,config:a}=this.model,s=r.host,o=this.blockLen,i=new Uint32Array(o);i.set(n),s.writeBuffer(this.idsT.buffer,0,i),tn.write(s,a,this.rope,t,o);let u=a.num_attention_heads,l=a.num_key_value_heads,c=t+o;for(let f of this.attn)s.writeBuffer(f.buffer,0,new Uint32Array([o,c,t,u,l,f.window,0,0]));for(let f of this.cacheWrites)s.writeBuffer(f.buffer,0,new Uint32Array([o,f.kv,f.kv,0,f.kv,t*f.kv,0,0]));let d=this.hiddenSize;return s.writeBuffer(this.lastRowUniform,0,new Uint32Array([1,d,d,(n.length-1)*d,d,0,0,0])),this.col.enqueue(this.steps),(await r.readTensor(this.tokenIdT))[0]}};async function*wo(e){let n=[];for(;n.length0;){let t=n.shift();e.shouldSubmit()&&n.lengththis.#i(t)}}catch(r){throw this.#i(t),r}}#i(n){if(n.maxLength===Dn.defaultCapacity(this.config)&&this.#e.length<2){this.#e.push(n);return}n.dispose()}async#s(n,t){let r=this.#t.get(n);return r||(r=new Gt(this,n),await r.build(t),this.#t.set(n,r),this.#n.push(r)),r}async#o(n,t,r){if(r+t.length<=n.maxLength){let u=this.#a.get(n);if(!u){u=new Map,this.#a.set(n,u);let p=256;for(let f of[32,128,256]){if(f>n.maxLength||f>p)continue;let m=new Ot(this,n,f);await m.build(),u.set(f,m),this.#r.push(m)}}let l=0,c=r,d=0;for(;l192&&u.has(256)?256:p>96&&u.has(128)?128:32,m=Math.min(p,f);if(c+f>n.maxLength||!u.has(f))return(await Or(this,t.subarray(l),c,n)).nextToken;let _=0;d=await u.get(f).run(t.subarray(l,l+m),c),l+=m,c+=m}return d}return(await Or(this,t,r,n)).nextToken}async*streamTokenIdsFromCache(n){let t=n.generation_state;if(!t?.cache)throw new Error("streamTokenIdsFromCache requires generation_state.cache");yield*this.#u(To(n.input_ids),t.cache,n)}async*streamTokenIds(n){let t=this.createGenerationState(n.generation_state??{});try{yield*this.#u(To(n.input_ids),t.cache,n)}finally{this.#i(t.cache)}}async*#u(n,t,r){let{maxNewTokens:a,eosTokenId:s,stopOnEos:o,onPrefillDone:i}=_o(r);if(n.length===0)throw new Error("streamTokenIds requires at least one input token");let u=t.get_seq_length(),l=0,c=await this.#o(t,n,u);l&&console.error(`[ttft] #prefill total ${(performance.now()-l).toFixed(2)}ms (tokens=${n.length})`),t.advance(n.length),u=t.get_seq_length(),i?.({tokens:n.length,cache_length:u});let d=c,p=0,f=null;try{if(vo>1){if(o&&Rt(d,s)||(yield d,p+=1,p>=a))return;let m=f=await this.#s(t,u),_=a-p,E=0;yield*wo({depth:vo,shouldSubmit:()=>E<_,submit:()=>{let b={result:m.submitStep(E===0?d:null,u+E)};return E+=1,b},accept:function*(b,F){return t.advance(1),o&&Rt(F,s)?!0:(yield F,p+=1,p>=a)}});return}for(;p=a));){f||(f=await this.#s(t,u));let m=await f.step(d,u);t.advance(1),u=t.get_seq_length(),d=m}}finally{f?.reportTiming()}}dispose(){for(let n of this.#n)n.dispose();for(let n of this.#r)n.dispose();for(let n of this.#e)n.dispose();this.#e.length=0,en(this.weights)}};var So="google/gemma-4-E2B-it-qat-mobile-transformers",kp="https://huggingface.co",xp=[1,106];function Ep(e,n="main"){let t=e??So;return/^https?:/i.test(t)||t.startsWith("/")||t.startsWith(".")?t:`${kp}/${t}/resolve/${n}`}var Mr=class e{static DEFAULT_MODEL_ID=So;#e;#t;#n;#a;#r;#i;#s;#o;#u=[];#l=!1;constructor(n){this.#e=n.runtime,this.#t=n.ownsRuntime,this.#n=n.model,this.#a=n.tokenizer,this.#r=n.chatTemplate,this.#i=n.tokenizerConfig,this.#s=n.eosTokenIds,this.#o=n.model.createGenerationState({})}static async load(n=null,t={}){let r=t.onProgress??(()=>{}),a=Ep(n,t.revision??"main"),s=t.fetch??(t.accessToken?Op(t.accessToken):void 0),o={cache:t.cache,force:t.force,cacheName:t.cacheName,fetch:s,signal:t.signal};r({status:"init",message:"Requesting WebGPU device"});let i=t.runtime??await vs(t.runtimeOptions??{}),u=!t.runtime;i.captureShaders=!0;try{r({status:"tokenizer",message:"Loading tokenizer"});let{tokenizer:l,chatTemplate:c,tokenizerConfig:d}=await Pp(a,o),p=await Ap(a,o);r({status:"weights",kind:"bytes",message:"Downloading weights",loaded:0,total:void 0});let f=await Ft.fromSnapshot(i,a,mn,{cache:t.cache,force:t.force,cacheName:t.cacheName,fetch:s,signal:t.signal,onProgress:m=>{let _=m;if(bn(_.processed)){r({status:"weights",kind:"tensors",loaded:_.processed,total:bn(_.total)?_.total:void 0,fraction:bn(_.total)&&_.total>0?_.processed/_.total:void 0,message:_.label});return}bn(_.loaded)&&r({status:"weights",kind:"bytes",loaded:_.loaded,total:bn(_.total)?_.total:null,fraction:bn(_.total)&&_.total>0?_.loaded/_.total:void 0,fromCache:_.fromCache,message:_.fromCache?"Loading cached weights":"Downloading weights"})}});return r({status:"ready",message:"Ready",fraction:1}),new e({runtime:i,ownsRuntime:u,model:f,tokenizer:l,chatTemplate:c,tokenizerConfig:d,eosTokenIds:p})}catch(l){throw u&&await i.destroy(),l}}get runtime(){return this.#e}encodePrompt(n){let t=this.#r.render({messages:n,tools:null,bos_token:this.#i.bos_token,eos_token:this.#i.eos_token,add_generation_prompt:!0});return this.#a.encode(t,{add_special_tokens:!1}).ids}async*generate(n,t={}){if(this.#l)throw new Error("Gemma4Mobile has been disposed");let r=t.maxNewTokens??512,a=t.eosTokenId??this.#s,s=this.encodePrompt(n),o=Gp(this.#u,s);o!==this.#u.length&&(this.#c(),o=0);let i=s.slice(o);i.length===0&&(this.#c(),i=s.slice());let u=[],l="",c=!1;try{for await(let d of this.#n.streamTokenIdsFromCache({input_ids:[i],generation_state:this.#o,max_new_tokens:r,eos_token_id:a,stop_on_eos:!0})){if(t.signal?.aborted){c=!0;break}u.push(d);let p=this.#a.decode(u,{skip_special_tokens:!0}),f=p.startsWith(l)?p.slice(l.length):this.#a.decode([d],{skip_special_tokens:!0});l=p,yield{token:d,delta:f,text:l}}}finally{if(c)this.#c();else{let d=u.length{try{return n.features.has(a)}catch{return!1}};return{vendor:t.vendor??"",architecture:t.architecture??"",device:t.device??"",description:t.description??"",isFallbackAdapter:t.isFallbackAdapter===!0,subgroupMinSize:t.subgroupMinSize,subgroupMaxSize:t.subgroupMaxSize,features:{shaderF16:r("shader-f16"),subgroups:r("subgroups"),subgroupMatrix:r("chromium-experimental-subgroup-matrix"),timestampQuery:r("timestamp-query")}}}get _model(){return this.#n}get _generationState(){return this.#o}get _eosTokenIds(){return this.#s}get _disposed(){return this.#l}reset(){this.#c()}#c(){this.#o.cache.truncate(0),this.#u=[]}dispose(){this.#l||(this.#l=!0,this.#n.dispose(),this.#t&&this.#e.destroy())}};async function Pp(e,n){let t=await mn.readJsonResource(e,"tokenizer.json",n),r=await mn.readJsonResource(e,"tokenizer_config.json",n),a=new fa(t,r),s=typeof r.chat_template=="string"?r.chat_template:await mn.readTextResourceOptional(e,"chat_template.jinja",n);if(!s)throw new Error("Gemma4 tokenizer is missing a chat_template (tokenizer_config.json / chat_template.jinja)");return{tokenizer:a,chatTemplate:new Hn(s),tokenizerConfig:r}}async function Ap(e,n){let r=(await mn.readJsonResourceOptional(e,"generation_config.json",n))?.eos_token_id;return typeof r=="number"?[r]:Array.isArray(r)&&r.length>0?r:[...xp]}function Gp(e,n){let t=Math.min(e.length,n.length),r=0;for(;r{let r=new Headers(t.headers);return r.set("Authorization",`Bearer ${e}`),globalThis.fetch(n,{...t,headers:r})}}var gy=Mr;export{So as DEFAULT_MODEL_ID,Mr as Gemma4Mobile,gy as default,Ep as resolveModelRoot}; +`]]}]])});function ae(e,n={}){let r=ss(e);return new Mn(r.manifest,{...n,assets:r.assets})}function ss(e){let n=Nc.get(e);if(n){let t=new Map(Cc);for(let[a,s]of n.assets)t.set(a,s);return{manifest:n.manifest,assets:Je(t)}}let r=ts.get(e);if(r){let t=new Map(rs);for(let[a,s]of r.assets)t.set(a,s);return{manifest:r.manifest,assets:Je(t)}}return jc(e)}function os(e){let n=new Set;for(let r of ar(e,""))for(let t of is(r))n.add(t);return n}function is(e){let n=new Set;for(let r of e.passes??[])zc(n,r);return n}function zc(e,n){if(n.source!==void 0){n.source.kind==="template"&&n.source.shader&&e.add(n.source.shader);return}n.shader&&e.add(n.shader)}function jc(e){throw new Error(`WebGPU op package ${e} is not embedded in this runtime`)}function ct(e,n){let r=[],t=a=>{let s=new URL(a,e);for(let o of n(s,{withFileTypes:!0})){let i=`${a}${o.name}`;o.isDirectory()?t(`${i}/`):o.isFile()&&$c(i)&&r.push(i)}};return t(""),r.sort((a,s)=>a.localeCompare(s))}function us(e,n){let r=new URL(pr,e);return ct(r,n).map(t=>`${pr}${t}`)}function ls(e){return e.replaceAll("\\","/").startsWith(pr)}function $c(e){return e.endsWith(".wgsl")||e.endsWith(".wgsl.jinja")}var pr,Cc,Nc,cs=he(()=>{"use strict";or();Bn();as();pr="ops/_shared/",Cc=new Map,Nc=new Map});var ds=he(()=>{"use strict";Bn()});var fr=he(()=>{"use strict";kn();An();nr();rr();nt();or();cs();ds();Bn();Bn();it()});function ps(e,n=[]){let r=new Set(Hc(n));return Kc.filter(t=>e.features.has(t)&&!r.has(t)).map(t=>t)}function Hc(e){return typeof e=="string"?e.split(",").map(n=>n.trim()).filter(Boolean):Array.isArray(e)?[...e]:e instanceof Set?[...e]:[]}function fs(e,n,r,t){let a=n.info,s=r?.wgslLanguageFeatures??globalThis.navigator?.gpu?.wgslLanguageFeatures,o=t?t.min:a.subgroupMinSize,i=t?t.max:a.subgroupMaxSize;return{adapterInfo:{vendor:a.vendor,architecture:a.architecture,device:a.device,description:a.description,isFallbackAdapter:a.isFallbackAdapter===!0,...typeof o=="number"?{subgroupMinSize:o}:{},...typeof i=="number"?{subgroupMaxSize:i}:{}},features:Yn(e.features),wgslLanguageFeatures:Jn(s),limits:er(e.limits)}}function ms(e){return{maxBufferSize:Number(e.limits.maxBufferSize),maxStorageBufferBindingSize:Number(e.limits.maxStorageBufferBindingSize),maxStorageBuffersPerShaderStage:Number(e.limits.maxStorageBuffersPerShaderStage),maxComputeWorkgroupStorageSize:Number(e.limits.maxComputeWorkgroupStorageSize)}}function gs({adapter:e,device:n,deviceInfo:r,destroy:t,gpu:a,syncPipelineCreation:s}){return{gpu:a,adapter:e,device:n,deviceInfo:r,createShaderModule:(i,u)=>n.createShaderModule({code:i,label:u}),createComputePipeline:s?async i=>{n.pushErrorScope("validation");let u=n.createComputePipeline(i),l=await n.popErrorScope();if(l)throw new Error(`createComputePipeline failed: ${l.message}`);return u}:i=>n.createComputePipelineAsync(i),createBuffer:i=>n.createBuffer(i),writeBuffer:(i,u,l)=>n.queue.writeBuffer(i,u,l),submit:async(i,u)=>{n.queue.submit(i),u.wait&&await n.queue.onSubmittedWorkDone()},mapRead:async(i,u,l)=>{await i.mapAsync(GPUMapMode.READ,u,l);let c=i.getMappedRange(u,l).slice(0);return i.unmap(),c},pushErrorScope:i=>n.pushErrorScope(i),popErrorScope:()=>n.popErrorScope(),destroy:t}}var Kc,hs=he(()=>{"use strict";fr();Kc=["shader-f16","subgroups","chromium-experimental-subgroup-matrix","timestamp-query","texture-formats-tier1","texture-formats-tier2"]});Br();var Si=class{constructor(e){this.trie=this._build_trie(e)}_build_trie(e){let n=Object.create(null);for(let r of e){let t=n;for(let a=0;at&&n.push(e.slice(t,a)),n.push(o),a+=o.length,t=a):++a}return t{let e=[...Array.from({length:94},(a,s)=>s+33),...Array.from({length:12},(a,s)=>s+161),...Array.from({length:82},(a,s)=>s+174)],n=e.slice(),r=0;for(let a=0;a<256;++a)e.includes(a)||(e.push(a),n.push(256+r),r+=1);let t=n.map(a=>String.fromCharCode(a));return Object.fromEntries(e.map((a,s)=>[a,t[s]]))})(),ki=e=>Object.fromEntries(Object.entries(e).map(([n,r])=>[r,n])),Ei=ki(sa),Jt=".,!?\u2026\u3002\uFF0C\u3001\u0964\u06D4\u060C",Pi=new Map([["(?i:'s|'t|'re|'ve|'m|'ll|'d)","(?:'([sS]|[tT]|[rR][eE]|[vV][eE]|[mM]|[lL][lL]|[dD]))"],["(?i:[sdmt]|ll|ve|re)","(?:[sS]|[dD]|[mM]|[tT]|[lL][lL]|[vV][eE]|[rR][eE])"],["[^\\r\\n\\p{L}\\p{N}]?+","[^\\r\\n\\p{L}\\p{N}]?"],["[^\\s\\p{L}\\p{N}]++","[^\\s\\p{L}\\p{N}]+"],["(?>\\p{Nd}{510})","(?:\\p{Nd}{510})"],["\\p{Nd}{3}+","(?:\\p{Nd}{3})+"],["\\G",""],[` ?[^(\\s|[${Jt}])]+`,` ?[^\\s${Jt}]+`]]),Vn="\\p{P}\\u0021-\\u002F\\u003A-\\u0040\\u005B-\\u0060\\u007B-\\u007E",Ir=e=>e.replace(/ \./g,".").replace(/ \?/g,"?").replace(/ \!/g,"!").replace(/ ,/g,",").replace(/ \' /g,"'").replace(/ n't/g,"n't").replace(/ 'm/g,"'m").replace(/ 's/g,"'s").replace(/ 've/g,"'ve").replace(/ 're/g,"'re"),Qn=(e,n=!0)=>{if(e.Regex!==void 0){let r=e.Regex.replace(/\\([#&~])/g,"$1");r=r.replace(/\\A/g,"^").replace(/\\z/g,"$").replace(/\\Z/g,"(?=\\r?\\n?$)");for(let[t,a]of Pi)r=r.replaceAll(t,a);try{return new RegExp(r,"gu")}catch(t){if(!(t instanceof SyntaxError)||!t.message.toLowerCase().includes("invalid property name"))throw t;let a=!1,s=r.replace(/(\\[pP])\{([^}=]+)\}/g,(o,i,u)=>{try{return new RegExp(`\\p{${u}}`,"u"),`${i}{${u}}`}catch{return a=!0,`${i}{Script=${u}}`}});if(!a)throw t;try{return new RegExp(s,"gu")}catch{throw t}}}else if(e.String!==void 0){let r=Ai(e.String);return new RegExp(n?r:`(${r})`,"gu")}else return console.warn("Unknown pattern type:",e),null},Ai=e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),Gi=(e,n,r)=>{let t=[],a=0;for(;ae>=19968&&e<=40959||e>=13312&&e<=19903||e>=131072&&e<=173791||e>=173824&&e<=177983||e>=177984&&e<=178207||e>=178208&&e<=183983||e>=63744&&e<=64255||e>=194560&&e<=195103,Ri=e=>Number.isInteger(e)||typeof e=="bigint",Wi=e=>{let n=0;for(let r of e)++n;return n},Fi=e=>oa(e.toLowerCase()),We=(...e)=>Array.prototype.concat.apply([],e),Dr=e=>new Map(Object.entries(e)),Mi=(e,n)=>{let r=[],t=0;for(let a of e.matchAll(n)){let s=a[0];t0&&r.push(s),t=a.index+s.length}return te.replace(/\p{M}/gu,""),ea=(e,n,r=[])=>{if(!e||Array.isArray(e)||typeof e!="object")return`${n} must be a valid object`;for(let t of r)if(!(t in e))return`${n} must contain a "${t}" property`;return null},Bi=e=>e.match(/\S+/g)||[],qi=class{constructor(){let e=function(...n){return e._call(...n)};return Object.setPrototypeOf(e,new.target.prototype)}},Sn=qi,Ii=class extends Sn{constructor(e){super(),this.config=e}_call(e){return this.normalize(e)}},Ne=Ii,Di=class extends Ne{tokenize_chinese_chars(e){let n=[];for(let r=0;rr.normalize("NFKC")).join("\uFF5E"):e=e.normalize("NFKC"),e}},Ci=Li,Ni=class extends Ne{constructor(e){super(e),this.normalizers=(e.normalizers??[]).map(n=>ia(n))}normalize(e){return this.normalizers.reduce((n,r)=>r?r.normalize(n):n,e)}},zi=Ni,ji=class extends Ne{normalize(e){let n=Qn(this.config.pattern??{});return n===null?e:e.replaceAll(n,this.config.content??"")}},$i=ji,Ki=class extends Ne{constructor(){super(...arguments),this.form="NFC"}normalize(e){return e=e.normalize(this.form),e}},Xn=Ki,Hi=class extends Xn{constructor(){super(...arguments),this.form="NFC"}},Vi=Hi,Qi=class extends Xn{constructor(){super(...arguments),this.form="NFD"}},Xi=Qi,Zi=class extends Xn{constructor(){super(...arguments),this.form="NFKC"}},Yi=Zi,Ji=class extends Xn{constructor(){super(...arguments),this.form="NFKD"}},eu=Ji,nu=class extends Ne{normalize(e){return this.config.strip_left&&this.config.strip_right?e=e.trim():(this.config.strip_left&&(e=e.trimStart()),this.config.strip_right&&(e=e.trimEnd())),e}},ru=nu,tu=class extends Ne{normalize(e){return oa(e)}},au=tu,su=class extends Ne{normalize(e){return e.toLowerCase()}},ou=su,iu=class extends Ne{normalize(e){return e=this.config.prepend+e,e}},uu=iu;function lu(e){if(e===null)return null;switch(e.type){case"BertNormalizer":return new Ui(e);case"Precompiled":return new Ci(e);case"Sequence":return new zi(e);case"Replace":return new $i(e);case"NFC":return new Vi(e);case"NFD":return new Xi(e);case"NFKC":return new Yi(e);case"NFKD":return new eu(e);case"Strip":return new ru(e);case"StripAccents":return new au(e);case"Lowercase":return new ou(e);case"Prepend":return new uu(e);default:throw new Error(`Unknown Normalizer type: ${e.type}`)}}var ia=lu,cu=class extends Sn{pre_tokenize(e,n){return(Array.isArray(e)?e.map(r=>this.pre_tokenize_text(r,n)):this.pre_tokenize_text(e,n)).flat()}_call(e,n){return this.pre_tokenize(e,n)}},Fe=cu,du=class extends Fe{constructor(e){super(),this.config=e,this.add_prefix_space=this.config.add_prefix_space??!1,this.trim_offsets=this.config.trim_offsets??!1,this.use_regex=this.config.use_regex??!0,this.pattern=/'s|'t|'re|'ve|'m|'ll|'d| ?\p{L}+| ?\p{N}+| ?[^\s\p{L}\p{N}]+|\s+(?!\S)|\s+/gu,this.byte_encoder=sa,this.text_encoder=new TextEncoder}pre_tokenize_text(e,n){return this.add_prefix_space&&!e.startsWith(" ")&&(e=" "+e),(this.use_regex?e.match(this.pattern)||[]:[e]).map(t=>Array.from(this.text_encoder.encode(t),a=>this.byte_encoder[a]).join(""))}},pu=du,fu=class extends Fe{pre_tokenize_text(e,n){return e.match(/\w+|[^\w\s]+/g)||[]}},mu=fu,gu=class extends Fe{constructor(e){super(),this.replacement=e.replacement??"\u2581",this.str_rep=e.str_rep||this.replacement,this.prepend_scheme=e.prepend_scheme??"always"}pre_tokenize_text(e,n){let{section_index:r=void 0}=n??{},t=e.replaceAll(" ",this.str_rep);return!t.startsWith(this.replacement)&&(this.prepend_scheme==="always"||this.prepend_scheme==="first"&&r===0)&&(t=this.str_rep+t),[t]}},hu=gu,yu=class extends Fe{constructor(e){super(),this.config=e,this.pattern=Qn(this.config.pattern??{},this.config.invert??!0)}pre_tokenize_text(e){return this.pattern===null?[]:this.config.invert?e.match(this.pattern)||[]:this.config.behavior?.toLowerCase()==="removed"?e.split(this.pattern).filter(n=>n):Mi(e,this.pattern)}},bu=yu,wu=class extends Fe{constructor(e){super(),this.config=e,this.pattern=new RegExp(`[^${Vn}]+|[${Vn}]+`,"gu")}pre_tokenize_text(e){return e.match(this.pattern)||[]}},_u=wu,vu=class extends Fe{constructor(e){super(),this.config=e;let n=`[^\\d]+|\\d${this.config.individual_digits?"":"+"}`;this.pattern=new RegExp(n,"gu")}pre_tokenize_text(e){return e.match(this.pattern)||[]}},Su=vu,Tu=class extends Fe{constructor(){super(),this.pattern=new RegExp(`[^\\s${Vn}]+|[${Vn}]`,"gu")}pre_tokenize_text(e,n){return e.trim().match(this.pattern)||[]}},xu=Tu,ku=class extends Fe{constructor(e){super(),this.config=e,this.pattern=Qn(this.config.pattern??{}),this.content=this.config.content??""}pre_tokenize_text(e){return this.pattern===null?[e]:[e.replaceAll(this.pattern,this.config.content??"")]}},Eu=ku,Pu=class extends Fe{constructor(e){super(),this.tokenizers=(e.pretokenizers??[]).map(n=>ua(n))}pre_tokenize_text(e,n){return this.tokenizers.reduce((r,t)=>t?t.pre_tokenize(r,n):r,[e])}},Au=Pu,Gu=class extends Fe{pre_tokenize_text(e){return Bi(e)}},Ou=Gu,Ru=class extends Fe{constructor(e){super(),this.config=e,this._length=e.length}pre_tokenize_text(e){let n=[];for(let r=0;rthis.max_input_chars_per_word){n.push(this.unk_token);continue}let a=!1,s=0,o=[];for(;s0&&(l=this.config.continuing_subword_prefix+l),this.tokens_to_ids.has(l)){u=l;break}--i}if(u===null){a=!0;break}o.push(u),s=i}a?n.push(this.unk_token):n.push(...o)}return n}},na=Bu,ra=class la{constructor(n,r){this.is_leaf=n,this.children=r}static default(){return new la(!1,new Map)}},qu=class{constructor(){this.root=ra.default()}extend(e){for(let n of e)this.push(n)}push(e){let n=this.root;for(let r of e){let t=n.children.get(r);t===void 0&&(t=ra.default(),n.children.set(r,t)),n=t}n.is_leaf=!0}*common_prefix_search(e){let n=this.root;if(n===void 0)return;let r="";for(let t of e){if(r+=t,n=n.children.get(t),n===void 0)return;n.is_leaf&&(yield r)}}},Iu=qu,qr=class ca{constructor(n,r,t,a,s){this.token_id=n,this.node_id=r,this.pos=t,this.length=a,this.score=s,this.prev=null,this.backtrace_score=0}clone(){let n=new ca(this.token_id,this.node_id,this.pos,this.length,this.score);return n.prev=this.prev,n.backtrace_score=this.backtrace_score,n}},Du=class{constructor(e,n,r){this.chars=Array.from(e),this.len=this.chars.length,this.bos_token_id=n,this.eos_token_id=r,this.nodes=[],this.begin_nodes=Array.from({length:this.len+1},()=>[]),this.end_nodes=Array.from({length:this.len+1},()=>[]);let t=new qr(this.bos_token_id??0,0,0,0,0),a=new qr(this.eos_token_id??0,1,this.len,0,0);this.nodes.push(t.clone()),this.nodes.push(a.clone()),this.begin_nodes[this.len].push(a),this.end_nodes[0].push(t)}insert(e,n,r,t){let a=this.nodes.length,s=new qr(t,a,e,n,r);this.begin_nodes[e].push(s),this.end_nodes[e+n].push(s),this.nodes.push(s)}viterbi(){let e=this.len,n=0;for(;n<=e;){if(this.begin_nodes[n].length==0)return[];for(let o of this.begin_nodes[n]){o.prev=null;let i=0,u=null;for(let l of this.end_nodes[n]){let c=l.backtrace_score+o.score;(u===null||c>i)&&(u=l.clone(),i=c)}if(u!==null)o.prev=u,o.backtrace_score=i;else return[]}++n}let r=[],a=this.begin_nodes[e][0].prev;if(a===null)return[];let s=a.clone();for(;s.prev!==null;)r.push(s.clone()),s=s.clone().prev.clone();return r.reverse(),r}piece(e){return this.chars.slice(e.pos,e.pos+e.length).join("")}tokens(){return this.viterbi().map(n=>this.piece(n))}token_ids(){return this.viterbi().map(n=>n.token_id)}},Uu=Du;function Lu(e){if(e.length===0)throw new Error("Array must not be empty");let n=e[0],r=0;for(let t=1;t[t,a])),this.bos_token=" ",this.bos_token_id=this.tokens_to_ids.get(this.bos_token),this.eos_token=n,this.eos_token_id=this.tokens_to_ids.get(this.eos_token),this.unk_token=this.vocab[this.unk_token_id],this.min_score=Lu(this.scores)[0],this.unk_score=this.min_score-10,this.scores[this.unk_token_id]=this.unk_score,this.trie=new Iu,this.trie.extend(this.vocab),this.fuse_unk=!0}populate_nodes(e){let n=e.chars,r=1,t=0;for(;tr>t,n=1/0){this._heap=[],this._comparator=e,this._max_size=n}get size(){return this._heap.length}is_empty(){return this.size===0}peek(){return this._heap[0]}push(...e){return this.extend(e)}extend(e){for(let n of e)if(this.size0&&this._swap(0,n),this._heap.pop(),this._sift_down(),e}replace(e){let n=this.peek();return this._heap[0]=e,this._sift_down(),n}_parent(e){return(e+1>>>1)-1}_left(e){return(e<<1)+1}_right(e){return e+1<<1}_greater(e,n){return this._comparator(this._heap[e],this._heap[n])}_swap(e,n){let r=this._heap[e];this._heap[e]=this._heap[n],this._heap[n]=r}_sift_up(){this._sift_up_from(this.size-1)}_sift_up_from(e){for(;e>0&&this._greater(e,this._parent(e));)this._swap(e,this._parent(e)),e=this._parent(e)}_sift_down(){let e=0;for(;this._left(e)this.capacity&&this.cache.delete(this.cache.keys().next().value)}clear(){this.cache.clear()}},$u=ju,Ku=class extends Zn{constructor(e){super(e),this.tokens_to_ids=Dr(e.vocab),this.unk_token_id=this.tokens_to_ids.get(e.unk_token),this.unk_token=e.unk_token,this.vocab=new Array(this.tokens_to_ids.size);for(let[r,t]of this.tokens_to_ids)this.vocab[t]=r;let n=Array.isArray(e.merges[0]);this.merges=n?e.merges:e.merges.map(r=>r.split(" ",2)),this.bpe_ranks=new Map(this.merges.map((r,t)=>[JSON.stringify(r),t])),this.end_of_word_suffix=e.end_of_word_suffix,this.continuing_subword_suffix=e.continuing_subword_suffix??null,this.byte_fallback=this.config.byte_fallback??!1,this.byte_fallback&&(this.text_encoder=new TextEncoder),this.ignore_merges=this.config.ignore_merges??!1,this.max_length_to_cache=256,this.cache_capacity=1e4,this.cache=new $u(this.cache_capacity)}clear_cache(){this.cache.clear()}bpe(e){if(e.length===0)return[];let n=this.cache.get(e);if(n!==void 0)return n;let r=Array.from(e);this.end_of_word_suffix&&(r[r.length-1]+=this.end_of_word_suffix);let t=[];if(r.length>1){let a=new zu((i,u)=>i.score`<0x${o.toString(16).toUpperCase().padStart(2,"0")}>`);s.every(o=>this.tokens_to_ids.has(o))?n.push(...s):this.unk_token!=null&&n.push(this.unk_token)}else this.unk_token!=null&&n.push(this.unk_token)}return n}},aa=Ku,Hu=class extends Zn{constructor(e,n){super(e);let r=e.vocab;this.tokens_to_ids=Dr(n.target_lang?r[n.target_lang]:r),this.bos_token=n.bos_token,this.bos_token_id=this.tokens_to_ids.get(this.bos_token),this.eos_token=n.eos_token,this.eos_token_id=this.tokens_to_ids.get(this.eos_token),this.pad_token=n.pad_token,this.pad_token_id=this.tokens_to_ids.get(this.pad_token),this.unk_token=n.unk_token,this.unk_token_id=this.tokens_to_ids.get(this.unk_token),this.vocab=new Array(this.tokens_to_ids.size);for(let[t,a]of this.tokens_to_ids)this.vocab[a]=t}encode(e){return e}},Vu=Hu;function Qu(e,n){switch(e.type){case"WordPiece":return new na(e);case"Unigram":return new ta(e,n.eos_token);case"BPE":return new aa(e);default:if(e.vocab)return Array.isArray(e.vocab)?new ta(e,n.eos_token):Object.hasOwn(e,"continuing_subword_prefix")&&Object.hasOwn(e,"unk_token")?Object.hasOwn(e,"merges")?new aa(e):new na(e):new Vu(e,{target_lang:n.target_lang,bos_token:n.bos_token,eos_token:n.eos_token,pad_token:n.pad_token,unk_token:n.unk_token});throw new Error(`Unknown TokenizerModel type: ${e?.type}`)}}var Xu=Qu,Zu=class extends Sn{constructor(e){super(),this.config=e}_call(e,...n){return this.post_process(e,...n)}},Tn=Zu,Yu=class extends Tn{post_process(e,n=null,r=!0){let t=n===null?this.config.single:this.config.pair,a=[],s=[];for(let o of t)"SpecialToken"in o?r&&(a.push(o.SpecialToken.id),s.push(o.SpecialToken.type_id)):"Sequence"in o&&(o.Sequence.id==="A"?(a=We(a,e),s=We(s,new Array(e.length).fill(o.Sequence.type_id))):o.Sequence.id==="B"&&(a=We(a,n),s=We(s,new Array(n.length).fill(o.Sequence.type_id))));return{tokens:a,token_type_ids:s}}},Ju=Yu,el=class extends Tn{post_process(e,n=null){return{tokens:e,tokens_pair:n}}},nl=el,rl=class extends Tn{constructor(e){super(e),this.sep=e.sep,this.cls=e.cls}post_process(e,n=null,r=!0){r&&(e=We([this.cls[0]],e,[this.sep[0]]));let t=new Array(e.length).fill(0);if(n){let a=[],s=r?[this.sep[0]]:[];e=We(e,a,n,s),t=We(t,new Array(n.length+a.length+s.length).fill(1))}return{tokens:e,token_type_ids:t}}},tl=rl,al=class extends Tn{constructor(e){super(e),this.sep=e.sep,this.cls=e.cls}post_process(e,n,r=!0){r&&(e=We([this.cls[0]],e,[this.sep[0]]));let t=new Array(e.length).fill(0);if(n){let a=r?[this.sep[0]]:[],s=r?[this.sep[0]]:[];e=We(e,a,n,s),t=We(t,new Array(n.length+a.length+s.length).fill(1))}return{tokens:e,token_type_ids:t}}},sl=al,ol=class extends Tn{constructor(e){super(e),this.processors=(e.processors??[]).map(n=>da(n))}post_process(e,n=null,r=!0){let t={tokens:e,tokens_pair:n};for(let a of this.processors)t=a.post_process(t.tokens,t.tokens_pair,r);return t}},il=ol;function ul(e){if(e===null)return null;switch(e.type){case"TemplateProcessing":return new Ju(e);case"ByteLevel":return new nl(e);case"BertProcessing":return new tl(e);case"RobertaProcessing":return new sl(e);case"Sequence":return new il(e);default:throw new Error(`Unknown PostProcessor type: ${e.type}`)}}var da=ul,ll=class extends Sn{constructor(e){super(),this.config=e,this.added_tokens=[],this.end_of_word_suffix=null,this.trim_offsets="trim_offsets"in e?e.trim_offsets:!1}_call(e){return this.decode(e)}decode(e){return this.decode_chain(e).join("")}},Ue=ll,cl=class extends Ue{constructor(e){super(e),this.byte_decoder=Ei,this.text_decoder=new TextDecoder("utf-8",{fatal:!1,ignoreBOM:!0}),this.end_of_word_suffix=null}convert_tokens_to_string(e){let n=e.join(""),r=new Uint8Array([...n].map(t=>this.byte_decoder[t]));return this.text_decoder.decode(r)}decode_chain(e){let n=[],r=[];for(let t of e)this.added_tokens.find(a=>a.content===t)!==void 0?(r.length>0&&(n.push(this.convert_tokens_to_string(r)),r=[]),n.push(t)):r.push(t);return r.length>0&&n.push(this.convert_tokens_to_string(r)),n}},dl=cl,pl=class extends Ue{constructor(e){super(e),this.cleanup=e.cleanup}decode_chain(e){return e.map((n,r)=>{if(r!==0){let t=this.config.prefix;t&&n.startsWith(t)?n=n.replace(t,""):n=" "+n}return this.cleanup&&(n=Ir(n)),n})}},fl=pl,ml=class extends Ue{constructor(e){super(e),this.replacement=e.replacement??"\u2581"}decode_chain(e){let n=[];for(let r=0;rn.replaceAll(this.suffix,r===e.length-1?"":" "))}},yl=hl,bl=class extends Ue{constructor(e){super(e),this.pad_token=e.pad_token??"",this.word_delimiter_token=e.word_delimiter_token??"",this.cleanup=e.cleanup}convert_tokens_to_string(e){if(e.length===0)return"";let n=[e[0]];for(let a=1;aa!==this.pad_token).join("");return this.cleanup&&(t=Ir(t).replaceAll(this.word_delimiter_token," ").trim()),t}decode_chain(e){return[this.convert_tokens_to_string(e)]}},wl=bl,_l=class extends Ue{constructor(e){super(e),this.decoders=(e.decoders??[]).map(n=>pa(n))}decode_chain(e){return this.decoders.reduce((n,r)=>r.decode_chain(n),e)}},vl=_l,Sl=class extends Ue{decode_chain(e){let n=Qn(this.config.pattern),r=this.config.content??"";return n===null?e:e.map(t=>t.replaceAll(n,r))}},Tl=Sl,xl=class extends Ue{decode_chain(e){return[e.join("")]}},kl=xl,El=class extends Ue{constructor(e){super(e),this.content=e.content??"",this.start=e.start??0,this.stop=e.stop??0}decode_chain(e){return e.map(n=>{let r=0;for(let a=0;a")){let s=parseInt(t.slice(3,5),16);isNaN(s)||(a=s)}if(a!==null)r.push(a);else{if(r.length>0){let s=this.text_decoder.decode(Uint8Array.from(r));n.push(s),r=[]}n.push(t)}}if(r.length>0){let t=this.text_decoder.decode(Uint8Array.from(r));n.push(t),r=[]}return n}},Gl=Al;function Ol(e){if(e===null)return null;switch(e.type){case"ByteLevel":return new dl(e);case"WordPiece":return new fl(e);case"Metaspace":return new gl(e);case"BPEDecoder":return new yl(e);case"CTC":return new wl(e);case"Sequence":return new vl(e);case"Replace":return new Tl(e);case"Fuse":return new kl(e);case"Strip":return new Pl(e);case"ByteFallback":return new Gl(e);default:throw new Error(`Unknown Decoder type: ${e.type}`)}}var pa=Ol,Rl=class{constructor(e,n){let r=ea(e,"Tokenizer",["model","decoder","post_processor","pre_tokenizer","normalizer"]);if(r)throw new Error(r);let t=ea(n,"Config");if(t)throw new Error(t);this.tokenizer=e,this.config=n,this.normalizer=ia(this.tokenizer.normalizer),this.pre_tokenizer=ua(this.tokenizer.pre_tokenizer),this.model=Xu(this.tokenizer.model,this.config),this.post_processor=da(this.tokenizer.post_processor),this.decoder=pa(this.tokenizer.decoder),this.special_tokens=[],this.all_special_ids=[],this.added_tokens=[];let a=[],s=[];this.added_tokens_map=new Map;for(let o of this.tokenizer.added_tokens){let i=new xi(o);if(this.added_tokens.push(i),this.model.tokens_to_ids.set(i.content,i.id),this.model.vocab[i.id]=i.content,i.special&&(this.special_tokens.push(i.content),this.all_special_ids.push(i.id)),this.added_tokens_map.set(i.content,i),i.normalized&&this.normalizer!==null){let u=this.normalizer(i.content);s.push(u),this.added_tokens_map.set(u,i)}else a.push(i.content)}(this.config.additional_special_tokens??[]).forEach(o=>{this.special_tokens.includes(o)||this.special_tokens.push(o)}),this.decoder&&(this.decoder.added_tokens=this.added_tokens,this.decoder.end_of_word_suffix=this.model.end_of_word_suffix),this.splitter_unnormalized=new Yt(a),this.splitter_normalized=new Yt(s),this.remove_space=this.config.remove_space,this.clean_up_tokenization_spaces=this.config.clean_up_tokenization_spaces??!0,this.do_lowercase_and_remove_accent=this.config.do_lowercase_and_remove_accent??!1}encode(e,{text_pair:n=null,add_special_tokens:r=!0,return_token_type_ids:t=null}={}){let{tokens:a,token_type_ids:s}=this.tokenize_helper(e,{text_pair:n,add_special_tokens:r}),o=a.map(u=>this.added_tokens_map.get(u)?.id??this.model.tokens_to_ids.get(u)??this.model.unk_token_id),i={ids:o,tokens:a,attention_mask:new Array(o.length).fill(1)};return t&&s&&(i.token_type_ids=s),i}decode(e,n={}){if(!Array.isArray(e)||e.length===0||!Ri(e[0]))throw Error("token_ids must be a non-empty array of integers.");let r=e.map(a=>this.model.vocab[Number(a)]??this.model.unk_token);n.skip_special_tokens&&(r=r.filter(a=>!this.special_tokens.includes(a)));let t=this.decoder?this.decoder(r):r.join(" ");return this.decoder&&this.decoder.end_of_word_suffix&&(t=t.replaceAll(this.decoder.end_of_word_suffix," "),n.skip_special_tokens&&(t=t.trim())),(n.clean_up_tokenization_spaces??this.clean_up_tokenization_spaces)&&(t=Ir(t)),t}tokenize(e,{text_pair:n=null,add_special_tokens:r=!1}={}){return this.tokenize_helper(e,{text_pair:n,add_special_tokens:r}).tokens}encode_text(e){if(e===null)return null;let n=this.splitter_unnormalized.split(e);return n.forEach((r,t)=>{let a=this.added_tokens_map.get(r);a&&(a.lstrip&&t>0&&(n[t-1]=n[t-1].trimEnd()),a.rstrip&&t{if(r.length===0)return[];if(this.added_tokens_map.has(r))return[r];if(this.remove_space===!0&&(r=r.trim().split(/\s+/).join(" ")),this.do_lowercase_and_remove_accent&&(r=Fi(r)),this.normalizer!==null&&(r=this.normalizer(r)),r.length===0)return[];let a=this.splitter_normalized.split(r);return a.forEach((s,o)=>{let i=this.added_tokens_map.get(s);i&&(i.lstrip&&o>0&&(a[o-1]=a[o-1].trimEnd()),i.rstrip&&o{if(s.length===0)return[];if(this.added_tokens_map.has(s))return[s];let o=this.pre_tokenizer!==null?this.pre_tokenizer(s,{section_index:t}):[s];return this.model(o)})})}tokenize_helper(e,{text_pair:n=null,add_special_tokens:r=!0}){let t=this.encode_text(e),a=this.encode_text(n||null);return this.post_processor?this.post_processor(t,a,r):{tokens:We(t??[],a??[])}}token_to_id(e){return this.model.tokens_to_ids.get(e)}id_to_token(e){return this.model.vocab[e]}get_added_tokens_decoder(){let e=new Map;for(let n of this.added_tokens)e.set(n.id,n);return e}get_vocab(e=!0){let n=new Map;for(let r=0;r{console.error("WebGPU uncaptured error:",a.error)}),gs({gpu:n,adapter:r,device:t,deviceInfo:fs(t,r,n),destroy:()=>t.destroy()})}Wn();var Vc=Object.freeze(["embed","qkv","qk_norm","rope_cache","attention","o_proj","conv","rms_norm","mlp","lm_head","other"]),Qc=new Set(Vc);function bs({label:e="profile",events:n=[],timestampUnit:r="ns"}={}){let t=n.map((i,u)=>Xc(i,u)),a=t.reduce((i,u)=>i+u.durationMs,0),s=ys(t,i=>i.group,a),o=ys(t.filter(i=>i.layer!==void 0),i=>`layer.${i.layer}`,a);return{label:e,timestampUnit:r,totalGpuMs:a,dispatchCount:t.length,groups:s,layers:o,events:t}}function pt({name:e="",cacheKey:n="",profile:r=null}={}){let t=Zc(n),a={model:r?.model??t.config?.model_type,phase:r?.phase??Yc(e,t),layer:r?.layer??t.layer,part:r?.part??t.part??Jc(e),...r};return a.group=nd(a.group??ed(a.part,e)),Object.fromEntries(Object.entries(a).filter(([,s])=>s!==void 0))}function Xc(e,n){let r=pt(e);return{index:n,name:e.name,cacheKey:e.cacheKey,dispatchWorkgroups:e.dispatchWorkgroups,startTimestamp:e.startTimestamp,endTimestamp:e.endTimestamp,durationMs:e.durationMs??0,model:r.model,phase:r.phase,layer:r.layer,part:r.part,group:r.group}}function ys(e,n,r){let t=new Map;for(let a of e){let s=n(a),o=t.get(s)??{group:s,dispatches:0,totalGpuMs:0};o.dispatches+=1,o.totalGpuMs+=a.durationMs,t.set(s,o)}return Array.from(t.values()).map(a=>({...a,meanGpuMs:a.dispatches>0?a.totalGpuMs/a.dispatches:0,percent:r>0?a.totalGpuMs/r*100:0})).sort((a,s)=>s.totalGpuMs-a.totalGpuMs)}function Zc(e){if(typeof e!="string")return{};let n=e.split("|weights:")[0],r=n.indexOf("{"),t=n.lastIndexOf("}"),a=r>=0&&t>r?n.slice(r,t+1):n;try{return JSON.parse(a)}catch{return{}}}function Yc(e,n){if(n.kind?.includes("decode")||e.includes("decode"))return"decode";if(n.kind?.includes("megakernel")||e.includes("causal_lm"))return"forward"}function Jc(e){return e.replace(/^llama_decode_/,"").replace(/^lfm2_decode_/,"").replace(/^llama_/,"")}function ed(e="",n=""){let r=`${e} ${n}`.toLowerCase();return r.includes("embed")?"embed":r.includes("qkv")?"qkv":r.includes("qk_head_norm")||r.includes("qk_norm")?"qk_norm":r.includes("rope_cache")?"rope_cache":r.includes("attention")?"attention":r.includes("o_proj")||r.includes("out_proj")?"o_proj":r.includes("conv")?"conv":r.includes("lm_head")||r.includes("argmax")||r.includes("final")?"lm_head":r.includes("gate")||r.includes("up")||r.includes("down_proj")?"mlp":r.includes("norm")?"rms_norm":"other"}function nd(e){return typeof e=="string"&&Qc.has(e)?e:"other"}var ln=class{runtime;dtype;shape;strides;byteOffset;layout;encoding;components;storage;buffer;size;byteLength;destroyed;constructor({runtime:n,dtype:r,shape:t,buffer:a,strides:s=Ca(t),byteOffset:o=0,layout:i,encoding:u,components:l,storage:c="buffer"}){this.runtime=n,this.dtype=r,this.shape=t,this.strides=s,this.byteOffset=o,this.layout=i,this.encoding=u,this.components=l,this.storage=c,this.buffer=a,this.size=Ve(t),this.byteLength=this.size*Rn(r),this.destroyed=!1}destroy(){this.destroyed||(this.buffer.destroy(),this.destroyed=!0)}},gr=class{host;pipelineCache;bindGroupCache;maxBindGroupCacheEntries;bufferIds;nextBufferId;profileSession;readbackPool;readbackPoolBytes;maxReadbackPoolBytes;destroyed;captureShaders;capturedShaders;constructor({host:n}){this.host=n,this.captureShaders=!1,this.capturedShaders=new Map,this.pipelineCache=new Map,this.bindGroupCache=new Map,this.maxBindGroupCacheEntries=4096,this.bufferIds=new WeakMap,this.nextBufferId=1,this.profileSession=null,this.readbackPool=new Map,this.readbackPoolBytes=0,this.maxReadbackPoolBytes=64*1024*1024,this.destroyed=!1}get device(){return this.host.deviceInfo}getRenderedShaders(){return[...this.capturedShaders].map(([n,r])=>({name:n,source:r}))}async destroy(){this.destroyed||(this.destroyed=!0,this.clearTransientCaches(),this.clearReadbackPool(),await this.host.destroy())}clearReadbackPool(){let n=0;for(let r of this.readbackPool.values())for(let t of r)t.destroy(),n++;return this.readbackPool.clear(),this.readbackPoolBytes=0,n}clearTransientCaches(){return{bindGroups:this.clearBindGroupCache()}}clearBindGroupCache(){let n=this.bindGroupCache.size;return this.bindGroupCache.clear(),n}startProfiling(n={}){if(this.profileSession!==null)throw new Error("A profiling session is already active");if(!this.device.features.has("timestamp-query"))throw new Error("Kernel profiling requires the WebGPU timestamp-query feature");this.profileSession={label:n.label??"kernel-profile",events:[]}}async stopProfiling(){if(this.profileSession===null)throw new Error("No profiling session is active");let n=this.profileSession;return this.profileSession=null,bs({label:n.label,events:n.events,timestampUnit:"ns"})}tensorFromTypedArray(n,r,t){if(!rd(n,t))throw new Error("Only float16/Uint16Array, float32/Float32Array and uint32/Uint32Array tensors are supported");let a=Ve(r);if(t.length!==a)throw new Error(`tensor data length ${t.length} does not match shape element count ${a}`);let s=this.host.createBuffer({label:"tensor",size:ft(t.byteLength),usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST|GPUBufferUsage.COPY_SRC,mappedAtCreation:!0}),o=s.getMappedRange();return t instanceof Float32Array?new Float32Array(o).set(t):t instanceof Uint16Array?new Uint16Array(o).set(t):t instanceof Int32Array?new Int32Array(o).set(t):new Uint32Array(o).set(t),s.unmap(),new ln({runtime:this,dtype:n,shape:r,buffer:s})}allocateWeightsBuffer({byteLength:n,dtype:r,shape:t,label:a="weights"}){if(!ws(r))throw new Error(`Unsupported dtype: ${r}`);if(!Number.isInteger(n)||n<0)throw new Error(`byteLength must be a nonnegative integer, got ${n}`);let s=this.host.createBuffer({label:a,size:n,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST|GPUBufferUsage.COPY_SRC});return new ln({runtime:this,dtype:r,shape:t,buffer:s})}writeWeightsRange(n,r,t){if(!(n instanceof ln))throw new Error("writeWeightsRange expects a WebGpuTensor");if(!Number.isInteger(r)||r<0)throw new Error(`byteOffset must be a nonnegative integer, got ${r}`);if(r+t.byteLength>n.byteLength)throw new Error(`write range [${r}, ${r+t.byteLength}] exceeds tensor byteLength ${n.byteLength}`);this.host.writeBuffer(n.buffer,r,t)}async copyBufferToBuffer({src:n,dst:r,srcOffset:t=0,dstOffset:a=0,byteLength:s,wait:o=!1}){if(s===0)return;let i=cn(n),u=cn(r),l=this.host.device.createCommandEncoder({label:"copyBufferToBuffer"});l.copyBufferToBuffer(i,t,u,a,s),await this.host.submit([l.finish()],{wait:o})}async queueIdle(){await this.host.device.queue.onSubmittedWorkDone()}empty(n,r,t="tensor-output"){if(!ws(n))throw new Error(`Unsupported dtype: ${n}`);let a=Ve(r)*Rn(n),s=this.host.createBuffer({label:t,size:ft(a),usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC|GPUBufferUsage.COPY_DST});return new ln({runtime:this,dtype:n,shape:r,buffer:s})}readTensor(n){if(n.byteLength===0)return n.dtype===ee.float32?Promise.resolve(new Float32Array(0)):n.dtype===ee.float16?Promise.resolve(new Uint16Array(0)):n.dtype===ee.int8?Promise.resolve(new Int32Array(0)):n.dtype===ee.int32?Promise.resolve(new Int32Array(0)):n.dtype===ee.uint8?Promise.resolve(new Uint32Array(0)):n.dtype===ee.uint32?Promise.resolve(new Uint32Array(0)):Promise.reject(new Error(`Unsupported dtype: ${n.dtype}`));let r=ft(n.byteLength),t=this.#e(r),a=this.host.device.createCommandEncoder({label:"readTensor"});a.copyBufferToBuffer(n.buffer,0,t,0,r),this.host.device.queue.submit([a.finish()]);let{dtype:s,byteLength:o}=n;return(async()=>{let i;try{i=await this.host.mapRead(t,0,r)}catch(u){throw this.#r(r,t),u}if(this.#r(r,t),r!==o&&(i=i.slice(0,o)),s===ee.float32)return new Float32Array(i);if(s===ee.float16)return new Uint16Array(i);if(s===ee.int8)return new Int32Array(i);if(s===ee.int32)return new Int32Array(i);if(s===ee.uint8)return new Uint32Array(i);if(s===ee.uint32)return new Uint32Array(i);throw new Error(`Unsupported dtype: ${s}`)})()}#e(n){let r=this.readbackPool.get(n);return r&&r.length>0?(this.readbackPoolBytes-=n,r.pop()):this.host.createBuffer({label:"tensor-readback",size:n,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ})}#r(n,r){if(this.readbackPoolBytes+n>this.maxReadbackPoolBytes){r.destroy();return}let t=this.readbackPool.get(n);t||(t=[],this.readbackPool.set(n,t)),t.push(r),this.readbackPoolBytes+=n}async runProgram(n,r={}){await this.runProgramSequence([n],r)}async runProgramSequence(n,r={}){let t=await this.prepareProgramSequence(n);await this.executePreparedProgramSequence(t,r)}async prepareProgramSequence(n){if(!Array.isArray(n)||n.length===0)throw new Error("prepareProgramSequence requires at least one program");let r=[];for(let t of n){if(td(t)){r.push(ad(t));continue}let{name:a,source:s,entryPoint:o="main",cacheKey:i=a,bindings:u,dispatchWorkgroups:l,profile:c}=t;if(typeof s!="string"||s.length===0)throw new Error("program requires WGSL source");if(!Array.isArray(u)||u.length===0)throw new Error("program requires bindings");if(!Array.isArray(l)||l.length!==3)throw new Error("program requires a 3D dispatchWorkgroups array");let d=await this.programPipeline({name:a,source:s,entryPoint:o,cacheKey:i,layoutFactory:()=>this.pipelineLayout(a,u)}),{bindGroup:p,extraBindGroups:f}=this.cachedBindGroups({name:a,cacheKey:i,pipeline:d,bindings:u});r.push({pipeline:d,bindGroup:p,...f?{extraBindGroups:f}:{},dispatchWorkgroups:l,name:a,cacheKey:i,profile:c})}return r}async executePreparedProgramSequence(n,r={}){if(!Array.isArray(n)||n.length===0)throw new Error("executePreparedProgramSequence requires at least one prepared step");let t=r.wait??!1;await this._runSteps(n,{wait:t,mergePass:!this.profileSession})}enqueuePreparedProgramSequence(n){if(!Array.isArray(n)||n.length===0)throw new Error("enqueuePreparedProgramSequence requires at least one prepared step");if(this.profileSession)throw new Error("enqueuePreparedProgramSequence cannot be used while profiling");let r=this.host.device.createCommandEncoder({label:"compute-dispatch"});_s(r,n),this.host.device.queue.submit([r.finish()])}async measurePreparedSequenceGpuMs(n){if(!this.host.device.features.has("timestamp-query"))return null;let r=this.createTimestampResources(2);try{let t=this.host.device.createCommandEncoder({label:"gpu-time-measure"});for(let l of n)l.kind==="copy"&&l.byteLength>0&&t.copyBufferToBuffer(l.src,l.srcOffset,l.dst,l.dstOffset,l.byteLength);let a=t.beginComputePass({label:"gpu-time-pass",timestampWrites:{querySet:r.querySet,beginningOfPassWriteIndex:0,endOfPassWriteIndex:1}}),s=!1,o=null,i=null;for(let l of n)if(!(l.kind==="copy"||mr(l.dispatchWorkgroups))){if(l.pipeline!==o&&(a.setPipeline(l.pipeline),o=l.pipeline),l.bindGroup!==i&&(a.setBindGroup(0,l.bindGroup),i=l.bindGroup),l.extraBindGroups)for(let c of l.extraBindGroups)a.setBindGroup(c.group,c.bindGroup),c.group===0&&(i=c.bindGroup);a.dispatchWorkgroups(l.dispatchWorkgroups[0],l.dispatchWorkgroups[1],l.dispatchWorkgroups[2]),s=!0}if(a.end(),!s)return null;t.resolveQuerySet(r.querySet,0,2,r.resolveBuffer,0),t.copyBufferToBuffer(r.resolveBuffer,0,r.readbackBuffer,0,16),await this.host.submit([t.finish()],{wait:!0});let u=await this.readTimestampBuffer(r.readbackBuffer,2);return Number(u[1]-u[0])/1e6}finally{r.querySet.destroy(),r.resolveBuffer.destroy(),r.readbackBuffer.destroy()}}createUniformU32(n,r){let t=new Uint32Array(n),a=this.host.createBuffer({label:r,size:t.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST});return this.host.writeBuffer(a,0,t),a}async _runSteps(n,{wait:r=!1,mergePass:t}){let a=!!this.profileSession,s=this.host.device.createCommandEncoder({label:a?"profiled-compute-dispatch":"compute-dispatch"});if(!a&&t){_s(s,n),await this.host.submit([s.finish()],{wait:r});return}let o=n.map((c,d)=>c.kind==="copy"||mr(c.dispatchWorkgroups)?-1:d).filter(c=>c>=0),i=a?o.length*2:0,u=a&&i>0?this.createTimestampResources(i):void 0,l=0;for(let c of n){if(c.kind==="copy"){c.byteLength>0&&s.copyBufferToBuffer(c.src,c.srcOffset,c.dst,c.dstOffset,c.byteLength);continue}if(mr(c.dispatchWorkgroups))continue;let d=s.beginComputePass({label:a?`${c.name??"compute"}-profile-pass`:"compute-pass",...a?{timestampWrites:{querySet:u.querySet,beginningOfPassWriteIndex:l*2,endOfPassWriteIndex:l*2+1}}:{}});if(d.setPipeline(c.pipeline),d.setBindGroup(0,c.bindGroup),c.extraBindGroups)for(let p of c.extraBindGroups)d.setBindGroup(p.group,p.bindGroup);d.dispatchWorkgroups(c.dispatchWorkgroups[0],c.dispatchWorkgroups[1],c.dispatchWorkgroups[2]),d.end(),l+=1}if(!a||u===void 0){await this.host.submit([s.finish()],{wait:r});return}try{s.resolveQuerySet(u.querySet,0,i,u.resolveBuffer,0),s.copyBufferToBuffer(u.resolveBuffer,0,u.readbackBuffer,0,i*8),await this.host.submit([s.finish()],{wait:r});let c=await this.readTimestampBuffer(u.readbackBuffer,i);for(let d=0;dr})}async _buildPipeline({cacheKey:n,name:r,entryPoint:t,layoutFactory:a,sourceFactory:s}){let o=this.pipelineCache.get(n);if(o)return o;let i=await s();this.captureShaders&&!this.capturedShaders.has(r)&&this.capturedShaders.set(r,i);let u=this.host.createShaderModule(i,r),l=await this.host.createComputePipeline({label:r,layout:a(),compute:{module:u,entryPoint:t}});return this.pipelineCache.set(n,l),l}cachedBindGroups({name:n,cacheKey:r,pipeline:t,bindings:a}){let s=new Map;for(let l of a){let c=l.group??0,d=s.get(c);d?d.push(l):s.set(c,[l])}let o=[...s.keys()].sort((l,c)=>l-c),i=this.buildGroupBindGroup(n,r,t,0,s.get(0)??[]),u=o.filter(l=>l!==0).map(l=>({group:l,bindGroup:this.buildGroupBindGroup(n,r,t,l,s.get(l))}));return u.length>0?{bindGroup:i,extraBindGroups:u}:{bindGroup:i}}buildGroupBindGroup(n,r,t,a,s){let o=s.map((l,c)=>{let d=sd(l),p={buffer:d,offset:l.offset??0};return l.size!==void 0&&l.size>0&&(p.size=l.size),{binding:l.binding??c,resource:p,cachePart:`${l.binding??c}:${this.bufferId(d)}:${p.offset}:${p.size??""}`}}),i=`${r}|g${a}|${o.map(l=>l.cachePart).join("|")}`,u=this.bindGroupCache.get(i);if(u===void 0&&(u=this.host.device.createBindGroup({label:`${n}-bind-group-${a}`,layout:t.getBindGroupLayout(a),entries:o.map(({binding:l,resource:c})=>({binding:l,resource:c}))}),this.bindGroupCache.set(i,u),this.bindGroupCache.size>this.maxBindGroupCacheEntries)){let l=this.bindGroupCache.keys().next().value;l!==void 0&&this.bindGroupCache.delete(l)}return u}bufferId(n){let r=this.bufferIds.get(n);return r===void 0&&(r=this.nextBufferId++,this.bufferIds.set(n,r)),r}pipelineLayout(n,r){let t=r.map((i,u)=>typeof i=="string"?{group:0,binding:u,type:i}:{group:i.group??0,binding:i.binding??u,type:i.type}),a=new Set,s=0;for(let i of t){if(!Number.isInteger(i.binding)||i.binding<0)throw new Error(`pipeline layout ${n} has invalid binding index ${i.binding}`);if(!Number.isInteger(i.group)||i.group<0)throw new Error(`pipeline layout ${n} has invalid bind group index ${i.group}`);let u=`${i.group}:${i.binding}`;if(a.has(u))throw new Error(`pipeline layout ${n} has duplicate binding index ${i.binding} in @group(${i.group})`);if(typeof i.type!="string"||i.type.length===0)throw new Error(`pipeline layout ${n} binding ${i.binding} is missing a buffer type`);a.add(u),s=Math.max(s,i.group)}let o=[];for(let i=0;i<=s;++i)o.push(this.host.device.createBindGroupLayout({label:`${n}-bgl${i}`,entries:t.filter(u=>u.group===i).map(u=>({binding:u.binding,visibility:GPUShaderStage.COMPUTE,buffer:{type:u.type}}))}));return this.host.device.createPipelineLayout({label:`${n}-layout`,bindGroupLayouts:o})}createTimestampResources(n){let r=n*8,t=this.host.device.createQuerySet({type:"timestamp",count:n}),a=this.host.createBuffer({label:"kernel-profile-timestamp-resolve",size:r,usage:GPUBufferUsage.QUERY_RESOLVE|GPUBufferUsage.COPY_SRC}),s=this.host.createBuffer({label:"kernel-profile-timestamp-readback",size:r,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ});return{querySet:t,resolveBuffer:a,readbackBuffer:s}}async readTimestampBuffer(n,r){let t=await this.host.mapRead(n,0,r*8),a=new BigUint64Array(t);return Array.from(a,s=>s)}recordProfileEvent(n,r,t){if(!this.profileSession)return;let a=t>r?t-r:0n,s=pt(n);this.profileSession.events.push({name:n.name,cacheKey:n.cacheKey,dispatchWorkgroups:n.dispatchWorkgroups,profile:n.profile,...s,startTimestamp:r.toString(),endTimestamp:t.toString(),durationMs:Number(a)/1e6})}};function rd(e,n){return e===ee.float16&&n instanceof Uint16Array||e===ee.float32&&n instanceof Float32Array||(e===ee.int8||e===ee.int32)&&n instanceof Int32Array||(e===ee.uint8||e===ee.uint32)&&n instanceof Uint32Array}function ws(e){return Object.values(ee).includes(e)}function ft(e){return Math.max(4,Math.ceil(e/4)*4)}function td(e){return e.kind==="copy"}function ad(e){if(!e.src||!e.dst)throw new Error("copy step requires src and dst (buffer or tensor)");let n=cn(e.src),r=cn(e.dst),t=e.srcOffset??0,a=e.dstOffset??0,s=e.byteLength;if(!Number.isInteger(s)||s<=0)throw new Error("copy step requires positive integer byteLength");return{kind:"copy",src:n,dst:r,srcOffset:t,dstOffset:a,byteLength:s,name:e.name??"copy"}}function sd(e){if(e.tensor!==void 0&&e.tensor!==null)return cn(e.tensor);if(e.buffer!==void 0&&e.buffer!==null)return cn(e.buffer);throw new Error(`binding ${e.binding??"?"} is missing tensor or buffer`)}function cn(e){return od(e)?e:e.buffer}function od(e){return e===null||typeof e!="object"?!1:"destroy"in e&&"mapAsync"in e&&"getMappedRange"in e&&!("buffer"in e)}function _s(e,n){let r=null,t=null,a=null,s=()=>{r!==null&&(r.end(),r=null),t=null,a=null};for(let o of n){if(o.kind==="copy"){s(),o.byteLength>0&&e.copyBufferToBuffer(o.src,o.srcOffset,o.dst,o.dstOffset,o.byteLength);continue}if(!mr(o.dispatchWorkgroups)){if(r===null&&(r=e.beginComputePass({label:"compute-sequence-pass"})),o.pipeline!==t&&(r.setPipeline(o.pipeline),t=o.pipeline),o.bindGroup!==a&&(r.setBindGroup(0,o.bindGroup),a=o.bindGroup),o.extraBindGroups)for(let i of o.extraBindGroups)r.setBindGroup(i.group,i.bindGroup),i.group===0&&(a=i.bindGroup);r.dispatchWorkgroups(o.dispatchWorkgroups[0],o.dispatchWorkgroups[1],o.dispatchWorkgroups[2])}}s()}function mr(e){return e[0]===0||e[1]===0||e[2]===0}async function vs(e={}){let n=e.host??await dt(e);return new gr({host:n})}var id=BigInt(1e8),ud=new TextDecoder("utf-8",{fatal:!0}),Ss=Object.freeze({BOOL:8,F4:4,F6_E2M3:6,F6_E3M2:6,U8:8,I8:8,F8_E5M2:8,F8_E4M3:8,F8_E8M0:8,F8_E4M3FNUZ:8,F8_E5M2FNUZ:8,I16:16,U16:16,F16:16,BF16:16,I32:32,U32:32,F32:32,F64:64,I64:64,U64:64,C64:64}),ld=Object.freeze({U8:Uint8Array,I8:Int8Array,I16:Int16Array,U16:Uint16Array,I32:Int32Array,U32:Uint32Array,F32:Float32Array,F64:Float64Array,I64:BigInt64Array,U64:BigUint64Array});function cd(e){let n=Ss[e];if(!n)throw new B(`Unknown dtype: ${e}`);return n}function Ts(e){return ld[e]??null}function xs(e,n){let r=n.BYTES_PER_ELEMENT;if(e.byteLength%r!==0)throw new B(`Byte length ${e.byteLength} not divisible by ${n.name} element size`);if(e.byteOffset%r===0)return new n(e.buffer,e.byteOffset,e.byteLength/r);let t=new ArrayBuffer(e.byteLength);return new Uint8Array(t).set(e),new n(t)}var B=class extends Error{constructor(n){super(n),this.name="SafeTensorsError"}};function ks(e){if(e.byteLength<8)throw new B(`File too small: ${e.byteLength} bytes < 8 byte header prefix`);let r=new DataView(e.buffer,e.byteOffset,e.byteLength).getBigUint64(0,!0);if(r>id)throw new B(`Header length ${r} exceeds maximum 100000000`);let t=Number(r),a=8+t;if(a>e.byteLength)throw new B(`Header length ${t} exceeds buffer size`);let s=e.subarray(8,a),o;try{o=ud.decode(s)}catch{throw new B("Header is not valid UTF-8")}let i;try{i=JSON.parse(o)}catch(u){let l=u instanceof Error?u.message:String(u);throw new B(`Header is not valid JSON: ${l}`)}if(i===null||typeof i!="object"||Array.isArray(i))throw new B("Header must be a JSON object");return{headerByteLength:t,dataStart:a,header:i}}function mt(e,n){let r=e.__metadata__;if(r!==void 0&&!pd(r))throw new B("__metadata__ must be a {string: string} map");let t=[];for(let[s,o]of Object.entries(e))s!=="__metadata__"&&t.push([s,dd(s,o)]);t.sort((s,o)=>s[1].dataOffsets[0]-o[1].dataOffsets[0]);let a=0;for(let[s,o]of t){let[i,u]=o.dataOffsets;if(i!==a)throw new B(`Invalid offset for tensor ${s}: expected ${a}, got ${i}`);let l=o.elementCount*cd(o.dtype);if(l%8!==0)throw new B(`Tensor ${s} has subbyte size ${l} bits not divisible by 8`);if(u-i!==l/8)throw new B(`Tensor ${s} byte length ${u-i} does not match shape*dtype ${l/8}`);a=u}if(n!==null&&a!==n)throw new B(`Data length mismatch: header expects ${a} bytes, got ${n}`);return{metadata:r??null,tensors:new Map(t),dataByteLength:a}}function dd(e,n){if(n===null||typeof n!="object"||Array.isArray(n))throw new B(`Tensor ${e}: info must be an object`);let{dtype:r,shape:t,data_offsets:a}=n;if(typeof r!="string"||!(r in Ss))throw new B(`Tensor ${e}: unknown dtype ${r}`);if(!Array.isArray(t)||!t.every(u=>Number.isInteger(u)&&u>=0))throw new B(`Tensor ${e}: shape must be an array of nonnegative integers`);if(!Array.isArray(a)||a.length!==2||!a.every(u=>Number.isInteger(u)&&u>=0))throw new B(`Tensor ${e}: data_offsets must be a 2-element array of nonnegative integers`);let[s,o]=a;if(o0){let c=new Uint8Array(n),d=[];for(;;){let{done:p,value:f}=await o.read();if(p)break;f&&(u+f.byteLength<=c.byteLength&&d.length===0?c.set(f,u):(d.length===0&&d.push(c.subarray(0,u)),d.push(f)),u+=f.byteLength,ht({onByteProgress:r,onProgress:t,loaded:u,delta:f.byteLength,total:i,fromCache:s}))}return d.length===0?u===n?c:c.subarray(0,u):Es(d,u)}let l=[];for(;;){let{done:c,value:d}=await o.read();if(c)break;d&&(l.push(d),u+=d.byteLength,ht({onByteProgress:r,onProgress:t,loaded:u,delta:d.byteLength,total:i,fromCache:s}))}return Es(l,u)}function ht({onByteProgress:e,onProgress:n,loaded:r,delta:t,total:a,fromCache:s}){e?.(t),n?.({loaded:r,total:a??null,fromCache:s})}function Es(e,n){if(e.length===0)return new Uint8Array(0);if(e.length===1&&e[0].byteLength===n)return e[0];let r=new Uint8Array(n),t=0;for(let a of e)r.set(a,t),t+=a.byteLength;return r}var md=128<<20,gd=1<<20,hd=4,qn=class{#e;#r;#n;metadata;url;totalSize;headerByteLength;dataByteLength;constructor({source:n,dataStart:r,metadata:t,tensors:a,headerByteLength:s,dataLength:o}){this.#e=n,this.#r=r,this.#n=a,this.metadata=t,this.url=n.url,this.totalSize=n.size,this.headerByteLength=s,this.dataByteLength=o??(n.size==null?null:n.size-r)}names(){return[...this.#n.keys()]}has(n){return this.#n.has(n)}info(n){let r=this.#t(n);return{dtype:r.dtype,shape:[...r.shape],dataOffsets:[...r.dataOffsets]}}byteLength(n){let r=this.#t(n);return r.dataOffsets[1]-r.dataOffsets[0]}async tensorBytes(n,r){let t=this.#t(n),[a,s]=t.dataOffsets,o=this.#r+a,i=this.#r+s,u=await this.#e.readTensor(o,i);if(u)return u;let l=await this.#e.readRange(o,i,r);return await this.#e.writeTensor(o,i,l),l}async tensorAs(n,r){let t=this.#t(n),a=Ts(t.dtype);if(!a)throw new B(`No native typed-array for dtype ${t.dtype}; use tensorBytes()`);return xs(await this.tensorBytes(n,r),a)}async batchBytes(n,r){if(n.length===0)return new Map;let t=n.map(u=>[u,this.#t(u)]),a=1/0,s=0;for(let[,u]of t)u.dataOffsets[0]s&&(s=u.dataOffsets[1]);let o=await this.#e.readRange(this.#r+a,this.#r+s,r),i=new Map;for(let[u,l]of t)i.set(u,o.subarray(l.dataOffsets[0]-a,l.dataOffsets[1]-a));return i}async streamAll(n,{concurrency:r=hd,chunkMaxBytes:t=md,chunkMaxGap:a=gd,names:s=null,onProgress:o,signal:i}={}){let u=this.#a(s);if(u.length===0)return;let l=yd(u,{maxBytes:t,maxGap:a}),c=l.reduce((G,C)=>G+(C.end-C.begin),0),d=0,p=new Map,f=(G={})=>{if(!o)return;let C=d;for(let S of p.values())C+=S;o({loaded:C,total:c,...G})},m=this.#r,_=this.#e,E=0,b=async G=>{let{begin:C,end:S,tensors:D}=l[G],P=m+C,N=m+S,R=S-C,V,z=!0,j=await Promise.all(D.map(g=>_.readTensor(m+g.begin,m+g.end)));for(let g of j)if(!g){z=!1;break}if(z){V=new Uint8Array(R);for(let g=0;g{p.set(G,(p.get(G)??0)+g),f({fromCache:!1,range:[P,N],inFlight:!0})}});let ne=z,Q=D.map(g=>({name:g.name,offset:g.begin-C,length:g.end-g.begin})),ve=Promise.resolve(n({begin:P,end:N,bytes:V,tensors:Q})),Z=ne?Promise.resolve():Promise.all(D.map((g,w)=>{if(j[w])return null;let T=V.subarray(g.begin-C,g.end-C);return _.writeTensor(m+g.begin,m+g.end,T).catch(()=>{})})).catch(()=>{});await Promise.all([ve,Z]),p.delete(G),d+=R,f({fromCache:ne,range:[P,N]})},W=async()=>{for(;;){if(i?.aborted)throw i.reason??new Error("aborted");let G=E++;if(G>=l.length)return;await b(G)}},q=[];for(let G=0;Go&&t.push({name:a,begin:o,end:i})}return t.sort((a,s)=>a.begin-s.begin),t}#t(n){let r=this.#n.get(n);if(!r)throw new B(`Unknown tensor: ${n}`);return r}};function yd(e,{maxBytes:n,maxGap:r}){let t=[],a=null;for(let s of e){if(!a){a={begin:s.begin,end:s.end,tensors:[s]};continue}let o=s.begin-a.end,i=s.end-a.begin;o<=r&&i<=n?(a.end=s.end,a.tensors.push(s)):(t.push(a),a={begin:s.begin,end:s.end,tensors:[s]})}return a&&t.push(a),t}async function Gs(e,{headerProbeBytes:n}){let r=e.size==null?n:Math.min(n,e.size),t=await e.readRange(0,r);if(t.byteLength<8)throw new B(`Probe returned ${t.byteLength} bytes; need at least ${8}`);let a=new DataView(t.buffer,t.byteOffset,t.byteLength).getBigUint64(0,!0);if(a>BigInt(1e8))throw new B(`Header length ${a} exceeds maximum ${1e8}`);let s=Number(a),o=8+s,i;if(t.byteLength>=o)i=t.subarray(0,o);else{let l=await e.readRange(t.byteLength,o);i=new Uint8Array(o),i.set(t),i.set(l,t.byteLength)}let{header:u}=ks(i);return{header:u,headerByteLength:s,dataStart:o,dataLength:e.size==null?null:e.size-o}}function dn(e){return e instanceof Error?e.message:String(e)}function Os(e){return e.byteOffset===0&&e.byteLength===e.buffer.byteLength&&e.buffer instanceof ArrayBuffer?e.buffer:e.slice().buffer}var bd=262144,wd="safetensors-cache-v1",pn="chunks",fn="meta";async function Ws(e,n={},r){let t=n.cacheKey??(typeof e=="string"?e:e.toString()),a=n.cache===!1,s=!!n.force,o=a||n.source?null:n.chunkCache??_d(n.cacheName??wd);if(o&&!s)try{let m=await o.getMeta(t);if(m&&m.header&&Number.isFinite(m.size)&&Number.isFinite(m.dataStart)){let _=await r(e,{...n,chunkCache:o,knownSize:m.size,knownAcceptsRanges:m.acceptsRanges??!0}),E=m.size-m.dataStart,{metadata:b,tensors:W}=mt(m.header,E);return new qn({source:_,dataStart:m.dataStart,metadata:b,tensors:W,headerByteLength:m.dataStart-8,dataLength:E})}}catch(m){typeof console<"u"&&console.warn(`safetensors meta cache read failed: ${dn(m)}`)}let i=await r(e,{...n,chunkCache:o}),{header:u,headerByteLength:l,dataStart:c,dataLength:d}=await Gs(i,{headerProbeBytes:n.headerProbeBytes??bd}),{metadata:p,tensors:f}=mt(u,d);return o&&!s&&i.size!=null&&o.putMeta(t,{size:i.size,dataStart:c,header:u,acceptsRanges:i.acceptsRanges}).catch(()=>{}),new qn({source:i,dataStart:c,metadata:p,tensors:f,headerByteLength:l,dataLength:d})}function Fs(e){return{requireRangeRequests:!!(e.requireRangeRequests??e.requireRanges??!1),knownSize:e.knownSize,knownAcceptsRanges:e.knownAcceptsRanges}}function Ms(e,n){let{chunkCache:r}=n,t=n.cacheKey??e.url,a=!!n.force;return{...e,async readTensor(s,o){if(a)return null;try{return await r.get(t,s,o)}catch(i){return typeof console<"u"&&console.warn(`safetensors cache read failed: ${dn(i)}`),null}},async writeTensor(s,o,i){try{let u=i.byteOffset===0&&i.byteLength===i.buffer.byteLength?i:new Uint8Array(i);await r.put(t,s,o,u)}catch(u){typeof console<"u"&&console.warn(`safetensors cache write failed: ${dn(u)}`)}}}}var Rs=new Map;function _d(e){return typeof indexedDB>"u"?null:{async get(n,r,t){let a=await hr(e);return new Promise((s,o)=>{let u=a.transaction(pn,"readonly").objectStore(pn).get([n,r,t]);u.onsuccess=async()=>{let l=u.result;if(!l)return s(null);s(new Uint8Array(await l.arrayBuffer()))},u.onerror=()=>o(u.error)})},async put(n,r,t,a){let s=await hr(e);return new Promise((o,i)=>{let l=s.transaction(pn,"readwrite").objectStore(pn).put(new Blob([Os(a)]),[n,r,t]);l.onsuccess=()=>o(),l.onerror=()=>i(l.error)})},async getMeta(n){let r=await hr(e);return new Promise((t,a)=>{let o=r.transaction(fn,"readonly").objectStore(fn).get(n);o.onsuccess=()=>t(o.result??null),o.onerror=()=>a(o.error)})},async putMeta(n,r){let t=await hr(e);return new Promise((a,s)=>{let i=t.transaction(fn,"readwrite").objectStore(fn).put(r,n);i.onsuccess=()=>a(),i.onerror=()=>s(i.error)})}}}function hr(e){let n=Rs.get(e);if(n)return n;let r=new Promise((t,a)=>{let s=indexedDB.open(e,2);s.onupgradeneeded=()=>{let o=s.result;o.objectStoreNames.contains(pn)||o.createObjectStore(pn),o.objectStoreNames.contains(fn)||o.createObjectStore(fn)},s.onsuccess=()=>t(s.result),s.onerror=()=>a(s.error),s.onblocked=()=>a(new Error("indexedDB open blocked"))});return Rs.set(e,r),r}var Bs=(e,n={})=>Ws(e,n,vd);async function vd(e,n){let r=await Ps(e,n,Fs(n));return n.chunkCache?Ms(r,{...n,chunkCache:n.chunkCache}):r}function Is({readTextResource:e,openSafeTensorsResource:n}){async function r(s,o,i){return JSON.parse(await e(s,o,i))}async function t(s,o,i){return qs(()=>r(s,o,i))}async function a(s,o,i){return qs(()=>e(s,o,i))}return Object.freeze({readJsonResource:r,readJsonResourceOptional:t,readTextResource:e,readTextResourceOptional:a,openSafeTensorsResource:n})}var yt=class extends Error{url;status;statusText;constructor(n,r){super(`GET ${n} failed: ${r.status} ${r.statusText}`),this.name="ResourceFetchError",this.url=n,this.status=r.status,this.statusText=r.statusText}};function bt(e,n){let r=e instanceof URL?e.toString():String(e),t=new URL(Sd(r),globalThis.location?.href);return new URL(n,t).toString()}async function Ds(e,n={}){let r=n.fetch??globalThis.fetch;if(typeof r!="function")throw new Error("No fetch implementation available");let t=await xd(n);if(t&&!n.force){let s=await t.match(e);if(s)return s.text()}let a=await r(e,{signal:n.signal});if(!a.ok)throw new yt(e,a);if(t)try{await t.put(e,a.clone())}catch(s){typeof console<"u"&&console.warn(`resource cache write failed: ${dn(s)}`)}return a.text()}function Sd(e){return e.endsWith("/")?e:`${e}/`}async function qs(e){try{return await e()}catch(n){if(!Td(n))throw n;return null}}function Td(e){return typeof e=="object"&&e!==null&&(e.code==="ENOENT"||e.status===404)}async function xd(e={}){if(e.cache===!1)return null;let n=e.cacheStorage??globalThis.caches;return n?.open?n.open(e.cacheName??"bonsai-pipeline-v1"):null}var mn=Is({readTextResource:kd,openSafeTensorsResource:Ed});async function kd(e,n,r={}){return Ds(bt(e,n),r)}async function Ed(e,n,r={}){return Bs(bt(e,n),r)}var Pd={tensor:e=>e.destroy(),buffer:e=>e.destroy(),map:e=>e.clear(),set:e=>e.clear()};function en(e,n=new Set){yr(e,n,Pd)}function yr(e,n,r){if(!(e==null||typeof e!="object")&&!n.has(e)&&(n.add(e),!(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))){if(Ad(e)){r.tensor(e);return}if(Gd(e)){r.buffer(e);return}if(e instanceof Map){for(let t of e.values())yr(t,n,r);r.map(e);return}if(e instanceof Set){for(let t of e.values())yr(t,n,r);r.set(e);return}for(let t of Object.keys(e))yr(e[t],n,r)}}function Ad(e){let n=e;return Array.isArray(n.shape)&&typeof n.dtype=="string"&&typeof n.destroy=="function"&&n.buffer!=null&&typeof n.buffer.destroy=="function"}function Gd(e){let n=e;return typeof n.destroy=="function"&&typeof n.mapAsync=="function"&&typeof n.getMappedRange=="function"}var wt="sliding_attention",_t="full_attention";function Od(e){return e&&typeof e=="object"&&e.text_config&&typeof e.text_config=="object"?{...e.text_config}:e??{}}function Ae(e,n,r){let t=e[n];if(t==null){if(r!==void 0)return r;throw new Error(`Gemma4Config: missing required integer field "${n}"`)}let a=Number(t);if(!Number.isInteger(a))throw new Error(`Gemma4Config: field "${n}" must be an integer, got ${t}`);return a}var Dn=class{model_type="gemma4_text";vocab_size;vocab_size_per_layer_input;hidden_size;intermediate_size;num_hidden_layers;num_attention_heads;num_key_value_heads;head_dim;global_head_dim;hidden_size_per_layer_input;num_kv_shared_layers;sliding_window;rms_norm_eps;final_logit_softcapping;use_double_wide_mlp;tie_word_embeddings;max_position_embeddings;layer_types;firstKvSharedLayer;layers;slidingRopeTheta;fullRopeTheta;fullPartialRotaryFactor;embedScale;perLayerEmbedScale;constructor(n={}){let r=Od(n);this.vocab_size=Ae(r,"vocab_size"),this.vocab_size_per_layer_input=Ae(r,"vocab_size_per_layer_input",this.vocab_size),this.hidden_size=Ae(r,"hidden_size"),this.intermediate_size=Ae(r,"intermediate_size"),this.num_hidden_layers=Ae(r,"num_hidden_layers"),this.num_attention_heads=Ae(r,"num_attention_heads"),this.num_key_value_heads=Ae(r,"num_key_value_heads"),this.head_dim=Ae(r,"head_dim"),this.global_head_dim=Ae(r,"global_head_dim",this.head_dim),this.hidden_size_per_layer_input=Ae(r,"hidden_size_per_layer_input"),this.num_kv_shared_layers=Ae(r,"num_kv_shared_layers",0),this.sliding_window=Ae(r,"sliding_window"),this.rms_norm_eps=Number(r.rms_norm_eps??1e-6),this.final_logit_softcapping=Number(r.final_logit_softcapping??0)||0,this.use_double_wide_mlp=!!r.use_double_wide_mlp,this.tie_word_embeddings=!!(r.tie_word_embeddings??!1),this.max_position_embeddings=Ae(r,"max_position_embeddings",131072);let t=r.rope_parameters??{};this.slidingRopeTheta=Number(t?.[wt]?.rope_theta??1e4),this.fullRopeTheta=Number(t?.[_t]?.rope_theta??1e6),this.fullPartialRotaryFactor=Number(t?.[_t]?.partial_rotary_factor??.25);let a=Array.isArray(r.layer_types)?r.layer_types:null;if(this.layer_types=a?a.slice():Array.from({length:this.num_hidden_layers},(o,i)=>(i+1)%5===0?_t:wt),this.layer_types.length!==this.num_hidden_layers)throw new Error(`Gemma4Config: layer_types length ${this.layer_types.length} != num_hidden_layers ${this.num_hidden_layers}`);this.firstKvSharedLayer=this.num_hidden_layers-this.num_kv_shared_layers;let s={};for(let o=0;o{let u=o===wt,l=u?this.head_dim:this.global_head_dim,c=i>=this.firstKvSharedLayer&&this.firstKvSharedLayer>=0,d=this.use_double_wide_mlp&&c;return{index:i,layerType:o,isSliding:u,headDim:l,qOut:this.num_attention_heads*l,kvOut:this.num_key_value_heads*l,attnBits:4,mlpBits:c?2:4,intermediate:d?this.intermediate_size*2:this.intermediate_size,slidingWindow:u?this.sliding_window:0,ropeTheta:u?this.slidingRopeTheta:this.fullRopeTheta,partialRotaryFactor:u?1:this.fullPartialRotaryFactor,isKvShared:c,kvSourceLayer:c?s[o]:i}}),this.embedScale=Math.sqrt(this.hidden_size),this.perLayerEmbedScale=Math.sqrt(this.hidden_size_per_layer_input),this.validate()}validate(){if(this.num_attention_heads%this.num_key_value_heads!==0)throw new Error("Gemma4Config: num_attention_heads must be divisible by num_key_value_heads");for(let n of this.layers)if(n.isKvShared&&(n.kvSourceLayer===void 0||n.kvSourceLayer<0))throw new Error(`Gemma4Config: no KV source layer for shared layer ${n.index} (${n.layerType})`)}};var Us=8192,Un=class e{batchSize=1;maxLength;seqLength=0;keys;values;constructor(n,r,t){this.maxLength=n,this.keys=r,this.values=t}static defaultCapacity(n){return Math.max(1,Math.min(Us,n.max_position_embeddings))}static allocate(n,r,t){let a=Math.max(1,Math.min(t??Us,r.max_position_embeddings)),s=new Array(r.num_hidden_layers).fill(null),o=new Array(r.num_hidden_layers).fill(null);for(let i of r.layers)i.isKvShared||(s[i.index]=n.empty("float32",[a,i.kvOut],`gemma4-cache-k-${i.index}`),o[i.index]=n.empty("float32",[a,i.kvOut],`gemma4-cache-v-${i.index}`));return new e(a,s,o)}keyT(n){let r=this.keys[n];if(!r)throw new Error(`Gemma4DynamicCache: layer ${n} has no KV storage (is it a shared layer?)`);return r}valueT(n){let r=this.values[n];if(!r)throw new Error(`Gemma4DynamicCache: layer ${n} has no KV storage (is it a shared layer?)`);return r}get_seq_length(){return this.seqLength}advance(n){if(!Number.isInteger(n)||n<0)throw new Error(`advance(${n}) invalid`);if(this.seqLength+n>this.maxLength)throw new Error(`KV cache overflow: ${this.seqLength}+${n} > ${this.maxLength}`);this.seqLength+=n}truncate(n){if(!Number.isInteger(n)||n<0||n>this.maxLength)throw new Error(`truncate(${n}) invalid`);this.seqLength=n}dispose(){for(let n of this.keys)en(n);for(let n of this.values)en(n);this.keys.fill(null),this.values.fill(null)}};function Ls(e){let n=e&32768?-1:1,r=e>>>10&31,t=e&1023;return r===31?t===0?n*(1/0):NaN:r===0?n*2**-14*(t/1024):n*2**(r-15)*(1+t/1024)}function vt(e){let n=new Uint16Array(e.length);for(let r=0;r>>16&32768,t=n>>>23&255,a=n&8388607;if(t===255)return a!==0?r|32256:r|31744;let s=t-127+15;if(s>=31)return r|31743;if(s<=0){if(s<-10)return r;let c=a|8388608,d=14-s,p=1<>>d;return(f>p||f===p&&(m&1)===1)&&(m+=1),r|m}let o=4096,i=a&8191,u=a>>>13,l=s;return(i>o||i===o&&(u&1)===1)&&(u+=1,u===1024&&(u=0,l+=1)),l>=31?r|31743:r|l<<10|u}var Wd=new Set(["F32","BF16","F16"]),Fd=new Set(["float32","float16"]);function zs(e,n,r){Id(e,n);let t=Dd(e);if(r.byteLength%t!==0)throw new Error(`source byte length ${r.byteLength} not divisible by ${t}`);return e==="F32"&&n==="float32"?Ns(r,Float32Array,4):e==="F16"&&n==="float16"?Ns(r,Uint16Array,2):Ud(e,n)(r)}function Md(e){return typeof e=="string"&&Wd.has(e)}function Bd(e){return typeof e=="string"&&Fd.has(e)}function xt(e){if(!Md(e))throw new Error(`Unsupported source dtype: ${e}`)}function qd(e){if(!Bd(e))throw new Error(`Unsupported target dtype: ${e}`)}function Id(e,n){xt(e),qd(n)}function Dd(e){if(e==="F32")return 4;if(e==="BF16"||e==="F16")return 2;throw new Error(`Unsupported source dtype: ${e}`)}function Ud(e,n){if(e==="BF16"&&n==="float32")return Ld;if(e==="BF16"&&n==="float16")return Cd;if(e==="F16"&&n==="float32")return jd;if(e==="F32"&&n==="float16")return zd;throw new Error(`No converter for ${e} -> ${n}`)}function Ns(e,n,r){let t=new n(e.byteLength/r);return new Uint8Array(t.buffer).set(e),t}function Ld(e){let n=e.byteLength/2,r=new Float32Array(n),t=new Uint32Array(r.buffer);if(e.byteOffset%2===0){let a=new Uint16Array(e.buffer,e.byteOffset,n);for(let s=0;s>>0,St($d[0])}var Tt=null;function Hd(){if(Tt)return Tt;let e=new Uint16Array(65536);for(let n=0;n<65536;++n)e[n]=Kd(n);return Tt=e,e}var br=class{specs;handlers;pending;constructor(n=[]){this.specs=n.map(wr),this.handlers=new Map,this.pending=new Set}add(n){return this.specs.push(wr(n)),this}tensor(n){return this.add(Qs(n))}group(n){return this.add(Ln(n))}prepare({reader:n,context:r={}}){this.handlers.clear(),this.pending.clear();for(let t of this.specs)if(t.type==="tensor")this.#e(t,n,r);else if(t.type==="group")this.#r(t,n,r);else throw new Error(`Unsupported weight plan spec type: ${t.type}`);return this}names(){return[...this.handlers.keys()]}async onChunk({bytes:n,tensors:r},t={}){let a=[];for(let s of r){let o=this.handlers.get(s.name);if(!o)continue;let i=n.subarray(s.offset,s.offset+s.length);a.push($s(o,i,t))}a.length&&await Promise.all(a)}async readSequential(n,r={}){for(let t of this.names()){let a=await n.read(t),s=this.handlers.get(t);s&&await $s(s,a,r)}}assertComplete(){if(this.pending.size>0){let n=[...this.pending].slice(0,5).join(", ");throw new Error(`WeightPlan incomplete - ${this.pending.size} tensor(s) never arrived (first: ${n})`)}}#e(n,r,t){let a=Ks(r,n.name);if(!a){Vs(n,t);return}Hs(n,a),this.#n(n.name,async(s,o)=>{this.pending.delete(n.name),await Xd(n,s,{...t,...o,description:a})},n.progressLabel??n.name)}#r(n,r,t){let a={},s=n.names.filter(u=>{let l=Ks(r,u);return l&&(a[u]=l),!l});if(s.length>0){Vs(n,t,s);return}for(let u of n.names)Hs(n,a[u],u);let o={},i=n.names.length;for(let u of n.names)this.#n(u,async(l,c)=>{if(this.pending.delete(u),o[u]=l,--i===0)try{await Zd(n,o,{...t,...c,descriptions:a})}finally{for(let d of n.names)delete o[d]}},n.progressLabel??u)}#n(n,r,t=n){if(this.handlers.has(n))throw new Error(`Duplicate WeightPlan handler for tensor: ${n}`);this.handlers.set(n,{name:n,progressLabel:t,receive:r}),this.pending.add(n)}};function Qs(e){return wr({type:"tensor",required:!0,...e})}function Ln(e){return wr({type:"group",required:!0,...e})}function Xs({name:e,required:n=!0,sourceDtype:r=null,targetDtype:t,shape:a=null,label:s=e,progressLabel:o=e,assign:i=null,missing:u=null,transform:l=null,upload:c=null,cleanup:d=null}){return Qs({name:e,required:n,sourceDtype:r,targetDtype:t,shape:a,label:s,progressLabel:o,transform:l??((p,{description:f})=>{if(!f)throw new Error(`WeightPlan tensor ${e} is missing a description`);let m=r??f.dtype;return xt(m),zs(m,t,p)}),upload:c??((p,{rt:f,description:m})=>{if(!f)throw new Error(`WeightPlan tensor ${e} upload requires context.rt`);if(!m)throw new Error(`WeightPlan tensor ${e} is missing a description`);let _=Ys(a,p.length,m);return f.tensorFromTypedArray(t,_,p)}),assign:i,missing:u,cleanup:d})}async function Zs(e,{source:n=null,reader:r,context:t={},concurrency:a,chunkMaxBytes:s,onProgress:o=null,signal:i}={}){let u=e instanceof br?e:new br(e);if(!r)throw new Error("WeightPlan execution requires a reader");try{u.prepare({reader:r,context:t});let l={...t,onTensorProgress:Vd(u,o)};return n?await n.streamAll(c=>u.onChunk(c,l),{concurrency:a,chunkMaxBytes:s,names:u.names(),onProgress:o,signal:i}):await u.readSequential(r,l),u.assertComplete(),u}finally{await Qd(n,r)}}async function $s(e,n,r){await e.receive(n,r),r.onTensorProgress?.({name:e.name,label:e.progressLabel})}function Vd(e,n){if(!n)return null;let r=0,t=e.names().length;return({name:a,label:s})=>{n({phase:"tensor",processed:++r,total:t,name:a,label:s})}}async function Qd(e,n){let r=new Set,t=e?[n,e]:[n];for(let a of t){let s=a.closeTarget??a;r.has(s)||(r.add(s),await a.close())}}function wr(e){if(!e||typeof e!="object")throw new Error("WeightPlan spec must be an object");if(e.type==="tensor"){if(typeof e.name!="string"||e.name.length===0)throw new Error("WeightPlan tensor spec requires a name");return{required:!0,...e}}if(e.type==="group"){if(!Array.isArray(e.names)||e.names.length===0)throw new Error("WeightPlan group spec requires a non-empty names array");for(let n of e.names)if(typeof n!="string"||n.length===0)throw new Error("WeightPlan group tensor names must be non-empty strings");return{required:!0,...e}}throw new Error(`Unknown WeightPlan spec type: ${e.type}`)}async function Xd(e,n,r){let t=e.transform?await e.transform(n,r):n,a=e.upload?await e.upload(t,r):t;e.run&&await e.run(a,r),e.assign?.(a,r),await e.cleanup?.(a,r)}async function Zd(e,n,r){let t=e.transform?await e.transform(n,r):n,a=e.upload?await e.upload(t,r):t;e.run&&await e.run(a,r),e.assign?.(a,r),await e.cleanup?.(a,r)}function Ks(e,n){return e.has(n)?e.describe(n):null}function Hs(e,n,r=e.type==="tensor"?e.name:"group"){if(e.sourceDtype&&n.dtype!==e.sourceDtype)throw new Error(`${r} has dtype ${n.dtype}; expected ${e.sourceDtype}`);if(e.shape){let t=Ys(e.shape,n.elementCount,n);if(t.length!==n.shape.length||t.some((a,s)=>a!==n.shape[s]))throw new Error(`${r} has shape [${n.shape}]; expected [${t}]`)}}function Vs(e,n,r=e.type==="tensor"?[e.name]:[...e.names]){if(e.required===!1){e.missing?.(r,n);return}throw new Error(`Missing required tensor${r.length===1?"":"s"}: ${r.join(", ")}`)}function Ys(e,n,r){return typeof e=="function"?e({valueLength:n,description:r}):Array.isArray(e)?e:r.shape?r.shape:[n]}Wn();function Js(e){return{has:r=>e.has(r),describe(r){let t=e.info(r),a=[...t.shape];return{dtype:t.dtype,shape:a,elementCount:Ve(a)}},async read(r){return e.tensorBytes(r)},async close(){await e.close()},closeTarget:e}}var v=Math.fround,Yd=v(1.4426950408889634),Jd=v(-.693145751953125),ep=v(-1428606765330187e-21),np=v(.0001980960224),rp=v(.001394256484),tp=v(.008333456703),ap=v(.04166637361),eo=v(.16666665941423425),sp=v(8.664339742),Me=(e,n,r)=>v(e*n+r),Cn=(e,n,r)=>v(e*n-r),_r=(e,n,r)=>v(r-e*n);function op(e){let n=Math.floor(e),r=e-n;return r>.5?n+1:r<.5||(n&1)===0?n:n+1}function no(e,n){let r=n>>1;return v(v(e*2**r)*2**(n-r))}function ip(e){let n=Math.abs(e);if(!(n<=sp))return e<0?-1:1;let r=op(v(n*Yd)),t=r,a=v(t*Jd),s=v(n+a),o=v(s-n),i=v(v(v(n-v(s-o))+v(a-o))+0);a=v(t*ep);let u=v(s+a);o=v(u-s);let l=v(v(v(s-v(u-o))+v(a-o))+i);s=u,i=l;let c=np;c=Me(c,s,rp),c=Me(c,s,tp),c=Me(c,s,ap);let d=v(s*c),p=Me(i,c,Cn(s,c,d)),f=v(d+eo);o=v(f-d),p=v(v(v(d-v(f-o))+v(eo-o))+p),d=f;let m=v(s*d),_=Me(s,p,Me(i,d,Cn(s,d,m)));f=v(m+.5),o=v(f-m),p=v(v(v(m-v(f-o))+v(.5-o))+_),d=f;let E=v(s*s),b=Me(v(s+s),i,Cn(s,s,E));m=v(E*d),_=Me(E,p,Me(b,d,Cn(E,d,m))),f=v(s+m),o=v(f-s),p=v(v(v(s-v(f-o))+v(m-o))+v(i+_)),d=f,f=v(1+d),p=v(v(v(1-f)+d)+p),d=f,d=no(d,r),p=no(p,r);let W=v(1/d),q=v(W*_r(p,W,_r(d,W,1))),G=v(d-W),C=v(v(v(v(d-G)-W)+p)-q),S=v(d+W),D=v(v(v(v(d-S)+W)+p)+q),P=v(1/S),N=v(G*P),R=Cn(P,G,N),V=_r(D,P,_r(S,P,1)),z=Me(N,V,Me(C,P,R)),j=v(N+z);return e<0?-j:j}function kt(e){let n=v(.7978845608028654),r=v(.044715),t=v(e),a=new Float32Array(256);for(let s=-128;s<128;++s){let o=v(s*t),i=v(v(o*o)*o),u=v(n*v(o+v(r*i))),l=ip(u);a[s+128]=v(v(.5*o)*v(1+l))}return a}function $e(e){let n=e.slice();return new Float32Array(n.buffer,n.byteOffset,n.byteLength>>>2)}var gn="model.language_model";async function ro(e,n,r,t={}){let a=[],s=(c,d,p,f,m,_=!1)=>{a.push(Ln({names:[`${c}.weight`,`${c}.weight_scale`,`${c}.input_activation_scale`,`${c}.output_activation_scale`],progressLabel:c,run:async E=>{let b=E[`${c}.weight`],W=E[`${c}.weight_scale`];if(!b||!W)throw new Error(`Missing tensors for ${c}`);let q=b.byteLength*8/(d*p);if(q!==2&&q!==4&&q!==8)throw new Error(`${c}: derived ${q}-bit from ${b.byteLength} bytes for [${d}, ${p}]`);if(_){let P=p*q/32,N=new Uint32Array(b.buffer.slice(b.byteOffset,b.byteOffset+b.byteLength)),R=new Uint32Array(N.length),V=P/4;for(let z=0;z{a.push(Ln({names:[`${c}.embedding_quantized`,`${c}.embedding_scale`],progressLabel:c,run:async E=>{let b=E[`${c}.embedding_quantized`],W=E[`${c}.embedding_scale`];if(!b||!W)throw new Error(`Missing tensors for ${c}`);let q=b.byteLength*8/(d*p);if(q!==2&&q!==4&&q!==8)throw new Error(`${c}: derived ${q}-bit from ${b.byteLength} bytes for [${d}, ${p}]`);let G=e.allocateWeightsBuffer({byteLength:b.byteLength,dtype:"uint32",shape:[d,p*q/32],label:`${c}.bits`});e.writeWeightsRange(G,0,b);let C=e.tensorFromTypedArray("float32",[d,m],$e(W));_({bitsT:G,scaleT:C,bits:q})}}))},i=(c,d,p,f)=>{a.push(Ln({names:[`${c}.weight`,`${c}.weight_scale`,`${c}.input_activation_scale`,`${c}.output_activation_scale`],progressLabel:c,run:async m=>{let _=m[`${c}.weight`],E=m[`${c}.weight_scale`];if(!_||!E)throw new Error(`Missing tensors for ${c}`);let b=new Int8Array(_.buffer,_.byteOffset,_.byteLength),W=$e(E),q=new Float32Array(d*p);for(let D=0;D{a.push(Xs({name:c,sourceDtype:"BF16",targetDtype:f,shape:d??void 0,assign:m=>p(m)}))},l={layers:n.layers.map(()=>({}))};o(`${gn}.embed_tokens`,n.vocab_size,n.hidden_size,2,1,c=>{l.embedTokens=c}),o(`${gn}.embed_tokens_per_layer`,n.vocab_size_per_layer_input,n.num_hidden_layers*n.hidden_size_per_layer_input,4,n.num_hidden_layers,c=>{l.embedTokensPerLayer=c}),u(`${gn}.per_layer_model_projection.weight`,[n.num_hidden_layers*n.hidden_size_per_layer_input,n.hidden_size],c=>{l.perLayerModelProjection=c},"float16"),u(`${gn}.per_layer_projection_norm.weight`,[n.hidden_size_per_layer_input],c=>{l.perLayerProjectionNorm=c}),u(`${gn}.norm.weight`,[n.hidden_size],c=>{l.finalNorm=c}),s("lm_head",n.vocab_size,n.hidden_size,2,c=>{l.lmHead=c},!0);for(let c of n.layers){let d=c.index,p=`${gn}.layers.${d}`,f=l.layers[d];u(`${p}.input_layernorm.weight`,[n.hidden_size],m=>{f.inputLn=m}),u(`${p}.post_attention_layernorm.weight`,[n.hidden_size],m=>{f.postAttnLn=m}),u(`${p}.pre_feedforward_layernorm.weight`,[n.hidden_size],m=>{f.preFfLn=m}),u(`${p}.post_feedforward_layernorm.weight`,[n.hidden_size],m=>{f.postFfLn=m}),u(`${p}.post_per_layer_input_norm.weight`,[n.hidden_size],m=>{f.postPleLn=m}),u(`${p}.layer_scalar`,[1],m=>{f.layerScalarT=m}),s(`${p}.self_attn.q_proj`,c.qOut,n.hidden_size,c.attnBits,m=>{f.qProj=m}),u(`${p}.self_attn.q_norm.weight`,[c.headDim],m=>{f.qNorm=m}),c.isKvShared?(f.kProj=null,f.vProj=null,f.kNorm=null):(s(`${p}.self_attn.k_proj`,c.kvOut,n.hidden_size,c.attnBits,m=>{f.kProj=m}),s(`${p}.self_attn.v_proj`,c.kvOut,n.hidden_size,c.attnBits,m=>{f.vProj=m}),u(`${p}.self_attn.k_norm.weight`,[c.headDim],m=>{f.kNorm=m})),s(`${p}.self_attn.o_proj`,n.hidden_size,c.qOut,c.attnBits,m=>{f.oProj=m}),s(`${p}.mlp.gate_proj`,c.intermediate,n.hidden_size,c.mlpBits,m=>{f.gateProj=m}),s(`${p}.mlp.up_proj`,c.intermediate,n.hidden_size,c.mlpBits,m=>{f.upProj=m}),s(`${p}.mlp.down_proj`,n.hidden_size,c.intermediate,c.mlpBits,m=>{f.downProj=m}),i(`${p}.per_layer_input_gate`,n.hidden_size_per_layer_input,n.hidden_size,m=>{f.perLayerInputGate=m}),i(`${p}.per_layer_projection`,n.hidden_size,n.hidden_size_per_layer_input,m=>{f.perLayerProjection=m})}await Zs(a,{source:r,reader:Js(r),context:{rt:e},concurrency:t.concurrency,chunkMaxBytes:t.chunkMaxBytes,onProgress:t.onProgress??null,signal:t.signal});for(let c of l.layers)c.gateGeluLutT=e.tensorFromTypedArray("float32",[256],kt(c.gateProj.outScale)),c.pleGeluLutT=e.tensorFromTypedArray("float32",[256],kt(c.perLayerInputGate.outScale));return l}var y=Math.fround,Y=(e,n,r)=>y(e*n+r);function vr(e,n){let r=y(e+n),t=y(r-e);return{x:r,y:y(y(e-y(r-t))+y(n-t))}}function Sr(e,n){let r=y(e.x+n),t=y(r-e.x);return{x:r,y:y(y(y(e.x-y(r-t))+y(n-t))+e.y)}}function up(e,n){let r=y(e.x+n.x),t=y(r-e.x),a=y(y(e.x-y(r-t))+y(n.x-t));return{x:r,y:y(a+y(e.y+n.y))}}function to(e,n){let r=y(e+n);return{x:r,y:y(y(e-r)+n)}}function At(e,n){let r=y(e+n.x);return{x:r,y:y(y(y(e-r)+n.x)+n.y)}}function lp(e,n){let r=y(e.x+n);return{x:r,y:y(y(y(e.x-r)+n)+e.y)}}function Et(e,n){let r=y(e.x+n.x);return{x:r,y:y(y(y(y(e.x-r)+n.x)+e.y)+n.y)}}function Tr(e,n){let r=y(e.x*n);return{x:r,y:Y(e.y,n,Y(e.x,n,-r))}}function xr(e,n){let r=y(e.x*n.x);return{x:r,y:Y(e.x,n.y,Y(e.y,n.x,Y(e.x,n.x,-r)))}}function ao(e,n){return Y(e.x,n.x,Y(e.y,n.x,y(e.x*n.y)))}function Er(e){let n=y(e.x*e.x);return{x:n,y:Y(y(e.x+e.x),e.y,Y(e.x,e.x,-n))}}function cp(e,n){let r=y(1/n.x),t=y(e.x*r),a=Y(r,e.x,-t),s=Y(-n.y,r,Y(-n.x,r,1));return{x:t,y:Y(t,s,Y(e.y,r,a))}}function dp(e){let n=y(e.x+e.y);return{x:n,y:y(y(e.x-n)+e.y)}}function pp(e,n){return{x:y(e.x*n),y:y(e.y*n)}}var Gt=new Float32Array(1),so=new Uint32Array(Gt.buffer);function oo(e){return Gt[0]=e,so[0]}function Pt(e){return so[0]=e>>>0,Gt[0]}function fp(e){let n=oo(e);return n=n>>>23&255,n-127}function mp(e,n){return Pt(oo(e)+(n<<23)|0)}function gp(e,n){let r=n>>31;r=(r+n>>6)-r<<4,n=n-(r<<2),r+=127,r=r>0?r:0,r=r>255?255:r;let t=Pt(r<<23>>>0);return e=y(y(y(y(e*t)*t)*t)*t),t=Pt(n+127<<23>>>0),y(e*t)}function kr(e){let n=Math.floor(e),r=e-n;return r>.5?n+1:r<.5||n%2===0?n:n+1}var hp=y(1.4426950408889634),yp=y(.693145751953125),bp=y(1428606765330187e-21),io=y(.3183098861837907),uo=y(3.1414794921875),lo=y(.0001131594181060791),co=y(1984187258941006e-24),wp=11754943508222875e-54;function _p(e){let n=el.type==="uniform");u?.buffer&&(o==="attn"?this.attnUniforms:this.cacheUniforms).push(u.buffer)}this.cleanups.push(s.cleanup),this.timing&&(this.collectMs+=performance.now()-t)}async buildSteps(){return this.rt.prepareProgramSequence(this.programs)}prependCopies(n){this.programs.unshift(...n.map(r=>({kind:"copy",src:r.src,dst:r.dst,srcOffset:r.srcOffset,dstOffset:0,byteLength:r.byteLength})))}enqueue(n){this.rt.enqueuePreparedProgramSequence(n)}disposeBuild(){for(let n of this.cleanups)n();this.programs=[],this.cleanups=[]}async flush(n=!0){if(this.programs.length===0)return;let r=this.timing?performance.now():0;await this.rt.runProgramSequence(this.programs,{wait:n}),this.timing&&(this.flushMs+=performance.now()-r);for(let t of this.cleanups)t();this.programs=[],this.cleanups=[]}};var oe={rms:ae("com.xenova.RMSNorm"),rope:ae("com.xenova.Rope1d"),mul:ae("com.xenova.MulBroadcast"),strided:ae("com.xenova.StridedCopy"),add:ae("com.xenova.AddInPlace"),qatMatmul:ae("com.xenova.gemma4.QatMatMul"),qatEmbed:ae("com.xenova.gemma4.QatEmbedGather"),attn:ae("com.xenova.gemma4.Attention"),argmax:ae("com.xenova.gemma4.ArgMax"),srq:ae("com.xenova.gemma4.SrqQuantize"),normAdd:ae("com.xenova.gemma4.DecodeNormAdd"),pleGate:ae("com.xenova.gemma4.PleGate"),gateUpNorm:ae("com.xenova.gemma4.DecodeGateUpNorm"),denseGemv:ae("com.xenova.gemma4.DenseGemv"),qkNormRope:ae("com.xenova.gemma4.DecodeQkNormRope"),pleGateFused:ae("com.xenova.gemma4.DecodePleGate"),rmsSrq:ae("com.xenova.gemma4.DecodeRmsSrq"),normAddNorm:ae("com.xenova.gemma4.DecodeNormAddNorm"),decodeAttn:ae("com.xenova.gemma4.DecodeAttention"),downNormAdd:ae("com.xenova.gemma4.DecodeDownNormAdd"),pleProjNorm:ae("com.xenova.gemma4.DecodePleProjNorm"),oprojNorm:ae("com.xenova.gemma4.DecodeOprojNorm"),qkvProj:ae("com.xenova.gemma4.DecodeQkvProj")},hn=e=>1<(1<>1,i=new Float32Array(n*o),u=new Float32Array(n*o),l=new Float32Array(o);for(let c=0;c>1,i=n.global_head_dim>>1;return{cosSlidingT:e.tensorFromTypedArray("float32",[r,o],a.cos),sinSlidingT:e.tensorFromTypedArray("float32",[r,o],a.sin),cosFullT:e.tensorFromTypedArray("float32",[r,i],s.cos),sinFullT:e.tensorFromTypedArray("float32",[r,i],s.sin)}},write(e,n,r,t,a){let{sliding:s,full:o}=ho(n,t,a);e.writeBuffer(r.cosSlidingT.buffer,0,s.cos),e.writeBuffer(r.sinSlidingT.buffer,0,s.sin),e.writeBuffer(r.cosFullT.buffer,0,o.cos),e.writeBuffer(r.sinFullT.buffer,0,o.sin)}};function ho(e,n,r){let t=e.head_dim>>1,a=Math.trunc(e.fullPartialRotaryFactor*e.global_head_dim/2);return{sliding:go(n,r,e.head_dim,e.slidingRopeTheta,t),full:go(n,r,e.global_head_dim,e.fullRopeTheta,a)}}async function nn(e,n){let r=await e.readTensor(n);return r instanceof Float32Array?new Float32Array(r):Float32Array.from(r)}async function Ot(e,n,r,t,a=!1,s,o=!0){let{rt:i,config:u,weights:l}=e,c=n.length,d=u.hidden_size,p=u.num_hidden_layers,f=u.hidden_size_per_layer_input,m=p*f,_=u.rms_norm_eps,E=u.num_attention_heads,b=u.vocab_size,W=E*u.global_head_dim,q=u.num_key_value_heads,G=q*u.global_head_dim,C=u.intermediate_size*2,S=new Xe(i),D=[],P=(z,j)=>{let ne=i.empty("float32",z,j);return D.push(ne),ne},N=(z,j)=>{let ne=i.tensorFromTypedArray(j instanceof Uint32Array?"uint32":"float32",z,j);return D.push(ne),ne},R=a?{hiddenStates:[],perLayerInputs:new Float32Array(0),lastHidden:new Float32Array(0),allLogits:new Float32Array(0)}:void 0,V=s?async(z,j)=>{await S.flush(),s.set(z,await nn(i,j))}:null;try{let z=N([1],new Float32Array([1/Math.sqrt(d)])),j=N([1],new Float32Array([Math.SQRT1_2])),ne=N([c],n),Q=P([c,d],"g4-hidden"),ve=P([c,m],"g4-ple"),Z=P([c,d],"g4-normed"),g=P([c,W],"g4-q"),w=P([c,W],"g4-qn"),T=P([c,G],"g4-k"),X=P([c,G],"g4-kn"),Be=P([c,G],"g4-v"),Te=P([c,G],"g4-vn"),Se=P([c,W],"g4-attn"),Ke=P([c,d],"g4-oproj"),Ze=P([c,d],"g4-ffnormed"),xe=P([c,C],"g4-gelu"),$=P([c,d],"g4-down"),K=P([c,f],"g4-ple-slice"),M=P([c,f],"g4-ple-gate"),J=P([c,f],"g4-ple-gelu"),ke=P([c,d],"g4-ple-projout"),x=P([c,d],"g4-aqH"),fe=P([c,W],"g4-aqQ"),pe=P([c,C],"g4-aqI"),ue=P([c,d],"g4-nrm-tail");S.qatEmbed({idsT:ne,bitsT:l.embedTokens.bitsT,scaleT:l.embedTokens.scaleT,yT:Q,seq:c,hidden:d,vocab:b,bits:l.embedTokens.bits,groupSize:d,embedScale:u.embedScale}),R&&(await S.flush(),R.hiddenStates.push(await nn(i,Q)));{let we=P([c,m],"g4-ple-id"),H=P([c,m],"g4-ple-proj");S.qatEmbed({idsT:ne,bitsT:l.embedTokensPerLayer.bitsT,scaleT:l.embedTokensPerLayer.scaleT,yT:we,seq:c,hidden:m,vocab:u.vocab_size_per_layer_input,bits:l.embedTokensPerLayer.bits,groupSize:f,embedScale:u.perLayerEmbedScale}),S.denseGemv({aT:Q,wT:l.perLayerModelProjection,outT:H,M:c,inFeatures:d,outFeatures:m,exact:o}),S.mul({xT:H,factorT:z,count:c*m,period:1}),S.rms({xT:H,wT:l.perLayerProjectionNorm,yT:ve,rows:c*p,dim:f,eps:_,exact:o}),S.addInPlace({yT:ve,xT:we,count:c*m}),S.mul({xT:ve,factorT:j,count:c*m,period:1})}R&&(await S.flush(),R.perLayerInputs=await nn(i,ve));let me=rn.create(i,u,c,r);D.push(me.cosSlidingT,me.sinSlidingT,me.cosFullT,me.sinFullT);for(let we=0;wer-t);return n[n.length>>1]}var Gr=class extends yn{model;cache;idsT;rope;attnUni=new Map;cacheUni=new Map;constructor(n,r){super(new Xe(n.rt)),this.model=n,this.cache=r}async build(n){let{rt:r,config:t,weights:a}=this.model,s=this.col,o=t.hidden_size,i=t.num_hidden_layers,u=t.hidden_size_per_layer_input,l=i*u,c=t.rms_norm_eps,d=t.num_attention_heads,p=t.vocab_size,f=d*t.global_head_dim,m=t.num_key_value_heads,_=m*t.global_head_dim,E=t.intermediate_size*2,b=1,W=this.uploadOwned([1],new Float32Array([1/Math.sqrt(o)])),q=this.uploadOwned([1],new Float32Array([Math.SQRT1_2]));this.idsT=this.uploadOwned([b],new Uint32Array([0])),this.rope=rn.create(r,t,b,n),this.owned.push(this.rope.cosSlidingT,this.rope.sinSlidingT,this.rope.cosFullT,this.rope.sinFullT);let G=this.allocOwned([b,o],"g4d-hidden"),C=this.allocOwned([b,l],"g4d-ple"),S=this.allocOwned([b,o],"g4d-normed"),D=this.allocOwned([b,f],"g4d-q"),P=this.allocOwned([b,_],"g4d-k"),N=this.allocOwned([b,_],"g4d-kn"),R=this.allocOwned([b,_],"g4d-v"),V=this.allocOwned([b,_],"g4d-vn"),z=this.allocOwned([b,f],"g4d-attn"),j=this.allocOwned([b,o],"g4d-ffnormed","float16"),ne=this.allocOwned([b,E],"g4d-gelu","float16"),Q=this.allocOwned([b,u],"g4d-ple-gelu"),ve=this.allocOwned([b],"g4d-ff-suma"),Z=this.allocOwned([b],"g4d-n-suma"),g=this.allocOwned([b,o],"g4d-final-norm"),w=this.allocOwned([b,l],"g4d-ple-id"),T=this.allocOwned([b,l],"g4d-ple-proj"),X=this.allocOwned([1,p],"g4d-logits"),Be=($,K,M)=>{let J=$.get(K);return J||(J=r.createUniformU32(new Uint32Array(8),`${M}-${K}`),$.set(K,J)),J},Te=($,K,M,J,ke,x,fe=b,pe)=>{s.qatMatmul({aT:$,bitsT:M.bitsT,scaleT:M.scaleT,sumAT:pe,outT:ke,M:fe,inFeatures:K,outFeatures:J,bits:x,inputScale:M.inScale,outputScale:M.outScale,blockMajor:M.blockMajor})},Se=t.layers.map(($,K)=>{let M=a.layers[K];return!$.isKvShared&&!!M.kProj&&!!M.vProj&&M.kProj.bits===M.qProj.bits&&M.vProj.bits===M.qProj.bits&&!M.qProj.blockMajor&&!_e.has("qproj")&&!_e.has("kv")}),Ke=[],Ze=[],xe=[];{let $=[],K=(M,J,ke,x)=>$.push({kind:"copy",name:"g4d-weight-pack",src:M,dst:J,srcOffset:0,dstOffset:ke,byteLength:x});for(let M=0;Mt[0])}async step(n,r){let{rt:t}=this.model;if(this.writeStepInputs(n,r),yo){let s=performance.now();this.col.enqueue(this.steps);let o=performance.now();await t.queueIdle();let i=performance.now(),u=await t.readTensor(this.idsT),l=performance.now();return Ar.push(o-s),Rt.push(i-o),Wt.push(l-i),u[0]}return this.col.enqueue(this.steps),(await t.readTensor(this.idsT))[0]}get _diagnostics(){return{rt:this.model.rt,idsT:this.idsT,steps:this.steps,writeStepInputs:(n,r)=>this.writeStepInputs(n,r),enqueue:()=>this.col.enqueue(this.steps),measureGpuMs:()=>this.model.rt.measurePreparedSequenceGpuMs?this.model.rt.measurePreparedSequenceGpuMs(this.steps):Promise.resolve(null)}}reportTiming(){if(!yo||Ar.length===0)return;let n=Ar.slice(2),r=Rt.slice(2),t=Wt.slice(2);console.error(`[g4d] per-token median: cpu-encode=${Ft(n).toFixed(2)}ms gpu-compute=${Ft(r).toFixed(2)}ms readback=${Ft(t).toFixed(2)}ms (n=${n.length})`),Ar.length=0,Rt.length=0,Wt.length=0}dispose(){this.reportTiming(),super.dispose();for(let n of[...this.attnUni.values(),...this.cacheUni.values()])n.destroy?.();this.attnUni.clear(),this.cacheUni.clear()}};var Tp=()=>!1,ie=new Set("".split(",").filter(Boolean)),Or=class extends yn{model;cache;blockLen;idsT;tokenIdT;lastRowUniform=null;rope;attn=[];cacheWrites=[];hiddenSize;constructor(n,r,t){super(new Xe(n.rt)),this.model=n,this.cache=r,this.blockLen=t,this.hiddenSize=n.config.hidden_size}async build(){let n=Tp(),{rt:r,config:t,weights:a}=this.model,s=this.col,o=this.cache,i=this.blockLen,u=0,l=t.hidden_size,c=t.num_hidden_layers,d=t.hidden_size_per_layer_input,p=c*d,f=t.rms_norm_eps,m=t.num_attention_heads,_=t.vocab_size,E=m*t.global_head_dim,b=t.num_key_value_heads,W=b*t.global_head_dim,q=t.intermediate_size*2,G=this.uploadOwned([1],new Float32Array([1/Math.sqrt(l)])),C=this.uploadOwned([1],new Float32Array([Math.SQRT1_2]));this.idsT=this.uploadOwned([i],new Uint32Array(i)),this.tokenIdT=this.uploadOwned([1],new Uint32Array(1));let S=this.allocOwned([i,l],"g4p-hidden"),D=this.allocOwned([i,p],"g4p-ple"),P=this.allocOwned([i,l],"g4p-normed"),N=this.allocOwned([i,E],"g4p-q"),R=this.allocOwned([i,E],"g4p-qn"),V=this.allocOwned([i,W],"g4p-k"),z=this.allocOwned([i,W],"g4p-kn"),j=this.allocOwned([i,W],"g4p-v"),ne=this.allocOwned([i,W],"g4p-vn"),Q=this.allocOwned([i,E],"g4p-attn"),ve=this.allocOwned([i,l],"g4p-oproj"),Z=this.allocOwned([i,l],"g4p-ffnormed"),g=this.allocOwned([i,q],"g4p-gelu"),w=this.allocOwned([i,l],"g4p-down"),T=this.allocOwned([i,d],"g4p-ple-slice"),X=this.allocOwned([i,d],"g4p-ple-gate"),Be=this.allocOwned([i,d],"g4p-ple-gelu"),Te=this.allocOwned([i,l],"g4p-ple-projout"),Se=this.allocOwned([i,l],"g4p-aqH"),Ke=this.allocOwned([i,E],"g4p-aqQ"),Ze=this.allocOwned([i,q],"g4p-aqI"),xe=this.allocOwned([i,l],"g4p-nrm-tail"),$=this.allocOwned([1,_],"g4p-logits");s.qatEmbed({idsT:this.idsT,bitsT:a.embedTokens.bitsT,scaleT:a.embedTokens.scaleT,yT:S,seq:i,hidden:l,vocab:_,bits:a.embedTokens.bits,groupSize:l,embedScale:t.embedScale});let K=this.allocOwned([i,p],"g4p-ple-id"),M=this.allocOwned([i,p],"g4p-ple-proj");s.qatEmbed({idsT:this.idsT,bitsT:a.embedTokensPerLayer.bitsT,scaleT:a.embedTokensPerLayer.scaleT,yT:K,seq:i,hidden:p,vocab:t.vocab_size_per_layer_input,bits:a.embedTokensPerLayer.bits,groupSize:d,embedScale:t.perLayerEmbedScale}),ie.has("ple")||s.denseGemv({aT:S,wT:a.perLayerModelProjection,outT:M,M:i,inFeatures:l,outFeatures:p,exact:n}),s.mul({xT:M,factorT:G,count:i*p,period:1}),ie.has("rms")||s.rms({xT:M,wT:a.perLayerProjectionNorm,yT:D,rows:i*c,dim:d,eps:f,exact:n}),s.addInPlace({yT:D,xT:K,count:i*p}),s.mul({xT:D,factorT:C,count:i*p,period:1}),this.rope=rn.create(r,t,i,u),this.owned.push(this.rope.cosSlidingT,this.rope.sinSlidingT,this.rope.cosFullT,this.rope.sinFullT);for(let fe=0;fethis.blockLen)throw new Error(`prefill block ${this.blockLen} cannot run ${n.length} tokens`);let{rt:t,config:a}=this.model,s=t.host,o=this.blockLen,i=new Uint32Array(o);i.set(n),s.writeBuffer(this.idsT.buffer,0,i),rn.write(s,a,this.rope,r,o);let u=a.num_attention_heads,l=a.num_key_value_heads,c=r+o;for(let f of this.attn)s.writeBuffer(f.buffer,0,new Uint32Array([o,c,r,u,l,f.window,0,0]));for(let f of this.cacheWrites)s.writeBuffer(f.buffer,0,new Uint32Array([o,f.kv,f.kv,0,f.kv,r*f.kv,0,0]));let d=this.hiddenSize;return s.writeBuffer(this.lastRowUniform,0,new Uint32Array([1,d,d,(n.length-1)*d,d,0,0,0])),this.col.enqueue(this.steps),(await t.readTensor(this.tokenIdT))[0]}};async function*wo(e){let n=[];for(;n.length0;){let r=n.shift();e.shouldSubmit()&&n.lengththis.#i(r)}}catch(t){throw this.#i(r),t}}#i(n){if(n.maxLength===Un.defaultCapacity(this.config)&&this.#e.length<2){this.#e.push(n);return}n.dispose()}async#s(n,r){let t=this.#r.get(n);return t||(t=new Gr(this,n),await t.build(r),this.#r.set(n,t),this.#n.push(t)),t}async#o(n,r,t){if(t+r.length<=n.maxLength){let u=this.#a.get(n);if(!u){u=new Map,this.#a.set(n,u);let p=256;for(let f of[32,128,256]){if(f>n.maxLength||f>p)continue;let m=new Or(this,n,f);await m.build(),u.set(f,m),this.#t.push(m)}}let l=0,c=t,d=0;for(;l192&&u.has(256)?256:p>96&&u.has(128)?128:32,m=Math.min(p,f);if(c+f>n.maxLength||!u.has(f))return(await Ot(this,r.subarray(l),c,n)).nextToken;let _=0;d=await u.get(f).run(r.subarray(l,l+m),c),l+=m,c+=m}return d}return(await Ot(this,r,t,n)).nextToken}async*streamTokenIdsFromCache(n){let r=n.generation_state;if(!r?.cache)throw new Error("streamTokenIdsFromCache requires generation_state.cache");yield*this.#u(So(n.input_ids),r.cache,n)}async*streamTokenIds(n){let r=this.createGenerationState(n.generation_state??{});try{yield*this.#u(So(n.input_ids),r.cache,n)}finally{this.#i(r.cache)}}async*#u(n,r,t){let{maxNewTokens:a,eosTokenId:s,stopOnEos:o,onPrefillDone:i}=_o(t);if(n.length===0)throw new Error("streamTokenIds requires at least one input token");let u=r.get_seq_length(),l=0,c=await this.#o(r,n,u);l&&console.error(`[ttft] #prefill total ${(performance.now()-l).toFixed(2)}ms (tokens=${n.length})`),r.advance(n.length),u=r.get_seq_length(),i?.({tokens:n.length,cache_length:u});let d=c,p=0,f=null;try{if(vo>1){if(o&&Rr(d,s)||(yield d,p+=1,p>=a))return;let m=f=await this.#s(r,u),_=a-p,E=0;yield*wo({depth:vo,shouldSubmit:()=>E<_,submit:()=>{let b={result:m.submitStep(E===0?d:null,u+E)};return E+=1,b},accept:function*(b,W){return r.advance(1),o&&Rr(W,s)?!0:(yield W,p+=1,p>=a)}});return}for(;p=a));){f||(f=await this.#s(r,u));let m=await f.step(d,u);r.advance(1),u=r.get_seq_length(),d=m}}finally{f?.reportTiming()}}dispose(){for(let n of this.#n)n.dispose();for(let n of this.#t)n.dispose();for(let n of this.#e)n.dispose();this.#e.length=0,en(this.weights)}};var To="google/gemma-4-E2B-it-qat-mobile-transformers",xp="https://huggingface.co",kp=[1,106];function Ep(e,n="main"){let r=e??To;return/^https?:/i.test(r)||r.startsWith("/")||r.startsWith(".")?r:`${xp}/${r}/resolve/${n}`}var Mt=class e{static DEFAULT_MODEL_ID=To;#e;#r;#n;#a;#t;#i;#s;#o;#u=[];#l=!1;constructor(n){this.#e=n.runtime,this.#r=n.ownsRuntime,this.#n=n.model,this.#a=n.tokenizer,this.#t=n.chatTemplate,this.#i=n.tokenizerConfig,this.#s=n.eosTokenIds,this.#o=n.model.createGenerationState({})}static async load(n=null,r={}){let t=r.onProgress??(()=>{}),a=Ep(n,r.revision??"main"),s=r.fetch??(r.accessToken?Op(r.accessToken):void 0),o={cache:r.cache,force:r.force,cacheName:r.cacheName,fetch:s,signal:r.signal};t({status:"init",message:"Requesting WebGPU device"});let i=r.runtime??await vs(r.runtimeOptions??{}),u=!r.runtime;i.captureShaders=!0;try{t({status:"tokenizer",message:"Loading tokenizer"});let{tokenizer:l,chatTemplate:c,tokenizerConfig:d}=await Pp(a,o),p=await Ap(a,o);t({status:"weights",kind:"bytes",message:"Downloading weights",loaded:0,total:void 0});let f=await Wr.fromSnapshot(i,a,mn,{cache:r.cache,force:r.force,cacheName:r.cacheName,fetch:s,signal:r.signal,onProgress:m=>{let _=m;if(bn(_.processed)){t({status:"weights",kind:"tensors",loaded:_.processed,total:bn(_.total)?_.total:void 0,fraction:bn(_.total)&&_.total>0?_.processed/_.total:void 0,message:_.label});return}bn(_.loaded)&&t({status:"weights",kind:"bytes",loaded:_.loaded,total:bn(_.total)?_.total:null,fraction:bn(_.total)&&_.total>0?_.loaded/_.total:void 0,fromCache:_.fromCache,message:_.fromCache?"Loading cached weights":"Downloading weights"})}});return t({status:"ready",message:"Ready",fraction:1}),new e({runtime:i,ownsRuntime:u,model:f,tokenizer:l,chatTemplate:c,tokenizerConfig:d,eosTokenIds:p})}catch(l){throw u&&await i.destroy(),l}}get runtime(){return this.#e}encodePrompt(n){let r=this.#t.render({messages:n,tools:null,bos_token:this.#i.bos_token,eos_token:this.#i.eos_token,add_generation_prompt:!0});return this.#a.encode(r,{add_special_tokens:!1}).ids}async*generate(n,r={}){if(this.#l)throw new Error("Gemma4Mobile has been disposed");let t=r.maxNewTokens??512,a=r.eosTokenId??this.#s,s=this.encodePrompt(n),o=Gp(this.#u,s);o!==this.#u.length&&(this.#c(),o=0);let i=s.slice(o);i.length===0&&(this.#c(),i=s.slice());let u=[],l="",c=!1;try{for await(let d of this.#n.streamTokenIdsFromCache({input_ids:[i],generation_state:this.#o,max_new_tokens:t,eos_token_id:a,stop_on_eos:!0})){if(r.signal?.aborted){c=!0;break}u.push(d);let p=this.#a.decode(u,{skip_special_tokens:!0}),f=p.startsWith(l)?p.slice(l.length):this.#a.decode([d],{skip_special_tokens:!0});l=p,yield{token:d,delta:f,text:l}}}finally{if(c)this.#c();else{let d=u.length{try{return n.features.has(a)}catch{return!1}};return{vendor:r.vendor??"",architecture:r.architecture??"",device:r.device??"",description:r.description??"",isFallbackAdapter:r.isFallbackAdapter===!0,subgroupMinSize:r.subgroupMinSize,subgroupMaxSize:r.subgroupMaxSize,features:{shaderF16:t("shader-f16"),subgroups:t("subgroups"),subgroupMatrix:t("chromium-experimental-subgroup-matrix"),timestampQuery:t("timestamp-query")}}}get _model(){return this.#n}get _generationState(){return this.#o}get _eosTokenIds(){return this.#s}get _disposed(){return this.#l}reset(){this.#c()}#c(){this.#o.cache.truncate(0),this.#u=[]}dispose(){this.#l||(this.#l=!0,this.#n.dispose(),this.#r&&this.#e.destroy())}};async function Pp(e,n){let r=await mn.readJsonResource(e,"tokenizer.json",n),t=await mn.readJsonResource(e,"tokenizer_config.json",n),a=new fa(r,t),s=typeof t.chat_template=="string"?t.chat_template:await mn.readTextResourceOptional(e,"chat_template.jinja",n);if(!s)throw new Error("Gemma4 tokenizer is missing a chat_template (tokenizer_config.json / chat_template.jinja)");return{tokenizer:a,chatTemplate:new Hn(s),tokenizerConfig:t}}async function Ap(e,n){let t=(await mn.readJsonResourceOptional(e,"generation_config.json",n))?.eos_token_id;return typeof t=="number"?[t]:Array.isArray(t)&&t.length>0?t:[...kp]}function Gp(e,n){let r=Math.min(e.length,n.length),t=0;for(;t{let t=new Headers(r.headers);return t.set("Authorization",`Bearer ${e}`),globalThis.fetch(n,{...r,headers:t})}}var gy=Mt;export{To as DEFAULT_MODEL_ID,Mt as Gemma4Mobile,gy as default,Ep as resolveModelRoot};