For a guide on Neowtext, please see: Help:Neowtext


-- MIT License https://github.com/paradoxum-wikis/neowbunto
package.preload.render=package.preload.render or function()local e=require("config");local t=require("parser");local a=require("eval");local o=require("wikitable");local i=require("tablecache");local n=string.byte;local s={[32]=true,[9]=true,[10]=true,[11]=true,[12]=true,[13]=true};local function h(e)local e=tostring(e or"");if s[n(e,1)]or s[n(e,-1)]then local t=e:find("%S")or(#e+1);local a=#e;while(a>=t)and e:find("^%s",a)do a=a-1;end return e:sub(t,a);else return e;end end local function r(e)local t=1;local function a()if t then local a=e:find("\n",t,true);local e=e:sub(t,(a or(#e+1))-1);t=a and(a+1);return e;else return nil;end end return a;end local d=false;local l={};local c={[2]="%.2f",[3]="%.3f"};local function u()if d==false then local e=mw and mw.language and mw.language.getContentLanguage();if e and e.formatNum then local function t(t)return e:formatNum(t);end d=t;else d=nil;end else end return d;end local function m(e)if n(e,-1)==48 then return(e:gsub("%.?0+$",""));else return e;end end local function w(e,t)if type(e)~="number"then return tostring(e);else if d==false then u();else end local t=t or 2;local e=(c[t]or("%."..t.."f")):format(e);if d then local t=l[e];if not t then local a=d(tonumber(m(e)));l[e]=a;t=a;end return t;else return tostring(tonumber(m(e)));end end end local function c(e)local t="";local e=tostring(e or"");for e in e:gmatch("|%s*([^|\n]+)%s*")do local e=h(e);if not e:match("^%-*$")and not e:match("=%s*$")then local e=e:gsub("[^%a%d]+","");if(e~="")and(e:lower()~="tabber")then t=e;else end else end end if(t=="")and e:find("-",1,true)and e:find("=",1,true)then for e in e:gmatch("%-?%-%s*|?%s*([^|\n<>={}\t/]+)%s*=%s*")do local e=h(e):gsub("[^%a%d]+","");if e~=""then t=e;else end end else end return t;end local function m(e)if e then math.randomseed(e);else end if not e and os and os.clock then math.randomseed(math.floor(os.clock()*777777777));else end return{id="rofbug-"..tostring(math.random(100000,999999)),classes={},["cell-count"]=0};end local function f(e)local t=e.id.."-c"..e["cell-count"];e["cell-count"]=e["cell-count"]+1;table.insert(e.classes,"mw-customtoggle-"..t.."-off");table.insert(e.classes,"mw-customtoggle-"..t.."-on");return t;end local function g(e,t,a)return'<span class="mw-collapsible mw-collapsed" id="mw-customcollapsible-'..e..'-off">'..t.."</span>"..'<span class="mw-collapsible" id="mw-customcollapsible-'..e..'-on">'..a.."</span>";end local function y()local e=mw and mw.title and mw.title.getCurrentTitle();local e=(e and e.text)or"";return(e~="")and e:find("/History",1,true)and true;end local function p(e)if not e or y()then return nil;else local e=mw and mw.title and mw.title.getCurrentTitle();local e=(e and e.text)or"TestPage";local t;if mw and mw.uri and mw.uri.encode then t=mw.uri.encode(e,"PATH");else t=e;end return'<div class="wds-button open-se">'.."[https://se.tds.wiki/tower/"..t.." Open in Statistics Editor]</div>";end end local function b(e,t,a)local o=t.id.."-label";local i={};for e,e in ipairs(t.classes)do table.insert(i,e);end table.insert(i,"mw-customtoggle-"..o.."-off");table.insert(i,"mw-customtoggle-"..o.."-on");local t=table.concat(i," ");local t='<div class="wds-button '..t..'">'..'<span class="mw-collapsible" id="mw-customcollapsible-'..o..'-on">Disable Rate of Fire Bug</span>'..'<span class="mw-collapsible mw-collapsed" id="mw-customcollapsible-'..o..'-off">Enable Rate of Fire Bug</span></div>';local a=p(a)or"";local e="<div>\n"..e.."\n</div>";return'<div class="rofbug-wrapper">'..t..a..e.."</div>";end local function v(e,a)if a[e]then return true;elseif e=="FNC-TOTALPRICE"then return true;elseif e:match("^FNC%-TOTAL%-(.+)$")then return true;elseif e:find("@",1,true)then local e=t["parse-pin-parts"](e);return a[e]or(e=="FNC-TOTALPRICE")or(e:match("^FNC%-TOTAL%-(.+)$")~=nil);else return false;end end local function k(e,o,i,n)return a["eval-node"](o,t["parse-var"](e,i,n,{}));end local function t(e,t,o,i)local n=o[e]and i[e];if n then local e,t=pcall(a["eval-node"],t,n);if e then return t;else return nil;end elseif not v(e,o)then return nil;else local e,t=pcall(k,e,t,o,i);if e then return t;else return nil;end end end local v=nil;local k=nil;local x=nil;local j=0;local q=nil;local function z(e)local t=t(e,v,k,x);if t==nil then return"$"..e.."$";elseif type(t)=="number"then return w(t);else local e=tostring(t);if e:find("$",1,true)then return q(e);else return e;end end end local function E(e)j=j+1;if j>12 then error("expand-dollars: nesting too deep");else end local e=tostring(e or""):gsub("%$([^%$]+)%$",z);j=j-1;return e;end q=E;local function z(e,t,a,o)v=t;k=a;x=o;j=-1;return q(e);end local function v(e)local t=tonumber(e);if not t then local a;local o=type(e)=="string";if o then if e:find("$",1,true)then o=e:gsub("%$%a[^%$]*%$","");else o=e;end end a=o;local a=a and a:match("[%d,]+%.?%d*");t=(a and tonumber((a:gsub(",",""))))or e;end return t;end local function k(e,t)local a="";local o=false;if e:lower():find("colspan",1,true)then for e in r(e)do if o then break;end local e=h(e);if(n(e,1)==33)and e:lower():find("colspan",1,true)then do local e=e:match("%|(.+)$");if e then local e=h(e);a=(t and t[e])or(t and t[e:gsub("%s+","")])or"";else end end o=true;else end end else end return a;end local function x(t,a,o,n,s,h,r,d)local a=a or"";local l=e["parse-number-list"](t[e["get-var-key"](t,a,"COST")]or"");local e=e["parse-schema"](t[e["get-var-key"](t,a,"SCHEMA")]);local d=d or{};local i=i["scope-page-cache"](h,a);local h={vars=t,prefix=a,costs=l,schema=e,["branch-map"]=d,["formula-env"]=o};return{vars=t,prefix=a,["formula-env"]=o,["parse-cache"]=n,["formula-asts"]=n,frame=s,["table-cache"]=i,branch=r or"",["branch-map"]=d,costs=l,schema=e,config=h};end local function j(e,t,o,i)return a["make-ctx"]({row=t or{},level=i or 0,branch=e.branch,["rof?"]=o or false,["table-cache"]=e["table-cache"],frame=e.frame,vars=e.vars,prefix=e.prefix,["formula-env"]=e["formula-env"],["parse-cache"]=e["parse-cache"],["formula-asts"]=e["formula-asts"],costs=e.costs,schema=e.schema,["branch-map"]=e["branch-map"],config=e.config});end local function q(e,t,a,o)e[t]=o;if a~=t then e[a]=o;else end return o;end local function E(e)for t in pairs(e)do e[t]=nil;end return e;end local function T(e,t,d,l,c,u,m,y,p,b,T,A,O,I)local N={};local S={};local H={};local R={};local I=(I or o["parse-table"](e,{},true))["line-cells"];local D={};local c=c or{};local L=next(c);local k=k(e,m);local m=A or x(t,T,d,l,y,b,k,m);m.branch=k;local y=j(m,{},false,0);local b;if L then b=j(m,{},true,0);else b=nil;end local m;local k=O;if not k then local e={};for t,a in pairs(t)do local o,i;if h(a)=="$FNC-RECURSION$"then o,i=t,true;else o,i=nil;end if(o~=nil)and(i~=nil)then e[o]=i;else end end k=e;end m=k;local t=next(m);local k=-1;local x=1;local j=0;local T={};local A={};local O=nil;local C=L and{};local function U(e)local function t(e)if m["$"..e.."$"]then return"$FNC-RECURSION$";else return"$"..e.."$";end end return(e:gsub("%$([^%$]+)%$",t));end local function m()O=T;a["bind-ctx!"](y,T,false,k);if L then return a["bind-ctx!"](b,C,true,k);else return nil;end end for e in r(e)do local r;if s[n(e,1)]then r=h(e);else r=e;end local s=n(r,1);if(s==124)and(n(r,2)==45)then x=1;if O==T then local e=T;T=E(A);A=e;else E(T);end if L then E(C);else end if k>=0 then q(T,"Level","Level",k);if L then q(C,"Level","Level",k);else end else end table.insert(H,e);elseif(s==33)and not r:lower():find("colspan",1,true)then j=j+1;if r:find("$",1,true)then local e=r:sub(2);local e=e:gsub("%|%|","!!");for e in(e.."!!"):gmatch("([^!]*)!!")do local e=h(e);if e~=""then local e=z(e,y,d,l);local e=o["clean-header-text"](e);if e~=""then table.insert(N,e);table.insert(S,(e:gsub("%s+","")));else end else end end else for e,e in ipairs(I[j])do table.insert(N,e);table.insert(S,(e:gsub("%s+","")));end end table.insert(H,e);elseif(s==124)and(n(r,2)~=125)then j=j+1;local e=I[j];m();for e,n in ipairs(e)do local n=n;if t then local e=U(n);if e:find("$FNC-RECURSION$",1,true)then local e=e:gsub("%$FNC%-RECURSION%$","");local e=h(e);if e~=""then R[x]=e;n=e;else n=R[x]or"";end else R[x]=nil;end else end local t=N[x];local s=S[x];if t=="Level"then do local e=o["parse-level-keys"](n);if#e>0 then local e=e[1];local t=tostring(e);local t=t:match("^%d+");k=((type(e)=="number")and e)or(t and tonumber(t))or(k+1);else k=tonumber(n)or(k+1);end end q(T,"Level","Level",k);if L then q(C,"Level","Level",k);else end m();else end local o=n;local h=n;if n:find("$",1,true)then o=z(n,y,d,l);if L then h=z(n,b,d,l);else end else end if o:find("{{#expr:",1,true)then o=a["expand-inline-expr"](o,y);else end if L and h:find("{{#expr:",1,true)then h=a["expand-inline-expr"](h,b);else end if t then q(T,t,s,v(o));if L then q(C,t,s,v(h));else end else end if L and t and c[t]then local e=tonumber(o)or tonumber(o:match("%d+%.?%d*"));if e then local e=i["rof-bug"](e,u);q(C,t,s,e);h=w(e,3);else end else end if L and(tostring(o)~=tostring(h))then local t=f(p);D[e]=g(t,tostring(o),tostring(h));else D[e]=o;end x=x+1;end table.insert(H,"|"..table.concat(D,"||",1,#e));else table.insert(H,e);end end return table.concat(H,"\n");end local function a(e,t)return e:match(t..'%s*=%s*"([^"]+)"')or e:match(t.."%s*=%s*'([^']+)'")or e:match(t.."%s*=%s*([^%s\"'/>]+)");end local function s(e,o,i,n,s)local s=s or{};local h={};local r={};local o=x(o,s.prefix or"",i,n,s.frame,s["table-cache"]or{},"",s["branch-map"]or{});local o=j(o,{},false,0);if not e:find("$",1,true)then return e;else for e in e:gmatch("%$([^%$]+)%$")do local e="$"..e.."$";h[e]=(h[e]or 0)+1;end local function s(e)local s="$"..e.."$";local t=t(e,o,i,n);if t==nil then if e:match("^FNC%-")then return"";else return s;end elseif type(t)=="number"then return w(t);else local t=tostring(t);local d,l=t:match("^%s*<ref%s*([^>]*)>(.-)</ref>%s*$");if d and((h[s]or 0)>1)then local e=e:gsub("[^%a%d]","");local e=a(d,"name")or e:lower();local t=a(d,"group");local a;if t then a=' group="'..t..'"';else a="";end local t=(r[s]or 0)+1;r[s]=t;if t==1 then return"<ref"..a..' name="'..e..'">'..l.."</ref>";else return"<ref"..a..' name="'..e..'"/>';end elseif t:find("$",1,true)then return z(t,o,i,n);else return t;end end end return(e:gsub("%$([^%$]+)%$",s));end end local function t(t,a,n,r,d)local l=(n and n["formula-env"])or e["formula-env"](a);local u={};local m=(n and n["rof-cols"])or{};local w=n and n["rof-offset"];local f=(n and n.prefix)or"";local g=(n and n["branch-map"])or{};local y=o["find-table-spans"](t);local p={};local b={};local v={};local k={};local j;do local e={};for t,a in pairs(a)do local o,i;if h(a)=="$FNC-RECURSION$"then o,i=t,true;else o,i=nil;end if(o~=nil)and(i~=nil)then e[o]=i;else end end j=e;end local q={};local z=#t;local E=1;local A="";for e,e in ipairs(y)do local a;if E<e.start then a=t:sub(E,e.start-1);else a="";end local t=c(a);local i;if t~=""then i=t;else i=A;end if t~=""then A=t;else end table.insert(v,a);table.insert(p,o["parse-table"](e.text,g,true));table.insert(b,i);E=e.stop+1;end local o=i["build-page-cache"](p,{prefix=f,["table-prefixes"]=b,["index-overrides"]=(n and n.index)or{},["rof-cols"]=m,["rof-offset"]=w});for t,i in ipairs(y)do local n=v[t];local s=b[t];if n~=""then table.insert(q,n);else end local n=k[s];local h;if n then h=n["branch-map"];else h=e["build-branch-map"](a,s);end local e=n or x(a,s,l,u,r,o,"",h);k[s]=e;local e=T(i.text,a,l,u,m,w,h,r,d,o,s,e,j,p[t]);table.insert(q,e);end if E<=z then table.insert(q,t:sub(E));else end return h(s(table.concat(q),a,l,u,{frame=r,["table-cache"]=o,prefix=f,["branch-map"]=g}));end local function a(e)return(e==32)or(e==9);end local function o(e)local e=tostring(e or"");local t={};local o=1;local i=1;local s=true;while s do local h=e:find("<var>",i,true);local r=h and e:find("</var>",h+5,true);if not r then s=false;else local s=h;while(s>o)and a(n(e,s-1))do s=s-1;end local h=r+6;while a(n(e,h))do h=h+1;end if n(e,h)==10 then h=h+1;else end table.insert(t,e:sub(o,s-1));o=h;i=h;end end table.insert(t,e:sub(o));return table.concat(t);end local function a(a,i,n)local n=n or{};d=false;l={};u();local e,s=e["parse-page-config"](a,n.prefix or"");local h=e.vars;local a=o(a);local o=next(e["rof-cols"]);local r=m(n.seed);local e=t(a,h,e,i,r);local t=s or n["is-fse"];if o then return b(e,r,t);elseif t then local t=p(true)or"";return'<div class="rofbug-wrapper">'..t.."</div>\n"..e;else return e;end end return{fmt=w,["extract-prefix"]=c,["new-toggle-builder"]=m,["next-cell-toggle!"]=f,["rof-cell-html"]=g,["make-editor-btn-html"]=p,["history-page?"]=y,["wrap-rofbug"]=b,["process-table"]=T,["build-out"]=t,["strip-var-blocks"]=o,["render-page"]=a,["finalize-output"]=s,["expand-dollars"]=z};end;package.preload.config=package.preload.config or function()local e=string.byte;local t=string.find;local a=string.sub;local o={[32]=true,[9]=true,[10]=true,[11]=true,[12]=true,[13]=true};local function i(t,i,n)local i=i;local n=n;while(i<=n)and o[e(t,i)]do i=i+1;end while(i<=n)and o[e(t,n)]do n=n-1;end return a(t,i,n);end local function n(t)local t=tostring(t or"");if o[e(t,1)]or o[e(t,-1)]then return i(t,1,#t);else return t;end end local function e(e)local o={};local e=tostring(e or"");local i=1;local n=t(e,"\n",1,true);while n do table.insert(o,a(e,i,n-1));i=n+1;n=t(e,"\n",i,true);end table.insert(o,a(e,i));return o;end local function a(e)local a={};local e=tostring(e or"");local o=#e;if e~=""then local n=1;local s=false;while not s do local t=t(e,";",n,true);local h;if t then h=t-1;else h=o;end table.insert(a,i(e,n,h));if t then n=t+1;else s=true;end end else end return a;end local function o(e)return tostring(e):match("^%$(.*)%$$")or tostring(e);end local function i(e)return"$"..e.."$";end local function s(e)return e:match("^FNC%-")or e:match("^FSE%-")or e:match("^ROFBUG");end local function h(e)return not s(e);end local function r(t)local a={};local o=false;for t in tostring(t or""):gmatch("<var>(.-)</var>")do local e=e(t);local t=1;while t<=#e do do local s=n(e[t]);if s~=""then local h=s:find("=",1,true);if h then local r=n(s:sub(1,h-1));local s=n(s:sub(h+1));do local a=s:sub(1,1);if((a=='"')or(a=="'"))and((s==a)or(s:sub(-1)~=a))then local o={s:sub(2)};local i=false;while not i and(t<#e)do t=t+1;table.insert(o,e[t]);if n(e[t]):sub(-1)==a then local e=table.concat(o,"\n");local t=e:find(a.."[^"..a.."]*$");if t then s=e:sub(1,t-1);else end i=true;else end end elseif(a=='"')or(a=="'")then s=s:sub(2,-2);else end end if not r:match("^%$.*%$$")then r=i(r);else end a[r]=s;if not o and r:find("FSE-",1,true)then o=true;else end else end else end end t=t+1;end end return a,o;end local function d(e,t,a)local t=t or"";if t~=""then local t=i("FNC-"..t.."-"..a);if e[t]~=nil then return t;else return i("FNC-"..a);end else return i("FNC-"..a);end end local function l(e,t,a)local t=t or"";if t~=""then local t=i(t.."-"..a);if e[t]~=nil then return t;else return i(a);end else return i(a);end end local function c(e)local e=tostring(e or"");if t(e,"<",1,true)then e=e:gsub("<ref[^>]*>.-</ref>","");e=e:gsub("<ref[^>]*/>","");else end return n(e);end local function t(e)local e=c(e);local t=e:lower();if e==""then return false;elseif e:find("{{",1,true)or t:find("#expr",1,true)then return false;elseif not e:find(";",1,true)then return tonumber((e:gsub(",","")))~=nil;else local t=true;for e,e in ipairs(a(e))do if not t then break;end if(e~="")and(tonumber((e:gsub(",","")))==nil)then t=false;else end end return t;end end local function c(e)local t={};local o=0;for e,e in ipairs(a(e))do local a;if e==""then a=0;else local t=tonumber(e)or tonumber((e:gsub(",","")));if not t then error("config: not a number in list: `"..e.."`");else end a=t;end if nil~=a then o=o+1;t[o]=a;else end end return t;end local function u(e)local t={};local o=0;for e,e in ipairs(a(e))do local a;if e~=""then a=e;else a=nil;end if nil~=a then o=o+1;t[o]=a;else end end return t;end local function m(e)if e and(n(e)~="")then return a(e);else return nil;end end local function w(e,t)local a=e[d(e,t,"SCHEMA")];if not a then return{};else local a=m(a)or{};local o=a[1]or"N";local i={};local n={};for e,e in ipairs(a)do if(e~=o)and not i[e]then i[e]=true;table.insert(n,e);else end end local t=d(e,t,"BRANCH");local a={};local o=1;for e,e in ipairs(u(e[t]or""))do if n[o]then a[e]=n[o];a[e:gsub("%s+","")]=n[o];o=o+1;else end end return a;end end local function f(e)local t={};local a=0;for e,e in ipairs(u(e or""))do local o;do local t,a=e:match("^(.-)%.(.+)$");if t then o={table=n(t),col=n(a)};else o={table=n(e),col=nil};end end if nil~=o then a=a+1;t[a]=o;else end end return t;end local function g(e)local t;if e["$FNC-ROFBUG-2019$"]then t=e["$FNC-ROFBUG-2019$"];elseif e["$FNC-ROFBUG-2020$"]then t=e["$FNC-ROFBUG-2020$"];else t=e["$FNC-ROFBUG-2022$"]or e["$FNC-ROFBUG$"]or e["$ROFBUG$"]or e["$ROFBUG-2022$"]or e["$ROFBUG-2020$"]or e["$ROFBUG-2019$"];end local a;if e["$FNC-ROFBUG-2019$"]then a=0.05;elseif e["$FNC-ROFBUG-2020$"]then a=0.03;else a=nil;end local e={};for t,t in ipairs(u(t or""))do e[t]=true;end return e,a;end local function y(e)local t={};for e,a in pairs(e)do local i,n;do local e=o(e);local e=e:match("^FSE%-(.+)$");if e then i,n=e,a;else i,n=nil;end end if(i~=nil)and(n~=nil)then t[i]=n;else end end return t;end local function p(e)local t={};for e,a in pairs(e)do local i,n;do local e=o(e);if h(e)then i,n=e,a;else i,n=nil;end end if(i~=nil)and(n~=nil)then t[i]=n;else end end return t;end local function b(e,t)local t=t or"";local a=d(e,t,"COST");local o=d(e,t,"SCHEMA");local i=d(e,t,"INDEX");local n,s=g(e);local o=m(e[o]);return{vars=e,prefix=t,costs=c(e[a]or""),["cost-key"]=a,schema=o,["branch-map"]=w(e,t),index=f(e[i]),["rof-cols"]=n,["rof-offset"]=s,fse=y(e),["formula-env"]=p(e)};end local function y(e,t)local e,a=r(e);local e=b(e,t);return e,a;end return{trim=n,["split-semi"]=a,["split-lines"]=e,["strip-var-key"]=o,["dollar-key"]=i,["config-name?"]=s,["formula-name?"]=h,["parse-vars"]=r,["get-var-key"]=d,["get-array-var-key"]=l,["is-numeric-array-body"]=t,["parse-number-list"]=c,["parse-string-list"]=u,["parse-schema"]=m,["build-branch-map"]=w,["parse-index-overrides"]=f,["parse-rofbug"]=g,["formula-env"]=p,["build-config"]=b,["parse-page-config"]=y};end;package.preload.parser=package.preload.parser or function()local e=require("lexer");local e=e.lex;local t=require("config");local a=nil;local function o(e,t)return e[t];end local function i(e)return e and e.type;end local function n(e,t,a)local e=o(e,t);return e and(e.type=="op")and(e.value==a);end local function s(e,t,a)local e=o(e,t);return e and(e.type=="op")and a:find(e.value,1,true);end local function h(e)if not e then return"parser: unexpected end of input";else local t;if e.value then t=" value="..tostring(e.value);else t="";end return"parser: unexpected token type="..tostring(e.type)..t;end end local r=string.byte;local d={[32]=true,[9]=true,[10]=true,[11]=true,[12]=true,[13]=true};local function l(e)local e=tostring(e or"");if d[r(e,1)]or d[r(e,-1)]then return(e:match("^%s*(.-)%s*$"));else return e;end end local function d(e)local e=l(e);local t=r(e,1);if(t==60)or(t==91)then return e:match("^<ref[%s/>]")or e:match("^%[%[[^%[%]]+%]%]$");else return nil;end end local function c(e)local e=l(e);if r(e,1)==123 then return e:match("^{{#expr:(.*)}}%s*$");else return nil;end end local function l(e)return c(e)~=nil;end local function u(e)return e:find("{{",1,true)and not l(e);end local function m(e)if r(e,1)==70 then return e:match("^FNC%-")or e:match("^FSE%-");else return nil;end end local function w(e,t)local a={};local o=false;for e,e in ipairs(e)do if o or(e==t)then o=true;table.insert(a,e);else end end table.insert(a,t);return"cyclic $VAR$ reference: "..table.concat(a," -> ");end local function f(e,t)return table.insert(e,t);end local function g(e)return table.remove(e);end local function y(e,t)local a=false;for e,e in ipairs(e)do if a then break;end if e==t then a=true;else end end return a;end local function p(e)if not e:find("@",1,true)then return e,nil,nil;else local t,a,o=e:match("^(.-)@(%d+)@(.+)$");if t then return t,tonumber(a),o;else local t,a=e:match("^(.-)@(%d+)$");if t then return t,tonumber(a),nil;else return e,nil,nil;end end end end local function b(e)if r(e,1)==70 then return e:match("^FNC%-TOTAL%-(.+)$");else return nil;end end local r=nil;local v=nil;local k=nil;local function x(e,t)return t or(e=="FNC-TOTALPRICE")or b(e)or m(e);end local function j(e,t,a)if not t or not tostring(e or""):find("$",1,true)then return tostring(e or"");else local function o(e)local o,i=p(e);if x(o,i)then return"$"..e.."$";else local i=t[o];if i==nil then error("undefined variable: $"..o.."$");else end if i:find(";",1,true)or l(i)then return"$"..e.."$";else if y(a,o)then error(w(a,o));else end f(a,o);local e=j(i,t,a);g(a);return e;end end end return(tostring(e or""):gsub("%$([^%$]+)%$",o));end end local function x(e,a,o,i)local n=o[e];if n==nil then local n,s=p(e);if s or(n=="FNC-TOTALPRICE")or b(n)then local t=r(e,a,o,i);o[e]=t;return t;else if y(i,e)then error(w(i,e));else end local n=a[e];if n==nil then error("undefined variable: $"..e.."$");else end if n:find(";",1,true)then local a;if t["is-numeric-array-body"](n)then a={"array",n};else a={"literal",n};end o[e]=a;return a;else f(i,e);local t=v(n,a,o,i);g(i);o[e]=t;return t;end end elseif nil~=n then local e=n;return e;else return nil;end end k=x;local function t(e,t,a,o)local e,i,n=p(e);local s=t and t[e];local h;if e=="FNC-TOTALPRICE"then h={"intrinsic","totalprice"};else local n=b(e);if n then h={"intrinsic","total",n};elseif m(e)then h={"varref",e};elseif i and s and s:find(";",1,true)then h={"array",s};else h=k(e,t,a,o);end end if i then return{"pin",i,n,h};else return h;end end r=t;local function t(e,t,n,s,d)local l=o(e,t);if not l then return error("parser: expected expression, got end of input");elseif l.type=="num"then return{"num",l.value},t+1;elseif l.type=="ident"then return{"ident",l.value},t+1;elseif l.type=="dotref"then return{"dotref",l.table,l.col},t+1;elseif l.type=="varref"then if n then return r(l.value,n,s,d),t+1;else return{"varref",l.value},t+1;end elseif l.type=="lparen"then local t,a=a(e,t+1,n,s,d);if i(o(e,a))~="rparen"then return error("parser: missing closing ')'");else return t,a+1;end else return error(h(l));end end local function i(e,a,i,s,h)local t,a=t(e,a,i,s,h);while n(e,a,"++")or n(e,a,"--")do local e=o(e,a).value;if e=="++"then t={"binop","+",t,{"num",1}};else t={"binop","-",t,{"num",1}};end a=a+1;end return t,a;end local function t(e,a,o,s,h)if n(e,a,"-")then local e,t=t(e,a+1,o,s,h);return{"unop","-",e},t;else return i(e,a,o,s,h);end end local function i(e,a,o,s,h)local t,a=t(e,a,o,s,h);if n(e,a,"**")then local e,a=i(e,a+1,o,s,h);return{"pow",t,e},a;else return t,a;end end local function t(e,t,a,n,h)local t,r=i(e,t,a,n,h);while s(e,r,"*/%")do local o=o(e,r).value;local e,a=i(e,r+1,a,n,h);t={"binop",o,t,e};r=a;end return t,r;end local function i(e,a,i,n,h)local a,r=t(e,a,i,n,h);while s(e,r,"+-")do local o=o(e,r).value;local e,t=t(e,r+1,i,n,h);a={"binop",o,a,e};r=t;end return a,r;end a=i;local function t(e)if not e or(#e==0)then error("parser: empty token list");else end local t,a=a(e,1,nil,nil,nil);if a<=#e then error(h(o(e,a)));else end return t;end local function i(a)return t(e(a));end local function n(t,i,n,s)if d(t)then return{"literal",t};else local r=c(t);if r then return{"mw-expr",r};elseif u(t)then return{"wikitext",t};else local s=s or{};local t=j(t,i,s);if d(t)then return{"literal",t};else local r=c(t);if r then return{"mw-expr",r};elseif u(t)then return{"wikitext",t};else local e=e(t);if#e==0 then error("parser: empty formula");else end local t,a=a(e,1,i,n,s);if a<=#e then error(h(o(e,a)));else end if(#e==1)and(e[1].type=="ident")then return{"soft-ident",e[1].value};else return t;end end end end end end v=n;local function e(e,t)local a={};local o={};local e=v(e,t,a,o);return e,a;end local function o(e)local t={};local a={};for o in pairs(e)do if not m(o)and(t[o]==nil)then k(o,e,t,a);else end end return t;end return{parse=t,["parse-string"]=i,["parse-formula"]=v,["parse-var"]=k,["parse-with-env"]=e,["parse-var-env"]=o,["parse-pin-parts"]=p,["literal-raw?"]=d,["mw-expr-body?"]=l,["extract-mw-expr"]=c,["wikitext-body?"]=u,["config-varref?"]=m,["parse-additive"]=a};end;package.preload.lexer=package.preload.lexer or function()local e=string.byte;local t=string.find;local a=string.sub;local o=table.insert;local function i(e)return e:match("^%s*(.-)%s*$");end local function n(e)return e and(48<=e)and(e<=57);end local function s(e)return e and(((48<=e)and(e<=57))or((65<=e)and(e<=90))or((97<=e)and(e<=122)));end local function h(e,a)local e,e=t(e,"^%s*",a);return e+1;end local function r(o,i)local s=e(o,i)==46;local h;if s then h=i+1;else h=i;end local h,h=t(o,"^[%d,_]*",h);local r;if not s and(e(o,h+1)==46)and n(e(o,h+2))then local e,e=t(o,"^[%d,_]*",h+2);r=e+1;else r=h+1;end local e=a(o,i,r-1);local t=tonumber(e)or tonumber((e:gsub("[,_]","")));if not t then error("lexer: invalid number `"..e.."`");else end return{type="num",value=t},r;end local function n(e,o)local t=t(e,"$",o+1,true);if not t then error("lexer: unclosed $ starting at position "..tostring(o));else end local e=a(e,o+1,t-1);if e==""then error("lexer: empty $...$ at position "..tostring(o));else end return{type="varref",value=e},t+1;end local function d(e,o)local n=t(e,"]]",o+2,true);if not n then error("lexer: unclosed [[ starting at position "..tostring(o));else end local e=i(a(e,o+2,n-1));local t=t(e,"|",1,true);local s;if t and(t>1)then s=a(e,1,t-1);else s=e;end local e=i(s);if e==""then error("lexer: empty [[...]] at position "..tostring(o));else end return e,n+2;end local function l(e,t)local e,t=d(e,t);return{type="ident",value=e},t;end local function c(a,o)return e(a,o+1)and not t(a,"^[%s%d%+%-%*/%%%(%)%$%.%[]",o+1);end local function u(t,a)return s(e(t,a-1))and s(e(t,a+1));end local function s(o,n)local s=n;local h=nil;local r=nil;local l=n;local m=true;while m do local t,t=t(o,"^%P*",s);s=t+1;local t=e(o,s);if t==46 then if not c(o,s)then s=s+1;elseif h then m=false;else h=s;s=s+1;end elseif t==45 then if h or u(o,s)then s=s+1;else m=false;end elseif(t==91)and(e(o,s+1)==91)then local e,t=d(o,s);r=(r or"")..a(o,l,s-1)..e;s=t;l=t;elseif not t or(t==40)or(t==41)or(t==36)or(t==91)or(t==93)or(t==43)or(t==42)or(t==47)or(t==37)then m=false;else s=s+1;end end local d=s-1;while true do local t;do local e=e(o,d);t=e and((e==32)or((9<=e)and(e<=13)));end if not t then break;end d=d-1;end local e;if r then e=i(r..a(o,l,s-1));else e=a(o,n,d);end if h then local t=t(e,".",1,true);local o=i(a(e,1,t-1));local e=i(a(e,t+1));if(o=="")or(e=="")then error("lexer: malformed table.col near position "..tostring(n));else end return{type="dotref",table=o,col=e},s;else if e==""then error("lexer: empty identifier at position "..tostring(n));else end return{type="ident",value=e},s;end end local function t(e)local e=e[#e];return e and((e.type=="ident")or(e.type=="rparen")or(e.type=="varref")or(e.type=="num")or(e.type=="dotref"));end local function i(o,i,h)local e,d=e(o,i,i+1);if e==40 then return{type="lparen"},i+1;elseif e==41 then return{type="rparen"},i+1;elseif e==36 then return n(o,i);elseif(e==91)and(d==91)then return l(o,i);elseif((48<=e)and(e<=57))or((e==46)and d and(48<=d)and(d<=57))then return r(o,i);elseif(e==42)and(d==42)then return{type="op",value="**"},i+2;elseif(e==43)and(d==43)and t(h)then return{type="op",value="++"},i+2;elseif(e==45)and(d==45)and t(h)then return{type="op",value="--"},i+2;elseif(e==43)or(e==45)or(e==42)or(e==47)or(e==37)then return{type="op",value=a(o,i,i)},i+1;else return s(o,i);end end local function e(e)if type(e)~="string"then error("lexer: expected a string");else end local t={};local a=#e;local n=h(e,1);while n<=a do local a,i=i(e,n,t);o(t,a);n=h(e,i);end return t;end return{lex=e};end;package.preload.eval=package.preload.eval or function()local e=require("config");local t=require("mwexpr");local a=require("parser");local function o(e,t)local a=#e;local o=#t;return(a>o)or((a==o)and(e<t));end local i=setmetatable({},{__mode="k"});local function n(e)if type(e)=="number"then return e;else local e=tostring(e or""):match("^%s*(.-)%s*$");local t=e:lower();if(t=="n/a")or(t=="na")or(t=="-")or(e=="")then return 0;else local e=e:gsub(",","");local t=tonumber(e);if t~=nil then return t;else local t;if e:find("$",1,true)then t=e:gsub("%$%a[^%$]*%$","");else t=e;end local e=t:match("%-?%d+%.?%d*");return e and tonumber(e);end end end end local function s(e,t)local a=n(e);if a==nil then error("eval: not a number for '"..(t or"?").."': "..tostring(e));else end return a;end local function h(e,t)local function a()if e and e["formula-name"]then return"unresolved identifier '"..t.."' in formula for $"..e["formula-name"].."$";else return"unresolved identifier '"..t.."'";end end return error(a());end local r=nil;local function d(e,t)local o=e["formula-env"]or(e.config and e.config["formula-env"]);local i=o and o[t];if i and(i~="")then local i=e["ident-stack"]or{};if i[t]then error("eval: cyclic formula '"..t.."'");else end i[t]=true;e["ident-stack"]=i;local n=e["formula-asts"]or e["parse-cache"];local a=(n and n[t])or a["parse-var"](t,o,e["parse-cache"]or{},{});local e,a=pcall(r,e,a);i[t]=nil;if e then return a;else return error(a,0);end else return nil;end end local function l(e)if(type(e)=="string")and e:find("$",1,true)then local t=e;if e:find("<ref",1,true)then t=e:gsub("<ref[^>]*>.-</ref>","");t=t:gsub("<ref[^>]*/>","");else end return t:match("%$([A-Za-z][%w%-]*)%$");else return nil;end end local function c(e,t,a,o,i,n)local s=e.row;e.row=t;local t,a=pcall(a,o,i,n);e.row=s;if t then return a;else return error(a,0);end end local function u(e,t,a,o)local i=n(a);if i~=nil then return i;else local i=l(a);if i then return c(e,t,d,e,i);else return s(a,o);end end end local function s(e,t,a)if a then local a=e[t.."_ROF"];if a~=nil then return a;else return e[t];end else return e[t];end end local function m(e,t)local a=e.row or{};local o=e["rof?"];local i=s(a,t,o);local n;if i~=nil then n=i;elseif t:find("%s")then n=s(a,(t:gsub("%s+","")),o);else n=nil;end if n==nil then if t=="Level"then return e.level;else return nil;end elseif type(n)=="number"then return n;else return u(e,a,n,t);end end local function u(e,t,a)if e then if a and(a~="")then return e[tostring(t)..a]or e[t];else return e[t];end else return nil;end end local function w(e,t,a)local o=e["table-cache"];local t=o and(o[t]or o[t:gsub("%s+","")]);local t=u(t,e.level,e.branch);if not t then return nil;else return c(e,t,m,e,a);end end local function c(e,t,a)local e=tonumber(e)or 0;if not a then if e>=0 then return e+1;else return nil;end else local o=a[1]or"N";local i;if t and(t~="")then i=t;else i=o;end local t=nil;local n=0;local s={};for a,h in ipairs(a)do if t then break;end if h==o then if(i==o)and(n==e)then t=a;else end n=n+1;else if not s[h]then s[h]=n;else end if(i==h)and(s[h]==e)then t=a;else end s[h]=s[h]+1;end end return t;end end local function f(e,t,a,o)local t=tonumber(t)or 0;if not o then local e=e or{};local a=0;local o=1;while(e[o]~=nil)and((o-1)<=t)do a=a+e[o];o=o+1;end return a;else local i=o[1]or"N";local n;if a and(a~="")then n=a;else n=i;end local a=0;local s=0;local h={};for o,r in ipairs(o)do local e=e[o]or 0;if r==i then if n==i then if s<=t then a=a+e;else end else a=a+e;end s=s+1;else if not h[r]then h[r]=s;else end if(n==r)and(h[r]<=t)then a=a+e;else end h[r]=h[r]+1;end end return a;end end local function g(e,t)if not t or(t=="")then return e.branch or"";else local e=e["branch-map"]or(e.config and e.config["branch-map"]);if e and e[t]then return e[t];elseif e and e[t:gsub("%s+","")]then return e[t:gsub("%s+","")];else return t;end end end local function y(e)return e.costs or(e.config and e.config.costs);end local function p(e)return e.schema or(e.config and e.config.schema);end local function b(e)local t=y(e);if not t then error("eval: $FNC-TOTALPRICE$ needs ctx.costs or ctx.config.costs");else end return f(t,e.level,e.branch or"",p(e));end local function y(e,t)local a={};for e,o in pairs(e.row or{})do if type(o)=="number"then if not t or t:find(e,1,true)then a[e]=o;else end if e:find("%s")then local e=e:gsub("%s+","");if not t or t:find(e,1,true)then a[e]=o;else end else end else end end if(e.level~=nil)and(not t or t:find("Level",1,true))then a.Level=e.level;else end return a;end local function v(e)return e and(((48<=e)and(e<=57))or((65<=e)and(e<=90))or((97<=e)and(e<=122))or(e==95));end local function k(e,t)local t=t-1;while(t>0)and(e:byte(t)==32)do t=t-1;end local a=t>0;if a then local e=e:byte(t);a=v(e)or(e==93);end return a;end local x={};local function j(e)if(e~=0)and(e==e)then local t=x[e];if not t then local a=tostring(e);x[e]=a;t=a;end return t;else return tostring(e);end end local function x(e,t,a)local o=#t;local i=e:find(t,1,true);if not i then return e;else local a=j(a);local n=nil;local s=1;while i do do local t=e:byte(i-1);local h=e:byte(i+o);if(t~=46)and not v(t)and((t~=32)or not k(e,i))and not v(h)then n=(n or"")..e:sub(s,i-1)..a;s=i+o;else end end i=e:find(t,i+o,true);end if n then return n..e:sub(s);else return e;end end end local function v(e,t)local e=e or"";if t then local a,i=next(t);if next(t,a)==nil then if type(i)=="number"then e=x(e,a,i);else end else local a={};for t,o in pairs(t)do if(type(o)=="number")and e:find(t,1,true)then table.insert(a,t);else end end table.sort(a,o);for a,a in ipairs(a)do e=x(e,a,t[a]);end end else end return e;end local function k(e,t,a)if type(a)=="number"then return a;else local o=l(a);if o then local a=e.row;e.row=t;local t,o=pcall(d,e,o);e.row=a;return t and(type(o)=="number")and o;else return n(a);end end end local function n(e,t)local e=tostring(e or"");do local a=t["table-cache"];local i={};local n={};if a then for a,o in pairs(a)do if(type(a)=="string")and(type(o)=="table")and not a:find("|",1,true)and e:find(a,1,true)and e:find(a..".",1,true)then local o=u(o,t.level,t.branch);if o then for h in pairs(o)do if(type(h)=="string")and e:find(h,1,true)and not h:match("_ROF$")then local a=a.."."..h;if(n[a]==nil)and e:find(a,1,true)then local e=k(t,o,s(o,h,t["rof?"]));n[a]=e or false;if e then table.insert(i,a);else end else end else end end else end else end end else end table.sort(i,o);for t,t in ipairs(i)do local a=tostring(n[t]);local o=#a;local i=1;local n=false;while not n do local t,s=e:find(t,i,true);if t then e=e:sub(1,t-1)..a..e:sub(s+1);i=t+o;else n=true;end end end end return e;end local function s(e,t)local a;local o=i[e];if not o then local t={};i[e]=t;o=t;end a=o;local o=a[t];if o~=nil then return o;else local e=tostring(e:callParserFunction({name="#expr",args={t}})or"");local e={e,tonumber(e)};a[t]=e;return e;end end local function i(e,t)return s(e,t)[2];end local function d(e)return e and(((65<=e)and(e<=90))or((97<=e)and(e<=122)));end local function l(e)local t=e:find(".",1,true);local a=false;while t and not a do a=d(e:byte(t-1))and d(e:byte(t+1));t=e:find(".",t+1,true);end return a;end local function d(e,t)local o=t["formula-env"]or(t.config and t.config["formula-env"])or{};local i=t["parse-cache"]or{};local n=t["ident-stack"]or{};if n[e]then error("eval: cyclic formula '"..e.."'");else end n[e]=true;t["ident-stack"]=n;local a=a["parse-var"](e,o,i,{});local t,a=pcall(r,t,a);n[e]=nil;if not t then return error(a,0);elseif type(a)~="number"then return error("eval: $"..e.."$ in #expr is not a number");else return a;end end local function k(e,t)if not e:find("$",1,true)then return e;else local function a(e)return tostring(d(e,t));end return(e:gsub("%$([^%$]+)%$",a));end end local function d(e,t)local e=k(tostring(e or""),t);local a;if l(e)then a=n(e,t);else a=e;end local e=y(t,a);return v(a,e);end local function n(e,a)local function o(e)local o,i=pcall(d,e,a);local n;if o then n=i;else n=e;end local e=a.frame;if e and e.callParserFunction then return s(e,n)[1];else return tostring(t.eval(n,{})or"");end end return(tostring(e or""):gsub("{{#expr:(.-)}}",o));end local function s(e,a)local e=d(e,a);local a=a.frame;if a and a.callParserFunction then local t=i(a,e);if t==nil then error("eval: #expr returned non-number for: "..e);else end return t;else return t.eval(e,{});end end local function t(e,t,a)local e=tostring(e or"");local i={};for e,t in pairs(t or{})do if type(t)=="number"then table.insert(i,e);else end end table.sort(i,o);if a and(t.Level==nil)then e=e:gsub("Level",tostring(a));else end for a,a in ipairs(i)do if e:find(a,1,true)then local o=a:gsub("([^%w])","%%%1");e=e:gsub(o,tostring(t[a]));else end end if a and e:find("Level",1,true)then e=e:gsub("Level",tostring(t.Level or a));else end return e;end local function o(e,a)local e=n(e,a);local e=t(e,a.row or{},a.level);local t=a.frame;local a;if t and t.preprocess then a=t:preprocess(e);else a=e;end local e=tostring(a);local e=e:match("^%s*(.-)%s*$");local e=tonumber(e);if e~=nil then return e;else return a;end end local function d(t,o)local i=t["formula-asts"]or t["parse-cache"];local n=t["formula-env"]or(t.config and t.config["formula-env"]);local s=t.vars or(t.config and t.config.vars)or{};local h=t.prefix or(t.config and t.config.prefix)or"";local e=e["get-array-var-key"](s,h,o);local e=(n and n[o])or s[e]or"";local i=i and i[o];if not i then if e and(e~="")then local s=t["parse-cache"]or{};local e=n or{[o]=e};i=a["parse-var"](o,e,s,{});if t["parse-cache"]then t["parse-cache"][o]=i;else end if t["formula-asts"]then t["formula-asts"][o]=i;else end else end else end return i;end local function l(e,t,a)local o=e.level;local i=e.row or{};local n=i.Level;e.level=t;i.Level=t;local t,a=pcall(r,e,a);e.level=o;i.Level=n;if t then return a;else return error(a,0);end end local function k(e,t,a,o,i,n,s)local h=e.level;local r=e.branch;e.level=t or e.level;e.branch=g(e,a);local t,a=pcall(o,i,n,s);e.level=h;e.branch=r;if t then return a;else return error(a,0);end end local function x(e,t)local a=d(e,t);if not a then error("eval: $FNC-TOTAL-"..t.."$ needs a formula or numeric series for $"..t.."$");else end local o=tonumber(e.level)or 0;local i=0;for o=0,o do local e=l(e,o,a);if type(e)~="number"then error("eval: $FNC-TOTAL-"..t.."$ at level "..tostring(o).." is not a number: "..tostring(e));else end i=i+e;end return i;end local function d(t,a)local o=t.totals and t.totals[a];if o then return f(o,t.level,t.branch or"",p(t));else local o=t.vars or(t.config and t.config.vars)or{};local i=t.prefix or(t.config and t.config.prefix)or"";local i=e["get-array-var-key"](o,i,a);local o=o[i]or"";local n=tostring(o):match("^%s*(.-)%s*$");if e["is-numeric-array-body"](o)then return f(e["parse-number-list"](o),t.level,t.branch or"",p(t));elseif n==""then return error("eval: $FNC-TOTAL-"..a.."$ has no numeric series or formula at "..tostring(i));else return x(t,a);end end end local function l(e,t,a)if e=="+"then return t+a;elseif e=="-"then return t-a;elseif e=="*"then return t*a;elseif e=="/"then if a==0 then return error("eval: division by zero");else return t/a;end elseif e=="%"then if a==0 then return error("eval: modulo by zero");else return t%a;end else return error("eval: unknown binop "..tostring(e));end end local j={};function j.num(e,e)return e[2];end function j.ident(e,t)return m(e,t[2])or h(e,t[2]);end j["soft-ident"]=function(e,t)return m(e,t[2])or t[2];end;function j.dotref(e,t)local e=w(e,t[2],t[3]);if e==nil then return error("eval: unresolved table lookup '"..t[2].."."..t[3].."'");else return e;end end function j.binop(e,t)return l(t[2],r(e,t[3]),r(e,t[4]));end function j.pow(e,t)return r(e,t[2])^r(e,t[3]);end function j.unop(e,t)return-r(e,t[3]);end function j.pin(e,t)return k(e,t[2],t[3],r,e,t[4]);end function j.intrinsic(e,t)local a=t[2];if a=="totalprice"then return b(e);elseif a=="total"then return d(e,t[3]);else return error("eval: unknown intrinsic "..tostring(t[2]));end end function j.array(t,a)local a=a[2];local e=e["split-semi"](a);local a=c(t.level,t.branch or"",p(t));if not a or(a<1)or(a>#e)then error("eval: array index out of range at level "..tostring(t.level or 0));else end local e=e[a]or"";local t=tonumber((e:gsub(",","")));if t~=nil then return t;else return e;end end function j.literal(e,e)return e[2];end j["mw-expr"]=function(e,t)return s(t[2],e);end;function j.wikitext(e,t)return o(t[2],e);end function j.varref(e,e)return error("eval: unspliced $VAR$ left in tree: $"..e[2].."$ (config keys are not formula-evaluable)");end local function e(e,t)local a=(type(t)=="table")and t[1];local o=a and j[a];if o then return o(e,t);else return error("eval: unhandled node tag "..tostring(a));end end r=e;local function e(e,t,o)local i;if o and next(o)then local e=a["parse-with-env"](e,o);i=e;else i=a["parse-string"](e);end return r(t,i);end local function a(e)local t=e.config;local e={row=e.row or{},level=e.level or 0,branch=e.branch or"",["rof?"]=e["rof?"]or false,["table-cache"]=e["table-cache"],frame=e.frame,["formula-name"]=e["formula-name"],["formula-asts"]=e["formula-asts"],["parse-cache"]=e["parse-cache"]or{},config=t,vars=e.vars or(t and t.vars),prefix=e.prefix or(t and t.prefix)or"",costs=e.costs or(t and t.costs),schema=e.schema or(t and t.schema),["branch-map"]=e["branch-map"]or(t and t["branch-map"]),totals=e.totals,["formula-env"]=e["formula-env"]or(t and t["formula-env"])};return e;end local function o(e,t,a,o)e.row=t or{};e.level=o or 0;e["rof?"]=a or false;return e;end return{["eval-node"]=r,["eval-string"]=e,["make-ctx"]=a,["bind-ctx!"]=o,["row-lookup"]=m,["table-lookup"]=w,["cache-get"]=u,["array-index"]=c,["sum-series"]=f,["sum-cost"]=b,["sum-total"]=d,["sum-formula-series"]=x,["resolve-branch"]=g,["expr-bindings"]=y,["materialize-expr"]=v,["expand-inline-expr"]=n,["call-parser-expr"]=i,["substitute-row-keys"]=t};end;package.preload.mwexpr=package.preload.mwexpr or function()local function e(e)local e=tostring(e);return(e:match("^%s*(.-)%s*$"));end local function t(e)return e and e:match("[%a_]");end local function a(e)return e and e:match("[%w_]");end local function o(e)return e and e:match("%d");end local function i(e)local e=tostring(e or"");local i={};local n=#e;local s=1;while s<=n do local h=e:sub(s,s);if h:match("%s")then s=s+1;elseif o(h)then local t=s;while(t<=n)and(o(e:sub(t,t))or(e:sub(t,t)=="."))do t=t+1;end table.insert(i,{type="num",value=tonumber(e:sub(s,t-1))});s=t;elseif t(h)then local t=s;while(t<=n)and a(e:sub(t,t))do t=t+1;end local e=e:sub(s,t-1);local a=e:lower();local function o()if(a=="e")or(a=="pi")or(a=="div")or(a=="mod")or(a=="and")or(a=="or")or(a=="not")or(a=="abs")or(a=="floor")or(a=="ceil")or(a=="trunc")or(a=="round")or(a=="sqrt")or(a=="ln")or(a=="exp")or(a=="sin")or(a=="cos")or(a=="tan")or(a=="asin")or(a=="acos")or(a=="atan")then return{type="word",value=a};else return{type="ident",value=e};end end table.insert(i,o());s=t;elseif(h=="<")and(e:sub(s+1,s+1)=="=")then table.insert(i,{type="op",value="<="});s=s+2;elseif(h==">")and(e:sub(s+1,s+1)=="=")then table.insert(i,{type="op",value=">="});s=s+2;elseif(h=="<")and(e:sub(s+1,s+1)==">")then table.insert(i,{type="op",value="<>"});s=s+2;elseif(h=="!")and(e:sub(s+1,s+1)=="=")then table.insert(i,{type="op",value="!="});s=s+2;elseif(h=="=")and(e:sub(s+1,s+1)=="=")then table.insert(i,{type="op",value="="});s=s+2;elseif h=="="then table.insert(i,{type="op",value="="});s=s+1;elseif(h=="+")or(h=="-")or(h=="*")or(h=="/")or(h=="^")or(h=="(")or(h==")")or(h=="<")or(h==">")then local e;if(h=="(")or(h==")")then if h=="("then e="lparen";else e="rparen";end else e="op";end table.insert(i,{type=e,value=h});s=s+1;else error("mwexpr: unexpected character '"..h.."' in #expr near position "..tostring(s));end end table.insert(i,{type="eof"});return i;end local function t(e)return e and(e~=0);end local function a(e)if e then return 1;else return 0;end end local function o(e,o)local e=i(e);local o=o or{};local i=1;local function n()return e[i];end local function e(e,t)local a=n();return(a.type==e)and((t==nil)or(a.value==t));end local function s()local e=n();i=i+1;return e;end local function i(e,t)local a=n();if not((a.type==e)and((t==nil)or(a.value==t)))then local o;if t then o=" "..t;else o="";end error("mwexpr: expected "..tostring(e)..o..", got "..tostring(a.type));else end return s();end local h=nil;local function r()local e=n();if e.type=="num"then s();return e.value;elseif(e.type=="word")and(e.value=="e")then s();return math.exp(1);elseif(e.type=="word")and(e.value=="pi")then s();return math.pi;elseif(e.type=="word")and((e.value=="abs")or(e.value=="floor")or(e.value=="ceil")or(e.value=="trunc")or(e.value=="round")or(e.value=="sqrt")or(e.value=="ln")or(e.value=="exp")or(e.value=="sin")or(e.value=="cos")or(e.value=="tan")or(e.value=="asin")or(e.value=="acos")or(e.value=="atan"))then local e=e.value;s();i("lparen");local t=h();i("rparen");if e=="abs"then return math.abs(t);elseif e=="floor"then return math.floor(t);elseif e=="ceil"then return math.ceil(t);elseif e=="trunc"then if t>=0 then return math.floor(t);else return math.ceil(t);end elseif e=="round"then return math.floor(t+0.5);elseif e=="sqrt"then return math.sqrt(t);elseif e=="ln"then return math.log(t);elseif e=="exp"then return math.exp(t);elseif e=="sin"then return math.sin(t);elseif e=="cos"then return math.cos(t);elseif e=="tan"then return math.tan(t);elseif e=="asin"then return math.asin(t);elseif e=="acos"then return math.acos(t);elseif e=="atan"then return math.atan(t);else return nil;end elseif e.type=="ident"then local e=e.value;s();local t=o[e]or o[e:lower()];if t==nil then error("mwexpr: unknown identifier '"..e.."'");else end return tonumber(t);elseif e.type=="lparen"then s();local e=h();i("rparen");return e;else return error("mwexpr: unexpected token "..tostring(e.type).." "..tostring(e.value));end end local function o()if e("op","+")then s();return o();elseif e("op","-")then s();return-o();elseif e("word","not")then s();return a(not t(o()));else return r();end end local function i()local t=o();if e("op","^")then s();return t^i();else return t;end end local function o()local t=i();while e("op","*")or e("op","/")or e("word","div")or e("word","mod")do local e=s().value;local a=i();if e=="*"then t=t*a;elseif(e=="/")or(e=="div")then if a==0 then t=error("mwexpr: division by zero");else t=t/a;end elseif e=="mod"then t=t%a;else t=t;end end return t;end local function i(e,t)local t=t or 0;local t=10^t;return math.floor((e*t)+0.5)/t;end local function r()local t=o();while e("word","round")do s();t=i(t,o());end return t;end local function o()local t=r();while e("op","+")or e("op","-")do local e=s().value;local a=r();if e=="+"then t=t+a;else t=t-a;end end return t;end local function i()local e=o();local t=n();if(t.type=="op")and((t.value=="=")or(t.value=="<>")or(t.value=="!=")or(t.value=="<")or(t.value==">")or(t.value=="<=")or(t.value==">="))then local t=s().value;local o=o();local function i()if t=="="then return e==o;elseif(t=="<>")or(t=="!=")then return e~=o;elseif t=="<"then return e<o;elseif t==">"then return e>o;elseif t=="<="then return e<=o;elseif t==">="then return e>=o;else return nil;end end return a(i());else return e;end end local function o()local o=i();while e("word","and")do s();local e=i();o=a(t(o)and t(e));end return o;end local function i()local i=o();while e("word","or")do s();local e=o();i=a(t(i)or t(e));end return i;end h=i;local e=h();if n().type~="eof"then error("mwexpr: trailing input near "..tostring(n().value));else end return e;end local function t(t)local e=e(t or"");return e:match("^{{#expr:(.*)}}%s*$");end local function e(e,t)return o(e,t);end local function a(a,o)local t=t(a)or a;return e(t,o);end return{tokenize=i,eval=e,["eval-wrapped"]=a,["strip-expr-wrapper"]=t,["parse-eval"]=o};end;package.preload.wikitable=package.preload.wikitable or function()local e=string.byte;local t=string.find;local a=string.lower;local o=string.sub;local i={[32]=true,[9]=true,[10]=true,[11]=true,[12]=true,[13]=true};local function n(t,a,n)local a=a;local n=n;while(a<=n)and i[e(t,a)]do a=a+1;end while(a<=n)and i[e(t,n)]do n=n-1;end return o(t,a,n);end local function o(t)local t=tostring(t or"");if i[e(t,1)]or i[e(t,-1)]then return n(t,1,#t);else return t;end end local function s(e)local e=tostring(e or""):gsub("%s+","");if t(e,"^%d+$")then return{tonumber(e)};else local t={};local a={};local function o(e)if not a[e]then a[e]=true;return table.insert(t,e);else return nil;end end local function a(e)local t,a,i,n=e:match("^(%d+)(%a+)[^%d%a]+(%d+)(%a+)$");if t and(a:upper()==n:upper())then local e=a:upper();for t=tonumber(t),tonumber(i)do o(tostring(t)..e);end return nil;else local t,a=e:match("^(%d+)(%a+)$");if t then return o(t..a:upper());else local t,a=e:match("^(%d+)[^%d]+(%d+)$");if t then for e=tonumber(t),tonumber(a)do o(e);end return nil;else local e=tonumber(e);if e then return o(e);else return nil;end end end end end for e in e:gmatch("[^/]+")do a(e);end return t;end end local function h(e)local e=o(e:match("^([^|]+)")or e);local t=e:lower();if t:match("^file:")or t:match("^image:")then return"";else return e;end end local function r(e)local e=o(e);if t(e,"<",1,true)then e=e:gsub("<ref[^>]*>.-</ref>","");e=e:gsub("<ref[^>]*/>","");e=e:gsub("<[^>]+>","");else end if t(e,"[[",1,true)then e=e:gsub("%[%[([^%]]+)%]%]",h);e=e:gsub("%[%[","");else end if t(e,"]]",1,true)then e=e:gsub("%]%]","");else end if t(e,"$",1,true)then e=e:gsub("%$[^%$]+%$","");else end return o(e);end local function h(e)local e=o(e);if t(e,"<",1,true)then e=e:gsub("<ref[^>]*>.-</ref>","");e=e:gsub("<ref[^>]*/>","");e=o(e);else end return e;end local function d(t)return(e(t,1)==33)and a(t):find("colspan",1,true);end local function a(t)return(e(t,1)==33)and not d(t);end local function l(e)local e=e:sub(2);local e=e:gsub("%|%|","!!");local t={};for e in(e.."!!"):gmatch("([^!]*)!!")do local e=r(e);if e~=""then table.insert(t,e);else end end return t;end local function c(e)local a={};local o=#e;local i=2;local s=false;while not s do local t=t(e,"||",i,true);local h;if t then h=t-1;else h=o;end table.insert(a,n(e,i,h));if t then i=t+2;else s=true;end end return a;end local function t(e)local e=e:match("%|(.+)$");if e then return r(e);else return nil;end end local function n(e,t)if not t or not e or(e=="")then return"";else return t[e]or t[e:gsub("%s+","")]or"";end end local function u(a,s,r)local s=s or{};local u={};local m={};local w={};local f=nil;local g="";local y=nil;local function p()if y then local e=y;if r then table.insert(m,{["raw-cells"]=e});else local t;do local a={};local o=0;for e,e in ipairs(e)do local e=h(e);if nil~=e then o=o+1;a[o]=e;else end end t=a;end local a={};local o=math.min(#u,#e);for t=1,o do local o=u[t];local i=o:gsub("%s+","");a[o]=e[t];a[i]=e[t];end table.insert(m,{["raw-cells"]=e,cells=t,["by-header"]=a,["level-raw"]=(#t>0)and t[1]});end y=nil;return nil;else return nil;end end for a in a:gmatch("([^\n]*)\n?")do local h;if i[e(a,1)]then h=o(a);else h=a;end local a=e(h,1);if a==33 then if d(h)then f=t(h);g=n(f,s);else local e=l(h);table.insert(w,e);for e,e in ipairs(e)do table.insert(u,e);end end elseif a==124 then local e=e(h,2);if e==45 then p();elseif e==125 then p();else local e=c(h);table.insert(w,e);if y then local t={};for e,e in ipairs(y)do table.insert(t,e);end for e,e in ipairs(e)do table.insert(t,e);end y=t;else y=e;end end else end end p();return{title=f,branch=g,headers=u,rows=m,source=a,["line-cells"]=w};end local function e(e)local t={};local e=tostring(e or"");local a=1;local o=false;while not o do local i=e:find("{|",a,true);if not i then o=true;else local n=e:find("|}",i,true);if not n then o=true;else local o=n+1;table.insert(t,{start=i,stop=o,text=e:sub(i,o)});a=o+1;end end end return t;end local function i(t)local a={};local o=0;for e,e in ipairs(e(t))do local e=e.text;if nil~=e then o=o+1;a[o]=e;else end end return a;end local function m(t,a)local o={};local i=0;for e,e in ipairs(e(t))do local e=u(e.text,a);if nil~=e then i=i+1;o[i]=e;else end end return o;end local function w(e,t)local a=e.headers;local e=e.title;local a=(#a>0)and a[1];if t then for t,t in ipairs(t)do if t.table and e and t.col and((t.table==e)or(t.table:gsub("%s+","")==e:gsub("%s+","")))then a=t.col;else end end else end return a;end local function f(e,t)local e=(t and e["by-header"][t])or e["level-raw"]or"";return s(e);end return{trim=o,["parse-level-keys"]=s,["clean-header-text"]=r,["strip-cell-refs"]=h,["split-header-cells"]=l,["split-row-cells"]=c,["header-line?"]=a,["title-line?"]=d,["extract-title"]=t,["detect-branch"]=n,["parse-table"]=u,["find-table-spans"]=e,["find-table-blocks"]=i,["parse-all-tables"]=m,["index-col"]=w,["row-level-keys"]=f};end;package.preload.tablecache=package.preload.tablecache or function()local e=require("wikitable");local t=e["parse-level-keys"];local a=e["strip-cell-refs"];local o=e.trim;local i=e["index-col"];local e=e["parse-all-tables"];local function n(e,t,a)if e then if a and(a~="")then return e[tostring(t)..a]or e[t];else return e[t];end else return nil;end end local function s(e,t)if e<=0 then return e;elseif t then return e+t;else local e=e*60;local t=math.floor(e+0.5);local a;if math.abs(e-t)<1e-9 then a=t+1.5;else a=math.ceil(e)+1;end return math.floor(((a/60)*1000)+0.5)/1000;end end local function h(e)local e=tostring(e or"");if e:find("<",1,true)then e=e:gsub("<ref[^>]*>.-</ref>","");e=e:gsub("<ref[^>]*/>","");e=e:gsub("<[^>]+>","");else end return o(e);end local function r(e)local t=tonumber(e);if t then return t;elseif e:find("<",1,true)then local e=a(e);local t;if e:find("<",1,true)then t=h(e);else t=e;end return tonumber(t)or t;else return o(e);end end local function a(e,t,a,o,i)local e=e(t,a,o,i);if type(e)=="number"then return e;else local e=h(tostring(e));return tonumber(e)or e;end end local function o(e,t,a,o)e[t]=o;if a~=t then e[a]=o;else end return o;end local function h(e)if type(e)=="number"then return e;else local t=tonumber(e);if t~=nil then return t;else local e=tostring(e or""):gsub("%$%a[^%$]*%$","");local e=e:match("%-?%d+%.?%d*");return e and tonumber(e);end end end local function d(e)if(type(e)=="number")and(e>=0)and(e<100000000000000.0)and(e==math.floor(e))then return{e};else return t(e);end end local function t(e,t,i)local i=i or{};local n=i["resolve-cell"];local l=i["rof-cols"]or{};local c=i["rof-offset"];local i=i["rof-bug"]or s;local s=e.headers or{};local u=#s;local m;do local e={};local t=0;for a,a in ipairs(s)do local a=a:gsub("%s+","");if nil~=a then t=t+1;e[t]=a;else end end m=e;end local t=t or s[1];local w=t and(t:gsub("%s+",""));local f=next(l);local g={};for e,e in ipairs(e.rows or{})do local y={};local p=f and{};local e=e["raw-cells"]or{};for t=1,math.min(u,#e)do local e=e[t];local s=s[t];local t=m[t];local d;if n then d=a(n,e,s,y,false);else d=r(e);end o(y,s,t,d);if f then local r;if n then r=a(n,e,s,p,true);else r=d;end if l[s]then local e=h(d);if e then r=i(e,c);else end else end o(p,s,t,r);else end end local e;if t then e=y[t]or y[w];else e=nil;end if e~=nil then local e=d(e);local t=y;if f then for e,a in pairs(p)do t[e.."_ROF"]=a;end else end if#e==1 then local e=e[1];if type(e)=="number"then t.Level=e;if f and(t.Level_ROF==nil)then t.Level_ROF=e;else end else end g[e]=t;else for e,e in ipairs(e)do local a={};for e,t in pairs(t)do a[e]=t;end if type(e)=="number"then a.Level=e;if f and(a.Level_ROF==nil)then a.Level_ROF=e;else end else end g[e]=a;end end else end end return g;end local function a(e,t,a,o)local o=o or"";local i;if o~=""then i=t.."|"..o;else i=t;end e[i]=a;e[i:gsub("%s+","")]=a;if not e[t]then e[t]=a;else end do local t=t:gsub("%s+","");if not e[t]then e[t]=a;else end end return e;end local function o(e,t)if e then local t=t or"";if t==""then return e;else local a={};local t="|"..t;local o=#t;for e,t in pairs(e)do if(type(e)=="string")and not e:find("|",1,true)then a[e]=t;else end end for e,i in pairs(e)do if(type(e)=="string")and(#e>o)and(e:sub(-o)==t)then local e=e:sub(1,#e-o);a[e]=i;local t=e:gsub("%s+","");if t~=e then a[t]=i;else end else end end return a;end else return nil;end end local function h(e,t)return e.title or(t and("Table"..tostring(t)))or"Table";end local function d(e,o)local o=o or{};local n={};local s=o["index-overrides"];local r=o.prefix or"";local d=o["table-prefixes"]or{};local l={};local c={};local u=nil;for e,m in ipairs(e or{})do local r=d[e]or r or"";local d=(l[r]or 0)+1;local w=m.title;local e=(w and(w~="")and w)or(u and(r~=u)and c[d])or h(m,e);local i=i(m,s);local t=t(m,i,o);l[r]=d;if not u and(r~="")then u=r;else end if r==u then c[d]=e;else end a(n,e,t,r);end return n;end local function i(t,a,o)return d(e(t,a or{}),o);end return{["cache-get"]=n,["rof-bug"]=s,["coerce-cell"]=r,["build-table-cache"]=t,["build-page-cache"]=d,["build-page-cache-from-text"]=i,["register-cache"]=a,["scope-page-cache"]=o};end;local e=require("render");local e=e["render-page"];local function t(e)return(tostring(e or""):match("^%s*(.-)%s*$"));end local function a(e)local e=e and e.args;local e=e and e[1];if e==nil then return"";else return t(e);end end local function t(e)local e=tostring(e or"");if e:find("&",1,true)then e=e:gsub("&lt;","<");e=e:gsub("&gt;",">");e=e:gsub("&amp;","&");else end return e;end local function o(e)local a;local o=mw and mw.text and mw.text.unstripNoWiki;if not o then local function e(e)return e;end o=e;end a=o;local e=a(e or"");return t(e);end local function t(e,t)if e and e.preprocess then return e:preprocess(t);else return t;end end local function i(i)local a=a(i);local a=o(a);if not a or(a=="")then return"'''Neowbunto''': No valid content found.";else return t(i,e(a,i));end end return{heeho=i,["content-arg"]=a};