Software /
code /
verse
File
buildscripts/squish @ 498:50d0bd035bb7
util.sasl.oauthbearer: Don't send authzid
It's not needed and not recommended in XMPP unless we want to act as
someone other than who we authenticate as. We find out the JID during
resource binding.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Fri, 23 Jun 2023 12:09:49 +0200 |
parent | 472:864c9dc27c60 |
line wrap: on
line source
#!/usr/bin/lua5.2 package.preload['optlex']=(function(...) local _ENV=_ENV; local function e(t,...) local e=package.loaded[t]or _ENV[t]or{_NAME=t}; package.loaded[t]=e; for t=1,select("#",...)do (select(t,...))(e); end _ENV=e; _M=e; return e; end local s=_G local u=require"string" local i=u.match local e=u.sub local r=u.find local l=u.rep local c error=s.error warn={} local n,o,d local q={ TK_KEYWORD=true, TK_NAME=true, TK_NUMBER=true, TK_STRING=true, TK_LSTRING=true, TK_OP=true, TK_EOS=true, } local b={ TK_COMMENT=true, TK_LCOMMENT=true, TK_EOL=true, TK_SPACE=true, } local h local function k(e) local t=n[e-1] if e<=1 or t=="TK_EOL"then return true elseif t==""then return k(e-1) end return false end local function g(e) local t=n[e+1] if e>=#n or t=="TK_EOL"or t=="TK_EOS"then return true elseif t==""then return g(e+1) end return false end local function E(a) local t=#i(a,"^%-%-%[=*%[") local a=e(a,t+1,-(t-1)) local e,t=1,0 while true do local a,n,i,o=r(a,"([\r\n])([\r\n]?)",e) if not a then break end e=a+1 t=t+1 if#o>0 and i~=o then e=e+1 end end return t end local function v(s,h) local a=i local t,e=n[s],n[h] if t=="TK_STRING"or t=="TK_LSTRING"or e=="TK_STRING"or e=="TK_LSTRING"then return"" elseif t=="TK_OP"or e=="TK_OP"then if(t=="TK_OP"and(e=="TK_KEYWORD"or e=="TK_NAME"))or (e=="TK_OP"and(t=="TK_KEYWORD"or t=="TK_NAME"))then return"" end if t=="TK_OP"and e=="TK_OP"then local t,e=o[s],o[h] if(a(t,"^%.%.?$")and a(e,"^%."))or (a(t,"^[~=<>]$")and e=="=")or (t=="["and(e=="["or e=="="))then return" " end return"" end local t=o[s] if e=="TK_OP"then t=o[h]end if a(t,"^%.%.?%.?$")then return" " end return"" else return" " end end local function j() local a,s,i={},{},{} local e=1 for t=1,#n do local n=n[t] if n~=""then a[e],s[e],i[e]=n,o[t],d[t] e=e+1 end end n,o,d=a,s,i end local function x(r) local t=o[r] local t=t local n if i(t,"^0[xX]")then local e=s.tostring(s.tonumber(t)) if#e<=#t then t=e else return end end if i(t,"^%d+%.?0*$")then t=i(t,"^(%d+)%.?0*$") if t+0>0 then t=i(t,"^0*([1-9]%d*)$") local a=#i(t,"0*$") local o=s.tostring(a) if a>#o+1 then t=e(t,1,#t-a).."e"..o end n=t else n="0" end elseif not i(t,"[eE]")then local a,t=i(t,"^(%d*)%.(%d+)$") if a==""then a=0 end if t+0==0 and a==0 then n="0" else local o=#i(t,"0*$") if o>0 then t=e(t,1,#t-o) end if a+0>0 then n=a.."."..t else n="."..t local a=#i(t,"^0*") local o=#t-a local a=s.tostring(#t) if o+2+#a<1+#t then n=e(t,-o).."e-"..a end end end else local t,a=i(t,"^([^eE]+)[eE]([%+%-]?%d+)$") a=s.tonumber(a) local h,o=i(t,"^(%d*)%.(%d*)$") if h then a=a-#o t=h..o end if t+0==0 then n="0" else local o=#i(t,"^0*") t=e(t,o+1) o=#i(t,"0*$") if o>0 then t=e(t,1,#t-o) a=a+o end local i=s.tostring(a) if a==0 then n=t elseif a>0 and(a<=1+#i)then n=t..l("0",a) elseif a<0 and(a>=-#t)then o=#t+a n=e(t,1,o).."."..e(t,o+1) elseif a<0 and(#i>=-a-#t)then o=-a-#t n="."..l("0",o)..t else n=t.."e"..a end end end if n and n~=o[r]then if h then c("<number> (line "..d[r]..") "..o[r].." -> "..n) h=h+1 end o[r]=n end end local function z(m) local t=o[m] local n=e(t,1,1) local f=(n=="'")and'"'or"'" local t=e(t,2,-2) local a=1 local l,s=0,0 while a<=#t do local c=e(t,a,a) if c=="\\"then local o=a+1 local d=e(t,o,o) local h=r("abfnrtv\\\n\r\"\'0123456789",d,1,true) if not h then t=e(t,1,a-1)..e(t,o) a=a+1 elseif h<=8 then a=a+2 elseif h<=10 then local i=e(t,o,o+1) if i=="\r\n"or i=="\n\r"then t=e(t,1,a).."\n"..e(t,o+2) elseif h==10 then t=e(t,1,a).."\n"..e(t,o+1) end a=a+2 elseif h<=12 then if d==n then l=l+1 a=a+2 else s=s+1 t=e(t,1,a-1)..e(t,o) a=a+1 end else local i=i(t,"^(%d%d?%d?)",o) o=a+1+#i local d=i+0 local h=u.char(d) local r=r("\a\b\f\n\r\t\v",h,1,true) if r then i="\\"..e("abfnrtv",r,r) elseif d<32 then i="\\"..d elseif h==n then i="\\"..h l=l+1 elseif h=="\\"then i="\\\\" else i=h if h==f then s=s+1 end end t=e(t,1,a-1)..i..e(t,o) a=a+#i end else a=a+1 if c==f then s=s+1 end end end if l>s then a=1 while a<=#t do local o,s,i=r(t,"([\'\"])",a) if not o then break end if i==n then t=e(t,1,o-2)..e(t,o) a=o else t=e(t,1,o-1).."\\"..e(t,o) a=o+2 end end n=f end t=n..t..n if t~=o[m]then if h then c("<string> (line "..d[m]..") "..o[m].." -> "..t) h=h+1 end o[m]=t end end local function _(u) local t=o[u] local h=i(t,"^%[=*%[") local a=#h local c=e(t,-a,-1) local s=e(t,a+1,-(a+1)) local n="" local t=1 while true do local a,o,r,h=r(s,"([\r\n])([\r\n]?)",t) local o if not a then o=e(s,t) elseif a>=t then o=e(s,t,a-1) end if o~=""then if i(o,"%s+$")then warn.lstring="trailing whitespace in long string near line "..d[u] end n=n..o end if not a then break end t=a+1 if a then if#h>0 and r~=h then t=t+1 end if not(t==1 and t==a)then n=n.."\n" end end end if a>=3 then local e,t=a-1 while e>=2 do local a="%]"..l("=",e-2).."%]" if not i(n,a)then t=e end e=e-1 end if t then a=l("=",t-2) h,c="["..a.."[","]"..a.."]" end end o[u]=h..n..c end local function w(u) local a=o[u] local h=i(a,"^%-%-%[=*%[") local t=#h local d=e(a,-t,-1) local s=e(a,t+1,-(t-1)) local n="" local a=1 while true do local o,t,r,h=r(s,"([\r\n])([\r\n]?)",a) local t if not o then t=e(s,a) elseif o>=a then t=e(s,a,o-1) end if t~=""then local a=i(t,"%s*$") if#a>0 then t=e(t,1,-(a+1))end n=n..t end if not o then break end a=o+1 if o then if#h>0 and r~=h then a=a+1 end n=n.."\n" end end t=t-2 if t>=3 then local e,a=t-1 while e>=2 do local t="%]"..l("=",e-2).."%]" if not i(n,t)then a=e end e=e-1 end if a then t=l("=",a-2) h,d="--["..t.."[","]"..t.."]" end end o[u]=h..n..d end local function p(a) local t=o[a] local i=i(t,"%s*$") if#i>0 then t=e(t,1,-(i+1)) end o[a]=t end local function A(o,a) if not o then return false end local t=i(a,"^%-%-%[=*%[") local t=#t local i=e(a,-t,-1) local e=e(a,t+1,-(t-1)) if r(e,o,1,true)then return true end end function optimize(t,i,r,a) local m=t["opt-comments"] local u=t["opt-whitespace"] local f=t["opt-emptylines"] local y=t["opt-eols"] local I=t["opt-strings"] local T=t["opt-numbers"] local O=t.KEEP h=t.DETAILS and 0 c=c or s.print if y then m=true u=true f=true end n,o,d =i,r,a local t=1 local a,r local s local function i(i,a,e) e=e or t n[e]=i or"" o[e]=a or"" end while true do a,r=n[t],o[t] local h=k(t) if h then s=nil end if a=="TK_EOS"then break elseif a=="TK_KEYWORD"or a=="TK_NAME"or a=="TK_OP"then s=t elseif a=="TK_NUMBER"then if T then x(t) end s=t elseif a=="TK_STRING"or a=="TK_LSTRING"then if I then if a=="TK_STRING"then z(t) else _(t) end end s=t elseif a=="TK_COMMENT"then if m then if t==1 and e(r,1,1)=="#"then p(t) else i() end elseif u then p(t) end elseif a=="TK_LCOMMENT"then if A(O,r)then if u then w(t) end s=t elseif m then local e=E(r) if b[n[t+1]]then i() a="" else i("TK_SPACE"," ") end if not f and e>0 then i("TK_EOL",l("\n",e)) end if u and a~=""then t=t-1 end else if u then w(t) end s=t end elseif a=="TK_EOL"then if h and f then i() elseif r=="\r\n"or r=="\n\r"then i("TK_EOL","\n") end elseif a=="TK_SPACE"then if u then if h or g(t)then i() else local a=n[s] if a=="TK_LCOMMENT"then i() else local e=n[t+1] if b[e]then if(e=="TK_COMMENT"or e=="TK_LCOMMENT")and a=="TK_OP"and o[s]=="-"then else i() end else local e=v(s,t+1) if e==""then i() else i("TK_SPACE"," ") end end end end end else error("unidentified token encountered") end t=t+1 end j() if y then t=1 if n[1]=="TK_COMMENT"then t=3 end while true do a,r=n[t],o[t] if a=="TK_EOS"then break elseif a=="TK_EOL"then local e,a=n[t-1],n[t+1] if q[e]and q[a]then local e=v(t-1,t+1) if e==""then i() end end end t=t+1 end j() end if h and h>0 then c()end return n,o,d end return{optimize=optimize} end) package.preload['optparser']=(function(...) local _ENV=_ENV; local function e(t,...) local e=package.loaded[t]or _ENV[t]or{_NAME=t}; package.loaded[t]=e; for t=1,select("#",...)do (select(t,...))(e); end _ENV=e; _M=e; return e; end local e=_G local a=require"string" local l=require"table" local s="etaoinshrdlucmfwypvbgkqjxz_ETAOINSHRDLUCMFWYPVBGKQJXZ" local d="etaoinshrdlucmfwypvbgkqjxz_0123456789ETAOINSHRDLUCMFWYPVBGKQJXZ" local w={} for e in a.gmatch([[ and break do else elseif end false for function if in local nil not or repeat return then true until while self _ENV]],"%S+")do w[e]=true end local h,u, m,o, c,v, r, n local function f(e) local i={} for n=1,#e do local e=e[n] local o=e.name if not i[o]then i[o]={ decl=0,token=0,size=0, } end local t=i[o] t.decl=t.decl+1 local i=e.xref local a=#i t.token=t.token+a t.size=t.size+a*#o if e.decl then e.id=n e.xcount=a if a>1 then e.first=i[2] e.last=i[a] end else t.id=n end end return i end local function y(e) local i=a.byte local n=a.char local a={ TK_KEYWORD=true,TK_NAME=true,TK_NUMBER=true, TK_STRING=true,TK_LSTRING=true, } if not e["opt-comments"]then a.TK_COMMENT=true a.TK_LCOMMENT=true end local e={} for t=1,#h do e[t]=u[t] end for t=1,#o do local t=o[t] local a=t.xref for t=1,t.xcount do local t=a[t] e[t]="" end end local t={} for e=0,255 do t[e]=0 end for o=1,#h do local o,e=h[o],e[o] if a[o]then for a=1,#e do local e=i(e,a) t[e]=t[e]+1 end end end local function o(a) local e={} for o=1,#a do local a=i(a,o) e[o]={c=a,freq=t[a],} end l.sort(e, function(t,e) return t.freq>e.freq end ) local t={} for a=1,#e do t[a]=n(e[a].c) end return l.concat(t) end s=o(s) d=o(d) end local function p() local t local n,h=#s,#d local e=r if e<n then e=e+1 t=a.sub(s,e,e) else local i,o=n,1 repeat e=e-i i=i*h o=o+1 until i>e local i=e%n e=(e-i)/n i=i+1 t=a.sub(s,i,i) while o>1 do local i=e%h e=(e-i)/h i=i+1 t=t..a.sub(d,i,i) o=o-1 end end r=r+1 return t,c[t]~=nil end function optimize(e,i,t,s,a) h,u,m,o =i,t,s,a r=0 n={} c=f(m) v=f(o) if e["opt-entropy"]then y(e) end local e={} for t=1,#o do e[t]=o[t] end l.sort(e, function(t,e) return t.xcount>e.xcount end ) local a,t,r={},1,false for o=1,#e do local e=e[o] if not e.preserve then a[t]=e t=t+1 elseif e.name=="self"then r=true end end e=a local s=#e while s>0 do local h,t repeat h,t=p() until not w[h] n[#n+1]=h local a=s if t then local i=m[c[h].id].xref local n=#i for t=1,s do local t=e[t] local s,e=t.act,t.rem while e<0 do e=o[-e].rem end local o for t=1,n do local t=i[t] if t>=s and t<=e then o=true end end if o then t.skip=true a=a-1 end end end while a>0 do local t=1 while e[t].skip do t=t+1 end a=a-1 local i=e[t] t=t+1 i.newname=h i.skip=true i.done=true local s,h=i.first,i.last local r=i.xref if s and a>0 then local n=a while n>0 do while e[t].skip do t=t+1 end n=n-1 local e=e[t] t=t+1 local n,t=e.act,e.rem while t<0 do t=o[-t].rem end if not(h<n or s>t)then if n>=i.act then for o=1,i.xcount do local o=r[o] if o>=n and o<=t then a=a-1 e.skip=true break end end else if e.last and e.last>=i.act then a=a-1 e.skip=true end end end if a==0 then break end end end end local a,t={},1 for o=1,s do local e=e[o] if not e.done then e.skip=false a[t]=e t=t+1 end end e=a s=#e end for e=1,#o do local e=o[e] local t=e.xref if e.newname then for a=1,e.xcount do local t=t[a] u[t]=e.newname end e.name,e.oldname =e.newname,e.name else e.oldname=e.name end end if r then n[#n+1]="self" end local e=f(o) end return{optimize=optimize} end) package.preload['llex']=(function(...) local _ENV=_ENV; local function e(t,...) local e=package.loaded[t]or _ENV[t]or{_NAME=t}; package.loaded[t]=e; for t=1,select("#",...)do (select(t,...))(e); end _ENV=e; _M=e; return e; end local y=_G local s=require"string" local l=s.find local c=s.match local n=s.sub local e='' local r='' local a=1 local d=1 local m={} local w={} local p={} local i='' local v={} for e in s.gmatch([[ and break do else elseif end false for function if in local nil not or repeat return then true until while]],"%S+")do v[e]=true end local function o(a,t) local e=#m+1 m[e]=a w[e]=t p[e]=d end local function h(t,s) local n=n local i=n(e,t,t) t=t+1 local e=n(e,t,t) if(e=="\n"or e=="\r")and(e~=i)then t=t+1 i=i..e end if s then o("TK_EOL",i)end d=d+1 a=t return t end function init(i,t) e=i r=t local t,n,e,i=l(e,"^(#[^\r\n]*)(\r?\n?)") if t then a=a+#e o("TK_COMMENT",e) if#i>0 then h(a,true)end end end function chunkid() if r and c(r,"^[=@]")then return n(r,2) end return"[string]" end function errorline(t,a) local e=error or y.error e(s.format("%s:%d: %s",chunkid(),a or d,t)) end local r=errorline local function u(t) local i=n local n=i(e,t,t) t=t+1 local o=#c(e,"=*",t) t=t+o a=t return(i(e,t,t)==n)and o or(-o)-1 end local function f(d,s) local t=a+1 local n=n local o=n(e,t,t) if o=="\r"or o=="\n"then t=h(t) end local o=t while true do local o,c,l=l(e,"([\r\n%]])",t) if not o then r(d and"unfinished long string"or "unfinished long comment") end t=o if l=="]"then if u(t)==s then i=n(e,i,a) a=a+1 return i end t=a else i=i.."\n" t=h(t) end end end local function b(u) local t=a local s=l local d=n while true do local n,l,o=s(e,"([\n\r\\\"\'])",t) if n then if o=="\n"or o=="\r"then r("unfinished string") end t=n if o=="\\"then t=t+1 o=d(e,t,t) if o==""then break end n=s("abfnrtv\n\r",o,1,true) if n then if n>7 then t=h(t) else t=t+1 end elseif s(o,"%D")then t=t+1 else local o,a,e=s(e,"^(%d%d?%d?)",t) t=a+1 if e+1>256 then r("escape sequence too large") end end else t=t+1 if o==u then a=t return d(e,i,t-1) end end else break end end r("unfinished string") end function llex() local s=l local d=c while true do local t=a while true do local c,m,l=s(e,"^([_%a][_%w]*)",t) if c then a=t+#l if v[l]then o("TK_KEYWORD",l) else o("TK_NAME",l) end break end local l,m,c=s(e,"^(%.?)%d",t) if l then if c=="."then t=t+1 end local u,h,i=s(e,"^%d*[%.%d]*([eE]?)",t) t=h+1 if#i==1 then if d(e,"^[%+%-]",t)then t=t+1 end end local i,t=s(e,"^[_%w]*",t) a=t+1 local e=n(e,l,t) if not y.tonumber(e)then r("malformed number") end o("TK_NUMBER",e) break end local m,w,c,l=s(e,"^((%s)[ \t\v\f]*)",t) if m then if l=="\n"or l=="\r"then h(t,true) else a=w+1 o("TK_SPACE",c) end break end local h=d(e,"^%p",t) if h then i=t local l=s("-[\"\'.=<>~",h,1,true) if l then if l<=2 then if l==1 then local r=d(e,"^%-%-(%[?)",t) if r then t=t+2 local h=-1 if r=="["then h=u(t) end if h>=0 then o("TK_LCOMMENT",f(false,h)) else a=s(e,"[\n\r]",t)or(#e+1) o("TK_COMMENT",n(e,i,a-1)) end break end else local e=u(t) if e>=0 then o("TK_LSTRING",f(true,e)) elseif e==-1 then o("TK_OP","[") else r("invalid long string delimiter") end break end elseif l<=5 then if l<5 then a=t+1 o("TK_STRING",b(h)) break end h=d(e,"^%.%.?%.?",t) else h=d(e,"^%p=?",t) end end a=t+#h o("TK_OP",h) break end local e=n(e,t,t) if e~=""then a=t+1 o("TK_OP",e) break end o("TK_EOS","") return end end end return{ llex=llex, init=init, chunkid=chunkid, tok=m, tokln=p, seminfo=w } end) package.preload['lparser']=(function(...) local _ENV=_ENV; local function e(t,...) local e=package.loaded[t]or _ENV[t]or{_NAME=t}; package.loaded[t]=e; for t=1,select("#",...)do (select(t,...))(e); end _ENV=e; _M=e; return e; end local U=_G local b=require"string" local D={} local T, j, A, C, d, r, P, t,k,l,y, p, a, W, q, N, u, g, E local f,n,w,_,x,v local e=b.gmatch local H={} for e in e("else elseif end until <eof>","%S+")do H[e]=true end local Y={} for e in e("if while do for repeat function local return break","%S+")do Y[e]=e.."_stat" end local S={} local V={} for e,a,t in e([[ {+ 6 6}{- 6 6}{* 7 7}{/ 7 7}{% 7 7} {^ 10 9}{.. 5 4} {~= 3 3}{== 3 3} {< 3 3}{<= 3 3}{> 3 3}{>= 3 3} {and 2 2}{or 1 1} ]],"{(%S+)%s(%d+)%s(%d+)}")do S[e]=a+0 V[e]=t+0 end local Z={["not"]=true,["-"]=true, ["#"]=true,} local ee=8 local function o(t,a) local e=error or U.error e(b.format("(source):%d: %s",a or l,t)) end local function e() P=A[d] t,k,l,y =T[d],j[d],A[d],C[d] d=d+1 end local function X() return T[d] end local function s(a) local e=t if e~="<number>"and e~="<string>"then if e=="<name>"then e=k end e="'"..e.."'" end o(a.." near "..e) end local function c(e) s("'"..e.."' expected") end local function o(a) if t==a then e();return true end end local function L(e) if t~=e then c(e)end end local function i(t) L(t);e() end local function F(e,t) if not e then s(t)end end local function h(e,a,t) if not o(e)then if t==l then c(e) else s("'"..e.."' expected (to close '"..a.."' at line "..t..")") end end end local function c() L("<name>") local t=k p=y e() return t end local function I(e,t) e.k="VK" end local function R(e) I(e,c()) end local function m(o,i) local e=a.bl local t if e then t=e.locallist else t=a.locallist end local e=#u+1 u[e]={ name=o, xref={p}, decl=p, } if i or o=="_ENV"then u[e].preserve=true end local a=#g+1 g[a]=e E[a]=t end local function z(e) local t=#g while e>0 do e=e-1 local t=t-e local a=g[t] local e=u[a] local o=e.name e.act=y g[t]=nil local i=E[t] E[t]=nil local t=i[o] if t then e=u[t] e.rem=-a end i[o]=a end end local function O() local t=a.bl local e if t then e=t.locallist else e=a.locallist end for t,e in U.pairs(e)do local e=u[e] e.rem=y end end local function y(e,t) if b.sub(e,1,1)=="("then return end m(e,t) end local function U(o,a) local t=o.bl local e if t then e=t.locallist while e do if e[a]then return e[a]end t=t.prev e=t and t.locallist end end e=o.locallist return e[a]or-1 end local function b(t,o,e) if t==nil then e.k="VGLOBAL" return"VGLOBAL" else local a=U(t,o) if a>=0 then e.k="VLOCAL" e.id=a return"VLOCAL" else if b(t.prev,o,e)=="VGLOBAL"then return"VGLOBAL" end e.k="VUPVAL" return"VUPVAL" end end end local function Q(o) local t=c() b(a,t,o) if o.k=="VGLOBAL"then local e=N[t] if not e then e=#q+1 q[e]={ name=t, xref={p}, } N[t]=e else local e=q[e].xref e[#e+1]=p end else local e=o.id local e=u[e].xref e[#e+1]=p end end local function p(t) local e={} e.isbreakable=t e.prev=a.bl e.locallist={} a.bl=e end local function b() local e=a.bl O() a.bl=e.prev end local function B() local e if not a then e=W else e={} end e.prev=a e.bl=nil e.locallist={} a=e end local function G() O() a=a.prev end local function U(t) local a={} e() R(a) t.k="VINDEXED" end local function K(t) e() n(t) i("]") end local function M(e) local e,a={},{} if t=="<name>"then R(e) else K(e) end i("=") n(a) end local function O(e) if e.v.k=="VVOID"then return end e.v.k="VVOID" end local function O(e) n(e.v) end local function J(a) local n=l local e={} e.v={} e.t=a a.k="VRELOCABLE" e.v.k="VVOID" i("{") repeat if t=="}"then break end local t=t if t=="<name>"then if X()~="="then O(e) else M(e) end elseif t=="["then M(e) else O(e) end until not o(",")and not o(";") h("}","{",n) end local function X() local i=0 if t~=")"then repeat local t=t if t=="<name>"then m(c()) i=i+1 elseif t=="..."then e() a.is_vararg=true else s("<name> or '...' expected") end until a.is_vararg or not o(",") end z(i) end local function M(n) local a={} local i=l local o=t if o=="("then if i~=P then s("ambiguous syntax (function call x new statement)") end e() if t==")"then a.k="VVOID" else f(a) end h(")","(",i) elseif o=="{"then J(a) elseif o=="<string>"then I(a,k) e() else s("function arguments expected") return end n.k="VCALL" end local function P(a) local t=t if t=="("then local t=l e() n(a) h(")","(",t) elseif t=="<name>"then Q(a) else s("unexpected symbol") end end local function O(a) P(a) while true do local t=t if t=="."then U(a) elseif t=="["then local e={} K(e) elseif t==":"then local t={} e() R(t) M(a) elseif t=="("or t=="<string>"or t=="{"then M(a) else return end end end local function R(o) local t=t if t=="<number>"then o.k="VKNUM" elseif t=="<string>"then I(o,k) elseif t=="nil"then o.k="VNIL" elseif t=="true"then o.k="VTRUE" elseif t=="false"then o.k="VFALSE" elseif t=="..."then F(a.is_vararg==true, "cannot use '...' outside a vararg function"); o.k="VVARARG" elseif t=="{"then J(o) return elseif t=="function"then e() x(o,false,l) return else O(o) return end e() end local function k(o,n) local a=t local i=Z[a] if i then e() k(o,ee) else R(o) end a=t local t=S[a] while t and t>n do local o={} e() local e=k(o,V[a]) a=e t=S[a] end return a end function n(e) k(e,0) end local function I(e) local t={} local e=e.v.k F(e=="VLOCAL"or e=="VUPVAL"or e=="VGLOBAL" or e=="VINDEXED","syntax error") if o(",")then local e={} e.v={} O(e.v) I(e) else i("=") f(t) return end t.k="VNONRELOC" end local function k(e,t) i("do") p(false) z(e) w() b() end local function R(e) local t=r y("(for index)") y("(for limit)") y("(for step)") m(e) i("=") _() i(",") _() if o(",")then _() else end k(1,true) end local function M(e) local t={} y("(for generator)") y("(for state)") y("(for control)") m(e) local e=1 while o(",")do m(c()) e=e+1 end i("in") local a=r f(t) k(e,false) end local function F(e) local a=false Q(e) while t=="."do U(e) end if t==":"then a=true U(e) end return a end function _() local e={} n(e) end local function k() local e={} n(e) end local function S() e() k() i("then") w() end local function P() local t,e={} m(c()) t.k="VLOCAL" z(1) x(e,false,l) end local function U() local e=0 local t={} repeat m(c()) e=e+1 until not o(",") if o("=")then f(t) else t.k="VVOID" end z(e) end function f(e) n(e) while o(",")do n(e) end end function x(a,t,e) B() i("(") if t then y("self",true) z(1) end X() i(")") v() h("end","function",e) G() end function w() p(false) v() b() end function for_stat() local o=r p(true) e() local a=c() local e=t if e=="="then R(a) elseif e==","or e=="in"then M(a) else s("'=' or 'in' expected") end h("end","for",o) b() end function while_stat() local t=r e() k() p(true) i("do") w() h("end","while",t) b() end function repeat_stat() local t=r p(true) p(false) e() v() h("until","repeat",t) k() b() b() end function if_stat() local a=r local o={} S() while t=="elseif"do S() end if t=="else"then e() w() end h("end","if",a) end function return_stat() local a={} e() local e=t if H[e]or e==";"then else f(a) end end function break_stat() local t=a.bl e() while t and not t.isbreakable do t=t.prev end if not t then s("no loop to break") end end function expr_stat() local e={} e.v={} O(e.v) if e.v.k=="VCALL"then else e.prev=nil I(e) end end function function_stat() local a=r local o,t={},{} e() local e=F(o) x(t,e,a) end function do_stat() local t=r e() w() h("end","do",t) end function local_stat() e() if o("function")then P() else U() end end local function i() r=l local e=t local t=Y[e] if t then D[t]() if e=="return"or e=="break"then return true end else expr_stat() end return false end function v() local e=false while not e and not H[t]do e=i() o(";") end end function parser() B() a.is_vararg=true e() v() L("<eof>") G() return q,u end function init(e,o,n) d=1 W={} local t=1 T,j,A,C={},{},{},{} for a=1,#e do local e=e[a] local i=true if e=="TK_KEYWORD"or e=="TK_OP"then e=o[a] elseif e=="TK_NAME"then e="<name>" j[t]=o[a] elseif e=="TK_NUMBER"then e="<number>" j[t]=0 elseif e=="TK_STRING"or e=="TK_LSTRING"then e="<string>" j[t]="" elseif e=="TK_EOS"then e="<eof>" else i=false end if i then T[t]=e A[t]=n[a] C[t]=a t=t+1 end end q,N,u={},{},{} g,E={},{} end D={ expr=n, exp1=_, explist1=f, body=x, block=w, for_stat=for_stat, while_stat=while_stat, repeat_stat=repeat_stat, if_stat=if_stat, return_stat=return_stat, break_stat=break_stat, expr_stat=expr_stat, function_stat=function_stat, do_stat=do_stat, local_stat=local_stat, chunk=v, parser=parser, init=init } return D end) package.preload['minichunkspy']=(function(...) local _ENV=_ENV; local function e(t,...) local e=package.loaded[t]or _ENV[t]or{_NAME=t}; package.loaded[t]=e; for t=1,select("#",...)do (select(t,...))(e); end _ENV=e; _M=e; return e; end local m,t,u=string,table,math local a,v,n,e=ipairs,setmetatable,type,assert local a=__END_OF_GLOBALS__ local c,l,i=m.char,m.byte,m.sub local w,d,g=u.frexp,u.ldexp,u.abs local p=t.concat local a=u.huge local k=a-a local o=false local r=4 local s=4 local h=8 local t={} local function y() t[#t+1] ={o,r,s,h} end local function b() o,r,s,h =unpack(t[#t]) t[#t]=nil end local function t(e,t) return e.new(e,t) end local f={} local t=t{ new= function(e,a) local a=a or{} local t=f[e]or{ __index=e, __call=t } f[e]=t return v(a,t) end, } local j=t{ unpack=function(t,t,e)return nil,e end, pack=function(e,e)return""end } local f={} local function v(e) local t=f[e]or t{ unpack=function(o,a,t) return i(a,t,t+e-1),t+e end, pack=function(a,t)return i(t,1,e)end } f[e]=t return t end local q=t{ unpack=function(a,t,e) return l(t,e,e),e+1 end, pack=function(t,e)return c(e)end } local i=t{ unpack= function(t,e,n) local i,e,t,a=l(e,n,n+3) if o then i,e,t,a=a,t,e,i end return i+e*256+t*256^2+a*256^3,n+4 end, pack= function(t,s) e(n(s)=="number", "unexpected value type to pack as an uint32") local i,a,t,e e=s%2^32 i=e%256;e=(e-i)/256 a=e%256;e=(e-a)/256 t=e%256;e=(e-t)/256 if o then i,a,t,e=e,t,a,i end return c(i,a,t,e) end } local x=t{ unpack= function(a,e,t) local a=i:unpack(e,t) local e=i:unpack(e,t+4) if o then a,e=e,a end return a+e*2^32,t+8 end, pack= function(a,t) e(n(t)=="number", "unexpected value type to pack as an uint64") local e=t%2^32 local t=(t-e)/2^32 if o then e,t=t,e end return i:pack(e)..i:pack(t) end } local function E(e,a) local t=i:unpack(e,a) local e=i:unpack(e,a+4) if o then t,e=e,t end local a=e%2^20 local t=t local o=t+a*2^32 e=(e-a)/2^20 local t=e%2^11 local e=e<=t and 1 or-1 return e,t,o end local function c(n,a,t) local e=t%2^32 local t=(t-e)/2^32 local e=e local t=((n<0 and 2^11 or 0)+a)*2^20+t if o then e,t=t,e end return i.pack(nil,e)..i.pack(nil,t) end local function _(e) if e~=e then return e end if e==0 then e=1/e end return e>0 and 1 or-1 end local l=d(1,-1022-52) local f=l*2^52 local z=d(2^52-1,-1022-52) local f=d(2^53-1,1023-52) e(l~=0 and l/2==0) e(f~=a) e(f*2==a) local d=t{ unpack= function(t,e,i) local n,o,t=E(e,i) local e if o==0 then e=d(t,-1022-52) elseif o==2047 then e=t==0 and a or k else e=d(2^52+t,o-1023-52) end e=n*e return e,i+8 end, pack= function(t,e) if e~=e then return c(1,2047,2^52-1) end local o=_(e) e=g(e) if e==a then return c(o,2047,0)end if e==0 then return c(o,0,0)end local t,a if e<=z then t=0 a=e/l else local o,e=w(e) a=(2*o-1)*2^52 t=e+1022 end return c(o,t,a) end } local a=q local l={ [4]=i, [8]=x } local w={ [4]=float, [8]=d } local c=t{ unpack=function(a,t,e) return l[r]:unpack(t,e) end, pack=function(t,e) return l[r]:pack(e) end, } local i=t{ unpack=function(a,e,t) return l[s]:unpack(e,t) end, pack=function(t,e) return l[s]:pack(e) end, } local g=t{ unpack=function(a,t,e) return w[h]:unpack(t,e) end, pack=function(t,e) return w[h]:pack(e) end, } local k=v(4) local f=t{ unpack= function(t,s,o) local i={} local e,a=1,1 while t[e]do local n=t[e] local t=n.name if not t then t,a=a,a+1 end i[t],o=n:unpack(s,o) e=e+1 end return i,o end, pack= function(a,n) local i={} local e,t=1,1 while a[e]do local o=a[e] local a=o.name if not a then a,t=t,t+1 end i[e]=o:pack(n[a]) e=e+1 end return p(i) end } local d=t{ unpack= function(n,t,e) local o,e=i:unpack(t,e) local a={} local i=n.type for o=1,o do a[o],e=i:unpack(t,e) end return a,e end, pack= function(o,a) local t=#a local e={i:pack(t)} local o=o.type for t=1,t do e[#e+1]=o:pack(a[t]) end return p(e) end } local q=t{ unpack= function(o,a,t) local t,a=i:unpack(a,t) e(t==0 or t==1, "unpacked an unexpected value "..t.." for a Boolean") return t==1,a end, pack= function(a,t) e(n(t)=="boolean", "unexpected value type to pack as a Boolean") return i:pack(t and 1 or 0) end } local c=t{ unpack= function(t,a,e) local t,e=c:unpack(a,e) local o=nil if t>0 then local t=t-1 o=a:sub(e,e+t-1) end return o,e+t end, pack= function(a,t) e(n(t)=="nil"or n(t)=="string", "unexpected value type to pack as a String") if t==nil then return c:pack(0) end return c:pack(#t+1)..t.."\000" end } local p=f{ v(4){name="signature"}, a{name="version"}, a{name="format"}, a{name="endianness"}, a{name="sizeof_int"}, a{name="sizeof_size_t"}, a{name="sizeof_insn"}, a{name="sizeof_Number"}, a{name="integral_flag"}, } local v={ [0]=j, [1]=q, [3]=g, [4]=c, } local g=t{ unpack= function(i,o,t) local t,i=a:unpack(o,t) local a=v[t] e(a,"unknown constant type "..t.." to unpack") local a,o=a:unpack(o,i) if t==3 then e(n(a)=="number") end return{ type=t, value=a },o end, pack= function(t,e) local e,t=e.type,e.value return a:pack(e)..v[e]:pack(t) end } local v=f{ c{name="name"}, i{name="startpc"}, i{name="endpc"} } local a=f{ c{name="name"}, i{name="line"}, i{name="last_line"}, a{name="num_upvalues"}, a{name="num_parameters"}, a{name="is_vararg"}, a{name="max_stack_size"}, d{name="insns",type=k}, d{name="constants",type=g}, d{name="prototypes",type=nil}, d{name="source_lines",type=i}, d{name="locals",type=v}, d{name="upvalues",type=c}, } e(a[10].name=="prototypes", "missed the function prototype list") a[10].type=a local a=t{ unpack= function(i,d,t) local n={} local t,i=p:unpack(d,t) e(t.signature=="\027Lua","signature check failed") e(t.version==81,"version mismatch") e(t.format==0,"format mismatch") e(t.endianness==0 or t.endianness==1,"endianness mismatch") e(l[t.sizeof_int],"int size unsupported") e(l[t.sizeof_size_t],"size_t size unsupported") e(t.sizeof_insn==4,"insn size unsupported") e(w[t.sizeof_Number],"number size unsupported") e(t.integral_flag==0,"integral flag mismatch; only floats supported") y() o=t.endianness==0 r=t.sizeof_size_t s=t.sizeof_int h=t.sizeof_Number n.header=t n.body,i=a:unpack(d,i) b() return n,i end, pack= function(e,t) local i y() local e=t.header o=e.endianness==0 r=e.sizeof_size_t s=e.sizeof_int h=e.sizeof_Number i=p:pack(t.header)..a:pack(t.body) b() return i end } local function o(e) if n(e)=="function"then return o(m.dump(e)) end local t=a:unpack(e,1) local a=a:pack(t) if e==a then return true end local t local t=u.min(#e,#a) for t=1,t do local a=e:sub(t,t) local e=e:sub(t,t) if a~=e then return false,("chunk roundtripping failed: ".. "first byte difference at index %d"):format(t) end end return false,("chunk round tripping failed: ".. "original length %d vs. %d"):format(#e,#a) end return{ disassemble=function(e)return a:unpack(e,1)end, assemble=function(e)return a:pack(e)end, validate=o } end) do local e={}; e["vio"]="local vio = {};\ vio.__index = vio; \ \9\ function vio.open(string)\ \9return setmetatable({ pos = 1, data = string }, vio);\ end\ \ function vio:read(format, ...)\ \9if self.pos >= #self.data then return; end\ \9if format == \"*a\" then\ \9\9local oldpos = self.pos;\ \9\9self.pos = #self.data;\ \9\9return self.data:sub(oldpos, self.pos);\ \9elseif format == \"*l\" then\ \9\9local data;\ \9\9data, self.pos = self.data:match(\"([^\\r\\n]*)\\r?\\n?()\", self.pos)\ \9\9return data;\ \9elseif format == \"*n\" then\ \9\9local data;\ \9\9data, self.pos = self.data:match(\"(%d+)()\", self.pos)\ \9\9return tonumber(data);\9\ \9elseif type(format) == \"number\" then\ \9\9local oldpos = self.pos;\ \9\9self.pos = self.pos + format;\ \9\9return self.data:sub(oldpos, self.pos-1);\ \9end\ end\ \ function vio:seek(whence, offset)\ \9if type(whence) == \"number\" then\ \9\9whence, offset = \"cur\", whence;\ \9end\ \9offset = offset or 0;\ \9\ \9if whence == \"cur\" then\ \9\9self.pos = self.pos + offset;\ \9elseif whence == \"set\" then\ \9\9self.pos = offset + 1;\ \9elseif whence == \"end\" then\ \9\9self.pos = #self.data - offset;\ \9end\ \9\ \9return self.pos;\ end\ \ local function _readline(f) return f:read(\"*l\"); end\ function vio:lines()\ \9return _readline, self;\ end\ \ function vio:write(...)\ \9for i=1,select('#', ...) do\ \9\9local dat = tostring(select(i, ...));\ \9\9self.data = self.data:sub(1, self.pos-1)..dat..self.data:sub(self.pos+#dat, -1);\ \9end\ end\ \ function vio:close()\ \9self.pos, self.data = nil, nil;\ end\ \ "e["gunzip.lua"]="local base_char,keywords=128,{\"and\",\"break\",\"do\",\"else\",\"elseif\",\"end\",\"false\",\"for\",\"function\",\"if\",\"in\",\"local\",\"nil\",\"not\",\"or\",\"repeat\",\"return\",\"then\",\"true\",\"until\",\"while\",\"read\",\"nbits\",\"nbits_left_in_byte\",\"wnd_pos\",\"output\",\"val\",\"input\",}; function prettify(code) return code:gsub(\"[\"..string.char(base_char)..\"-\"..string.char(base_char+#keywords)..\"]\", \ \9function (c) return keywords[c:byte()-base_char]; end) end return setfenv(assert(loadstring(prettify[===[ i,h,b,m,l,d,e,y,r,w,\ u,v,l,l=\ assert,error,ipairs,pairs,tostring,type,setmetatable,io,math,table.sort,\ math.max,string.char,io.open,_G;\ p(n)\ l={};\ e=e({},l)\ l:__index(l)\ n=n(l);e[l]=n\ n\ \ e\ \ l(n,l)\ l=l 1\ h({n},l+1)\ \ _(n)\ l={}\ l.outbs=n\ l.wnd={}\ l.=1\ l\ \ t(l,e)\ n=l.\ l.outbs(e)\ l.wnd[n]=e\ l.=n%32768+1\ \ n(l)\ i(l,'unexpected end of file')\ \ o(n,l)\ n%(l+l)>=l\ \ a=p((l) 2^l )\ c=e({},{__mode='k'})\ g(o)\ l=1\ e={}\ e:()\ n\ l<=#o \ n=o:byte(l)\ l=l+1\ \ n\ \ e\ \ l\ s(d)\ n,l,o=0,0,{};\ o:()\ l\ \ o:(e)\ e=e 1\ l<e \ e=d:()\ e \ n=n+a[l]*e\ l=l+8\ \ o=a[e]\ a=n%o\ n=(n-a)/o\ l=l-e\ a\ \ c[o]=\ o\ \ f(l)\ c[l] l s(g(l))\ \ s(l)\ n\ y.type(l)=='file'\ n=(n)l:write(v(n))\ d(l)=='function'\ n=l\ \ n\ \ d(e,o)\ l={}\ o \ e,n m(e)\ n~=0 \ l[#l+1]={=e,=n}\ \ \ \ n=1,#e-2,2 \ o,n,e=e[n],e[n+1],e[n+2]\ n~=0 \ e=o,e-1 \ l[#l+1]={=e,=n}\ \ \ \ \ w(l,(n,l)\ n.==l. n.<l. n.<l.\ )\ e=1\ o=0\ n,l b(l)\ l.~=o \ e=e*a[l.-o]\ o=l.\ \ l.code=e\ e=e+1\ \ e=r.huge\ c={}\ n,l b(l)\ e=r.min(e,l.)\ c[l.code]=l.\ \ o(n,e)\ l=0\ e=1,e \ e=n%2\ n=(n-e)/2\ l=l*2+e\ \ l\ \ d=p(\ (l) a[e]+o(l,e))\ l:(a)\ o,l=1,0\ 1 \ l==0 \ o=d[n(a:(e))]\ l=l+e\ \ n=n(a:())\ l=l+1\ o=o*2+n\ \ l=c[o]\ l \ l\ \ \ \ l\ \ b(l)\ a=2^1\ e=2^2\ c=2^3\ d=2^4\ n=l:(8)\ n=l:(8)\ n=l:(8)\ n=l:(8)\ t=l:(32)\ t=l:(8)\ t=l:(8)\ o(n,e)\ n=l:(16)\ e=0\ n=1,n \ e=l:(8)\ \ \ o(n,c)\ l:(8)~=0 \ \ o(n,d)\ l:(8)~=0 \ \ o(n,a)\ l:(16)\ \ \ p(l)\ f=l:(5)\ i=l:(5)\ e=n(l:(4))\ a=e+4\ e={}\ o={\ 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}\ n=1,a \ l=l:(3)\ n=o[n]\ e[n]=l\ \ e=d(e,)\ r(o)\ t={}\ a\ c=0\ c<o \ o=e:(l)\ e\ o<=15 \ e=1\ a=o\ o==16 \ e=3+n(l:(2))\ o==17 \ e=3+n(l:(3))\ a=0\ o==18 \ e=11+n(l:(7))\ a=0\ \ h'ASSERT'\ \ l=1,e \ t[c]=a\ c=c+1\ \ \ l=d(t,)\ l\ \ n=f+257\ l=i+1\ n=r(n)\ l=r(l)\ n,l\ \ a\ o\ c\ r\ h(e,n,l,d)\ l=l:(e)\ l<256 \ t(n,l)\ l==256 \ \ \ a \ l={[257]=3}\ e=1\ n=258,285,4 \ n=n,n+3 l[n]=l[n-1]+e \ n~=258 e=e*2 \ \ l[285]=258\ a=l\ \ o \ l={}\ e=257,285 \ n=u(e-261,0)\ l[e]=(n-(n%4))/4\ \ l[285]=0\ o=l\ \ a=a[l]\ l=o[l]\ l=e:(l)\ o=a+l\ c \ e={[0]=1}\ l=1\ n=1,29,2 \ n=n,n+1 e[n]=e[n-1]+l \ n~=1 l=l*2 \ \ c=e\ \ r \ n={}\ e=0,29 \ l=u(e-2,0)\ n[e]=(l-(l%2))/2\ \ r=n\ \ l=d:(e)\ a=c[l]\ l=r[l]\ l=e:(l)\ l=a+l\ e=1,o \ l=(n.-1-l)%32768+1\ t(n,i(n.wnd[l],'invalid distance'))\ \ \ \ \ u(l,a)\ i=l:(1)\ e=l:(2)\ r=0\ o=1\ c=2\ f=3\ e==r \ l:(l:())\ e=l:(16)\ o=n(l:(16))\ e=1,e \ l=n(l:(8))\ t(a,l)\ \ e==o e==c \ n,o\ e==c \ n,o=p(l)\ \ n=d{0,8,144,9,256,7,280,8,288,}\ o=d{0,5,32,}\ \ h(\ l,a,n,o\ );\ \ i~=0\ \ e(l)\ n,l=f(l.)\ ,_(s(l.))\ u(n,l)\ \ (n)\ l=f(n.)\ n=s(n.)\ b(l)\ e{=l,=n}\ l:(l:())\ l:()\ \ ]===], '@gunzip.lua')), getfenv())()"e["squish.debug"]="package.preload['minichunkspy']=(function(...)local _ENV=_ENV;local function module(name,...)local t=package.loaded[name]or _ENV[name]or{_NAME=name};package.loaded[name]=t;for i=1,select(\"#\",...)do(select(i,...))(t);end\ _ENV=t;_M=t;return t;end\ local string,table,math=string,table,math\ local ipairs,setmetatable,type,assert=ipairs,setmetatable,type,assert\ local _=__END_OF_GLOBALS__\ local string_char,string_byte,string_sub=string.char,string.byte,string.sub\ local table_concat=table.concat\ local math_abs,math_ldexp,math_frexp=math.abs,math.ldexp,math.frexp\ local Inf=math.huge\ local Nan=Inf-Inf\ local BIG_ENDIAN=false\ local function construct(class,...)return class.new(class,...)end\ local mt_memo={}local Field=construct{new=function(class,self)local self=self or{}local mt=mt_memo[class]or{__index=class,__call=construct}mt_memo[class]=mt\ return setmetatable(self,mt)end,}local None=Field{unpack=function(self,bytes,ix)return nil,ix end,pack=function(self,val)return\"\"end}local char_memo={}local function char(n)local field=char_memo[n]or Field{unpack=function(self,bytes,ix)return string_sub(bytes,ix,ix+n-1),ix+n\ end,pack=function(self,val)return string_sub(val,1,n)end}char_memo[n]=field\ return field\ end\ local uint8=Field{unpack=function(self,bytes,ix)return string_byte(bytes,ix,ix),ix+1\ end,pack=function(self,val)return string_char(val)end}local uint32=Field{unpack=function(self,bytes,ix)local a,b,c,d=string_byte(bytes,ix,ix+3)if BIG_ENDIAN then a,b,c,d=d,c,b,a end\ return a+b*256+c*256^2+d*256^3,ix+4\ end,pack=function(self,val)assert(type(val)==\"number\",\"unexpected value type to pack as an uint32\")local a,b,c,d\ d=val%2^32\ a=d%256;d=(d-a)/256\ b=d%256;d=(d-b)/256\ c=d%256;d=(d-c)/256\ if BIG_ENDIAN then a,b,c,d=d,c,b,a end\ return string_char(a,b,c,d)end}local int32=uint32{unpack=function(self,bytes,ix)local val,ix=uint32:unpack(bytes,ix)return val<2^32 and val or(val-2^31),ix\ end}local Byte=uint8\ local Size_t=uint32\ local Integer=int32\ local Number=char(8)local Insn=char(4)local Struct=Field{unpack=function(self,bytes,ix)local val={}local i,j=1,1\ while self[i]do\ local field=self[i]local key=field.name\ if not key then key,j=j,j+1 end\ val[key],ix=field:unpack(bytes,ix)i=i+1\ end\ return val,ix\ end,pack=function(self,val)local data={}local i,j=1,1\ while self[i]do\ local field=self[i]local key=field.name\ if not key then key,j=j,j+1 end\ data[i]=field:pack(val[key])i=i+1\ end\ return table_concat(data)end}local List=Field{unpack=function(self,bytes,ix)local len,ix=Integer:unpack(bytes,ix)local vals={}local field=self.type\ for i=1,len do\ vals[i],ix=field:unpack(bytes,ix)end\ return vals,ix\ end,pack=function(self,vals)local len=#vals\ local data={Integer:pack(len)}local field=self.type\ for i=1,len do\ data[#data+1]=field:pack(vals[i])end\ return table_concat(data)end}local Boolean=Field{unpack=function(self,bytes,ix)local val,ix=Integer:unpack(bytes,ix)assert(val==0 or val==1,\"unpacked an unexpected value \"..val..\" for a Boolean\")return val==1,ix\ end,pack=function(self,val)assert(type(val)==\"boolean\",\"unexpected value type to pack as a Boolean\")return Integer:pack(val and 1 or 0)end}local String=Field{unpack=function(self,bytes,ix)local len,ix=Integer:unpack(bytes,ix)local val=nil\ if len>0 then\ local string_len=len-1\ val=bytes:sub(ix,ix+string_len-1)end\ return val,ix+len\ end,pack=function(self,val)assert(type(val)==\"nil\"or type(val)==\"string\",\"unexpected value type to pack as a String\")if val==nil then\ return Integer:pack(0)end\ return Integer:pack(#val+1)..val..\"\\0\"end}local ChunkHeader=Struct{char(4){name=\"signature\"},Byte{name=\"version\"},Byte{name=\"format\"},Byte{name=\"endianness\"},Byte{name=\"sizeof_int\"},Byte{name=\"sizeof_size_t\"},Byte{name=\"sizeof_insn\"},Byte{name=\"sizeof_Number\"},Byte{name=\"integral_flag\"},}local ConstantTypes={[0]=None,[1]=Boolean,[3]=Number,[4]=String,}local Constant=Field{unpack=function(self,bytes,ix)local t,ix=Byte:unpack(bytes,ix)local field=ConstantTypes[t]assert(field,\"unknown constant type \"..t..\" to unpack\")local v,ix=field:unpack(bytes,ix)return{type=t,value=v},ix\ end,pack=function(self,val)local t,v=val.type,val.value\ return Byte:pack(t)..ConstantTypes[t]:pack(v)end}local Local=Struct{String{name=\"name\"},Integer{name=\"startpc\"},Integer{name=\"endpc\"}}local Function=Struct{String{name=\"name\"},Integer{name=\"line\"},Integer{name=\"last_line\"},Byte{name=\"num_upvalues\"},Byte{name=\"num_parameters\"},Byte{name=\"is_vararg\"},Byte{name=\"max_stack_size\"},List{name=\"insns\",type=Insn},List{name=\"constants\",type=Constant},List{name=\"prototypes\",type=nil},List{name=\"source_lines\",type=Integer},List{name=\"locals\",type=Local},List{name=\"upvalues\",type=String},}assert(Function[10].name==\"prototypes\",\"missed the function prototype list\")Function[10].type=Function\ local Chunk=Struct{ChunkHeader{name=\"header\"},Function{name=\"body\"}}local function validate(chunk)if type(chunk)==\"function\"then\ return validate(string.dump(chunk))end\ local f=Chunk:unpack(chunk,1)local chunk2=Chunk:pack(f)if chunk==chunk2 then return true end\ local i\ local len=math.min(#chunk,#chunk2)for i=1,len do\ local a=chunk:sub(i,i)local b=chunk:sub(i,i)if a~=b then\ return false,(\"chunk roundtripping failed: \"..\"first byte difference at index %d\"):format(i)end\ end\ return false,(\"chunk round tripping failed: \"..\"original length %d vs. %d\"):format(#chunk,#chunk2)end\ return{disassemble=function(chunk)return Chunk:unpack(chunk,1)end,assemble=function(disassembled)return Chunk:pack(disassembled)end,validate=validate}end)local cs=require\"minichunkspy\"local function ___adjust_chunk(chunk,newname,lineshift)local c=cs.disassemble(string.dump(chunk));c.body.name=newname;lineshift=-c.body.line;local function shiftlines(c)c.line=c.line+lineshift;c.last_line=c.last_line+lineshift;for i,line in ipairs(c.source_lines)do\ c.source_lines[i]=line+lineshift;end\ for i,f in ipairs(c.prototypes)do\ shiftlines(f);end\ end\ shiftlines(c.body);return assert(loadstring(cs.assemble(c),newname))();end\ "function require_resource(t)return e[t]or error("resource '"..tostring(t).."' not found");end end pcall(require,"luarocks.require"); local o={v="verbose",vv="very_verbose",o="output",q="quiet",qq="very_quiet",g="debug"} local e={use_http=false,module_compat=not not _ENV}; for t,a in ipairs(arg)do if a:match("^%-")then local t=a:match("^%-%-?([^%s=]+)()") t=(o[t]or t):gsub("%-+","_"); if t:match("^no_")then t=t:sub(4,-1); e[t]=false; else e[t]=a:match("=(.*)$")or true; end else base_path=a; end end if e.very_verbose then e.verbose=true;end if e.very_quiet then e.quiet=true;end local t=function()end local t,o,s,h=t,t,t,t; if not e.very_quiet then t=print;end if not e.quiet then o=print;end if e.verbose or e.very_verbose then s=print;end if e.very_verbose then h=print;end print=s; local i,d,n={},{},{}; function Module(e) if i[e]then s("Ignoring duplicate module definition for "..e); return function()end end local t=#i+1; i[t]={name=e,url=___fetch_url}; i[e]=i[t]; return function(e) i[t].path=e; end end function Resource(t,a) local e=#n+1; n[e]={name=t,path=a or t}; return function(t) n[e].path=t; end end function AutoFetchURL(e) ___fetch_url=e; end function Main(e) table.insert(d,e); end function Output(t) if e.output==nil then out_fn=t; end end function Option(t) t=t:gsub("%-","_"); if e[t]==nil then e[t]=true; return function(a) e[t]=a; end else return function()end; end end function GetOption(t) return e[t:gsub('%-','_')]; end function Message(t) if not e.quiet then o(t); end end function Error(a) if not e.very_quiet then t(a); end end function Exit() os.exit(1); end base_path=(base_path or"."):gsub("/$","").."/" squishy_file=base_path.."squishy"; out_fn=e.output; local r,a=pcall(dofile,squishy_file); if not r then t("Couldn't read squishy file: "..a); os.exit(1); end if not out_fn then t("No output file specified by user or squishy file"); os.exit(1); elseif#d==0 and#i==0 and#n==0 then t("No files, modules or resources. Not going to generate an empty file."); os.exit(1); end local r={}; function r.filesystem(e) local e,t=io.open(e); if not e then return false,t;end local t=e:read("*a"); e:close(); return t; end if e.use_http then function r.http(t) local e=require"socket.http"; local t,e=e.request(t); if e==200 then return t; end return false,"HTTP status code: "..tostring(e); end else function r.http(e) return false,"Module not found. Re-squish with --use-http option to fetch it from "..e; end end s("Resolving modules..."); do local e=package.config:sub(1,1); local n=package.config:sub(5,5); local o=package.path:gsub("[^;]+",function(t) if not t:match("^%"..e)then return base_path..t; end end):gsub("/%./","/"); local a=package.cpath:gsub("[^;]+",function(t) if not t:match("^%"..e)then return base_path..t; end end):gsub("/%./","/"); function resolve_module(t,a) t=t:gsub("%.",e); for e in a:gmatch("[^;]+")do e=e:gsub("%"..n,t); h("Looking for "..e) local t=io.open(e); if t then h("Found!"); t:close(); return e; end end return nil; end for a,e in ipairs(i)do if not e.path then e.path=resolve_module(e.name,o); if not e.path then t("Couldn't resolve module: "..e.name); else e.path=e.path:gsub("^"..base_path:gsub("%p","%%%1"),""); end end end end for a,e in ipairs(i)do if not e.path then t("Exiting due to missing modules without a path"); os.exit(1); end end if e.list_files or e.list_missing_files then local function t(t) if e.list_missing_files then local e=io.open(t); if e then e:close(); return; end end io.write(t,"\n"); end for a,e in pairs(d)do t(e); end for a,e in ipairs(i)do t(e.path); end for a,e in ipairs(n)do t(e.path); end return; end o("Writing "..out_fn.."..."); local a,l=io.open(out_fn,"w+"); if not a then t("Couldn't open output file: "..tostring(l)); os.exit(1); end if e.executable then if e.executable==true then a:write("#!/usr/bin/env lua\n"); else a:write("#!"..e.executable,"\n"); end end s("Packing modules..."); for o,i in ipairs(i)do local d,s=i.name,i.path; if i.path:sub(1,1)~="/"then s=base_path..i.path; end h("Packing "..d.." ("..s..")..."); local o,n=r.filesystem(s); if(not o)and i.url then local e=i.url:gsub("%?",i.path); h("Fetching: "..e) if e:match("^https?://")then o,n=r.http(e); elseif e:match("^file://")or e:match("^[/%.]")then local e,t=io.open((e:gsub("^file://",""))); if e then o,n=e:read("*a"); e:close(); else o,n=nil,t; end end end if o then o=o:gsub("^#[^\r\n]*\r?\n",""); if not e.debug then a:write("package.preload['",d,"'] = (function (...)\n"); if e.module_compat then a:write[[ local _ENV = _ENV; local function module(name, ...) local t = package.loaded[name] or _ENV[name] or { _NAME = name }; package.loaded[name] = t; for i = 1, select("#", ...) do (select(i, ...))(t); end _ENV = t; _M = t; return t; end ]]; end a:write(o); a:write(" end)\n"); else a:write("package.preload['",d,"'] = assert(loadstring(\n"); a:write(("%q\n"):format(o)); a:write(", ",("%q"):format("@"..s),"))\n"); end else t("Couldn't pack module '"..d.."': "..(n or"unknown error... path to module file correct?")); os.exit(1); end end if#n>0 then s("Packing resources...") a:write("do local resources = {};\n"); for o,e in ipairs(n)do local o,e=e.name,e.path; local e,i=io.open(base_path..e,"rb"); if not e then t("Couldn't load resource: "..tostring(i)); os.exit(1); end local t=e:read("*a"); local e=0; t:gsub("(=+)",function(t)e=math.max(e,#t);end); a:write(("resources[%q] = %q"):format(o,t)); end if e.virtual_io then local e=require_resource("vio"); if not e then t("Virtual IO requested but is not enabled in this build of squish"); else a:write(e,"\n") a:write[[local io_open, io_lines = io.open, io.lines; function io.open(fn, mode) if not resources[fn] then return io_open(fn, mode); else return vio.open(resources[fn]); end end function io.lines(fn) if not resources[fn] then return io_lines(fn); else return vio.open(resources[fn]):lines() end end local _dofile = dofile; function dofile(fn) if not resources[fn] then return _dofile(fn); else return assert(loadstring(resources[fn]))(); end end local _loadfile = loadfile; function loadfile(fn) if not resources[fn] then return _loadfile(fn); else return loadstring(resources[fn], "@"..fn); end end ]] end end a:write[[function require_resource(name) return resources[name] or error("resource '"..tostring(name).."' not found"); end end ]] end h("Finalising...") for e,o in pairs(d)do local e,i=io.open(base_path..o); if not e then t("Failed to open "..o..": "..i); os.exit(1); else a:write((e:read("*a"):gsub("^#.-\n",""))); e:close(); end end a:close(); o("OK!"); local h=require"optlex" local r=require"optparser" local a=require"llex" local d=require"lparser" local i={ none={}; debug={"whitespace","locals","entropy","comments","numbers"}; default={"comments","whitespace","emptylines","numbers","locals"}; basic={"comments","whitespace","emptylines"}; full={"comments","whitespace","emptylines","eols","strings","numbers","locals","entropy"}; } if e.minify_level and not i[e.minify_level]then t("Unknown minify level: "..e.minify_level); t("Available minify levels: none, basic, default, full, debug"); end for a,t in ipairs(i[e.minify_level or"default"]or{})do if e["minify_"..t]==nil then e["minify_"..t]=true; end end local n={ ["opt-locals"]=e.minify_locals; ["opt-comments"]=e.minify_comments; ["opt-entropy"]=e.minify_entropy; ["opt-whitespace"]=e.minify_whitespace; ["opt-emptylines"]=e.minify_emptylines; ["opt-eols"]=e.minify_eols; ["opt-strings"]=e.minify_strings; ["opt-numbers"]=e.minify_numbers; } local function i(e) t("minify: "..e);os.exit(1); end local function l(e) local t=io.open(e,"rb") if not t then i("cannot open \""..e.."\" for reading")end local a=t:read("*a") if not a then i("cannot read from \""..e.."\"")end t:close() return a end local function u(e,a) local t=io.open(e,"wb") if not t then i("cannot open \""..e.."\" for writing")end local a=t:write(a) if not a then i("cannot write to \""..e.."\"")end t:close() end function minify_string(e) a.init(e) a.llex() local t,e,a =a.tok,a.seminfo,a.tokln if n["opt-locals"]then r.print=print d.init(t,e,a) local o,a=d.parser() r.optimize(n,t,e,o,a) end h.print=print t,e,a =h.optimize(n,t,e,a) local e=table.concat(e) if string.find(e,"\r\n",1,1)or string.find(e,"\n\r",1,1)then h.warn.mixedeol=true end return e; end function minify_file(e,t) local e=l(e); e=minify_string(e); u(t,e); end if e.minify~=false then o("Minifying "..out_fn.."..."); minify_file(out_fn,out_fn); o("OK!"); end local h=require"llex" local i=128; local n={"and","break","do","else","elseif", "end","false","for","function","if", "in","local","nil","not","or","repeat", "return","then","true","until","while"} function uglify_file(l,o) local r,a=io.open(l); if not r then t("Can't open input file for reading: "..tostring(a)); return; end local a,s=io.open(o..".uglified","w+b"); if not a then t("Can't open output file for writing: "..tostring(s)); return; end local s=r:read("*a"); r:close(); local r,t=s:match("^(#.-\n)(.+)$"); local t=t or s; if r then a:write(r) end while i+#n<=255 and t:find("["..string.char(i).."-"..string.char(i+#n-1).."]")do i=i+1; end if i+#n>255 then a:write(t); a:close(); os.rename(o..".uglified",o); return; end local d={} for t,e in ipairs(n)do d[e]=string.char(i+t); end local r=0; s:gsub("(=+)",function(e)r=math.max(r,#e);end); h.init(t,"@"..l); h.llex() local s=h.seminfo; if e.uglify_level=="full"and i+#n<255 then local e={}; for o,a in ipairs(h.tok)do if a=="TK_NAME"or a=="TK_STRING"then local t=string.format("%q,%q",a,s[o]); if not e[t]then e[t]={type=a,value=s[o],count=0}; e[#e+1]=e[t]; end e[t].count=e[t].count+1; end end for t=1,#e do local e=e[t]; e.score=(e.count)*(#e.value-1)-#string.format("%q",e.value)-1; end table.sort(e,function(e,t)return e.score>t.score;end); local t=255-(i+#n); for t=t+1,#e do e[t]=nil; end local t=#n; for a,e in ipairs(e)do if e.score>0 then table.insert(n,e.value); d[e.value]=string.char(i+t+a); end end end a:write("local base_char,keywords=",tostring(i),",{"); for t,e in ipairs(n)do a:write(string.format("%q",e),','); end a:write[[}; function prettify(code) return code:gsub("["..string.char(base_char).."-"..string.char(base_char+#keywords).."]", function (c) return keywords[c:byte()-base_char]; end) end ]] a:write[[return setfenv(assert(loadstring(prettify]] a:write("[",string.rep("=",r+1),"["); for e,t in ipairs(h.tok)do if t=="TK_KEYWORD"or t=="TK_NAME"or t=="TK_STRING"then local t=d[s[e]]; if t then a:write(t); else a:write(s[e]); end else a:write(s[e]); end end a:write("]",string.rep("=",r+1),"]"); a:write(", '@",o,"')), getfenv())()"); a:close(); os.rename(o..".uglified",o); end if e.uglify then o("Uglifying "..out_fn.."..."); uglify_file(out_fn,out_fn); o("OK!"); end local i=require"minichunkspy" function compile_string(t,a) local o=string.dump(loadstring(t,a)); if((not e.debug)or e.compile_strip)and e.compile_strip~=false then local t=i.disassemble(o); local function a(e) e.source_lines,e.locals,e.upvalues={},{},{}; for t,e in ipairs(e.prototypes)do a(e); end end s("Stripping debug info..."); a(t.body); return i.assemble(t); end return o; end function compile_file(a,e) local o,a=io.open(a); if not o then t("Can't open input file for reading: "..tostring(a)); return; end local a,i=io.open(e..".compiled","w+"); if not a then t("Can't open output file for writing: "..tostring(i)); return; end local i=o:read("*a"); o:close(); local t,o=i:match("^(#.-\n)(.+)$"); local o=o or i; if t then a:write(t) end a:write(compile_string(o,e)); os.rename(e..".compiled",e); end if e.compile then o("Compiling "..out_fn.."..."); compile_file(out_fn,out_fn); o("OK!"); end function gzip_file(e,a) local o,e=io.open(e); if not o then t("Can't open input file for reading: "..tostring(e)); return; end local e,i=io.open(a..".gzipped","wb+"); if not e then t("Can't open output file for writing: "..tostring(i)); return; end local i=o:read("*a"); o:close(); local n,o=i:match("^(#.-\n)(.+)$"); local o=o or i; if n then e:write(n) end local i,n=io.open(a..".pregzip","wb+"); if not i then t("Can't open temp file for writing: "..tostring(n)); return; end i:write(o); i:close(); local t=io.popen("gzip -c '"..a..".pregzip'"); o=t:read("*a"); t:close(); os.remove(a..".pregzip"); local t=0; o:gsub("(=+)",function(e)t=math.max(t,#e);end); e:write("local ungz = (function ()",require_resource"gunzip.lua"," end)()\n"); e:write[[return assert(loadstring((function (i)local o={} ungz{input=i,output=function(b)table.insert(o,string.char(b))end}return table.concat(o)end) ]]; e:write((string.format("%q",o):gsub("\026","\\026"))); e:write(", '@",a,"'))()"); e:close(); os.rename(a..".gzipped",a); end if e.gzip then o("Gzipping "..out_fn.."..."); gzip_file(out_fn,out_fn); o("OK!"); end