-
-
Save Fingercomp/61156a246367980316a20cb753f9391b to your computer and use it in GitHub Desktop.
local UlikV=load([===[ | |
local rA5U=20160728.17 | |
local Uc06="-[ JSON.lua package by Jeffrey Friedl (http://regex.info/blog/lua/json) version 20160728.17 ]-"local lcBL={VERSION=rA5U,AUTHOR_NOTE=Uc06}local DHPxI=" " | |
local dx={pretty=true,align_keys=false,indent=DHPxI} | |
local RRuSHnxf={__tostring=function()return"JSON array"end}RRuSHnxf.__index=RRuSHnxf | |
local mcYOuT={__tostring=function()return"JSON object"end}mcYOuT.__index=mcYOuT;function lcBL:newArray(iXxD6s) | |
return setmetatable(iXxD6s or{},RRuSHnxf)end;function lcBL:newObject(oiY)return | |
setmetatable(oiY or{},mcYOuT)end;local function Rr(FsYIVlkf) | |
return | |
type(FsYIVlkf)=='number'and FsYIVlkf or FsYIVlkf.N end | |
local scRP0={__index=isNumber,__tostring=function(HLXS0Q_)return HLXS0Q_.S end,__unm=function(Kw)return | |
Rr(Kw)end,__concat=function(nvaIsNv7,vDnoL55) | |
return tostring(nvaIsNv7)..tostring(vDnoL55)end,__add=function(xlAK,zr1y)return Rr(xlAK)+Rr(zr1y)end,__sub=function(Hs,jk)return | |
Rr(Hs)-Rr(jk)end,__mul=function(qzSFyIO,Z65) | |
return Rr(qzSFyIO)*Rr(Z65)end,__div=function(umyCNfj,FT)return Rr(umyCNfj)/Rr(FT)end,__mod=function(YVLXYq,bJfct)return | |
Rr(YVLXYq)%Rr(bJfct)end,__pow=function(OhuFpq_N,Dzg)return | |
Rr(OhuFpq_N)^Rr(Dzg)end,__lt=function(_4O,C)return Rr(_4O)<Rr(C)end,__eq=function(fLI2zRe,_Fr2YU)return | |
Rr(fLI2zRe)==Rr(_Fr2YU)end,__le=function(Xfn,U)return | |
Rr(Xfn)<=Rr(U)end} | |
function lcBL:asNumber(Ebsw) | |
if getmetatable(Ebsw)==scRP0 then return Ebsw elseif | |
type(Ebsw)=='table'and | |
type(Ebsw.S)=='string'and type(Ebsw.N)=='number'then return setmetatable(Ebsw,scRP0)else | |
local UlikV={S=tostring(Ebsw),N=tonumber(Ebsw)}return setmetatable(UlikV,scRP0)end end | |
local function AI0R2TQ6(JtAjijkG) | |
if JtAjijkG<=127 then return string.char(JtAjijkG)elseif JtAjijkG<=2047 then | |
local s=math.floor(JtAjijkG/0x40)local YAtG_LV3=JtAjijkG- (0x40*s)return | |
string.char(0xC0+s,0x80+YAtG_LV3)elseif JtAjijkG<=65535 then | |
local LfEJbh_=math.floor(JtAjijkG/0x1000)local JD=JtAjijkG-0x1000*LfEJbh_ | |
local u=math.floor(JD/0x40)local pzDMZwG=JD-0x40*u;LfEJbh_=0xE0+LfEJbh_;u=0x80+u | |
pzDMZwG=0x80+pzDMZwG | |
if | |
(LfEJbh_==0xE0 and u<0xA0)or | |
(LfEJbh_==0xED and u>0x9F)or(LfEJbh_==0xF0 and u<0x90)or(LfEJbh_==0xF4 and u>0x8F)then return"?"else return string.char(LfEJbh_,u,pzDMZwG)end else local XPoQB=math.floor(JtAjijkG/0x40000) | |
local XxJ=JtAjijkG-0x40000*XPoQB;local o5sms=math.floor(XxJ/0x1000) | |
XxJ=XxJ-0x1000*o5sms;local JQi1jg=math.floor(XxJ/0x40)local wVzn=XxJ-0x40*JQi1jg | |
return string.char( | |
0xF0+XPoQB,0x80+o5sms,0x80+JQi1jg,0x80+wVzn)end end | |
function lcBL:onDecodeError(pE,RSjapQ,QJf,zC)if RSjapQ then | |
if QJf then | |
pE=string.format("%s at char %d of: %s",pE,QJf,RSjapQ)else pE=string.format("%s: %s",pE,RSjapQ)end end | |
if zC~=nil then pE=pE.." (".. | |
lcBL:encode(zC)..")"end | |
if self.assert then self.assert(false,pE)else assert(false,pE)end end;lcBL.onDecodeOfNilError=lcBL.onDecodeError | |
lcBL.onDecodeOfHTMLError=lcBL.onDecodeError | |
function lcBL:onEncodeError(pfZ3SPy_,pDNa2ox6) | |
if pDNa2ox6 ~=nil then pfZ3SPy_=pfZ3SPy_.. | |
" ("..lcBL:encode(pDNa2ox6)..")"end;if self.assert then self.assert(false,pfZ3SPy_)else | |
assert(false,pfZ3SPy_)end end | |
local function yA(Do6yo7nm,y06X3k,ivnJjrA,d3fMjkg) | |
local el=y06X3k:match('^-?[1-9]%d*',ivnJjrA)or y06X3k:match("^-?0",ivnJjrA)if not el then | |
Do6yo7nm:onDecodeError("expected number",y06X3k,ivnJjrA,d3fMjkg.etc)end | |
local Wu_uIt=ivnJjrA+el:len()local w=y06X3k:match('^%.%d+',Wu_uIt)or""Wu_uIt=Wu_uIt+ | |
w:len() | |
local sgeP=y06X3k:match('^[eE][-+]?%d+',Wu_uIt)or""Wu_uIt=Wu_uIt+sgeP:len()local CM=el..w..sgeP;if | |
d3fMjkg.decodeNumbersAsObjects then return lcBL:asNumber(CM),Wu_uIt end | |
if | |
( | |
d3fMjkg.decodeIntegerStringificationLength and(el:len()>=d3fMjkg.decodeIntegerStringificationLength or | |
sgeP:len()>0))or | |
(d3fMjkg.decodeDecimalStringificationLength and | |
( | |
w:len()>=d3fMjkg.decodeDecimalStringificationLength or sgeP:len()>0))then return CM,Wu_uIt end;local Qlmlet=tonumber(CM)if not Qlmlet then | |
Do6yo7nm:onDecodeError("bad number",y06X3k,ivnJjrA,d3fMjkg.etc)end;return Qlmlet,Wu_uIt end | |
local function XmVolesU(_,RkGFh6,hw18,nvCiFt7r)if RkGFh6:sub(hw18,hw18)~='"'then | |
_:onDecodeError("expected string's opening quote",RkGFh6,hw18,nvCiFt7r.etc)end;local xSebv5Jc=hw18+1 | |
local mMp=RkGFh6:len()local rDtVf="" | |
while xSebv5Jc<=mMp do local vj=RkGFh6:sub(xSebv5Jc,xSebv5Jc)if | |
vj=='"'then return rDtVf,xSebv5Jc+1 end | |
if vj~='\\'then rDtVf=rDtVf..vj;xSebv5Jc= | |
xSebv5Jc+1 elseif RkGFh6:match('^\\b',xSebv5Jc)then rDtVf=rDtVf.."\b"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\f',xSebv5Jc)then rDtVf=rDtVf.."\f"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\n',xSebv5Jc)then rDtVf=rDtVf.."\n"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\r',xSebv5Jc)then rDtVf=rDtVf.."\r"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\t',xSebv5Jc)then rDtVf=rDtVf.."\t"xSebv5Jc= | |
xSebv5Jc+2 else | |
local z=RkGFh6:match('^\\u([0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])',xSebv5Jc) | |
if z then xSebv5Jc=xSebv5Jc+6;local Zg=tonumber(z,16) | |
if | |
Zg>=0xD800 and Zg<=0xDBFF then | |
local ykRppH=RkGFh6:match('^\\u([dD][cdefCDEF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])',xSebv5Jc) | |
if ykRppH then xSebv5Jc=xSebv5Jc+6;Zg=0x2400+ (Zg-0xD800)*0x400+ | |
tonumber(ykRppH,16)else end end;rDtVf=rDtVf..AI0R2TQ6(Zg)else rDtVf=rDtVf.. | |
RkGFh6:match('^\\(.)',xSebv5Jc)xSebv5Jc=xSebv5Jc+2 end end end | |
_:onDecodeError("unclosed string",RkGFh6,hw18,nvCiFt7r.etc)end | |
local function eZ0l3ch(WQ6,y36Aetn)local iPL3B4cr,GI2hz6SK=WQ6:find("^[ \n\r\t]+",y36Aetn)if GI2hz6SK then | |
return GI2hz6SK+1 else return y36Aetn end end;local W_63_9 | |
local function h9dyA_4T(Oh,PG,n,O)if PG:sub(n,n)~='{'then | |
Oh:onDecodeError("expected '{'",PG,n,O.etc)end;local N5UjTN=eZ0l3ch(PG,n+1)local qLH5=Oh.strictTypes and | |
Oh:newObject{}or{}if | |
PG:sub(N5UjTN,N5UjTN)=='}'then return qLH5,N5UjTN+1 end | |
local tE=PG:len() | |
while N5UjTN<=tE do local VcV0EuD,pX4gCR=XmVolesU(Oh,PG,N5UjTN,O) | |
N5UjTN=eZ0l3ch(PG,pX4gCR)if PG:sub(N5UjTN,N5UjTN)~=':'then | |
Oh:onDecodeError("expected colon",PG,N5UjTN,O.etc)end | |
N5UjTN=eZ0l3ch(PG,N5UjTN+1)local gad4ZcL,pX4gCR=W_63_9(Oh,PG,N5UjTN,O)qLH5[VcV0EuD]=gad4ZcL | |
N5UjTN=eZ0l3ch(PG,pX4gCR)local dk=PG:sub(N5UjTN,N5UjTN) | |
if dk=='}'then return qLH5,N5UjTN+1 end;if PG:sub(N5UjTN,N5UjTN)~=','then | |
Oh:onDecodeError("expected comma or '}'",PG,N5UjTN,O.etc)end | |
N5UjTN=eZ0l3ch(PG,N5UjTN+1)end;Oh:onDecodeError("unclosed '{'",PG,n,O.etc)end | |
local function oh(E,OO,y,cR6rJlAl)if OO:sub(y,y)~='['then | |
E:onDecodeError("expected '['",OO,y,cR6rJlAl.etc)end;local M6ilzGJ=eZ0l3ch(OO,y+1)local iW6CD=E.strictTypes and | |
E:newArray{}or{}if | |
OO:sub(M6ilzGJ,M6ilzGJ)==']'then return iW6CD,M6ilzGJ+1 end | |
local wZdg=1;local BaX=OO:len() | |
while M6ilzGJ<=BaX do | |
local SJsW11k,Ki1HJT=W_63_9(E,OO,M6ilzGJ,cR6rJlAl)iW6CD[wZdg]=SJsW11k;wZdg=wZdg+1;M6ilzGJ=eZ0l3ch(OO,Ki1HJT) | |
local wjim8xCV=OO:sub(M6ilzGJ,M6ilzGJ)if wjim8xCV==']'then return iW6CD,M6ilzGJ+1 end;if | |
OO:sub(M6ilzGJ,M6ilzGJ)~=','then | |
E:onDecodeError("expected comma or '['",OO,M6ilzGJ,cR6rJlAl.etc)end | |
M6ilzGJ=eZ0l3ch(OO,M6ilzGJ+1)end | |
E:onDecodeError("unclosed '['",OO,y,cR6rJlAl.etc)end | |
W_63_9=function(E,QLam,qTDt,v)qTDt=eZ0l3ch(QLam,qTDt) | |
if qTDt>QLam:len()then E:onDecodeError("unexpected end of string",QLam, | |
nil,v.etc)end | |
if QLam:find('^"',qTDt)then return XmVolesU(E,QLam,qTDt,v.etc)elseif | |
QLam:find('^[-0123456789 ]',qTDt)then return yA(E,QLam,qTDt,v)elseif QLam:find('^%{',qTDt)then | |
return h9dyA_4T(E,QLam,qTDt,v)elseif QLam:find('^%[',qTDt)then return oh(E,QLam,qTDt,v)elseif QLam:find('^true',qTDt)then return true, | |
qTDt+4 elseif QLam:find('^false',qTDt)then return false,qTDt+5 elseif | |
QLam:find('^null',qTDt)then return nil,qTDt+4 else | |
E:onDecodeError("can't parse JSON",QLam,qTDt,v.etc)end end | |
function lcBL:decode(Ta,u,nArcvQl)if type(nArcvQl)~='table'then nArcvQl={}end;if u~=nil then | |
nArcvQl.etc=u end;if | |
type(self)~='table'or self.__index~=lcBL then | |
lcBL:onDecodeError("JSON:decode must be called in method format",nil,nil,nArcvQl.etc)end | |
if Ta==nil then | |
self:onDecodeOfNilError(string.format("nil passed to JSON:decode()"), | |
nil,nil,nArcvQl.etc)elseif type(Ta)~='string'then | |
self:onDecodeError(string.format("expected string argument to JSON:decode(), got %s",type(Ta)), | |
nil,nil,nArcvQl.etc)end;if Ta:match('^%s*$')then return nil end;if Ta:match('^%s*<')then | |
self:onDecodeOfHTMLError(string.format("html passed to JSON:decode()"),Ta, | |
nil,nArcvQl.etc)end | |
if | |
Ta:sub(1,1):byte()==0 or | |
(Ta:len()>=2 and Ta:sub(2,2):byte()==0)then | |
self:onDecodeError("JSON package groks only UTF-8, sorry",Ta,nil,nArcvQl.etc)end;if nArcvQl.decodeNumbersAsObjects==nil then | |
nArcvQl.decodeNumbersAsObjects=self.decodeNumbersAsObjects end;if | |
nArcvQl.decodeIntegerStringificationLength==nil then | |
nArcvQl.decodeIntegerStringificationLength=self.decodeIntegerStringificationLength end;if | |
nArcvQl.decodeDecimalStringificationLength==nil then | |
nArcvQl.decodeDecimalStringificationLength=self.decodeDecimalStringificationLength end | |
local h6Ub7U,Gm=pcall(W_63_9,self,Ta,1,nArcvQl)if h6Ub7U then return Gm else | |
if self.assert then self.assert(false,Gm)else assert(false,Gm)end;return nil,Gm end end | |
local function DZXGTh(YKA7cU) | |
if YKA7cU=="\n"then return"\\n"elseif YKA7cU=="\r"then return"\\r"elseif YKA7cU=="\t"then return"\\t"elseif YKA7cU=="\b"then | |
return"\\b"elseif YKA7cU=="\f"then return"\\f"elseif YKA7cU=='"'then return'\\"'elseif YKA7cU=='\\'then return'\\\\'else return | |
string.format("\\u%04x",YKA7cU:byte())end end | |
local Su9Koz='['..'"'.. | |
'%\\'..'%z'..'\001'..'-'..'\031'..']'local Uk7e=AI0R2TQ6(0x2028)local KwQCk_G=AI0R2TQ6(0x2029) | |
local function ptZa(mCsewfX,yY) | |
local Xf=mCsewfX:gsub(Su9Koz,DZXGTh)if yY.stringsAreUtf8 then | |
Xf=Xf:gsub(Uk7e,'\\u2028'):gsub(KwQCk_G,'\\u2029')end;return'"'..Xf..'"'end | |
local function PEqsd(UlFdiZ7v,U,wFeA)local JQgI={}local N={}local fs52REi=false;local PUNkgaiM | |
for X in pairs(U)do | |
if type(X)=='string'then | |
table.insert(JQgI,X)elseif type(X)=='number'then table.insert(N,X) | |
if X<=0 or X>=math.huge then | |
fs52REi=true elseif not PUNkgaiM or X>PUNkgaiM then PUNkgaiM=X end else | |
UlFdiZ7v:onEncodeError("can't encode table with a key of type "..type(X),wFeA)end end | |
if#JQgI==0 and not fs52REi then | |
if#N>0 then return nil,PUNkgaiM elseif | |
tostring(U)=="JSON array"then return nil elseif tostring(U)=="JSON object"then return{}else return nil end end;table.sort(JQgI)local s6FbB | |
if#N>0 then if UlFdiZ7v.noKeyConversion then | |
UlFdiZ7v:onEncodeError("a table with both numeric and string keys could be an object or array; aborting",wFeA)end | |
s6FbB={}for dc61,aguhyl in pairs(U)do s6FbB[dc61]=aguhyl end | |
table.sort(N) | |
for p,gOPDv in ipairs(N)do local aSdZU3=tostring(gOPDv) | |
if s6FbB[aSdZU3]==nil then | |
table.insert(JQgI,aSdZU3)s6FbB[aSdZU3]=U[gOPDv]else | |
UlFdiZ7v:onEncodeError( | |
"conflict converting table with mixed-type keys into a JSON object: key "..gOPDv.." exists both as a string and a number.",wFeA)end end end;return JQgI,nil,s6FbB end;local iSj | |
function iSj(YKDL,oFyb6OLp,oGdh_mv,WjvvK,TASVwBgU,KjUncMB,XkT) | |
if oFyb6OLp==nil or | |
(not XkT and TASVwBgU and TASVwBgU.null and oFyb6OLp== | |
TASVwBgU.null)then return'null'elseif | |
type(oFyb6OLp)=='string'then return ptZa(oFyb6OLp,TASVwBgU)elseif type(oFyb6OLp)=='number'then | |
if | |
oFyb6OLp~=oFyb6OLp then return"null"elseif oFyb6OLp>=math.huge then return"1e+9999"elseif oFyb6OLp<=-math.huge then | |
return"-1e+9999"else return tostring(oFyb6OLp)end elseif type(oFyb6OLp)=='boolean'then return tostring(oFyb6OLp)elseif type(oFyb6OLp)~= | |
'table'then | |
YKDL:onEncodeError("can't convert "..type(oFyb6OLp).." to JSON",WjvvK)elseif getmetatable(oFyb6OLp)==scRP0 then return tostring(oFyb6OLp)else | |
local c3dr=oFyb6OLp;if type(TASVwBgU)~='table'then TASVwBgU={}end;if type(KjUncMB)~= | |
'string'then KjUncMB=""end | |
if oGdh_mv[c3dr]then | |
YKDL:onEncodeError("table ".. | |
tostring(c3dr).." is a child of itself",WjvvK)else oGdh_mv[c3dr]=true end;local NGH;local tIc,MD2O,HQ=PEqsd(YKDL,c3dr,WjvvK) | |
if MD2O then local cng={}for lE=1,MD2O do | |
table.insert(cng,iSj(YKDL,c3dr[lE],oGdh_mv,WjvvK,TASVwBgU,KjUncMB))end | |
if TASVwBgU.pretty then NGH="[ ".. | |
table.concat(cng,", ").." ]"else NGH="[".. | |
table.concat(cng,",").."]"end elseif tIc then local nI2F0id=HQ or c3dr | |
if TASVwBgU.pretty then local N4aMD_P={}local pCi=0 | |
for lNOqUk8,YAnZNei in ipairs(tIc)do | |
local h8YWR44E=iSj(YKDL,tostring(YAnZNei),oGdh_mv,WjvvK,TASVwBgU,KjUncMB,true) | |
if TASVwBgU.align_keys then pCi=math.max(pCi,#h8YWR44E)end;table.insert(N4aMD_P,h8YWR44E)end | |
local NzeoQJ=KjUncMB..tostring(TASVwBgU.indent or"") | |
local AwGfFV=NzeoQJ..string.rep(" ",pCi).. | |
(TASVwBgU.align_keys and" "or"") | |
local wCRY="%s%"..string.format("%d",pCi).."s: %s"local d0uKSVw1={} | |
for VF,fTrMe in ipairs(tIc)do | |
local ypDndT8=iSj(YKDL,nI2F0id[fTrMe],oGdh_mv,WjvvK,TASVwBgU,AwGfFV) | |
table.insert(d0uKSVw1,string.format(wCRY,NzeoQJ,N4aMD_P[VF],ypDndT8))end;NGH="{\n".. | |
table.concat(d0uKSVw1,",\n").."\n"..KjUncMB.."}"else local MV65={} | |
for Y3D66Ym9,q in | |
ipairs(tIc)do | |
local PhJ=iSj(YKDL,nI2F0id[q],oGdh_mv,WjvvK,TASVwBgU,KjUncMB) | |
local h=iSj(YKDL,tostring(q),oGdh_mv,WjvvK,TASVwBgU,KjUncMB,true) | |
table.insert(MV65,string.format("%s:%s",h,PhJ))end;NGH="{"..table.concat(MV65,",").."}"end else NGH="[]"end;oGdh_mv[c3dr]=false;return NGH end end | |
function lcBL:encode(j2K,r8hgwQ,_6U)if type(self)~='table'or self.__index~=lcBL then | |
lcBL:onEncodeError("JSON:encode must be called in method format",r8hgwQ)end;if | |
type(_6U)~='table'then _6U={}end;return iSj(self,j2K,{},r8hgwQ,_6U)end | |
function lcBL:encode_pretty(GLSzBQs,c,xg)if type(self)~='table'or self.__index~=lcBL then | |
lcBL:onEncodeError("JSON:encode_pretty must be called in method format",c)end;if | |
type(xg)~='table'then xg=dx end;return iSj(self,GLSzBQs,{},c,xg)end;function lcBL.__tostring()return"JSON encode/decode package"end | |
lcBL.__index=lcBL | |
function lcBL:new(Id2KoP_G)local Y2or={}if Id2KoP_G then | |
for zN8ASHV5,iju in pairs(Id2KoP_G)do Y2or[zN8ASHV5]=iju end end | |
return setmetatable(Y2or,lcBL)end;return lcBL:new() | |
]===])() | |
local JtAjijkG=(function() | |
local h6Ub7U=[[ Copyright (c) The python-semanticversion project | |
All rights reserved. | |
Redistribution and use in source and binary forms, with or without | |
modification, are permitted provided that the following conditions are met: | |
1. Redistributions of source code must retain the above copyright notice, this | |
list of conditions and the following disclaimer. | |
2. Redistributions in binary form must reproduce the above copyright notice, | |
this list of conditions and the following disclaimer in the documentation | |
and/or other materials provided with the distribution. | |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | |
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
]] | |
h6Ub7U=[[ The use of the library is similar to the original one, | |
check the documentation here: https://python-semanticversion.readthedocs.io/en/latest/ | |
]]local Gm,YKA7cU,mCsewfX;do local dc61=table | |
Gm,YKA7cU,mCsewfX=dc61.concat,dc61.insert,dc61.unpack end;local yY | |
yY=function(aguhyl) | |
do local p=tonumber(aguhyl)if p then | |
return p,true else return aguhyl,false end end end;local Xf | |
Xf=function(gOPDv)return | |
gOPDv and gOPDv[1]=='0'and tonumber(gOPDv and gOPDv~='0')end;local UlFdiZ7v | |
UlFdiZ7v=function(aSdZU3,YKDL)if aSdZU3 ==YKDL then return 0 end | |
if aSdZU3 >YKDL then return 1 end;if aSdZU3 <YKDL then return-1 end end;local U | |
U=function(oFyb6OLp,oGdh_mv)local WjvvK,TASVwBgU=yY(oFyb6OLp)local KjUncMB,XkT=yY(oGdh_mv) | |
if TASVwBgU and XkT then return | |
UlFdiZ7v(WjvvK,KjUncMB)elseif TASVwBgU then return-1 elseif XkT then return 1 else return UlFdiZ7v(WjvvK,KjUncMB)end end;local wFeA | |
wFeA=function(c3dr,NGH)local tIc | |
do local MD2O={}for HQ=1,#c3dr do | |
if NGH[HQ]then MD2O[c3dr[HQ]]=NGH[HQ]end end;tIc=MD2O end | |
for cng,lE in pairs(tIc)do local nI2F0id=U(cng,lE)if nI2F0id~=0 then return nI2F0id end end;return UlFdiZ7v(#c3dr,#NGH)end;local JQgI | |
do local N4aMD_P | |
local pCi={_coerce=function(AwGfFV,wCRY,d0uKSVw1)if d0uKSVw1 ==nil then d0uKSVw1=false end;if | |
wCRY==nil and d0uKSVw1 then return wCRY end;return tonumber(wCRY)end,next_major=function(lNOqUk8) | |
if | |
lNOqUk8.prerelease and lNOqUk8.minor==0 and lNOqUk8.patch==0 then | |
return | |
JQgI(Gm((function()local YAnZNei={}local h8YWR44E=1 | |
local VF={lNOqUk8.major,lNOqUk8.minor,lNOqUk8.patch}for fTrMe=1,#VF do local ypDndT8=VF[fTrMe]YAnZNei[h8YWR44E]=tostring(ypDndT8)h8YWR44E= | |
h8YWR44E+1 end | |
return YAnZNei end)(),'.'))else | |
return | |
JQgI(Gm((function()local MV65={}local Y3D66Ym9=1;local q={lNOqUk8.major+1,0,0} | |
for PhJ=1,#q do | |
local h=q[PhJ]MV65[Y3D66Ym9]=tostring(h)Y3D66Ym9=Y3D66Ym9+1 end;return MV65 end)(),'.'))end end,next_minor=function(j2K)if | |
not(j2K.minor)then | |
error("Partial version doesn't contain the minor component!")end | |
if | |
j2K.prerelease and j2K.patch==0 then | |
return | |
JQgI(Gm((function()local r8hgwQ={}local _6U=1;local GLSzBQs={j2K.major,j2K.minor,j2K.patch} | |
for c=1,# | |
GLSzBQs do local xg=GLSzBQs[c]r8hgwQ[_6U]=tostring(xg)_6U=_6U+1 end;return r8hgwQ end)(),'.'))else | |
return | |
JQgI(Gm((function()local Id2KoP_G={}local Y2or=1;local zN8ASHV5={j2K.major,j2K.minor+1,0}for iju=1,#zN8ASHV5 | |
do local XsWgh=zN8ASHV5[iju]Id2KoP_G[Y2or]=tostring(XsWgh) | |
Y2or=Y2or+1 end;return Id2KoP_G end)(),'.'))end end,next_patch=function(l4Hdz)if | |
not(l4Hdz.patch)then | |
error("Partial version doesn't contain the patch component!")end | |
if l4Hdz.prerelease then | |
return | |
JQgI(Gm((function()local NSXCgSH={}local Wq=1 | |
local SbOQ={l4Hdz.major,l4Hdz.minor,l4Hdz.patch}for IiuHGo=1,#SbOQ do local cGqxtYr=SbOQ[IiuHGo]NSXCgSH[Wq]=tostring(cGqxtYr) | |
Wq=Wq+1 end;return NSXCgSH end)(),'.'))else | |
return | |
JQgI(Gm((function()local bgJFKeeZ={}local yu9fg0nN=1 | |
local wgx={l4Hdz.major,l4Hdz.minor,l4Hdz.patch+1}for zlU7X=1,#wgx do local t=wgx[zlU7X]bgJFKeeZ[yu9fg0nN]=tostring(t) | |
yu9fg0nN=yu9fg0nN+1 end;return bgJFKeeZ end)(),'.'))end end,coerce=function(f6qbO,kk,QrubIAv)if | |
QrubIAv==nil then QrubIAv=false end;local bLHDW | |
bLHDW=function(JYrf2) | |
local KHDOUlRY,I0JvPpn=JYrf2:match('^(%d+)(.*)$')if not(KHDOUlRY)then return nil end;local Ce4ZE=KHDOUlRY | |
local OVx_mN,lB=I0JvPpn:match('^%.(%d+)(.*)$') | |
if OVx_mN then I0JvPpn=lB;Ce4ZE=Ce4ZE.. ('.'..OVx_mN)end;local byE;byE,lB=I0JvPpn:match('^%.(%d+)(.*)$')if byE then I0JvPpn=lB;Ce4ZE=Ce4ZE.. ( | |
'.'..byE)end;return JYrf2,Ce4ZE end;local YjFd7b,jZgPYb=bLHDW(kk)if not(YjFd7b)then | |
error("Version string lacks a numerical component: "..tostring(kk))end | |
local zN2=kk:sub(1,#jZgPYb)if not QrubIAv then while({zN2:gsub('.','')})[2]<2 do | |
zN2=zN2 ..'.0'end end;if | |
#jZgPYb==#kk then return JQgI(zN2,QrubIAv)end | |
local IN69pa5=kk:sub(#jZgPYb+1)IN69pa5=IN69pa5:gsub('[^a-zA-Z0-9+.-]','-') | |
local UOWJ,WtalJw=nil,nil | |
if IN69pa5:sub(1,1)=='+'then UOWJ=''WtalJw=IN69pa5:sub(2)elseif | |
IN69pa5:sub(1,1)=='.'then UOWJ=''WtalJw=IN69pa5:sub(2)elseif | |
IN69pa5:sub(1,1)=='-'then IN69pa5=IN69pa5:sub(2) | |
do local bITCI=IN69pa5:find('+')if bITCI then UOWJ,WtalJw=IN69pa5:sub(1, | |
bITCI-1),IN69pa5:sub(bITCI+1,-1)else | |
UOWJ,WtalJw=IN69pa5,''end end else | |
do local K=IN69pa5:find('+')if K then | |
UOWJ,WtalJw=IN69pa5:sub(1,K-1),IN69pa5:sub(K+1,-1)else UOWJ,WtalJw=IN69pa5,''end end end;WtalJw=WtalJw:gsub('+','.')if UOWJ and UOWJ~=''then | |
zN2=zN2 .. ('-'..UOWJ)end;if WtalJw and WtalJw~=''then | |
zN2=zN2 .. ('+'..WtalJw)end;return f6qbO.__class(zN2,QrubIAv)end,parse=function(F5dtVpnN,kxeBp,a,kQ)if | |
a==nil then a=false end;if kQ==nil then kQ=false end;if not kxeBp or | |
type(kxeBp)~='string'or kxeBp==''then | |
error("Invalid empty version string: ".. | |
tostring(tostring(kxeBp)))end;local EE9LAE | |
if a then | |
EE9LAE=F5dtVpnN.__class.partialVersionRe else EE9LAE=F5dtVpnN.__class.versionRe end;local iVx,eg,AQviNt,T6,NviN0i=EE9LAE(F5dtVpnN.__class,kxeBp)if not iVx then | |
error( | |
"Invalid version string: "..tostring(kxeBp))end;if Xf(iVx)then | |
error("Invalid leading zero in major: "..tostring(kxeBp))end;if Xf(eg)then | |
error("Invalid leading zero in minor: ".. | |
tostring(kxeBp))end;if Xf(AQviNt)then | |
error("Invalid leading zero in patch: ".. | |
tostring(kxeBp))end;iVx=tonumber(iVx) | |
eg=F5dtVpnN:_coerce(eg,a)AQviNt=F5dtVpnN:_coerce(AQviNt,a) | |
if T6 ==nil then if a and NviN0i==nil then return{iVx,eg,AQviNt, | |
nil,nil}else T6={}end elseif T6 ==''then | |
T6={}else do local BlMQce={}local o=1 | |
for dpRE in T6:gmatch('[^.]+')do BlMQce[o]=dpRE;o=o+1 end;T6=BlMQce end | |
F5dtVpnN:_validateIdentifiers(T6,false)end | |
if NviN0i==nil then if a then NviN0i=nil else NviN0i={}end elseif NviN0i==''then NviN0i={}else | |
do local fEiXwWq={} | |
local r3JzMga6=1;for Tuyw in NviN0i:gmatch('[^.]+')do fEiXwWq[r3JzMga6]=Tuyw | |
r3JzMga6=r3JzMga6+1 end;NviN0i=fEiXwWq end;F5dtVpnN:_validateIdentifiers(NviN0i,true)end;return{iVx,eg,AQviNt,T6,NviN0i}end,_validateIdentifiers=function(FYLcr2nu,ioS69,AiP)if | |
AiP==nil then AiP=false end | |
for S2jwpoi=1,#ioS69 do local _WX9u=ioS69[S2jwpoi]if not _WX9u then | |
error( | |
"Invalid empty identifier ".. | |
tostring(_WX9u).." in "..tostring(Gm(ioS69,'.')))end;if | |
_WX9u:sub(1,1)=='0'and tonumber(_WX9u)and _WX9u~='0'and not AiP then | |
error("Invalid leading zero in identifier "..tostring(_WX9u))end end end,__pairs=function(u0riyU)return | |
pairs({u0riyU.major,u0riyU.minor,u0riyU.patch,u0riyU.prerelease,u0riyU.build})end,__ipairs=function(UH)return | |
ipairs({UH.major,UH.minor,UH.patch,UH.prerelease,UH.build})end,__tostring=function(WNph) | |
local ytF=tostring(WNph.major) | |
if WNph.minor~=nil then ytF=ytF.. ('.'..WNph.minor)end | |
if WNph.patch~=nil then ytF=ytF.. ('.'..WNph.patch)end | |
if WNph.prerelease and#WNph.prerelease>0 or | |
WNph.partial and WNph.prerelease and#WNph.prerelease==0 and WNph.build==nil then ytF=ytF.. ('-'.. | |
Gm(WNph.prerelease,'.'))end;if | |
WNph.build and#WNph.build>0 or WNph.partial and WNph.build and# | |
WNph.build==0 then | |
ytF=ytF.. ('+'..Gm(WNph.build,'.'))end;return ytF end,_comparsionFunctions=function(d,gRm)if | |
gRm==nil then gRm=false end;local LPX0 | |
LPX0=function(qao,ipUPIzc) | |
if qao and ipUPIzc then | |
return wFeA(qao,ipUPIzc)elseif qao then return-1 elseif ipUPIzc then return 1 else return 0 end end;local g | |
g=function(N8,Gzk)if N8 ==Gzk then return 0 else return'not implemented'end end;local _l | |
_l=function(J7nsK)local dXbd | |
dXbd=function(vQj,sVBxyy) | |
if vQj==nil or sVBxyy==nil then return 0 else return J7nsK(vQj,sVBxyy)end end;return dXbd end | |
if gRm then | |
return{UlFdiZ7v,_l(UlFdiZ7v),_l(UlFdiZ7v),_l(LPX0),_l(g)}else return{UlFdiZ7v,UlFdiZ7v,UlFdiZ7v,LPX0,g}end end,__compare=function(N9d,S7) | |
local bJtvRSR=N9d:_comparsionFunctions( | |
N9d.partial or S7.partial) | |
local aBhZK5={{bJtvRSR[1],N9d.major,S7.major},{bJtvRSR[2],N9d.minor,S7.minor},{bJtvRSR[3],N9d.patch,S7.patch},{bJtvRSR[4],N9d.prerelease,S7.prerelease},{bJtvRSR[5],N9d.build,S7.build}} | |
for Jz8JUscj=1,#aBhZK5 do local OtGmbAgE=aBhZK5[Jz8JUscj]local oU_r,n_lv,UYQF=mCsewfX(OtGmbAgE) | |
local WXx=oU_r(n_lv,UYQF)if WXx~=0 then return WXx end end;return 0 end,__compareHelper=function(W4EuxJXi,BlYNd61h,XDPndG,sJYFQIP4) | |
local Ogq0S2=W4EuxJXi:__compare(BlYNd61h)if Ogq0S2 =='not implemented'then return sJYFQIP4 end;return | |
XDPndG(Ogq0S2)end,__eq=function(n8Cw3SR,GJqd7gt) | |
local slE5aDm2;slE5aDm2=function(aL_g)return aL_g==0 end;return | |
n8Cw3SR:__compareHelper(GJqd7gt,slE5aDm2,false)end,__lt=function(IMUI10L,vPA) | |
local pUXZ6G4;pUXZ6G4=function(mk)return mk<0 end;return | |
IMUI10L:__compareHelper(vPA,pUXZ6G4,false)end,__le=function(OeQex1U4,i0cV9) | |
local EGD;EGD=function(VWiGCreH)return VWiGCreH<=0 end;return | |
OeQex1U4:__compareHelper(i0cV9,EGD,false)end}pCi.__index=pCi | |
N4aMD_P=setmetatable({__init=function(B_kkL,uEO6Y,i_053JPY)if i_053JPY==nil then i_053JPY=false end | |
local l,UK,NzaICo,k1X83nYm,xxzxfj=mCsewfX(B_kkL:parse(uEO6Y,i_053JPY)) | |
B_kkL.major,B_kkL.minor,B_kkL.patch,B_kkL.prerelease,B_kkL.build,B_kkL.partial=l,UK,NzaICo,k1X83nYm,xxzxfj,i_053JPY end,__base=pCi,__name="Version"},{__index=pCi,__call=function(_ad1m4I,...) | |
local H1QsS=setmetatable({},pCi)_ad1m4I.__init(H1QsS,...)return H1QsS end})pCi.__class=N4aMD_P;local NzeoQJ=N4aMD_P | |
NzeoQJ.versionRe=function(NzeoQJ,rIMx) | |
local TiA,Y51P,ichL,NOK=rIMx:match('^(%d+)%.(%d+)%.(%d+)(.*)$')if not(TiA)then return nil end | |
local Alv,YeLO2=NOK:match('^%-([0-9a-zA-z.-]+)(.*)$')if Alv then NOK=YeLO2 end;local CkrmO | |
CkrmO,YeLO2=NOK:match('^%+([0-9a-zA-Z.-]+)(.*)$')if CkrmO then NOK=YeLO2 end;if#NOK>0 then return nil end | |
return TiA,Y51P,ichL,Alv,CkrmO end | |
NzeoQJ.partialVersionRe=function(NzeoQJ,ooovsSJe)local s5IsD,KvYEVoXt=ooovsSJe:match('^(%d+)(.*)$')if not | |
(s5IsD)then return nil end | |
local VWWD_P,zsMuNkv=KvYEVoXt:match('^%.(%d+)(.*)$')if VWWD_P then KvYEVoXt=zsMuNkv end;local aXxi | |
aXxi,zsMuNkv=KvYEVoXt:match('^%.(%d+)(.*)$')if aXxi then KvYEVoXt=zsMuNkv end;local Q18a7QTy | |
Q18a7QTy,zsMuNkv=KvYEVoXt:match('^%-([0-9a-zA-Z.-]*)(.*)$')if Q18a7QTy then KvYEVoXt=zsMuNkv end;local K5Rp6 | |
K5Rp6,zsMuNkv=KvYEVoXt:match('^%+([0-9a-zA-Z.-]*)(.*)$')if K5Rp6 then KvYEVoXt=zsMuNkv end;if#KvYEVoXt>0 then return nil end;return s5IsD, | |
VWWD_P,aXxi,Q18a7QTy,K5Rp6 end;JQgI=N4aMD_P end;local N | |
do local GTIA | |
local gdPUe={parse=function(pcN_ceXY,_P)if not _P or type(_P)~='string'or _P==''then | |
error( | |
"Invalid empty requirement specification: "..tostring(tostring(_P)))end;if _P=='*'then return | |
{pcN_ceXY.__class.KIND_ANY,''}end | |
local rq,mo=pcN_ceXY.__class:reSpec(_P)if not rq then | |
error("Invalid requirement specification: "..tostring(_P))end;rq= | |
pcN_ceXY.__class.KIND_ALIASES[rq]or rq;local I=JQgI(mo,true) | |
if I.build~=nil and | |
rq~=pcN_ceXY.__class.KIND_EQUAL and rq~= | |
pcN_ceXY.__class.KIND_NEQ then | |
error( | |
"Invalid requirement specification "..tostring(_P)..": build numbers have no ordering")end;return{rq,I}end,match=function(RAAJAsR,c1pjj7) | |
local BMv=RAAJAsR.kind | |
if RAAJAsR.__class.KIND_ANY==BMv then return true elseif | |
RAAJAsR.__class.KIND_LT==BMv then return c1pjj7 <RAAJAsR.spec elseif RAAJAsR.__class.KIND_LTE==BMv then return | |
c1pjj7 <=RAAJAsR.spec elseif | |
RAAJAsR.__class.KIND_EQUAL==BMv then return c1pjj7 ==RAAJAsR.spec elseif | |
RAAJAsR.__class.KIND_GTE==BMv then return c1pjj7 >=RAAJAsR.spec elseif RAAJAsR.__class.KIND_GT==BMv then return | |
c1pjj7 >RAAJAsR.spec elseif RAAJAsR.__class.KIND_NEQ==BMv then return | |
c1pjj7 ~=RAAJAsR.spec elseif | |
RAAJAsR.__class.KIND_CARET==BMv then return RAAJAsR.spec<=c1pjj7 and | |
c1pjj7 <RAAJAsR.spec:next_major()elseif | |
RAAJAsR.__class.KIND_TILDE==BMv then | |
return RAAJAsR.spec<=c1pjj7 and c1pjj7 < | |
RAAJAsR.spec:next_minor()else return | |
error("Unexpected match kind: "..tostring(RAAJAsR.kind))end end,__tostring=function(NQh8)return | |
tostring(NQh8.kind)..tostring(NQh8.spec)end,__eq=function(P,bkTe) | |
return | |
P.kind==bkTe.kind and P.spec==bkTe.spec end}gdPUe.__index=gdPUe | |
GTIA=setmetatable({__init=function(ohmPbyDd,D) | |
ohmPbyDd.kind,ohmPbyDd.spec=mCsewfX(ohmPbyDd:parse(D))end,__base=gdPUe,__name="SpecItem"},{__index=gdPUe,__call=function(DfDLWkT,...) | |
local MTU8HP4d=setmetatable({},gdPUe)DfDLWkT.__init(MTU8HP4d,...)return MTU8HP4d end})gdPUe.__class=GTIA;local _bxEn=GTIA;_bxEn.KIND_ANY='*'_bxEn.KIND_LT='<' | |
_bxEn.KIND_LTE='<='_bxEn.KIND_EQUAL='=='_bxEn.KIND_SHORTEQ='='_bxEn.KIND_EMPTY='' | |
_bxEn.KIND_GTE='>='_bxEn.KIND_GT='>'_bxEn.KIND_NEQ='!='_bxEn.KIND_CARET='^' | |
_bxEn.KIND_TILDE='~' | |
_bxEn.KIND_ALIASES={[_bxEn.__class.KIND_SHORTEQ]=_bxEn.__class.KIND_EQUAL,[_bxEn.__class.KIND_EMPTY]=_bxEn.__class.KIND_EQUAL} | |
_bxEn.reSpec=function(_bxEn,hIM_cG0i)local jD,me=hIM_cG0i:match('^(.-)(%d.*)$') | |
if not | |
( | |
jD=='<'or | |
jD=='<='or jD==''or jD=='='or jD=='=='or jD=='>='or jD=='>'or jD=='!='or jD=='^'or jD=='~')then return nil else return jD,me end end;N=GTIA end;local fs52REi | |
do local sgU5HAMG | |
local FDydY={parse=function(PEZ_,c)local ElbTbcZG={}local r3=1;for p in c:gmatch('[^,]+')do ElbTbcZG[r3]=N(p) | |
r3=r3+1 end;return ElbTbcZG end,match=function(UiVYRok,jvPsY9) | |
local tEBmuypm=UiVYRok.specs;for hW=1,#tEBmuypm do local iOcgdUx=tEBmuypm[hW]if not iOcgdUx:match(jvPsY9)then | |
return false end end;return | |
true end,filter=function(kCwLIk,_l) | |
local rjQ=0 | |
return function() | |
while true do rjQ=rjQ+1;local Euo0=_l[rjQ]if not(Euo0)then return nil end;if | |
kCwLIk:match(Euo0)then return Euo0 end end end end,select=function(LIV,vydlAbZ3) | |
local BXxv5z;do local mKLU={}local Him=1 | |
for cPDhu in LIV:filter(vydlAbZ3)do mKLU[Him]=cPDhu;Him=Him+1 end;BXxv5z=mKLU end | |
if | |
#BXxv5z>0 then local UQnOS=BXxv5z[1]for tRWU=1,#BXxv5z do local X2Zy_nb=BXxv5z[tRWU] | |
if UQnOS<X2Zy_nb then UQnOS=X2Zy_nb end end;return UQnOS else return nil end end,__index=function(ITtw3N7E,yozOp)if | |
ITtw3N7E:match(yozOp)then return true else return nil end end,__pairs=function(wxU)return | |
pairs(wxU.specs)end,__ipairs=function(kOmS5sy)return ipairs(kOmS5sy.specs)end,__tostring=function(CLSdD) | |
return | |
Gm((function() | |
local Fh={}local IlAPA=1;local jLKMpQuK=CLSdD.specs;for sUQpby=1,#jLKMpQuK do local mbA=jLKMpQuK[sUQpby] | |
Fh[IlAPA]=tostring(mbA)IlAPA=IlAPA+1 end;return Fh end)(),',')end,__eq=function(_qPhpaFx,zex) | |
local pPGcdu=_qPhpaFx.specs | |
for rjp=1,#pPGcdu do local cT2z=pPGcdu[rjp]local zke1tWps=false;local gRFA=zex.specs | |
for jX9a0tJX=1,#gRFA do | |
local YFy4TGc=gRFA[jX9a0tJX]if cT2z==YFy4TGc then zke1tWps=true;break end end;if not zke1tWps then return false end end;return true end}FDydY.__index=FDydY | |
sgU5HAMG=setmetatable({__init=function(YjpbYkCb,L1p7luJ)if type(L1p7luJ)=='string'then | |
L1p7luJ={L1p7luJ}end;local eH | |
do local WpOZ={}local fD2289=1 | |
for folfO=1,#L1p7luJ do | |
local vtsK=L1p7luJ[folfO]WpOZ[fD2289]=YjpbYkCb:parse(vtsK)fD2289=fD2289+1 end;eH=WpOZ end;YjpbYkCb.specs={} | |
for E1p4Mv=1,#eH do local IHap=eH[E1p4Mv]for rDvV=1,#IHap do local RX1L2q=IHap[rDvV] | |
YKA7cU(YjpbYkCb.specs,RX1L2q)end end end,__base=FDydY,__name="Spec"},{__index=FDydY,__call=function(bCBtWguf,...) | |
local q=setmetatable({},FDydY)bCBtWguf.__init(q,...)return q end})FDydY.__class=sgU5HAMG;fs52REi=sgU5HAMG end;local PUNkgaiM | |
PUNkgaiM=function(e1sXUN4f,x)return UlFdiZ7v(JQgI(e1sXUN4f,JQgI(x)))end;local s6FbB | |
s6FbB=function(VP,IQwqq)return fs52REi(VP):match(JQgI(IQwqq))end;local X | |
X=function(Xcc4)return({JQgI:parse(Xcc4)})[1]end | |
return{Spec=fs52REi,SpecItem=N,Version=JQgI,compare=PUNkgaiM,match=s6FbB,validate=X}end)()local s;s=require("component").isAvailable;local YAtG_LV3,LfEJbh_ | |
do | |
local fqw5=require("shell")YAtG_LV3,LfEJbh_=fqw5.parse,fqw5.getWorkingDirectory end;local JD=require("shell")local u,pzDMZwG,XPoQB,XxJ,o5sms | |
do | |
local qnVfOeRE=require("filesystem") | |
u,pzDMZwG,XPoQB,XxJ,o5sms=qnVfOeRE.isDirectory,qnVfOeRE.exists,qnVfOeRE.makeDirectory,qnVfOeRE.concat,qnVfOeRE.copy end;local JQi1jg=require("filesystem")local wVzn,pE | |
do | |
local YIiSKsxK=require("serialization")wVzn,pE=YIiSKsxK.serialize,YIiSKsxK.unserialize end;local RSjapQ;RSjapQ=require("event").pull;local QJf,zC;do | |
local Ua=require("term")QJf,zC=Ua.clearLine,Ua.getCursor end;local pfZ3SPy_ | |
pfZ3SPy_=os.exit;local pDNa2ox6,Do6yo7nm | |
do local qeJtG=io;pDNa2ox6,Do6yo7nm=qeJtG.write,qeJtG.stderr end;local y06X3k,ivnJjrA | |
do local pdpNgBcZ=table;y06X3k,ivnJjrA=pdpNgBcZ.insert,pdpNgBcZ.unpack end;local d3fMjkg=JQi1jg.list;local el,Wu_uIt={},{}local w=nil;local sgeP={}local CM={} | |
local Qlmlet="/etc/hpm/module/"local _="/var/lib/hpm/dist/"local RkGFh6=0;local hw18="/etc/hpm/hpm.cfg" | |
local nvCiFt7r=[[Usage: hpm OPTIONS COMMAND | |
See `man hpm` for more info.]] | |
local xSebv5Jc=[[-- << Global settings >> ------------------------------------------------------- | |
-- A directory where package manifests will be placed. | |
-- It will be created if it doesn't exist. | |
dist = "/var/lib/hpm/dist" | |
-- A place where to search for custom hpm modules. | |
-- It will be created if it doesn't exist. | |
modules = "/etc/hpm/module" | |
-- << Settings related to the hel module >> ------------------------------------ | |
hel = {} | |
-- If set to `false`, hpm will *only* remove a package that hpm is told to | |
-- remove. Otherwise, all of its dependants will be also removed. | |
hel.remove_dependants = true | |
-- << Settings related to the oppm module >> ----------------------------------- | |
oppm = {} | |
-- A directory where package manifests will be stored for faster access. | |
oppm.cache_directory = "/var/cache/hpm/oppm" | |
-- See hel.remove_dependants above. | |
oppm.remove_dependants = true]] | |
local mMp={info=function(...) | |
if el.v then | |
return | |
print(table.concat((function(...)local wV={}local rLd=1;local z8oF={...}for DB6A7N=1,#z8oF do local VhYX=z8oF[DB6A7N] | |
wV[rLd]=tostring(VhYX)rLd=rLd+1 end;return wV end)(...),"\t"))end end,print=function(...) | |
if | |
not(el.q)then | |
return | |
print(table.concat((function(...)local Ha7ErH={}local rjU95v=1;local sxBl={...}for m=1,#sxBl do local nD4LhX6z=sxBl[m] | |
Ha7ErH[rjU95v]=tostring(nD4LhX6z)rjU95v=rjU95v+1 end;return Ha7ErH end)(...),"\t"))end end,error=function(...) | |
if | |
not(el.q)then | |
return | |
Do6yo7nm:write( | |
table.concat((function(...)local iN={}local Lq=1;local s9tW={...} | |
for R61K=1,#s9tW do | |
local Jf4os=s9tW[R61K]iN[Lq]=tostring(Jf4os)Lq=Lq+1 end;return iN end)(...),"\t")..'\n')end end,fatal=function(...) | |
if | |
not(el.q)then | |
Do6yo7nm:write( | |
table.concat((function(...)local a4xc={}local e=1;local la5={...}for i=1,#la5 do local R=la5[i] | |
a4xc[e]=tostring(R)e=e+1 end;return a4xc end)(...),"\t")..'\n')end;return pfZ3SPy_(1)end}local rDtVf | |
rDtVf=function(xWVu,Yw8Yxix)if not(xWVu)then return mMp.fatal(Yw8Yxix)end end;local vj | |
vj=function(i)return | |
mMp.fatal((tostring(i))..": Not implemented yet!")end;local z | |
z=function()pDNa2ox6(nvCiFt7r)return pfZ3SPy_(0)end;local Zg | |
Zg=function(VoXG,JL0I04c)if not(VoXG)then mMp.fatal(JL0I04c)end;return VoXG end;local ykRppH | |
ykRppH=function(En6r_K97,T4AA,VnuCKTdu) | |
if not(type(En6r_K97 ==T4AA))then | |
mMp.fatal("Value '".. | |
tostring(En6r_K97).. | |
"' is "..tostring(type(VnuCKTdu))..", however, a ".. | |
tostring(T4AA).." is expected.")end;return VnuCKTdu end;local WQ6 | |
WQ6=function(XnNgn)return ykRppH(XnNgn,"number",tonumber(XnNgn))end;local y36Aetn | |
y36Aetn=function(H1JD)return ykRppH(H1JD,"string",tostring(H1JD))end;local iPL3B4cr | |
iPL3B4cr=function(gEEa9I,ULLLDUm) | |
for e4F3,GsfNt7 in pairs(ULLLDUm)do if GsfNt7 ==gEEa9I then return true,e4F3 end end;return false end;local GI2hz6SK | |
GI2hz6SK=function(fF0)local YWPfQKb2=0 | |
for r,OS0Zp3i in pairs(fF0)do YWPfQKb2=YWPfQKb2+1 end;return YWPfQKb2 end;local Oh | |
Oh=function(BK) | |
if type(BK)=="nil"then return true elseif type(BK)=="string"then | |
return not BK or#BK<1 elseif type(BK)=="table"then return not BK or GI2hz6SK(BK)<1 else | |
return true end end;local PG | |
PG=function(Idjbe70) | |
for B=1,#Idjbe70 do local nDjt=Idjbe70[B]if not nDjt then return false end end;return true end;local n | |
n=function(NVWt)return pzDMZwG(NVWt)and u(NVWt)end;local O | |
O=function(efuUGMh)return pzDMZwG(efuUGMh)and not u(efuUGMh)end;local N5UjTN | |
N5UjTN=function(p4nNp)return p4nNp==1 and""or"s"end;local qLH5 | |
qLH5=function(VW)return VW~=1 and""or"s"end;local tE | |
tE=function(Zt)return Zt==1 and"is"or"are"end;local VcV0EuD | |
VcV0EuD=function(V)return V:match("^([^:]-):?([^:@]+)@?([^:@]*)$")end;local pX4gCR | |
pX4gCR=function(mzeTI) | |
if | |
JQi1jg.get(JD.resolve(mzeTI)).isReadOnly()then return false,"the path is readonly!"elseif not pzDMZwG(mzeTI)then | |
return false,"the filesystem node doesn't exist."else | |
if | |
not(u(mzeTI)or JQi1jg.isLink(mzeTI))then return JQi1jg.remove(mzeTI)else for sy4J in Zg(d3fMjkg(mzeTI))do | |
pX4gCR(XxJ(mzeTI,sy4J))end;return JQi1jg.remove(mzeTI)end end end;local gad4ZcL | |
gad4ZcL=function()local ztJhP_u8=el.c or el.config or hw18 | |
if | |
not O(ztJhP_u8)then local ys=JQi1jg.path(ztJhP_u8) | |
if not n(ys)then local X,zLtWO09=XPoQB(ys)if not X then | |
return false, | |
"Failed to create '".. | |
tostring(ys).."' directory for the config file: "..tostring(zLtWO09)end end;local rMQ1um8,U2=io.open(ztJhP_u8,"w") | |
if rMQ1um8 then | |
rMQ1um8:write(xSebv5Jc)rMQ1um8:close()else return false, | |
"Failed to open config file for writing: "..tostring(U2)end end;local D,XIcl=io.open(ztJhP_u8,"r") | |
if D then local Z=D:read("*all") | |
D:close()local ZDICnKE={} | |
(load(Z,"config","t",ZDICnKE))()local L | |
L=function(B58)if B58 ==nil then B58={}end | |
return | |
setmetatable(B58,{__index={get=function(PYVzrNl,KTVmRC,Pa) | |
if type(B58[PYVzrNl])~="nil"then | |
if | |
type(B58[PYVzrNl])=="table"then return L(B58[PYVzrNl])end;return B58[PYVzrNl]end | |
mMp.error("Attempt to access undeclared config field '"..tostring(PYVzrNl).."'!")if not Pa then return KTVmRC else return L(KTVmRC)end end}})end;CM=L(ZDICnKE)Qlmlet=CM.get("modules",Qlmlet) | |
_=CM.get("dist",_)return CM else | |
return false,"Failed to open config file for reading: "..tostring(XIcl)end end;local dk | |
dk=function()if not(s("internet"))then | |
mMp.fatal("This command requires an internet card to run!")end;w=w or | |
require("internet").request end;local E;E=function(bmK)dk()return pcall(w,bmK)end;local OO | |
OO=function() | |
if not | |
n(Qlmlet)then local j,vMgKnGj=XPoQB(Qlmlet)if not j then | |
return false,"Failed to create '".. | |
tostring(Qlmlet).. | |
"' directory for custom modules: "..tostring(vMgKnGj)end end;local OJPc3R=Zg(d3fMjkg(Qlmlet)) | |
for M9K in OJPc3R do | |
local Zeu=M9K:match("^(.+)%..+$") | |
local Q2_d=(loadfile(XxJ(Qlmlet,M9K),"t",_ENV))()if Q2_d then sgeP[Zeu]=Q2_d end end;return true end;local y | |
y=function(W0iTcMIt)local N=W0iTcMIt;local Hald6SO | |
do local Dq=W0iTcMIt:find(':')if Dq then | |
N=W0iTcMIt:sub(Dq+1)Hald6SO=W0iTcMIt:sub(1,Dq-1)end end | |
if not Hald6SO then local y3Ur={} | |
for GL70F7uL,Hald6SO in pairs(sgeP)do | |
if Hald6SO[N]then if type(Hald6SO[N])=="table"and | |
Hald6SO[N].__public==true then | |
y06X3k(y3Ur,{class=Hald6SO,module=GL70F7uL,method=Hald6SO[N]})end end end | |
if#y3Ur>1 then local lqANrrJA=nil;for WUFTXBy6,Hald6SO in pairs(y3Ur)do | |
if Hald6SO.module=="hel"then lqANrrJA=WUFTXBy6;break end end;if lqANrrJA then | |
y3Ur={y3Ur[lqANrrJA]}end end | |
if#y3Ur>1 then | |
mMp.print("Ambiguous choice: method ".. | |
tostring(N).." is implemented in the following modules:")for aEZf=1,#y3Ur do local Hald6SO=y3Ur[aEZf] | |
mMp.print(" * "..tostring(Hald6SO.module))end | |
mMp.print( | |
"Choose a specific module by prepending its name with a colon, e.g., ".. | |
tostring(y3Ur[1].module)..":"..tostring(N)..".")return false elseif#y3Ur==0 then | |
mMp.error("Unknown command: "..tostring(N))return false else Hald6SO=y3Ur[1].module | |
mMp.info("Note, using "..tostring(Hald6SO)..":".. | |
tostring(N)..".")return | |
function(...)return y3Ur[1].method(y3Ur[1].class,...)end end else | |
if sgeP[Hald6SO]and Oh(N)then local QjQ_o={} | |
for wDiq_,QYA5WJOY in pairs(sgeP[Hald6SO])do if type(QYA5WJOY)== | |
"table"and QYA5WJOY.__public==true then | |
y06X3k(QjQ_o,tostring(wDiq_))end end | |
mMp.print("Available module-specific commands: "..tostring(table.concat(QjQ_o,", ")))return false end | |
if | |
not sgeP[Hald6SO]or not sgeP[Hald6SO][N]or | |
sgeP[Hald6SO][N]and | |
(type(sgeP[Hald6SO][N])~="table"or | |
sgeP[Hald6SO][N].__public~=true)then | |
mMp.error("Unknown command: "..tostring(Hald6SO)..":"..tostring(N))return false else return function(...) | |
return sgeP[Hald6SO][N](sgeP[Hald6SO],...)end end end end;local cR6rJlAl | |
cR6rJlAl=function(yliV8) | |
if not yliV8 or yliV8 ==""then yliV8="hel"else yliV8=yliV8 end;return sgeP[yliV8]or sgeP.default end;local M6ilzGJ | |
M6ilzGJ=function(rjpKFl,YUGQovw,...)if rjpKFl==nil then rjpKFl=sgeP.default end | |
if | |
rjpKFl[YUGQovw]then return rjpKFl[YUGQovw](rjpKFl,...)else return | |
sgeP.default[YUGQovw](sgeP.default,...)end end;local iW6CD | |
iW6CD=function(XZt7GyF,Zn3SC,D4,crA9EKx)if Zn3SC==nil then Zn3SC="hel"end | |
if D4 ==nil then D4=XxJ(_,Zn3SC)end;if crA9EKx==nil then crA9EKx=XZt7GyF.name end;if not XZt7GyF then | |
return false,"'nil' given"end | |
if not n(D4)then local Wp9xT,P=XPoQB(D4)if not Wp9xT then | |
return false,"Failed to create '".. | |
tostring(XxJ(D4,Zn3SC)).."' directory for manifest files: "..tostring(P)end end;local IcsJ,A=io.open(XxJ(D4,crA9EKx),"w") | |
if IcsJ then | |
IcsJ:write(wVzn(XZt7GyF))IcsJ:close()return true else return false, | |
"Failed to open file for writing: "..tostring(A)end end;local wZdg | |
wZdg=function(o0_XG8FI,jLsxpw,x)if x==nil then x="hel"end | |
jLsxpw=jLsxpw or XxJ(_,x,o0_XG8FI) | |
if O(jLsxpw)then local AXNfV,cX=io.open(jLsxpw,"rb") | |
if AXNfV then | |
local iyx=Zg(pE(AXNfV:read("*all")))AXNfV:close()return iyx else return false, | |
"Failed to open manifest for '"..tostring(o0_XG8FI).."' package: ".. | |
tostring(cX)end else return false, | |
"No manifest found for '"..tostring(o0_XG8FI).."' package"end end;local BaX | |
BaX=function(bxvn,mWYrzB)if mWYrzB==nil then mWYrzB="hel"end | |
local O7kX=XxJ(_,mWYrzB,bxvn) | |
if O(O7kX)then return pX4gCR(O7kX)else return false, | |
"No manifest found for '"..tostring(bxvn).."' package"end end;local SJsW11k | |
SJsW11k=function(Q4XSpdY)return | |
setmetatable({__public=true},{__call=function(fzTyrQ9F,...)return Q4XSpdY(...)end})end;local Ki1HJT | |
Ki1HJT=function(fAumJ0i,i0) | |
return | |
function()local tZliF4,jlmopoj=pcall(fAumJ0i) | |
if not(tZliF4)then return false, | |
"Could not download '".. | |
tostring(i0).."': "..tostring(jlmopoj)else return jlmopoj end end end;local wjim8xCV | |
wjim8xCV=function(R,uS_N6,o5SLRA) | |
if uS_N6 ==nil then uS_N6="Could not download '%s': %s"end;if o5SLRA==nil then o5SLRA="Could not download '%s': %s"end | |
local ztwXaCR,M2WtMgiq,FgfME=E(R)if not(ztwXaCR and M2WtMgiq)then | |
return false,uS_N6:format(R,FgfME)end;local ylH9o=""for CC4Kfjh,FgfME in Ki1HJT(M2WtMgiq)do | |
if CC4Kfjh then | |
ylH9o=ylH9o..CC4Kfjh else return false,o5SLRA:format(R,FgfME)end end;return ylH9o end;local EQLam | |
EQLam=function() | |
if not(el.y)then | |
io.write("Press [ENTER] to continue...")local k=select(3,RSjapQ("key_down"))if k==13 then QJf()return true else | |
io.write("\n")return false end else return true end end;local qTDt | |
qTDt=function(eUQ0x)local r0OR=0;local pYHkv={} | |
if not(Oh(eUQ0x.install))then | |
local hxZHlgP={"Packages to INSTALL:",table.concat(eUQ0x.install," ")}y06X3k(pYHkv,hxZHlgP)r0OR=r0OR+#eUQ0x.install else | |
eUQ0x.install={}end | |
if not(Oh(eUQ0x.reinstall))then | |
local zct={"Packages to REINSTALL:",table.concat(eUQ0x.reinstall," ")}y06X3k(pYHkv,zct)r0OR=r0OR+#eUQ0x.reinstall else | |
eUQ0x.reinstall={}end | |
if not(Oh(eUQ0x.upgrade))then | |
local WQk6Wkd={"Packages to UPGRADE:",table.concat(eUQ0x.upgrade," ")}y06X3k(pYHkv,WQk6Wkd)r0OR=r0OR+#eUQ0x.upgrade else | |
eUQ0x.upgrade={}end | |
if not(Oh(eUQ0x.remove))then | |
local t={"Packages to REMOVE:",table.concat(eUQ0x.remove," ")}y06X3k(pYHkv,t)r0OR=r0OR+#eUQ0x.remove else | |
eUQ0x.remove={}end | |
do | |
local pRCHPl={tostring(#eUQ0x.install).." to INSTALL, ".. | |
tostring(#eUQ0x.reinstall).. | |
" to REINSTALL, ".. | |
tostring(#eUQ0x.upgrade).." to UPGRADE, "..tostring(#eUQ0x.remove).. | |
" to REMOVE."}y06X3k(pYHkv,pRCHPl)end | |
for sCffg4HK,EyljhkFp in pairs(pYHkv)do for sCffg4HK,uGDn542 in pairs(EyljhkFp)do | |
if sCffg4HK==1 then mMp.print(uGDn542)else mMp.print(" ".. | |
tostring(uGDn542))end end;if | |
sCffg4HK~=#pYHkv then mMp.print("")end end | |
if r0OR>1 then if not(EQLam())then return pfZ3SPy_(7)end end end | |
do local DQ;local s6Ahlni_={}s6Ahlni_.__index=s6Ahlni_ | |
DQ=setmetatable({__init=function()end,__base=s6Ahlni_,__name="default"},{__index=s6Ahlni_,__call=function(H,...) | |
local YlzZm=setmetatable({},s6Ahlni_)H.__init(YlzZm,...)return YlzZm end})s6Ahlni_.__class=DQ;local T6dNu=DQ | |
T6dNu.install=function()return | |
mMp.fatal("Incorrect source is provided! No default 'install' implementation.")end | |
T6dNu.remove=function(T6dNu,vj9879b5,cotcYZ1f)if cotcYZ1f==nil then cotcYZ1f="hel"end | |
if vj9879b5 then | |
if vj9879b5.files then | |
for FRcmT,zfl in | |
pairs(vj9879b5.files)do local itxD=XxJ(zfl.dir,zfl.name)local JPHs7A,yzYgnMtr=pX4gCR(itxD) | |
if | |
not(JPHs7A)then return false,"Failed to remove '".. | |
tostring(itxD).."': "..tostring(yzYgnMtr)end end end;return BaX(vj9879b5.name,cotcYZ1f)else | |
return false,"Package can't be removed: the manifest is empty."end end | |
T6dNu.save=function()return | |
mMp.fatal("Incorrect source is provided! No default 'save' implementation.")end;sgeP.default=DQ end | |
do local o;local wmkJ=sgeP.default;local I1={}I1.__index=I1 | |
setmetatable(I1,wmkJ.__base) | |
o=setmetatable({__init=function(R60Ru4bj,...)return o.__parent.__init(R60Ru4bj,...)end,__base=I1,__name="hel",__parent=wmkJ},{__index=function(eQWRf,WT2AX) | |
local _AvO=rawget(I1,WT2AX)if _AvO==nil then local qEO=rawget(eQWRf,"__parent") | |
if qEO then return qEO[WT2AX]end else return _AvO end end,__call=function(q,...) | |
local WUY7=setmetatable({},I1)q.__init(WUY7,...)return WUY7 end})I1.__class=o;local gXu5hG=o;gXu5hG.URL="https://hel-roottree.rhcloud.com/" | |
gXu5hG.parsePackageJSON=function(gXu5hG,_puepou,DYLeJ)if | |
DYLeJ==nil then DYLeJ=JtAjijkG.Spec("*")end;local udbF=nil | |
local dt1={} | |
for UjlBMb,PKWIJ9 in pairs(_puepou.versions)do local rQYWEt=JtAjijkG.Version(UjlBMb)if not | |
(rQYWEt)then | |
mMp.fatal("Could not parse the version in package: "..tostring(rQYWEt))end;dt1[rQYWEt]=PKWIJ9 end | |
local V7eMEiVW,Co1tUVas=pcall(function()return | |
DYLeJ:select((function()local nCwsa={}local IPPy=1 | |
for zYGA2q2,I9Mw in pairs(dt1)do nCwsa[IPPy]=zYGA2q2;IPPy=IPPy+1 end;return nCwsa end)())end)if not(V7eMEiVW)then | |
mMp.fatal("Could not select the best version: "..tostring(Co1tUVas))end | |
udbF=tostring(Co1tUVas)if not(Co1tUVas)then | |
mMp.fatal("No candidate for version specification '"..tostring(DYLeJ).."' found!")end | |
local B={name=_puepou.name,version=udbF,files={},dependencies={}}for e,BUtIET in pairs(dt1[Co1tUVas].files)do local NvAj=BUtIET.dir;local Icg=BUtIET.name | |
y06X3k(B.files,{url=e,dir=NvAj,name=Icg})end;for PzMsk,axLuO in | |
pairs(dt1[Co1tUVas].depends)do local j=axLuO.version;local As=axLuO.type | |
y06X3k(B.dependencies,{name=PzMsk,version=j,type=As})end | |
return B end | |
gXu5hG.getPackageSpec=function(gXu5hG,JmCzKm) | |
mMp.info("Downloading package data for "..tostring(JmCzKm).." ...") | |
local Mwhc,A6z=E(gXu5hG.URL.."packages/"..JmCzKm)if not(Mwhc)then | |
mMp.fatal("HTTP request error: "..A6z)end;local _Mk=""for L9 in A6z do _Mk=_Mk..L9 end | |
local PXrrrSid=UlikV:decode(_Mk)if not(PXrrrSid)then | |
mMp.fatal("Incorrect JSON format!\n"..tostring(_Mk))end;return PXrrrSid.data end | |
gXu5hG.rawInstall=function(gXu5hG,_KZPScl,dbTwy,R4f819q)if dbTwy==nil then dbTwy=false end | |
if R4f819q==nil then R4f819q=false end;local Kj1I | |
if R4f819q then Kj1I=XxJ(LfEJbh_(),_KZPScl.name)else Kj1I="/"end | |
if R4f819q and not n(Kj1I)then local nTUMgqomA,Id5sIM=XPoQB(Kj1I) | |
if not(nTUMgqomA)then | |
mMp.fatal( | |
"Failed creating '".. | |
tostring(Kj1I).."' directory for package '"..tostring(_KZPScl.name).. | |
"'! \n"..tostring(Id5sIM))end elseif not R4f819q then local gZM2ANLt=wZdg(_KZPScl.name,nil,"hel") | |
if gZM2ANLt then | |
if | |
gZM2ANLt.version==tostring(_KZPScl.version)then | |
mMp.print("'".. | |
tostring(_KZPScl.name).."@".. | |
tostring(gZM2ANLt.version).."' is already installed, skipping...")return gZM2ANLt else | |
mMp.fatal("'".. | |
tostring(_KZPScl.name).. | |
"@".. | |
tostring(_KZPScl.version).. | |
"' was attempted to install, however, another version of the same package is already installed: '"..tostring(_KZPScl.name).. | |
"@"..tostring(gZM2ANLt.version).."'")end end end | |
for aC72qEnu,B60J in pairs(_KZPScl.files)do | |
mMp.info("Fetching '"..tostring(B60J.name).."' ...")local Y4=Zg(wjim8xCV(B60J.url)) | |
local f=XxJ(Kj1I,B60J.dir) | |
if not n(f)then local yeCnvcd6,Iq93c6cA=XPoQB(f)if not(yeCnvcd6)then | |
mMp.fatal("Failed to create '".. | |
tostring(f).. | |
"' directory for '".. | |
tostring(B60J.name).."'! \n"..tostring(Iq93c6cA))end end | |
do local nsM0h;B60J,nsM0h=io.open(XxJ(f,B60J.name),"w")if | |
not(B60J)then | |
mMp.fatal("Could not open '"..tostring(XxJ(f,B60J.name)).. | |
"' for writing: "..tostring(nsM0h))end | |
B60J:write(Y4)B60J:close()end end;return | |
{name=_KZPScl.name,version=tostring(_KZPScl.version),files=_KZPScl.files,dependencies=_KZPScl.dependencies,manual=dbTwy}end | |
gXu5hG.resolveDependencies=function(gXu5hG,Czi,IlxN,EA_3x01A,m54tY2)if IlxN==nil then IlxN={}end | |
if EA_3x01A==nil then EA_3x01A={}end;if m54tY2 ==nil then m54tY2={}end | |
for WJWMdKI=1,#Czi do local AhbP=Czi[WJWMdKI]local QHFgYUN,RoEsr7So | |
QHFgYUN,RoEsr7So=AhbP.name,AhbP.version;local dX=false;for Rz=1,#IlxN do local j177r=IlxN[Rz] | |
if j177r.pkg.name==QHFgYUN then dX=true;break end end | |
if not(dX)then | |
y06X3k(EA_3x01A,{name=QHFgYUN,version=""})local j=wZdg(QHFgYUN,nil,"hel") | |
if not j or not | |
RoEsr7So:match(JtAjijkG.Version(j.version))then | |
local qCaFw=gXu5hG:getPackageSpec(QHFgYUN)local syvPi=gXu5hG:parsePackageJSON(qCaFw,RoEsr7So) | |
EA_3x01A[#EA_3x01A].version=syvPi.version;local NrgSK2=syvPi.dependencies | |
for wIH=1,#NrgSK2 do local TYWkpc=NrgSK2[wIH]dX=false | |
for k=1,#IlxN do | |
local J=IlxN[k]if J.pkg.name==TYWkpc.name then dX=true;break end end | |
if not dX then local gtlO9=nil;for Lun,beUJXhjw in pairs(EA_3x01A)do | |
if beUJXhjw.name==TYWkpc.name then gtlO9=Lun;break end end | |
if gtlO9 then | |
if | |
EA_3x01A[gtlO9].version==TYWkpc.version then | |
mMp.fatal("Circular dependencies detected: '".. | |
tostring(QHFgYUN).. | |
"@".. | |
tostring(syvPi.version).. | |
"' depends on '".. | |
tostring(TYWkpc.name).. | |
"@".. | |
tostring(TYWkpc.version).. | |
"', and '".. | |
tostring(EA_3x01A[gtlO9].name).. | |
"@"..tostring(EA_3x01A[gtlO9].version).. | |
"' depends on '"..tostring(QHFgYUN).."@".. | |
tostring(syvPi.version).."'.")else | |
mMp.fatal("Attempted to install two versions of the same package: '".. | |
tostring(TYWkpc.name).. | |
"@".. | |
tostring(TYWkpc.version).. | |
"' and '".. | |
tostring(EA_3x01A[gtlO9].name).. | |
"@".. | |
tostring(EA_3x01A[gtlO9].version).. | |
"' when resolving dependencies for '"..tostring(QHFgYUN).."@".. | |
tostring(syvPi.version).."'.")end end | |
gXu5hG:resolveDependencies({{name=TYWkpc.name,version=JtAjijkG.Spec(TYWkpc.version)}},IlxN,EA_3x01A,m54tY2)end end;y06X3k(IlxN,{pkg=syvPi}) | |
y06X3k(m54tY2,{pkg=syvPi})else y06X3k(IlxN,{pkg=j})end;EA_3x01A[#EA_3x01A]=nil end end;return m54tY2 end | |
gXu5hG.getPackageDependants=function(gXu5hG,zY7adu,Nlvw,K55)if Nlvw==nil then Nlvw={}end;if K55 ==nil then K55={}end | |
for BJcMTdMi=1,#zY7adu | |
do local f1MKKJ=zY7adu[BJcMTdMi]local nFf=false | |
for EIqL41=1,#Nlvw do local iv=Nlvw[EIqL41]if | |
iv.name==f1MKKJ then nFf=true;break end end | |
if not(nFf)then y06X3k(K55,{name=f1MKKJ}) | |
local rfmMR4=wZdg(f1MKKJ,nil,"hel") | |
if rfmMR4 then y06X3k(Nlvw,{name=f1MKKJ,manifest=rfmMR4}) | |
local Tq2I=Zg(d3fMjkg(XxJ(_,"hel"))) | |
for GNo in Tq2I do rfmMR4=Zg(wZdg(GNo,nil,"hel")) | |
local e5x=rfmMR4.dependencies | |
for QrONvWGq=1,#e5x do local D94fnZaa=e5x[QrONvWGq] | |
if D94fnZaa.name==f1MKKJ then nFf=false | |
for XI=1,#Nlvw do | |
local FNi=Nlvw[XI]if FNi.name==GNo then nFf=true;break end end | |
if not nFf then | |
for pRW2nEmK=1,#K55 do local OR=K55[pRW2nEmK]if OR.name==GNo then | |
mMp.fatal("Circular dependencies detected: ".. | |
tostring(GNo))end end;gXu5hG:getPackageDependants({GNo},Nlvw,K55)end end end end else | |
mMp.fatal("Package ".. | |
tostring(f1MKKJ).." is referenced as a dependant of another package, however, this package isn't installed.")end;K55[#K55]=nil end end;return Nlvw end | |
gXu5hG.install=SJsW11k(function(gXu5hG,...) | |
if el.l or el["local"]then local f5=JD.resolve(...) | |
local UAc=Zg(wZdg(f5,XxJ(f5,"manifest")))local Ef=gXu5hG:resolveDependencies(UAc.depends,nil)local P=el.d or | |
el.onlyDeps;local F4AWvI={}for GYVN=1,#Ef do local DNlB1V=Ef[GYVN] | |
y06X3k(F4AWvI, | |
tostring(DNlB1V.pkg.name).."@"..tostring(DNlB1V.pkg.version))end;if not(P)then | |
y06X3k(F4AWvI, | |
tostring(UAc.name).."@"..tostring(UAc.version))end;qTDt({install=F4AWvI}) | |
for erb6G_E=1,# | |
Ef,1 do local QFUU10K=Ef[erb6G_E] | |
mMp.print("Installing '".. | |
tostring(QFUU10K.pkg.name).."@".. | |
tostring(QFUU10K.pkg.version).."'...")UAc=gXu5hG:rawInstall(QFUU10K.pkg,false,false) | |
local xNPDtul,k8=iW6CD(UAc,"hel") | |
if xNPDtul then | |
mMp.info("Saved the manifest of '"..tostring(UAc.name).."'.")else | |
mMp.fatal("Couldn't save the manifest of '"..tostring(UAc.name).. | |
"': "..tostring(k8)..".")end end | |
if not P then | |
mMp.print("Installing '"..tostring(UAc.name).. | |
"@"..tostring(UAc.version).."'...") | |
for fghe,vFXf in pairs(UAc.files)do if not n(XxJ(vFXf.dir,vFXf.name))then | |
XPoQB(vFXf.dir)end | |
local CA0uX7n,ze5Vpc3=o5sms(XxJ(f5,vFXf.url),XxJ(vFXf.dir,vFXf.name))if not(CA0uX7n)then | |
mMp.fatal("Cannot copy file '"..tostring(vFXf.name).. | |
"': "..tostring(ze5Vpc3))end end;local HmgRk,UuCdpVi=iW6CD(UAc,"hel") | |
if HmgRk then | |
mMp.info("Saved the manifest of '".. | |
tostring(UAc.name).."'.")else | |
mMp.fatal("Couldn't save the manifest of '"..tostring(UAc.name).. | |
"': "..tostring(UuCdpVi)..".")end end end;local Arww={}local BYH={...} | |
for vwK8=1,#BYH do local Sk_SiC=BYH[vwK8] | |
local X0bgPvA,M9CyqH=Sk_SiC:match("^(.+)@(.+)$"or Sk_SiC)if Oh(M9CyqH)then M9CyqH="*"end | |
mMp.info("Creating version specification for "..tostring(M9CyqH).. | |
" ...") | |
local z0x4qSAN,X0GTupeV=pcall(function()return JtAjijkG.Spec(M9CyqH)end)if not(z0x4qSAN)then | |
mMp.fatal("Could not parse the version specification: "..tostring(X0GTupeV).."!")end | |
y06X3k(Arww,{name=X0bgPvA,version=X0GTupeV})end;local o7E8TLH=el.r or el.reinstall;local N5N27Jd=el.s or el.save | |
local m=gXu5hG:resolveDependencies(Arww)local nK={}local _zr={} | |
for rQ=1,#m do local k=false | |
repeat local Oc=m[rQ] | |
if o7E8TLH then local IHovU=false | |
for e_wDQjk=1,#Arww do | |
local ClglY=Arww[e_wDQjk]if ClglY.name==Oc.pkg.name then IHovU=true;break end end;if IHovU then | |
y06X3k(nK,tostring(Oc.pkg.name).."@"..tostring(Oc.pkg.version))k=true;break end end | |
y06X3k(_zr,tostring(Oc.pkg.name).."@"..tostring(Oc.pkg.version))k=true until true;if not k then break end end;qTDt({install=_zr,reinstall=nK}) | |
if o7E8TLH then local S | |
do local NKetZhs={}local EFLZ0N1=1;for gL=1,# | |
Arww do local m4=Arww[gL] | |
NKetZhs[EFLZ0N1]=Zg(wZdg(m4.name,nil,"hel"))EFLZ0N1=EFLZ0N1+1 end | |
S=NKetZhs end;gXu5hG:_remove(S,true,false)end | |
for rNOL8G=1,#m do local q=m[rNOL8G] | |
mMp.print("Installing '"..tostring(q.pkg.name).."@".. | |
tostring(q.pkg.version).."'...") | |
local lKO=gXu5hG:rawInstall(q.pkg,iPL3B4cr(q.pkg.name,Arww),N5N27Jd)local hcwgu,omgCdqp8=iW6CD(lKO,"hel") | |
if hcwgu then | |
mMp.info("Saved the manifest of '".. | |
tostring(lKO.name).."'.")else | |
mMp.fatal("Couldn't save the manifest of '"..tostring(lKO.name).. | |
"': "..tostring(omgCdqp8)..".")end end end) | |
gXu5hG.remove=SJsW11k(function(gXu5hG,...)local X17eHTx={...}local SGF={} | |
for myIHU=1,#X17eHTx do local xxNCdF=X17eHTx[myIHU] | |
local _cl1b=Zg(wZdg(xxNCdF,nil,"hel"))y06X3k(SGF,_cl1b)end;return gXu5hG:_remove(SGF,false)end) | |
gXu5hG._remove=function(gXu5hG,Xz18nk,P,sTX4)if P==nil then P=false end;if sTX4 ==nil then sTX4=true end;local A0TJx | |
if not | |
CM.get("hel",{},true).get("remove_dependants",true)or not sTX4 then | |
do local Nqdkw={} | |
local t=1;for QbMO=1,#Xz18nk do local wYZ=Xz18nk[QbMO] | |
Nqdkw[t]={name=wYZ.name,manifest=wYZ}t=t+1 end;A0TJx=Nqdkw end else | |
A0TJx=gXu5hG:getPackageDependants((function()local aMd={}local o0pf=1;for tx1LD=1,#Xz18nk do local N3ROeR=Xz18nk[tx1LD] | |
aMd[o0pf]=N3ROeR.name;o0pf=o0pf+1 end;return aMd end)())end | |
if not(P)then | |
qTDt({remove=(function()local I1oQVnUd={}local oTX=1 | |
for WZlF4=1,#A0TJx do local IxqPDOWH=A0TJx[WZlF4] | |
I1oQVnUd[oTX]="hel:".. | |
tostring(IxqPDOWH.manifest.name).."@"..tostring(IxqPDOWH.manifest.version)oTX=oTX+1 end;return I1oQVnUd end)()})end | |
for GZqV=1,#A0TJx do local OVubrDw_=A0TJx[GZqV] | |
mMp.print("Removing '".. | |
tostring(OVubrDw_.manifest.name).. | |
"@"..tostring(OVubrDw_.manifest.version).."' ...") | |
Zg(o.__parent.remove(gXu5hG,OVubrDw_.manifest,"hel"))end;return true end | |
gXu5hG.upgrade=SJsW11k(function(gXu5hG)local G2_TeR8={} | |
for QnNOl in Zg(d3fMjkg(XxJ(_,"hel")))do if not | |
(u(XxJ(_,"hel",QnNOl)))then | |
y06X3k(G2_TeR8,Zg(wZdg(QnNOl,nil,"hel")))end end;local yk={} | |
for aQs=1,#G2_TeR8 do local uow_0tb=G2_TeR8[aQs] | |
local tykg=gXu5hG:getPackageSpec(uow_0tb.name)local C_pPyW=gXu5hG:parsePackageJSON(tykg) | |
uow_0tb.latest={spec=tykg,data=C_pPyW} | |
if JtAjijkG.Version(uow_0tb.latest.data.version)> | |
JtAjijkG.Version(uow_0tb.version)then y06X3k(yk,uow_0tb)end end | |
gXu5hG:resolveDependencies((function()local mgb4b={}local LOBqxO=1 | |
for m8=1,#yk do local mcoAHO=yk[m8] | |
mgb4b[LOBqxO]={name=mcoAHO.name,version=JtAjijkG.Spec(mcoAHO.latest.data.version)}LOBqxO=LOBqxO+1 end;return mgb4b end)())local OPSPMfr_ | |
do local d3gFWO={}local D=1 | |
for obodPKnu=1,#yk do local kgdzk=yk[obodPKnu] | |
d3gFWO[D]= | |
tostring(kgdzk.name).."@{".. | |
tostring(kgdzk.version).." => ".. | |
tostring(kgdzk.latest.data.version).."}"D=D+1 end;OPSPMfr_=d3gFWO end;qTDt({upgrade=OPSPMfr_}) | |
for oVSp=1,#yk do local uBJ=yk[oVSp] | |
gXu5hG:_remove({uBJ},true,false) | |
mMp.print("Installing '".. | |
tostring(uBJ.name).."@".. | |
tostring(uBJ.latest.data.version).."'...") | |
local A=gXu5hG:rawInstall(uBJ.latest.data,uBJ.manual,false)local MP,jb=iW6CD(A,"hel") | |
if MP then | |
mMp.info("Saved the manifest of '"..tostring(A.name).."'.")else | |
mMp.fatal("Couldn't save the manifest of '".. | |
tostring(A.name).."': "..tostring(jb)..".")end end end) | |
gXu5hG.info=SJsW11k(function(gXu5hG,uKSj,YXgXQB)if YXgXQB==nil then YXgXQB="*"end;if Oh(uKSj)then | |
mMp.fatal("Usage: hpm hel:info <package name> [<version specification>]")end | |
if Oh(YXgXQB)then YXgXQB="*"end | |
mMp.print("Creating version specification for "..tostring(YXgXQB).." ...") | |
local bvL1X4,PPNahh=pcall(function()return JtAjijkG.Spec(YXgXQB)end)if not(bvL1X4)then | |
mMp.fatal("Could not parse the version specification: "..tostring(PPNahh).."!")end | |
local z2g=gXu5hG:getPackageSpec(uKSj)local m9JTkVv6=gXu5hG:parsePackageJSON(z2g,PPNahh)local Q={} | |
y06X3k(Q, | |
"- Package name: "..tostring(z2g.name)) | |
y06X3k(Q,"- Description:\n"..tostring(z2g.description)) | |
y06X3k(Q,"- Package owners: "..tostring(table.concat(z2g.owners,", "))) | |
y06X3k(Q,"- Authors:\n".. | |
tostring(table.concat((function()local bWkP={}local JtFj=1;local PQ3=z2g.authors | |
for _xCtN=1,#PQ3 do | |
local JVpe=PQ3[_xCtN]bWkP[JtFj]=" - "..tostring(JVpe)JtFj=JtFj+1 end;return bWkP end)(),"\n"))) | |
y06X3k(Q,"- License: "..tostring(z2g.license)) | |
y06X3k(Q,"- Versions: "..tostring(GI2hz6SK(z2g.versions))..", latest: ".. | |
tostring(m9JTkVv6.version)) | |
y06X3k(Q," - Files: "..tostring(#m9JTkVv6.files)) | |
y06X3k(Q," - Depends: ".. | |
tostring(table.concat((function()local nG36XmZC={}local Vf26=1;local xUGt=m9JTkVv6.dependencies;for _U=1,#xUGt | |
do local hkI39=xUGt[_U]nG36XmZC[Vf26]=tostring(hkI39.name).."@".. | |
tostring(hkI39.version)Vf26= | |
Vf26+1 end | |
return nG36XmZC end)()))) | |
y06X3k(Q," - Changes:\n".. | |
tostring(z2g.versions[m9JTkVv6.version].changes))y06X3k(Q,"- Stats:") | |
y06X3k(Q," - Views: "..tostring(z2g.stats.views)) | |
y06X3k(Q,"- Creation date: ".. | |
tostring(z2g.stats.date.created).." UTC") | |
y06X3k(Q,"- Last updated: "..tostring(z2g.stats.date["last-updated"]).. | |
" UTC")return mMp.print(table.concat(Q,"\n"))end)if wmkJ.__inherited then wmkJ.__inherited(wmkJ,o)end | |
sgeP.hel=o end | |
do local MwwN;local oZ9=sgeP.default;local OXlT0={}OXlT0.__index=OXlT0 | |
setmetatable(OXlT0,oZ9.__base) | |
MwwN=setmetatable({__init=function(zIYNIXy1,...)return MwwN.__parent.__init(zIYNIXy1,...)end,__base=OXlT0,__name="oppm",__parent=oZ9},{__index=function(c,mReHt4h) | |
local I7=rawget(OXlT0,mReHt4h)if I7 ==nil then local Upw=rawget(c,"__parent") | |
if Upw then return Upw[mReHt4h]end else return I7 end end,__call=function(nqBfKL,...) | |
local gs3a=setmetatable({},OXlT0)nqBfKL.__init(gs3a,...)return gs3a end})OXlT0.__class=MwwN;local V=MwwN | |
V.REPOS="https://raw.githubusercontent.com/OpenPrograms/openprograms.github.io/master/repos.cfg"V.PACKAGES="https://raw.githubusercontent.com/%s/master/programs.cfg" | |
V.FILES="https://raw.githubusercontent.com/%s/%s"V.DIRECTORY="https://api.github.com/repos/%s/contents/%s?ref=%s" | |
V.DEFAULT_CACHE_DIRECTORY="/var/cache/hpm/oppm" | |
V.cacheDirectory=function(V) | |
local AkKaBC=CM.get("oppm",{},true).get("cache_directory",V.DEFAULT_CACHE_DIRECTORY) | |
if not(n(AkKaBC))then local OmRH8,GY=XPoQB(AkKaBC)if not(OmRH8)then | |
mMp.fatal( | |
"Could not create the cache directory at "..tostring(AkKaBC)..": "..tostring(GY))end end;return AkKaBC end | |
V.listCache=function(V)local oukM79R={}local D_j=V:cacheDirectory() | |
local mZPe4w=Zg(d3fMjkg(D_j)) | |
for OvZ in mZPe4w do | |
if u(XxJ(D_j,OvZ))then | |
local cBOpf=Zg(d3fMjkg(XxJ(D_j,OvZ))) | |
for KZYA5y in cBOpf do | |
if u(XxJ(D_j,OvZ,KZYA5y))then | |
local YoCAN7OU=Zg(d3fMjkg(XxJ(D_j,OvZ,KZYA5y))) | |
for FoP in YoCAN7OU do local jqtWXY=XxJ(D_j,OvZ,KZYA5y,FoP) | |
if not(u(jqtWXY))then local XgRb | |
do | |
local GoP6,cZ_=io.open(jqtWXY,"r")if not GoP6 then | |
return false,"Could not open '".. | |
tostring(jqtWXY).."' for reading: "..tostring(cZ_)end | |
PG=GoP6:read("*all")XgRb=pE(PG)GoP6:close()end;local G3e=XxJ(OvZ,KZYA5y) | |
y06X3k(oukM79R,{path=jqtWXY,repo=G3e,pkg=FoP,data=XgRb})end end end end end end;return oukM79R end | |
V.fixCache=function(V)local NYc8=V:cacheDirectory()local Dff8=Zg(d3fMjkg(NYc8)) | |
for lEYwsOG9 in Dff8 do | |
local M=true;local Vt95q2G=XxJ(NYc8,lEYwsOG9) | |
if u(Vt95q2G)then | |
local jsPbwU=Zg(d3fMjkg(Vt95q2G)) | |
for Wvs3rd6o in jsPbwU do local UdVlP=true;local N=XxJ(Vt95q2G,Wvs3rd6o) | |
if u(N)then | |
local v9mB_RUi=Zg(d3fMjkg(N)) | |
for hX in v9mB_RUi do local AVU=true;local I=XxJ(N,hX) | |
if not(u(I))then AVU,UdVlP,M=false,false,false end;if AVU then pX4gCR(I)end end end;if UdVlP then pX4gCR(N)end end end;if M then pX4gCR(Vt95q2G)end end;return true end | |
V.resolveDirectory=function(V,_x5O1,eFI8dI3,i) | |
local l6xUetCb=Zg(wjim8xCV(V.DIRECTORY:format(_x5O1,i,eFI8dI3)))l6xUetCb=UlikV:decode(l6xUetCb) | |
if l6xUetCb.message then | |
return false,"Could not fetch ".. | |
tostring(_x5O1)..":".. | |
tostring(eFI8dI3).."/"..tostring(i).. | |
": "..tostring(l6xUetCb.message)end;local lOb_Sv={}local VspvGB9V=1 | |
for LrFLp5=1,#l6xUetCb do local GfB7=l6xUetCb[LrFLp5] | |
if GfB7.type=="file"then | |
lOb_Sv[VspvGB9V]={name=GfB7.name,url=GfB7.download_url,path=GfB7.path}VspvGB9V=VspvGB9V+1 end end;return lOb_Sv end | |
V.updateCache=function(V)local Iz_w1j=V:cacheDirectory()local G=Zg(V:listCache()) | |
local X7YKzX,od0VOF=wjim8xCV(V.REPOS) | |
if not(X7YKzX)then return false,"Could not fetch ".. | |
tostring(V.REPOS)..": "..tostring(od0VOF)end;X7YKzX=pE(X7YKzX)local oO6SbZ={} | |
for kef2zBS,Z in pairs(X7YKzX)do local ze0=false | |
repeat | |
if Z.repo then | |
mMp.info("Fetching '".. | |
tostring(kef2zBS).."' at '"..tostring(Z.repo).."' ...")local ylW3uC0,N_G1 | |
ylW3uC0,N_G1,od0VOF=E(V.PACKAGES:format(Z.repo)) | |
if not(ylW3uC0 and N_G1)then | |
mMp.error("Could not fetch '"..tostring(kef2zBS).. | |
"' at '".. | |
tostring(Z.repo).."': "..tostring(od0VOF))ze0=true;break end;local wkGNE="" | |
for ylW3uC0,BV in function()return pcall(N_G1)end do | |
if not ylW3uC0 then | |
mMp.error("Could not fetch '".. | |
tostring(kef2zBS).. | |
"' at '"..tostring(Z.repo).."': "..tostring(BV))wkGNE=false;break else if not BV then break end;wkGNE=wkGNE..BV end end;if wkGNE==false then ze0=true;break end;if Oh(wkGNE)then | |
mMp.error("Could not fetch '".. | |
tostring(kef2zBS).."' at '"..tostring(Z.repo).."'")ze0=true;break end;local ccK | |
ccK,od0VOF=pE(wkGNE) | |
if not ccK then | |
mMp.error("Manifest '"..tostring(kef2zBS).. | |
"' at '"..tostring(Z.repo).."' is malformed: ".. | |
tostring(od0VOF))ze0=true;break end | |
for HnLY,cm51CH1n in pairs(ccK)do local iWrSgT=false | |
repeat | |
if HnLY:match("[^A-Za-z0-9._-]")then | |
mMp.error( | |
"Package name contains illegal characters: "..tostring(kef2zBS)..":"..tostring(HnLY).."!")iWrSgT=true;break end | |
y06X3k(oO6SbZ,{repo=Z.repo,name=HnLY,data=cm51CH1n})iWrSgT=true until true;if not iWrSgT then break end end end;ze0=true until true;if not ze0 then break end end;local UE_vrsNx={} | |
for C=1,#oO6SbZ do local YK1=oO6SbZ[C]local t96Qtz,HjKNi,Ub9iqg | |
t96Qtz,HjKNi,Ub9iqg=YK1.name,YK1.repo,YK1.data;if iPL3B4cr(XxJ(HjKNi,t96Qtz),UE_vrsNx)then | |
mMp.error("There're multiple packages under the same name: ".. | |
tostring(t96Qtz).."!")end | |
if not | |
(n(XxJ(Iz_w1j,HjKNi)))then local wNbC65Ta | |
wNbC65Ta,od0VOF=XPoQB(XxJ(Iz_w1j,HjKNi)) | |
if not(wNbC65Ta)then return false, | |
"Could not create directory '"..tostring(XxJ(Iz_w1j,HjKNi)).."': ".. | |
tostring(od0VOF)end end;local r_S8HFRo | |
r_S8HFRo,od0VOF=io.open(XxJ(Iz_w1j,HjKNi,t96Qtz),"w") | |
if not(r_S8HFRo)then return false, | |
"Could not open '"..tostring(XxJ(Iz_w1j,HjKNi,t96Qtz)).. | |
"' for writing: "..tostring(od0VOF)end;do | |
r_S8HFRo:write(wVzn({name=t96Qtz,repo=HjKNi,data=Ub9iqg}))r_S8HFRo:close()end;local qIF4RFBv | |
do for xOiPW,Z9j in | |
pairs(G)do | |
if Z9j.repo==HjKNi and Z9j.pkg==t96Qtz then qIF4RFBv=xOiPW;break end end end;if qIF4RFBv then table.remove(G,qIF4RFBv)else | |
y06X3k(UE_vrsNx,XxJ(HjKNi,t96Qtz))end end;mMp.print("Removing old cache files ...")for r=1,#G do local OnJ1=G[r] | |
local KFU0;KFU0=OnJ1.path;pX4gCR(KFU0)end | |
mMp.print("Fixing bad cache nodes ...")V:fixCache() | |
mMp.print("- ".. | |
tostring(#oO6SbZ).." program".. | |
tostring(N5UjTN(#oO6SbZ)).." cached.") | |
mMp.print("- ".. | |
tostring(#UE_vrsNx).." package".. | |
tostring(N5UjTN(#UE_vrsNx)).." "..tostring(tE( | |
#UE_vrsNx)).." new.") | |
mMp.print("- "..tostring(#G).. | |
" package"..tostring(N5UjTN(#G)).." no longer exist".. | |
tostring(qLH5(#G))..".")return true end | |
V.parseLocalPath=function(V,Pvuq,lOpDJ) | |
if lOpDJ:sub(1,2)=="//"then | |
return XxJ(Pvuq,lOpDJ:sub(3))else return XxJ(Pvuq,"usr",lOpDJ)end end | |
V.rawInstall=function(V,YLe,lTH,JL,FpU_E)if lTH==nil then lTH="/"end;if JL==nil then JL=false end;if FpU_E==nil then | |
FpU_E=false end;local JWtwnQ2t=V:listCache() | |
local uEKPPpj_={filesInstalled=0,packagesInstalled=0} | |
if FpU_E and not n(lTH)then local hXgSzEI,AUQ=XPoQB(lTH)if not(hXgSzEI)then | |
mMp.fatal( | |
"Failed to create '"..tostring(lTH).."' directory for package '".. | |
tostring(YLe).."'! \n"..tostring(AUQ))end elseif | |
not FpU_E then local B=wZdg(YLe,nil,"oppm")if B then | |
mMp.print("'".. | |
tostring(YLe).."' is already installed, skipping...")return B,uEKPPpj_ end end;local aYO4NN | |
for J=1,#JWtwnQ2t do local coSiE=JWtwnQ2t[J]local wm,_O,smj,obBu | |
wm,_O,smj,obBu=coSiE.path,coSiE.pkg,coSiE.repo,coSiE.data;if _O==YLe then aYO4NN=coSiE;break end end;if not(aYO4NN)then | |
mMp.fatal("No such package: "..tostring(YLe))end;local CtG9nSQL={}local uZtK5yX=aYO4NN.repo | |
for cbQlG,YZQu1DR4 in | |
pairs(aYO4NN.data.data.files)do local kza={} | |
if cbQlG:sub(1,1)==":"then | |
kza=V:resolveDirectory(uZtK5yX,cbQlG:sub(2,cbQlG:find("/")-1, | |
nil),cbQlG:sub(cbQlG:find("/")+1))else | |
kza={{name=JQi1jg.name(cbQlG),path=cbQlG,url=V.FILES:format(uZtK5yX,cbQlG)}}end;local YLe | |
for CvGDk_2=1,#kza do local EGpun=kza[CvGDk_2]local LNlhK,cnx_1g | |
YLe,LNlhK,cnx_1g=EGpun.name,EGpun.path,EGpun.url;local eV=Zg(wjim8xCV(cnx_1g)) | |
local DGQnw=V:parseLocalPath(lTH,YZQu1DR4)if not(n(DGQnw))then XPoQB(DGQnw)end | |
do | |
local yLgHuF,fpL=io.open(XxJ(DGQnw,YLe),"w")if not yLgHuF then | |
mMp.fatal("Could not open file for writing: "..tostring(fpL))end;yLgHuF:write(eV) | |
yLgHuF:close()end;uEKPPpj_.filesInstalled=uEKPPpj_.filesInstalled+1 | |
y06X3k(CtG9nSQL,{name=YLe,url=cnx_1g,dir=DGQnw})end end;local kr2CYaS={}if aYO4NN.data.data.dependencies then | |
for k6 in | |
pairs(aYO4NN.data.data.dependencies)do y06X3k(kr2CYaS,{name=k6})end end;uEKPPpj_.packagesInstalled= | |
uEKPPpj_.packagesInstalled+1;return | |
{name=YLe,files=CtG9nSQL,dependencies=kr2CYaS,manual=JL},uEKPPpj_ end | |
V.resolveDependencies=function(V,m,rvNhq6v,gC,QO)if rvNhq6v==nil then rvNhq6v={}end;if gC==nil then gC={}end;if | |
QO==nil then QO={}end;local VvzMQHj=V:listCache() | |
for fSYJX=1,#m do local WV=m[fSYJX]local yUho4MXRx=false;for J2=1,# | |
rvNhq6v do local hgrBfz0w=rvNhq6v[J2] | |
if hgrBfz0w==WV then yUho4MXRx=true;break end end | |
if not(yUho4MXRx)then | |
gC[WV]=true;local Gi=wZdg(WV,nil,"oppm") | |
if not Gi then local wpv1 | |
for I9IMuWm=1,#VvzMQHj do local a=VvzMQHj[I9IMuWm] | |
local rZ;rZ=a.pkg;if rZ==WV then wpv1=a;break end end | |
if not(wpv1)then return false,"Unknown package: "..tostring(WV)end | |
if wpv1.data.data.dependencies then | |
for VKTNfzUf in pairs(wpv1.data.data.dependencies)do | |
yUho4MXRx=false;for Oms4=1,#rvNhq6v do local JfA=rvNhq6v[Oms4] | |
if JfA==VKTNfzUf then yUho4MXRx=true;break end end | |
if not(yUho4MXRx)then | |
if | |
gC[VKTNfzUf]then | |
mMp.fatal("Circular dependencies detected: '".. | |
tostring(WV).."' depends on '".. | |
tostring(VKTNfzUf).."', and '".. | |
tostring(VKTNfzUf).."' depends on '"..tostring(WV).."'.")end;V:resolveDependencies({VKTNfzUf},rvNhq6v,gC,QO)end end end;y06X3k(QO,WV)end;y06X3k(rvNhq6v,WV)gC[WV]=nil end end;return QO end | |
V.getPackageDependants=function(V,CPu1,pfyhF,pglFz82w)if pfyhF==nil then pfyhF={}end | |
if pglFz82w==nil then pglFz82w={}end | |
for RkeCL=1,#CPu1 do local LoW_7e=CPu1[RkeCL]local mLgQ=false | |
for ng=1,#pfyhF do local Pp_NboV=pfyhF[ng]if Pp_NboV.name== | |
LoW_7e then mLgQ=true;break end end | |
if not(mLgQ)then y06X3k(pglFz82w,{name=LoW_7e}) | |
local owAp3u2G=wZdg(LoW_7e,nil,"oppm") | |
if owAp3u2G then | |
y06X3k(pfyhF,{name=LoW_7e,manifest=owAp3u2G})local OH0C=Zg(d3fMjkg(XxJ(_,"oppm"))) | |
for kmQkm9cr in OH0C do | |
owAp3u2G=Zg(wZdg(kmQkm9cr,nil,"oppm"))local IE97m=owAp3u2G.dependencies | |
for wey=1,#IE97m do local hThO6=IE97m[wey] | |
if | |
hThO6.name==LoW_7e then mLgQ=false;for zXU=1,#pfyhF do local HmJym2=pfyhF[zXU] | |
if HmJym2.name==kmQkm9cr then mLgQ=true;break end end | |
if not mLgQ then | |
for Jjb7Am5=1,#pglFz82w do | |
local UwqY7A=pglFz82w[Jjb7Am5]if UwqY7A.name==kmQkm9cr then | |
mMp.fatal("Circular dependencies detected: "..tostring(kmQkm9cr))end end | |
V:getPackageDependants({kmQkm9cr},pfyhF,pglFz82w)end end end end else | |
mMp.fatal("Package ".. | |
tostring(LoW_7e).." is referenced as a dependant of another package, however, this package isn't installed.")end;pglFz82w[#pglFz82w]=nil end end;return pfyhF end | |
V.whatDependsOn=function(V,k)local d7gPKcw=Zg(wZdg(k,nil,"oppm"))local naeNp={} | |
local gA=Zg(d3fMjkg(XxJ(_,"oppm"))) | |
for r in gA do d7gPKcw=Zg(wZdg(r,nil,"oppm")) | |
local LWe=d7gPKcw.dependencies;for _3Tq=1,#LWe do local Rq1hByv=LWe[_3Tq] | |
if Rq1hByv.name==k then y06X3k(naeNp,r)end end end;return naeNp end | |
V.install=SJsW11k(function(V,...)local iFk={...}local sEFtmNgB=el.r or el.reinstall | |
local qxiez0Cn=el.s or el.save;local Ck_H=Zg(V:resolveDependencies(iFk)) | |
qTDt({install=(function()local _QFw_It={} | |
local WLqHf=1;for vN=1,#Ck_H do local BIwW6_=Ck_H[vN] | |
if | |
not sEFtmNgB or not iPL3B4cr(BIwW6_,iFk)then _QFw_It[WLqHf]=BIwW6_;WLqHf=WLqHf+1 end end | |
return _QFw_It end)(),reinstall= | |
sEFtmNgB and | |
(function()local Vdfc3={}local CzM7PG=1 | |
for RKf6s5=1,#Ck_H do local tP9E_=Ck_H[RKf6s5]if iPL3B4cr(tP9E_,iFk)then | |
Vdfc3[CzM7PG]=tP9E_;CzM7PG=CzM7PG+1 end end;return Vdfc3 end)()or nil})local Sc={filesInstalled=0,packagesInstalled=0} | |
if sEFtmNgB then local Y1WX | |
do local G06Z2={}local K=1 | |
for tQx9TV=1,#iFk do | |
local FL7g2o=iFk[tQx9TV]G06Z2[K]=Zg(wZdg(FL7g2o,nil,"oppm"))K=K+1 end;Y1WX=G06Z2 end;V:_remove(Y1WX,true,false)end | |
for dkh7Tt9=1,#Ck_H do local XiNd_H=Ck_H[dkh7Tt9] | |
mMp.print("Installing '"..tostring(XiNd_H).."'...")local Q_c4px86;if qxiez0Cn then | |
Q_c4px86="./"..tostring(XiNd_H).."/"else Q_c4px86="/"end | |
local _F6VYt,ITv3PH1i=V:rawInstall(XiNd_H,Q_c4px86,iPL3B4cr(XiNd_H,iFk),qxiez0Cn) | |
Sc.filesInstalled=Sc.filesInstalled+ITv3PH1i.filesInstalled | |
Sc.packagesInstalled=Sc.packagesInstalled+ITv3PH1i.packagesInstalled | |
if Sc.packagesInstalled~=0 then local _5fF,OUQqQp=iW6CD(_F6VYt,"oppm") | |
if _5fF then | |
mMp.info( | |
"Saved the manifest of '"..tostring(_F6VYt.name).."'.")else | |
mMp.fatal("Couldn't save the manifest of '"..tostring(_F6VYt.name).. | |
"': "..tostring(OUQqQp)..".")end end end | |
mMp.print("- ".. | |
tostring(Sc.packagesInstalled).." package".. | |
tostring(N5UjTN(Sc.packagesInstalled)).." installed.")return | |
mMp.print("- ".. | |
tostring(Sc.filesInstalled).." file".. | |
tostring(N5UjTN(Sc.filesInstalled)).." installed.")end) | |
V.remove=SJsW11k(function(V,...)local OyOfzTWn={...}local rx={}for ijvSrZA1=1,#OyOfzTWn do local STNuSN6=OyOfzTWn[ijvSrZA1]local PYOeGnAZ=Zg(wZdg(STNuSN6, | |
nil,"oppm")) | |
y06X3k(rx,PYOeGnAZ)end;return | |
V:_remove(rx,false)end) | |
V._remove=function(V,s10ar5XH,YoKhvIs,I2ipE)if YoKhvIs==nil then YoKhvIs=false end | |
if I2ipE==nil then I2ipE=true end;local qS730I | |
if not | |
CM.get("oppm",{},true).get("remove_dependants",true)or not I2ipE then | |
do | |
local PYEbnua={}local Um4ZYiT=1 | |
for AF=1,#s10ar5XH do local shIHW=s10ar5XH[AF] | |
PYEbnua[Um4ZYiT]={name=shIHW.name,manifest=shIHW}Um4ZYiT=Um4ZYiT+1 end;qS730I=PYEbnua end else | |
qS730I=V:getPackageDependants((function()local H5={}local HYY=1;for C3=1,#s10ar5XH do local SkCMMH=s10ar5XH[C3] | |
H5[HYY]=SkCMMH.name;HYY=HYY+1 end;return H5 end)())end | |
if not(YoKhvIs)then | |
qTDt({remove=(function()local kvvs={}local _yTx3S94=1;for Mm=1,#qS730I do local g524=qS730I[Mm] | |
kvvs[_yTx3S94]=tostring(g524.name)_yTx3S94=_yTx3S94+1 end | |
return kvvs end)()})end | |
for WUdVeYc=1,#qS730I do local lHep6wo=qS730I[WUdVeYc] | |
mMp.print("Removing '".. | |
tostring(lHep6wo.manifest.name).."' ...") | |
Zg(MwwN.__parent.remove(V,lHep6wo.manifest,"oppm"))end;return true end | |
V.cache=SJsW11k(function(V,BKZsJ,...)local Sw=BKZsJ | |
if"update"==Sw then | |
mMp.print("Updating OpenPrograms program cache ...")Zg(V:updateCache())return mMp.print("Done.")elseif"fix"==Sw then | |
mMp.print("Fixing OpenPrograms program cache ...")Zg(V:fixCache())return mMp.print("Done.")else | |
mMp.error("Unknown command.")return mMp.print("Usage: hpm oppm:cache {update|fix}")end end) | |
V.autoremove=SJsW11k(function(V)local W67mm9p6={}local oBxdTi6u={} | |
local T7hLe5j=Zg(d3fMjkg(XxJ(_,"oppm"))) | |
for I_ in T7hLe5j do local J2Jin=Zg(wZdg(I_,nil,"oppm"))if not(J2Jin.manual)then | |
local Rvg=V:getPackageDependants(I_) | |
if#Rvg==1 then y06X3k(W67mm9p6,I_)y06X3k(oBxdTi6u,I_)end end end | |
while true do local HpdA=false;T7hLe5j=Zg(d3fMjkg(XxJ(_,"oppm"))) | |
for DsAJbW in | |
T7hLe5j do | |
if not(iPL3B4cr(DsAJbW,W67mm9p6))then | |
local AXfX=Zg(wZdg(DsAJbW,nil,"oppm")) | |
if not(AXfX.manual)then local btcUUhB=V:getPackageDependants(DsAJbW) | |
table.remove(btcUUhB,1) | |
if | |
PG((function()local iw0S={}local Tjg=1;for n2srE7H=1,#btcUUhB do local Rf=btcUUhB[n2srE7H] | |
iw0S[Tjg]=iPL3B4cr(Rf.name,W67mm9p6)Tjg=Tjg+1 end;return iw0S end)())then | |
for X9ZjrTz=1,#btcUUhB do local tYFIuD=btcUUhB[X9ZjrTz] | |
local Ht5Ge,l=iPL3B4cr(tYFIuD.name,oBxdTi6u)if l then table.remove(oBxdTi6u,l)end end;y06X3k(W67mm9p6,DsAJbW)y06X3k(oBxdTi6u,DsAJbW)HpdA=true end end end end;if not(HpdA)then break end end | |
qTDt({remove=(function() | |
if#W67mm9p6 >0 then local IO={}local YDJY=1 | |
for t=1,#W67mm9p6 do local Rdi8NIft=W67mm9p6[t]IO[YDJY]="oppm:".. | |
tostring(Rdi8NIft)YDJY=YDJY+1 end;return IO else return nil end end)()})for J0uTkQ9=1,#oBxdTi6u do local sd6k=oBxdTi6u[J0uTkQ9] | |
V:_remove({Zg(wZdg(sd6k,nil,"oppm"))},false)end | |
mMp.print("Done.")return true end)if oZ9.__inherited then oZ9.__inherited(oZ9,MwwN)end | |
sgeP.oppm=MwwN end;local v | |
v=function()local a=Zg(d3fMjkg(_))Oh=true | |
for lK7 in a do local KWMxs7a=JQi1jg.name(lK7) | |
if | |
u(XxJ(_,KWMxs7a))then local T=Zg(d3fMjkg(XxJ(_,KWMxs7a))) | |
for LBIp4 in T do | |
if not | |
(u(XxJ(_,KWMxs7a,LBIp4)))then local A5=Zg(wZdg(LBIp4,nil,KWMxs7a)) | |
mMp.print( | |
KWMxs7a..":"..LBIp4 .. | |
(A5.version and" @ "..A5.version or""))Oh=false end end end end | |
if Oh then return mMp.print("No packages installed.")end end;local Ta | |
Ta=function(...)Wu_uIt,el=YAtG_LV3(...)if#Wu_uIt<1 then return z()end end;local unArcvQl | |
unArcvQl=function()local PV168s0f=Wu_uIt[1] | |
if"list"==PV168s0f then return v()elseif"help"==PV168s0f then return z()else | |
do | |
local bjK=y(Wu_uIt[1]) | |
if bjK then | |
return | |
bjK(ivnJjrA((function()local Us1Xh={}local rs59=1;for R=2,#Wu_uIt do local rGa2MaGH=Wu_uIt[R]Us1Xh[rs59]=rGa2MaGH;rs59= | |
rs59+1 end;return Us1Xh end)()))end end end end;Ta(...)Zg(gad4ZcL())OO()unArcvQl()return RkGFh6; |
local s=load([===[ | |
local rA5U=20160728.17 | |
local Uc06="-[ JSON.lua package by Jeffrey Friedl (http://regex.info/blog/lua/json) version 20160728.17 ]-"local lcBL={VERSION=rA5U,AUTHOR_NOTE=Uc06}local DHPxI=" " | |
local dx={pretty=true,align_keys=false,indent=DHPxI} | |
local RRuSHnxf={__tostring=function()return"JSON array"end}RRuSHnxf.__index=RRuSHnxf | |
local mcYOuT={__tostring=function()return"JSON object"end}mcYOuT.__index=mcYOuT;function lcBL:newArray(iXxD6s) | |
return setmetatable(iXxD6s or{},RRuSHnxf)end;function lcBL:newObject(oiY)return | |
setmetatable(oiY or{},mcYOuT)end;local function Rr(FsYIVlkf) | |
return | |
type(FsYIVlkf)=='number'and FsYIVlkf or FsYIVlkf.N end | |
local scRP0={__index=isNumber,__tostring=function(HLXS0Q_)return HLXS0Q_.S end,__unm=function(Kw)return | |
Rr(Kw)end,__concat=function(nvaIsNv7,vDnoL55) | |
return tostring(nvaIsNv7)..tostring(vDnoL55)end,__add=function(xlAK,zr1y)return Rr(xlAK)+Rr(zr1y)end,__sub=function(Hs,jk)return | |
Rr(Hs)-Rr(jk)end,__mul=function(qzSFyIO,Z65) | |
return Rr(qzSFyIO)*Rr(Z65)end,__div=function(umyCNfj,FT)return Rr(umyCNfj)/Rr(FT)end,__mod=function(YVLXYq,bJfct)return | |
Rr(YVLXYq)%Rr(bJfct)end,__pow=function(OhuFpq_N,Dzg)return | |
Rr(OhuFpq_N)^Rr(Dzg)end,__lt=function(_4O,C)return Rr(_4O)<Rr(C)end,__eq=function(fLI2zRe,_Fr2YU)return | |
Rr(fLI2zRe)==Rr(_Fr2YU)end,__le=function(Xfn,U)return | |
Rr(Xfn)<=Rr(U)end} | |
function lcBL:asNumber(Ebsw) | |
if getmetatable(Ebsw)==scRP0 then return Ebsw elseif | |
type(Ebsw)=='table'and | |
type(Ebsw.S)=='string'and type(Ebsw.N)=='number'then return setmetatable(Ebsw,scRP0)else | |
local UlikV={S=tostring(Ebsw),N=tonumber(Ebsw)}return setmetatable(UlikV,scRP0)end end | |
local function AI0R2TQ6(JtAjijkG) | |
if JtAjijkG<=127 then return string.char(JtAjijkG)elseif JtAjijkG<=2047 then | |
local s=math.floor(JtAjijkG/0x40)local YAtG_LV3=JtAjijkG- (0x40*s)return | |
string.char(0xC0+s,0x80+YAtG_LV3)elseif JtAjijkG<=65535 then | |
local LfEJbh_=math.floor(JtAjijkG/0x1000)local JD=JtAjijkG-0x1000*LfEJbh_ | |
local u=math.floor(JD/0x40)local pzDMZwG=JD-0x40*u;LfEJbh_=0xE0+LfEJbh_;u=0x80+u | |
pzDMZwG=0x80+pzDMZwG | |
if | |
(LfEJbh_==0xE0 and u<0xA0)or | |
(LfEJbh_==0xED and u>0x9F)or(LfEJbh_==0xF0 and u<0x90)or(LfEJbh_==0xF4 and u>0x8F)then return"?"else return string.char(LfEJbh_,u,pzDMZwG)end else local XPoQB=math.floor(JtAjijkG/0x40000) | |
local XxJ=JtAjijkG-0x40000*XPoQB;local o5sms=math.floor(XxJ/0x1000) | |
XxJ=XxJ-0x1000*o5sms;local JQi1jg=math.floor(XxJ/0x40)local wVzn=XxJ-0x40*JQi1jg | |
return string.char( | |
0xF0+XPoQB,0x80+o5sms,0x80+JQi1jg,0x80+wVzn)end end | |
function lcBL:onDecodeError(pE,RSjapQ,QJf,zC)if RSjapQ then | |
if QJf then | |
pE=string.format("%s at char %d of: %s",pE,QJf,RSjapQ)else pE=string.format("%s: %s",pE,RSjapQ)end end | |
if zC~=nil then pE=pE.." (".. | |
lcBL:encode(zC)..")"end | |
if self.assert then self.assert(false,pE)else assert(false,pE)end end;lcBL.onDecodeOfNilError=lcBL.onDecodeError | |
lcBL.onDecodeOfHTMLError=lcBL.onDecodeError | |
function lcBL:onEncodeError(pfZ3SPy_,pDNa2ox6) | |
if pDNa2ox6 ~=nil then pfZ3SPy_=pfZ3SPy_.. | |
" ("..lcBL:encode(pDNa2ox6)..")"end;if self.assert then self.assert(false,pfZ3SPy_)else | |
assert(false,pfZ3SPy_)end end | |
local function yA(Do6yo7nm,y06X3k,ivnJjrA,d3fMjkg) | |
local el=y06X3k:match('^-?[1-9]%d*',ivnJjrA)or y06X3k:match("^-?0",ivnJjrA)if not el then | |
Do6yo7nm:onDecodeError("expected number",y06X3k,ivnJjrA,d3fMjkg.etc)end | |
local Wu_uIt=ivnJjrA+el:len()local w=y06X3k:match('^%.%d+',Wu_uIt)or""Wu_uIt=Wu_uIt+ | |
w:len() | |
local sgeP=y06X3k:match('^[eE][-+]?%d+',Wu_uIt)or""Wu_uIt=Wu_uIt+sgeP:len()local CM=el..w..sgeP;if | |
d3fMjkg.decodeNumbersAsObjects then return lcBL:asNumber(CM),Wu_uIt end | |
if | |
( | |
d3fMjkg.decodeIntegerStringificationLength and(el:len()>=d3fMjkg.decodeIntegerStringificationLength or | |
sgeP:len()>0))or | |
(d3fMjkg.decodeDecimalStringificationLength and | |
( | |
w:len()>=d3fMjkg.decodeDecimalStringificationLength or sgeP:len()>0))then return CM,Wu_uIt end;local Qlmlet=tonumber(CM)if not Qlmlet then | |
Do6yo7nm:onDecodeError("bad number",y06X3k,ivnJjrA,d3fMjkg.etc)end;return Qlmlet,Wu_uIt end | |
local function XmVolesU(_,RkGFh6,hw18,nvCiFt7r)if RkGFh6:sub(hw18,hw18)~='"'then | |
_:onDecodeError("expected string's opening quote",RkGFh6,hw18,nvCiFt7r.etc)end;local xSebv5Jc=hw18+1 | |
local mMp=RkGFh6:len()local rDtVf="" | |
while xSebv5Jc<=mMp do local vj=RkGFh6:sub(xSebv5Jc,xSebv5Jc)if | |
vj=='"'then return rDtVf,xSebv5Jc+1 end | |
if vj~='\\'then rDtVf=rDtVf..vj;xSebv5Jc= | |
xSebv5Jc+1 elseif RkGFh6:match('^\\b',xSebv5Jc)then rDtVf=rDtVf.."\b"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\f',xSebv5Jc)then rDtVf=rDtVf.."\f"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\n',xSebv5Jc)then rDtVf=rDtVf.."\n"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\r',xSebv5Jc)then rDtVf=rDtVf.."\r"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\t',xSebv5Jc)then rDtVf=rDtVf.."\t"xSebv5Jc= | |
xSebv5Jc+2 else | |
local z=RkGFh6:match('^\\u([0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])',xSebv5Jc) | |
if z then xSebv5Jc=xSebv5Jc+6;local Zg=tonumber(z,16) | |
if | |
Zg>=0xD800 and Zg<=0xDBFF then | |
local ykRppH=RkGFh6:match('^\\u([dD][cdefCDEF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])',xSebv5Jc) | |
if ykRppH then xSebv5Jc=xSebv5Jc+6;Zg=0x2400+ (Zg-0xD800)*0x400+ | |
tonumber(ykRppH,16)else end end;rDtVf=rDtVf..AI0R2TQ6(Zg)else rDtVf=rDtVf.. | |
RkGFh6:match('^\\(.)',xSebv5Jc)xSebv5Jc=xSebv5Jc+2 end end end | |
_:onDecodeError("unclosed string",RkGFh6,hw18,nvCiFt7r.etc)end | |
local function eZ0l3ch(WQ6,y36Aetn)local iPL3B4cr,GI2hz6SK=WQ6:find("^[ \n\r\t]+",y36Aetn)if GI2hz6SK then | |
return GI2hz6SK+1 else return y36Aetn end end;local W_63_9 | |
local function h9dyA_4T(Oh,PG,n,O)if PG:sub(n,n)~='{'then | |
Oh:onDecodeError("expected '{'",PG,n,O.etc)end;local N5UjTN=eZ0l3ch(PG,n+1)local qLH5=Oh.strictTypes and | |
Oh:newObject{}or{}if | |
PG:sub(N5UjTN,N5UjTN)=='}'then return qLH5,N5UjTN+1 end | |
local tE=PG:len() | |
while N5UjTN<=tE do local VcV0EuD,pX4gCR=XmVolesU(Oh,PG,N5UjTN,O) | |
N5UjTN=eZ0l3ch(PG,pX4gCR)if PG:sub(N5UjTN,N5UjTN)~=':'then | |
Oh:onDecodeError("expected colon",PG,N5UjTN,O.etc)end | |
N5UjTN=eZ0l3ch(PG,N5UjTN+1)local gad4ZcL,pX4gCR=W_63_9(Oh,PG,N5UjTN,O)qLH5[VcV0EuD]=gad4ZcL | |
N5UjTN=eZ0l3ch(PG,pX4gCR)local dk=PG:sub(N5UjTN,N5UjTN) | |
if dk=='}'then return qLH5,N5UjTN+1 end;if PG:sub(N5UjTN,N5UjTN)~=','then | |
Oh:onDecodeError("expected comma or '}'",PG,N5UjTN,O.etc)end | |
N5UjTN=eZ0l3ch(PG,N5UjTN+1)end;Oh:onDecodeError("unclosed '{'",PG,n,O.etc)end | |
local function oh(E,OO,y,cR6rJlAl)if OO:sub(y,y)~='['then | |
E:onDecodeError("expected '['",OO,y,cR6rJlAl.etc)end;local M6ilzGJ=eZ0l3ch(OO,y+1)local iW6CD=E.strictTypes and | |
E:newArray{}or{}if | |
OO:sub(M6ilzGJ,M6ilzGJ)==']'then return iW6CD,M6ilzGJ+1 end | |
local wZdg=1;local BaX=OO:len() | |
while M6ilzGJ<=BaX do | |
local SJsW11k,Ki1HJT=W_63_9(E,OO,M6ilzGJ,cR6rJlAl)iW6CD[wZdg]=SJsW11k;wZdg=wZdg+1;M6ilzGJ=eZ0l3ch(OO,Ki1HJT) | |
local wjim8xCV=OO:sub(M6ilzGJ,M6ilzGJ)if wjim8xCV==']'then return iW6CD,M6ilzGJ+1 end;if | |
OO:sub(M6ilzGJ,M6ilzGJ)~=','then | |
E:onDecodeError("expected comma or '['",OO,M6ilzGJ,cR6rJlAl.etc)end | |
M6ilzGJ=eZ0l3ch(OO,M6ilzGJ+1)end | |
E:onDecodeError("unclosed '['",OO,y,cR6rJlAl.etc)end | |
W_63_9=function(E,QLam,qTDt,v)qTDt=eZ0l3ch(QLam,qTDt) | |
if qTDt>QLam:len()then E:onDecodeError("unexpected end of string",QLam, | |
nil,v.etc)end | |
if QLam:find('^"',qTDt)then return XmVolesU(E,QLam,qTDt,v.etc)elseif | |
QLam:find('^[-0123456789 ]',qTDt)then return yA(E,QLam,qTDt,v)elseif QLam:find('^%{',qTDt)then | |
return h9dyA_4T(E,QLam,qTDt,v)elseif QLam:find('^%[',qTDt)then return oh(E,QLam,qTDt,v)elseif QLam:find('^true',qTDt)then return true, | |
qTDt+4 elseif QLam:find('^false',qTDt)then return false,qTDt+5 elseif | |
QLam:find('^null',qTDt)then return nil,qTDt+4 else | |
E:onDecodeError("can't parse JSON",QLam,qTDt,v.etc)end end | |
function lcBL:decode(Ta,u,nArcvQl)if type(nArcvQl)~='table'then nArcvQl={}end;if u~=nil then | |
nArcvQl.etc=u end;if | |
type(self)~='table'or self.__index~=lcBL then | |
lcBL:onDecodeError("JSON:decode must be called in method format",nil,nil,nArcvQl.etc)end | |
if Ta==nil then | |
self:onDecodeOfNilError(string.format("nil passed to JSON:decode()"), | |
nil,nil,nArcvQl.etc)elseif type(Ta)~='string'then | |
self:onDecodeError(string.format("expected string argument to JSON:decode(), got %s",type(Ta)), | |
nil,nil,nArcvQl.etc)end;if Ta:match('^%s*$')then return nil end;if Ta:match('^%s*<')then | |
self:onDecodeOfHTMLError(string.format("html passed to JSON:decode()"),Ta, | |
nil,nArcvQl.etc)end | |
if | |
Ta:sub(1,1):byte()==0 or | |
(Ta:len()>=2 and Ta:sub(2,2):byte()==0)then | |
self:onDecodeError("JSON package groks only UTF-8, sorry",Ta,nil,nArcvQl.etc)end;if nArcvQl.decodeNumbersAsObjects==nil then | |
nArcvQl.decodeNumbersAsObjects=self.decodeNumbersAsObjects end;if | |
nArcvQl.decodeIntegerStringificationLength==nil then | |
nArcvQl.decodeIntegerStringificationLength=self.decodeIntegerStringificationLength end;if | |
nArcvQl.decodeDecimalStringificationLength==nil then | |
nArcvQl.decodeDecimalStringificationLength=self.decodeDecimalStringificationLength end | |
local h6Ub7U,Gm=pcall(W_63_9,self,Ta,1,nArcvQl)if h6Ub7U then return Gm else | |
if self.assert then self.assert(false,Gm)else assert(false,Gm)end;return nil,Gm end end | |
local function DZXGTh(YKA7cU) | |
if YKA7cU=="\n"then return"\\n"elseif YKA7cU=="\r"then return"\\r"elseif YKA7cU=="\t"then return"\\t"elseif YKA7cU=="\b"then | |
return"\\b"elseif YKA7cU=="\f"then return"\\f"elseif YKA7cU=='"'then return'\\"'elseif YKA7cU=='\\'then return'\\\\'else return | |
string.format("\\u%04x",YKA7cU:byte())end end | |
local Su9Koz='['..'"'.. | |
'%\\'..'%z'..'\001'..'-'..'\031'..']'local Uk7e=AI0R2TQ6(0x2028)local KwQCk_G=AI0R2TQ6(0x2029) | |
local function ptZa(mCsewfX,yY) | |
local Xf=mCsewfX:gsub(Su9Koz,DZXGTh)if yY.stringsAreUtf8 then | |
Xf=Xf:gsub(Uk7e,'\\u2028'):gsub(KwQCk_G,'\\u2029')end;return'"'..Xf..'"'end | |
local function PEqsd(UlFdiZ7v,U,wFeA)local JQgI={}local N={}local fs52REi=false;local PUNkgaiM | |
for X in pairs(U)do | |
if type(X)=='string'then | |
table.insert(JQgI,X)elseif type(X)=='number'then table.insert(N,X) | |
if X<=0 or X>=math.huge then | |
fs52REi=true elseif not PUNkgaiM or X>PUNkgaiM then PUNkgaiM=X end else | |
UlFdiZ7v:onEncodeError("can't encode table with a key of type "..type(X),wFeA)end end | |
if#JQgI==0 and not fs52REi then | |
if#N>0 then return nil,PUNkgaiM elseif | |
tostring(U)=="JSON array"then return nil elseif tostring(U)=="JSON object"then return{}else return nil end end;table.sort(JQgI)local s6FbB | |
if#N>0 then if UlFdiZ7v.noKeyConversion then | |
UlFdiZ7v:onEncodeError("a table with both numeric and string keys could be an object or array; aborting",wFeA)end | |
s6FbB={}for dc61,aguhyl in pairs(U)do s6FbB[dc61]=aguhyl end | |
table.sort(N) | |
for p,gOPDv in ipairs(N)do local aSdZU3=tostring(gOPDv) | |
if s6FbB[aSdZU3]==nil then | |
table.insert(JQgI,aSdZU3)s6FbB[aSdZU3]=U[gOPDv]else | |
UlFdiZ7v:onEncodeError( | |
"conflict converting table with mixed-type keys into a JSON object: key "..gOPDv.." exists both as a string and a number.",wFeA)end end end;return JQgI,nil,s6FbB end;local iSj | |
function iSj(YKDL,oFyb6OLp,oGdh_mv,WjvvK,TASVwBgU,KjUncMB,XkT) | |
if oFyb6OLp==nil or | |
(not XkT and TASVwBgU and TASVwBgU.null and oFyb6OLp== | |
TASVwBgU.null)then return'null'elseif | |
type(oFyb6OLp)=='string'then return ptZa(oFyb6OLp,TASVwBgU)elseif type(oFyb6OLp)=='number'then | |
if | |
oFyb6OLp~=oFyb6OLp then return"null"elseif oFyb6OLp>=math.huge then return"1e+9999"elseif oFyb6OLp<=-math.huge then | |
return"-1e+9999"else return tostring(oFyb6OLp)end elseif type(oFyb6OLp)=='boolean'then return tostring(oFyb6OLp)elseif type(oFyb6OLp)~= | |
'table'then | |
YKDL:onEncodeError("can't convert "..type(oFyb6OLp).." to JSON",WjvvK)elseif getmetatable(oFyb6OLp)==scRP0 then return tostring(oFyb6OLp)else | |
local c3dr=oFyb6OLp;if type(TASVwBgU)~='table'then TASVwBgU={}end;if type(KjUncMB)~= | |
'string'then KjUncMB=""end | |
if oGdh_mv[c3dr]then | |
YKDL:onEncodeError("table ".. | |
tostring(c3dr).." is a child of itself",WjvvK)else oGdh_mv[c3dr]=true end;local NGH;local tIc,MD2O,HQ=PEqsd(YKDL,c3dr,WjvvK) | |
if MD2O then local cng={}for lE=1,MD2O do | |
table.insert(cng,iSj(YKDL,c3dr[lE],oGdh_mv,WjvvK,TASVwBgU,KjUncMB))end | |
if TASVwBgU.pretty then NGH="[ ".. | |
table.concat(cng,", ").." ]"else NGH="[".. | |
table.concat(cng,",").."]"end elseif tIc then local nI2F0id=HQ or c3dr | |
if TASVwBgU.pretty then local N4aMD_P={}local pCi=0 | |
for lNOqUk8,YAnZNei in ipairs(tIc)do | |
local h8YWR44E=iSj(YKDL,tostring(YAnZNei),oGdh_mv,WjvvK,TASVwBgU,KjUncMB,true) | |
if TASVwBgU.align_keys then pCi=math.max(pCi,#h8YWR44E)end;table.insert(N4aMD_P,h8YWR44E)end | |
local NzeoQJ=KjUncMB..tostring(TASVwBgU.indent or"") | |
local AwGfFV=NzeoQJ..string.rep(" ",pCi).. | |
(TASVwBgU.align_keys and" "or"") | |
local wCRY="%s%"..string.format("%d",pCi).."s: %s"local d0uKSVw1={} | |
for VF,fTrMe in ipairs(tIc)do | |
local ypDndT8=iSj(YKDL,nI2F0id[fTrMe],oGdh_mv,WjvvK,TASVwBgU,AwGfFV) | |
table.insert(d0uKSVw1,string.format(wCRY,NzeoQJ,N4aMD_P[VF],ypDndT8))end;NGH="{\n".. | |
table.concat(d0uKSVw1,",\n").."\n"..KjUncMB.."}"else local MV65={} | |
for Y3D66Ym9,q in | |
ipairs(tIc)do | |
local PhJ=iSj(YKDL,nI2F0id[q],oGdh_mv,WjvvK,TASVwBgU,KjUncMB) | |
local h=iSj(YKDL,tostring(q),oGdh_mv,WjvvK,TASVwBgU,KjUncMB,true) | |
table.insert(MV65,string.format("%s:%s",h,PhJ))end;NGH="{"..table.concat(MV65,",").."}"end else NGH="[]"end;oGdh_mv[c3dr]=false;return NGH end end | |
function lcBL:encode(j2K,r8hgwQ,_6U)if type(self)~='table'or self.__index~=lcBL then | |
lcBL:onEncodeError("JSON:encode must be called in method format",r8hgwQ)end;if | |
type(_6U)~='table'then _6U={}end;return iSj(self,j2K,{},r8hgwQ,_6U)end | |
function lcBL:encode_pretty(GLSzBQs,c,xg)if type(self)~='table'or self.__index~=lcBL then | |
lcBL:onEncodeError("JSON:encode_pretty must be called in method format",c)end;if | |
type(xg)~='table'then xg=dx end;return iSj(self,GLSzBQs,{},c,xg)end;function lcBL.__tostring()return"JSON encode/decode package"end | |
lcBL.__index=lcBL | |
function lcBL:new(Id2KoP_G)local Y2or={}if Id2KoP_G then | |
for zN8ASHV5,iju in pairs(Id2KoP_G)do Y2or[zN8ASHV5]=iju end end | |
return setmetatable(Y2or,lcBL)end;return lcBL:new() | |
]===])() | |
local YAtG_LV3=(function() | |
local yY=[[ Copyright (c) The python-semanticversion project | |
All rights reserved. | |
Redistribution and use in source and binary forms, with or without | |
modification, are permitted provided that the following conditions are met: | |
1. Redistributions of source code must retain the above copyright notice, this | |
list of conditions and the following disclaimer. | |
2. Redistributions in binary form must reproduce the above copyright notice, | |
this list of conditions and the following disclaimer in the documentation | |
and/or other materials provided with the distribution. | |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | |
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
]] | |
yY=[[ The use of the library is similar to the original one, | |
check the documentation here: https://python-semanticversion.readthedocs.io/en/latest/ | |
]]local Xf,UlFdiZ7v,U;do local aSdZU3=table | |
Xf,UlFdiZ7v,U=aSdZU3.concat,aSdZU3.insert,aSdZU3.unpack end;local wFeA | |
wFeA=function(YKDL) | |
do local oFyb6OLp=tonumber(YKDL)if | |
oFyb6OLp then return oFyb6OLp,true else return YKDL,false end end end;local JQgI | |
JQgI=function(oGdh_mv)return oGdh_mv and oGdh_mv[1]=='0'and | |
tonumber(oGdh_mv and oGdh_mv~='0')end;local N | |
N=function(WjvvK,TASVwBgU)if WjvvK==TASVwBgU then return 0 end | |
if WjvvK>TASVwBgU then return 1 end;if WjvvK<TASVwBgU then return-1 end end;local fs52REi | |
fs52REi=function(KjUncMB,XkT)local c3dr,NGH=wFeA(KjUncMB)local tIc,MD2O=wFeA(XkT) | |
if NGH and MD2O then | |
return N(c3dr,tIc)elseif NGH then return-1 elseif MD2O then return 1 else return N(c3dr,tIc)end end;local PUNkgaiM | |
PUNkgaiM=function(HQ,cng)local lE;do local nI2F0id={}for N4aMD_P=1,#HQ do if cng[N4aMD_P]then | |
nI2F0id[HQ[N4aMD_P]]=cng[N4aMD_P]end end | |
lE=nI2F0id end | |
for pCi,NzeoQJ in pairs(lE)do | |
local AwGfFV=fs52REi(pCi,NzeoQJ)if AwGfFV~=0 then return AwGfFV end end;return N(#HQ,#cng)end;local s6FbB | |
do local wCRY | |
local d0uKSVw1={_coerce=function(YAnZNei,h8YWR44E,VF)if VF==nil then VF=false end | |
if h8YWR44E==nil and VF then return h8YWR44E end;return tonumber(h8YWR44E)end,next_major=function(fTrMe) | |
if | |
fTrMe.prerelease and fTrMe.minor==0 and fTrMe.patch==0 then | |
return | |
s6FbB(Xf((function()local ypDndT8={}local MV65=1 | |
local Y3D66Ym9={fTrMe.major,fTrMe.minor,fTrMe.patch}for q=1,#Y3D66Ym9 do local PhJ=Y3D66Ym9[q]ypDndT8[MV65]=tostring(PhJ) | |
MV65=MV65+1 end;return ypDndT8 end)(),'.'))else | |
return | |
s6FbB(Xf((function()local h={}local j2K=1;local r8hgwQ={fTrMe.major+1,0,0} | |
for _6U=1,#r8hgwQ do | |
local GLSzBQs=r8hgwQ[_6U]h[j2K]=tostring(GLSzBQs)j2K=j2K+1 end;return h end)(),'.'))end end,next_minor=function(c)if | |
not(c.minor)then | |
error("Partial version doesn't contain the minor component!")end | |
if c.prerelease and c.patch==0 then | |
return | |
s6FbB(Xf((function() | |
local xg={}local Id2KoP_G=1;local Y2or={c.major,c.minor,c.patch} | |
for zN8ASHV5=1,#Y2or do | |
local iju=Y2or[zN8ASHV5]xg[Id2KoP_G]=tostring(iju)Id2KoP_G=Id2KoP_G+1 end;return xg end)(),'.'))else | |
return | |
s6FbB(Xf((function()local XsWgh={}local l4Hdz=1;local NSXCgSH={c.major,c.minor+1,0} | |
for Wq=1,#NSXCgSH do | |
local SbOQ=NSXCgSH[Wq]XsWgh[l4Hdz]=tostring(SbOQ)l4Hdz=l4Hdz+1 end;return XsWgh end)(),'.'))end end,next_patch=function(IiuHGo)if | |
not(IiuHGo.patch)then | |
error("Partial version doesn't contain the patch component!")end | |
if IiuHGo.prerelease then | |
return | |
s6FbB(Xf((function()local cGqxtYr={} | |
local bgJFKeeZ=1;local yu9fg0nN={IiuHGo.major,IiuHGo.minor,IiuHGo.patch} | |
for wgx=1,# | |
yu9fg0nN do local zlU7X=yu9fg0nN[wgx] | |
cGqxtYr[bgJFKeeZ]=tostring(zlU7X)bgJFKeeZ=bgJFKeeZ+1 end;return cGqxtYr end)(),'.'))else | |
return | |
s6FbB(Xf((function()local t={}local f6qbO=1 | |
local kk={IiuHGo.major,IiuHGo.minor,IiuHGo.patch+1} | |
for QrubIAv=1,#kk do local bLHDW=kk[QrubIAv]t[f6qbO]=tostring(bLHDW)f6qbO=f6qbO+1 end;return t end)(),'.'))end end,coerce=function(YjFd7b,jZgPYb,zN2)if | |
zN2 ==nil then zN2=false end;local IN69pa5 | |
IN69pa5=function(OVx_mN) | |
local lB,byE=OVx_mN:match('^(%d+)(.*)$')if not(lB)then return nil end;local bITCI=lB | |
local K,F5dtVpnN=byE:match('^%.(%d+)(.*)$')if K then byE=F5dtVpnN;bITCI=bITCI.. ('.'..K)end;local kxeBp | |
kxeBp,F5dtVpnN=byE:match('^%.(%d+)(.*)$') | |
if kxeBp then byE=F5dtVpnN;bITCI=bITCI.. ('.'..kxeBp)end;return OVx_mN,bITCI end;local UOWJ,WtalJw=IN69pa5(jZgPYb)if not(UOWJ)then | |
error("Version string lacks a numerical component: ".. | |
tostring(jZgPYb))end | |
local JYrf2=jZgPYb:sub(1,#WtalJw) | |
if not zN2 then while({JYrf2:gsub('.','')})[2]<2 do JYrf2= | |
JYrf2 ..'.0'end end;if#WtalJw==#jZgPYb then return s6FbB(JYrf2,zN2)end;local KHDOUlRY=jZgPYb:sub( | |
#WtalJw+1) | |
KHDOUlRY=KHDOUlRY:gsub('[^a-zA-Z0-9+.-]','-')local I0JvPpn,Ce4ZE=nil,nil | |
if KHDOUlRY:sub(1,1)=='+'then I0JvPpn='' | |
Ce4ZE=KHDOUlRY:sub(2)elseif KHDOUlRY:sub(1,1)=='.'then I0JvPpn=''Ce4ZE=KHDOUlRY:sub(2)elseif | |
KHDOUlRY:sub(1,1)=='-'then KHDOUlRY=KHDOUlRY:sub(2) | |
do | |
local a=KHDOUlRY:find('+')if a then | |
I0JvPpn,Ce4ZE=KHDOUlRY:sub(1,a-1),KHDOUlRY:sub(a+1,-1)else I0JvPpn,Ce4ZE=KHDOUlRY,''end end else do local kQ=KHDOUlRY:find('+') | |
if kQ then I0JvPpn,Ce4ZE=KHDOUlRY:sub(1,kQ-1),KHDOUlRY:sub( | |
kQ+1,-1)else I0JvPpn,Ce4ZE=KHDOUlRY,''end end end;Ce4ZE=Ce4ZE:gsub('+','.')if I0JvPpn and I0JvPpn~=''then JYrf2=JYrf2 .. | |
('-'..I0JvPpn)end;if | |
Ce4ZE and Ce4ZE~=''then JYrf2=JYrf2 .. ('+'..Ce4ZE)end;return | |
YjFd7b.__class(JYrf2,zN2)end,parse=function(EE9LAE,iVx,eg,AQviNt)if | |
eg==nil then eg=false end;if AQviNt==nil then AQviNt=false end;if not iVx or | |
type(iVx)~='string'or iVx==''then | |
error("Invalid empty version string: ".. | |
tostring(tostring(iVx)))end;local T6 | |
if eg then | |
T6=EE9LAE.__class.partialVersionRe else T6=EE9LAE.__class.versionRe end;local NviN0i,BlMQce,o,dpRE,fEiXwWq=T6(EE9LAE.__class,iVx)if not NviN0i then | |
error( | |
"Invalid version string: "..tostring(iVx))end;if JQgI(NviN0i)then | |
error("Invalid leading zero in major: ".. | |
tostring(iVx))end;if JQgI(BlMQce)then | |
error("Invalid leading zero in minor: ".. | |
tostring(iVx))end;if JQgI(o)then | |
error("Invalid leading zero in patch: ".. | |
tostring(iVx))end;NviN0i=tonumber(NviN0i) | |
BlMQce=EE9LAE:_coerce(BlMQce,eg)o=EE9LAE:_coerce(o,eg) | |
if dpRE==nil then if eg and fEiXwWq==nil then return | |
{NviN0i,BlMQce,o,nil,nil}else dpRE={}end elseif dpRE==''then dpRE={}else | |
do | |
local r3JzMga6={}local Tuyw=1 | |
for FYLcr2nu in dpRE:gmatch('[^.]+')do r3JzMga6[Tuyw]=FYLcr2nu;Tuyw=Tuyw+1 end;dpRE=r3JzMga6 end;EE9LAE:_validateIdentifiers(dpRE,false)end | |
if fEiXwWq==nil then if eg then fEiXwWq=nil else fEiXwWq={}end elseif fEiXwWq==''then fEiXwWq={}else do | |
local ioS69={}local AiP=1 | |
for S2jwpoi in fEiXwWq:gmatch('[^.]+')do ioS69[AiP]=S2jwpoi;AiP=AiP+1 end;fEiXwWq=ioS69 end | |
EE9LAE:_validateIdentifiers(fEiXwWq,true)end;return{NviN0i,BlMQce,o,dpRE,fEiXwWq}end,_validateIdentifiers=function(_WX9u,u0riyU,UH)if | |
UH==nil then UH=false end | |
for WNph=1,#u0riyU do local ytF=u0riyU[WNph]if not ytF then | |
error( | |
"Invalid empty identifier ".. | |
tostring(ytF).." in "..tostring(Xf(u0riyU,'.')))end;if | |
ytF:sub(1,1)=='0'and | |
tonumber(ytF)and ytF~='0'and not UH then | |
error("Invalid leading zero in identifier "..tostring(ytF))end end end,__pairs=function(d)return | |
pairs({d.major,d.minor,d.patch,d.prerelease,d.build})end,__ipairs=function(gRm)return | |
ipairs({gRm.major,gRm.minor,gRm.patch,gRm.prerelease,gRm.build})end,__tostring=function(LPX0) | |
local g=tostring(LPX0.major) | |
if LPX0.minor~=nil then g=g.. ('.'..LPX0.minor)end | |
if LPX0.patch~=nil then g=g.. ('.'..LPX0.patch)end | |
if LPX0.prerelease and#LPX0.prerelease>0 or | |
LPX0.partial and LPX0.prerelease and#LPX0.prerelease==0 and LPX0.build==nil then g=g.. ('-'.. | |
Xf(LPX0.prerelease,'.'))end | |
if | |
LPX0.build and#LPX0.build>0 or LPX0.partial and LPX0.build and# | |
LPX0.build==0 then g=g.. ('+'..Xf(LPX0.build,'.'))end;return g end,_comparsionFunctions=function(_l,qao)if | |
qao==nil then qao=false end;local ipUPIzc | |
ipUPIzc=function(J7nsK,dXbd) | |
if J7nsK and dXbd then | |
return PUNkgaiM(J7nsK,dXbd)elseif J7nsK then return-1 elseif dXbd then return 1 else return 0 end end;local N8 | |
N8=function(vQj,sVBxyy)if vQj==sVBxyy then return 0 else return'not implemented'end end;local Gzk | |
Gzk=function(N9d)local S7 | |
S7=function(bJtvRSR,aBhZK5)if bJtvRSR==nil or aBhZK5 ==nil then return 0 else | |
return N9d(bJtvRSR,aBhZK5)end end;return S7 end;if qao then return{N,Gzk(N),Gzk(N),Gzk(ipUPIzc),Gzk(N8)}else return | |
{N,N,N,ipUPIzc,N8}end end,__compare=function(Jz8JUscj,OtGmbAgE) | |
local oU_r=Jz8JUscj:_comparsionFunctions( | |
Jz8JUscj.partial or OtGmbAgE.partial) | |
local n_lv={{oU_r[1],Jz8JUscj.major,OtGmbAgE.major},{oU_r[2],Jz8JUscj.minor,OtGmbAgE.minor},{oU_r[3],Jz8JUscj.patch,OtGmbAgE.patch},{oU_r[4],Jz8JUscj.prerelease,OtGmbAgE.prerelease},{oU_r[5],Jz8JUscj.build,OtGmbAgE.build}} | |
for UYQF=1,#n_lv do local WXx=n_lv[UYQF]local W4EuxJXi,BlYNd61h,XDPndG=U(WXx) | |
local sJYFQIP4=W4EuxJXi(BlYNd61h,XDPndG)if sJYFQIP4 ~=0 then return sJYFQIP4 end end;return 0 end,__compareHelper=function(Ogq0S2,n8Cw3SR,GJqd7gt,slE5aDm2) | |
local aL_g=Ogq0S2:__compare(n8Cw3SR)if aL_g=='not implemented'then return slE5aDm2 end | |
return GJqd7gt(aL_g)end,__eq=function(IMUI10L,vPA) | |
local pUXZ6G4;pUXZ6G4=function(mk)return mk==0 end;return | |
IMUI10L:__compareHelper(vPA,pUXZ6G4,false)end,__lt=function(OeQex1U4,i0cV9) | |
local EGD;EGD=function(VWiGCreH)return VWiGCreH<0 end;return | |
OeQex1U4:__compareHelper(i0cV9,EGD,false)end,__le=function(B_kkL,uEO6Y) | |
local i_053JPY;i_053JPY=function(l)return l<=0 end;return | |
B_kkL:__compareHelper(uEO6Y,i_053JPY,false)end}d0uKSVw1.__index=d0uKSVw1 | |
wCRY=setmetatable({__init=function(UK,NzaICo,k1X83nYm) | |
if k1X83nYm==nil then k1X83nYm=false end;local xxzxfj,_ad1m4I,H1QsS,rIMx,TiA=U(UK:parse(NzaICo,k1X83nYm)) | |
UK.major,UK.minor,UK.patch,UK.prerelease,UK.build,UK.partial=xxzxfj,_ad1m4I,H1QsS,rIMx,TiA,k1X83nYm end,__base=d0uKSVw1,__name="Version"},{__index=d0uKSVw1,__call=function(Y51P,...) | |
local ichL=setmetatable({},d0uKSVw1)Y51P.__init(ichL,...)return ichL end})d0uKSVw1.__class=wCRY;local lNOqUk8=wCRY | |
lNOqUk8.versionRe=function(lNOqUk8,NOK) | |
local Alv,YeLO2,CkrmO,ooovsSJe=NOK:match('^(%d+)%.(%d+)%.(%d+)(.*)$')if not(Alv)then return nil end | |
local s5IsD,KvYEVoXt=ooovsSJe:match('^%-([0-9a-zA-z.-]+)(.*)$')if s5IsD then ooovsSJe=KvYEVoXt end;local VWWD_P | |
VWWD_P,KvYEVoXt=ooovsSJe:match('^%+([0-9a-zA-Z.-]+)(.*)$')if VWWD_P then ooovsSJe=KvYEVoXt end;if#ooovsSJe>0 then return nil end;return | |
Alv,YeLO2,CkrmO,s5IsD,VWWD_P end | |
lNOqUk8.partialVersionRe=function(lNOqUk8,zsMuNkv)local aXxi,Q18a7QTy=zsMuNkv:match('^(%d+)(.*)$')if | |
not(aXxi)then return nil end | |
local K5Rp6,GTIA=Q18a7QTy:match('^%.(%d+)(.*)$')if K5Rp6 then Q18a7QTy=GTIA end;local gdPUe | |
gdPUe,GTIA=Q18a7QTy:match('^%.(%d+)(.*)$')if gdPUe then Q18a7QTy=GTIA end;local _bxEn | |
_bxEn,GTIA=Q18a7QTy:match('^%-([0-9a-zA-Z.-]*)(.*)$')if _bxEn then Q18a7QTy=GTIA end;local pcN_ceXY | |
pcN_ceXY,GTIA=Q18a7QTy:match('^%+([0-9a-zA-Z.-]*)(.*)$')if pcN_ceXY then Q18a7QTy=GTIA end;if#Q18a7QTy>0 then return nil end;return aXxi, | |
K5Rp6,gdPUe,_bxEn,pcN_ceXY end;s6FbB=wCRY end;local X | |
do local _P | |
local rq={parse=function(I,RAAJAsR)if | |
not RAAJAsR or type(RAAJAsR)~='string'or RAAJAsR==''then | |
error("Invalid empty requirement specification: "..tostring(tostring(RAAJAsR)))end;if RAAJAsR== | |
'*'then return{I.__class.KIND_ANY,''}end | |
local c1pjj7,BMv=I.__class:reSpec(RAAJAsR)if not c1pjj7 then | |
error("Invalid requirement specification: "..tostring(RAAJAsR))end;c1pjj7= | |
I.__class.KIND_ALIASES[c1pjj7]or c1pjj7;local NQh8=s6FbB(BMv,true) | |
if | |
NQh8.build~=nil and c1pjj7 ~=I.__class.KIND_EQUAL and c1pjj7 ~= | |
I.__class.KIND_NEQ then | |
error( | |
"Invalid requirement specification "..tostring(RAAJAsR)..": build numbers have no ordering")end;return{c1pjj7,NQh8}end,match=function(P,bkTe) | |
local ohmPbyDd=P.kind | |
if P.__class.KIND_ANY==ohmPbyDd then return true elseif P.__class.KIND_LT==ohmPbyDd then return bkTe< | |
P.spec elseif P.__class.KIND_LTE==ohmPbyDd then return bkTe<=P.spec elseif | |
P.__class.KIND_EQUAL==ohmPbyDd then return bkTe==P.spec elseif P.__class.KIND_GTE==ohmPbyDd then return bkTe>= | |
P.spec elseif P.__class.KIND_GT==ohmPbyDd then return bkTe>P.spec elseif | |
P.__class.KIND_NEQ==ohmPbyDd then return bkTe~=P.spec elseif P.__class.KIND_CARET==ohmPbyDd then | |
return | |
P.spec<=bkTe and bkTe<P.spec:next_major()elseif P.__class.KIND_TILDE==ohmPbyDd then return P.spec<=bkTe and | |
bkTe<P.spec:next_minor()else return | |
error("Unexpected match kind: "..tostring(P.kind))end end,__tostring=function(D)return | |
tostring(D.kind)..tostring(D.spec)end,__eq=function(DfDLWkT,MTU8HP4d)return | |
DfDLWkT.kind==MTU8HP4d.kind and DfDLWkT.spec==MTU8HP4d.spec end}rq.__index=rq | |
_P=setmetatable({__init=function(hIM_cG0i,jD) | |
hIM_cG0i.kind,hIM_cG0i.spec=U(hIM_cG0i:parse(jD))end,__base=rq,__name="SpecItem"},{__index=rq,__call=function(me,...) | |
local sgU5HAMG=setmetatable({},rq)me.__init(sgU5HAMG,...)return sgU5HAMG end})rq.__class=_P;local mo=_P;mo.KIND_ANY='*'mo.KIND_LT='<'mo.KIND_LTE='<=' | |
mo.KIND_EQUAL='=='mo.KIND_SHORTEQ='='mo.KIND_EMPTY=''mo.KIND_GTE='>='mo.KIND_GT='>' | |
mo.KIND_NEQ='!='mo.KIND_CARET='^'mo.KIND_TILDE='~' | |
mo.KIND_ALIASES={[mo.__class.KIND_SHORTEQ]=mo.__class.KIND_EQUAL,[mo.__class.KIND_EMPTY]=mo.__class.KIND_EQUAL} | |
mo.reSpec=function(mo,FDydY)local PEZ_,c=FDydY:match('^(.-)(%d.*)$') | |
if not | |
( | |
PEZ_=='<'or PEZ_=='<='or PEZ_==''or PEZ_=='='or PEZ_=='=='or PEZ_=='>='or PEZ_=='>'or PEZ_=='!='or PEZ_=='^'or PEZ_=='~')then return nil else | |
return PEZ_,c end end;X=_P end;local dc61 | |
do local ElbTbcZG | |
local r3={parse=function(pUiVYRok,jvPsY9)local tEBmuypm={}local hW=1;for iOcgdUx in jvPsY9:gmatch('[^,]+')do | |
tEBmuypm[hW]=X(iOcgdUx)hW=hW+1 end;return tEBmuypm end,match=function(kCwLIk,_l) | |
local rjQ=kCwLIk.specs | |
for Euo0=1,#rjQ do local LIV=rjQ[Euo0]if not LIV:match(_l)then return false end end;return true end,filter=function(vydlAbZ3,BXxv5z) | |
local mKLU=0 | |
return function() | |
while true do mKLU=mKLU+1;local Him=BXxv5z[mKLU]if not(Him)then return nil end;if | |
vydlAbZ3:match(Him)then return Him end end end end,select=function(cPDhu,UQnOS) | |
local tRWU | |
do local X2Zy_nb={}local ITtw3N7E=1;for yozOp in cPDhu:filter(UQnOS)do X2Zy_nb[ITtw3N7E]=yozOp;ITtw3N7E= | |
ITtw3N7E+1 end;tRWU=X2Zy_nb end | |
if#tRWU>0 then local wxU=tRWU[1]for kOmS5sy=1,#tRWU do local CLSdD=tRWU[kOmS5sy] | |
if wxU<CLSdD then wxU=CLSdD end end;return wxU else return nil end end,__index=function(Fh,IlAPA)if | |
Fh:match(IlAPA)then return true else return nil end end,__pairs=function(jLKMpQuK)return | |
pairs(jLKMpQuK.specs)end,__ipairs=function(sUQpby)return ipairs(sUQpby.specs)end,__tostring=function(mbA) | |
return | |
Xf((function() | |
local _qPhpaFx={}local zex=1;local pPGcdu=mbA.specs;for rjp=1,#pPGcdu do local cT2z=pPGcdu[rjp] | |
_qPhpaFx[zex]=tostring(cT2z)zex=zex+1 end;return _qPhpaFx end)(),',')end,__eq=function(zke1tWps,gRFA) | |
local jX9a0tJX=zke1tWps.specs | |
for YFy4TGc=1,#jX9a0tJX do local YjpbYkCb=jX9a0tJX[YFy4TGc]local L1p7luJ=false;local eH=gRFA.specs | |
for WpOZ=1,#eH do | |
local fD2289=eH[WpOZ]if YjpbYkCb==fD2289 then L1p7luJ=true;break end end;if not L1p7luJ then return false end end;return true end}r3.__index=r3 | |
ElbTbcZG=setmetatable({__init=function(folfO,vtsK) | |
if type(vtsK)=='string'then vtsK={vtsK}end;local E1p4Mv | |
do local IHap={}local rDvV=1;for RX1L2q=1,#vtsK do local bCBtWguf=vtsK[RX1L2q] | |
IHap[rDvV]=folfO:parse(bCBtWguf)rDvV=rDvV+1 end;E1p4Mv=IHap end;folfO.specs={} | |
for q=1,#E1p4Mv do local e1sXUN4f=E1p4Mv[q]for x=1,#e1sXUN4f do local VP=e1sXUN4f[x] | |
UlFdiZ7v(folfO.specs,VP)end end end,__base=r3,__name="Spec"},{__index=r3,__call=function(IQwqq,...) | |
local Xcc4=setmetatable({},r3)IQwqq.__init(Xcc4,...)return Xcc4 end})r3.__class=ElbTbcZG;dc61=ElbTbcZG end;local aguhyl | |
aguhyl=function(fqw5,qnVfOeRE)return N(s6FbB(fqw5,s6FbB(qnVfOeRE)))end;local p | |
p=function(YIiSKsxK,Ua)return dc61(YIiSKsxK):match(s6FbB(Ua))end;local gOPDv;gOPDv=function(qeJtG) | |
return({s6FbB:parse(qeJtG)})[1]end;return | |
{Spec=dc61,SpecItem=X,Version=s6FbB,compare=aguhyl,match=p,validate=gOPDv}end)()local LfEJbh_;LfEJbh_=require("component").isAvailable;local JD,u | |
do | |
local pdpNgBcZ=require("shell")JD,u=pdpNgBcZ.parse,pdpNgBcZ.getWorkingDirectory end;local pzDMZwG=require("shell")local XPoQB,XxJ,o5sms,JQi1jg,wVzn;do | |
local wV=require("filesystem") | |
XPoQB,XxJ,o5sms,JQi1jg,wVzn=wV.isDirectory,wV.exists,wV.makeDirectory,wV.concat,wV.copy end | |
local pE=require("filesystem")local RSjapQ,QJf;do local rLd=require("serialization") | |
RSjapQ,QJf=rLd.serialize,rLd.unserialize end;local zC | |
zC=require("event").pull;local pfZ3SPy_,pDNa2ox6,Do6yo7nm;do local z8oF=require("term") | |
pfZ3SPy_,pDNa2ox6,Do6yo7nm=z8oF.clearLine,z8oF.getCursor,z8oF.clear end;local y06X3k;y06X3k=os.exit | |
local ivnJjrA,d3fMjkg | |
do local DB6A7N=io;ivnJjrA,d3fMjkg=DB6A7N.write,DB6A7N.stderr end;local el,Wu_uIt | |
do local VhYX=table;el,Wu_uIt=VhYX.insert,VhYX.unpack end;local w=pE.list;local sgeP,CM={},{}local Qlmlet=nil;local _={}local RkGFh6={}local hw18={} | |
local nvCiFt7r="/etc/hpm/module/"local xSebv5Jc="/var/lib/hpm/dist/"local mMp=0;local rDtVf="/etc/hpm/hpm.cfg" | |
local vj=[[Usage: hpm OPTIONS COMMAND | |
See `man hpm` for more info.]] | |
local z=[[-- << Global settings >> ------------------------------------------------------- | |
-- A directory where package manifests will be placed. | |
-- It will be created if it doesn't exist. | |
dist = "/var/lib/hpm/dist" | |
-- A place where to search for custom hpm modules. | |
-- It will be created if it doesn't exist. | |
modules = "/etc/hpm/module" | |
-- << Settings related to the hel module >> ------------------------------------ | |
hel = {} | |
-- If set to `false`, hpm will *only* remove a package that hpm is told to | |
-- remove. Otherwise, all of its dependants will be also removed. | |
hel.remove_dependants = true | |
-- << Settings related to the oppm module >> ----------------------------------- | |
oppm = {} | |
-- A cache file where package manifests will be stored for faster access. | |
oppm.cache_file = "/var/cache/hpm/oppm" | |
-- See hel.remove_dependants above. | |
oppm.remove_dependants = true]] | |
local Zg={info=function(...) | |
if sgeP.v then | |
return | |
print(table.concat((function(...)local Ha7ErH={}local rjU95v=1;local sxBl={...}for m=1,#sxBl do local nD4LhX6z=sxBl[m] | |
Ha7ErH[rjU95v]=tostring(nD4LhX6z)rjU95v=rjU95v+1 end;return Ha7ErH end)(...),"\t"))end end,print=function(...) | |
if | |
not(sgeP.q)then | |
return | |
print(table.concat((function(...)local iN={}local Lq=1;local s9tW={...}for R61K=1,#s9tW do local Jf4os=s9tW[R61K] | |
iN[Lq]=tostring(Jf4os)Lq=Lq+1 end;return iN end)(...),"\t"))end end,error=function(...) | |
if | |
not(sgeP.q)then | |
return | |
d3fMjkg:write( | |
table.concat((function(...)local a4xc={}local e=1;local la5={...}for i=1,#la5 do local R=la5[i] | |
a4xc[e]=tostring(R)e=e+1 end;return a4xc end)(...),"\t")..'\n')end end,fatal=function(...) | |
if | |
not(sgeP.q)then | |
d3fMjkg:write( | |
table.concat((function(...)local xWVu={}local Yw8Yxix=1;local i={...} | |
for VoXG=1,#i do | |
local JL0I04c=i[VoXG]xWVu[Yw8Yxix]=tostring(JL0I04c)Yw8Yxix=Yw8Yxix+1 end;return xWVu end)(...),"\t")..'\n')end;return y06X3k(1)end}local ykRppH | |
ykRppH=function(En6r_K97,T4AA)if not(En6r_K97)then return Zg.fatal(T4AA)end end;local WQ6 | |
WQ6=function(VnuCKTdu)return | |
Zg.fatal((tostring(VnuCKTdu))..": Not implemented yet!")end;local y36Aetn | |
y36Aetn=function()ivnJjrA(vj)return y06X3k(0)end;local iPL3B4cr | |
iPL3B4cr=function(XnNgn,H1JD)if not(XnNgn)then Zg.fatal(H1JD)end;return XnNgn end;local GI2hz6SK | |
GI2hz6SK=function(gEEa9I,ULLLDUm,e4F3) | |
if not(type(gEEa9I==ULLLDUm))then | |
Zg.fatal("Value '".. | |
tostring(gEEa9I).. | |
"' is "..tostring(type(e4F3)).. | |
", however, a "..tostring(ULLLDUm).." is expected.")end;return e4F3 end;local Oh;Oh=function(GsfNt7) | |
return GI2hz6SK(GsfNt7,"number",tonumber(GsfNt7))end;local PG | |
PG=function(fF0)return | |
GI2hz6SK(fF0,"string",tostring(fF0))end;local n | |
n=function(YWPfQKb2,r) | |
for OS0Zp3i,BK in pairs(r)do if BK==YWPfQKb2 then return true,OS0Zp3i end end;return false end;local O | |
O=function(Idjbe70)local B=0;for nDjt,NVWt in pairs(Idjbe70)do B=B+1 end;return B end;local N5UjTN | |
N5UjTN=function(efuUGMh) | |
if type(efuUGMh)=="nil"then return true elseif type(efuUGMh)=="string"then return | |
not efuUGMh or#efuUGMh<1 elseif type(efuUGMh)=="table"then return | |
not efuUGMh or O(efuUGMh)<1 else return true end end;local qLH5 | |
qLH5=function(p4nNp) | |
for VW=1,#p4nNp do local Zt=p4nNp[VW]if not Zt then return false end end;return true end;local tE | |
tE=function(V)return XxJ(V)and XPoQB(V)end;local VcV0EuD | |
VcV0EuD=function(mzeTI)return XxJ(mzeTI)and not XPoQB(mzeTI)end;local pX4gCR | |
pX4gCR=function(sy4J)return sy4J==1 and""or"s"end;local gad4ZcL | |
gad4ZcL=function(ztJhP_u8)return ztJhP_u8 ~=1 and""or"s"end;local dk | |
dk=function(D)return D==1 and"is"or"are"end;local E | |
E=function(XIcl)return XIcl:match("^([^:]-):?([^:@]+)@?([^:@]*)$")end;local OO | |
OO=function(ys) | |
if | |
pE.get(pzDMZwG.resolve(ys)).isReadOnly()then return false,"the path is readonly!"elseif not XxJ(ys)then | |
return false,"the filesystem node doesn't exist."else | |
if not(XPoQB(ys)or pE.isLink(ys))then | |
return pE.remove(ys)else | |
for rMQ1um8 in iPL3B4cr(w(ys))do OO(JQi1jg(ys,rMQ1um8))end;return pE.remove(ys)end end end;local y | |
y=function()local U2=sgeP.c or sgeP.config or rDtVf | |
if | |
not VcV0EuD(U2)then local Z=pE.path(U2) | |
if not tE(Z)then local B58,PYVzrNl=o5sms(Z)if not B58 then | |
return false,"Failed to create '".. | |
tostring(Z).."' directory for the config file: "..tostring(PYVzrNl)end end;local ZDICnKE,L=io.open(U2,"w")if ZDICnKE then ZDICnKE:write(z) | |
ZDICnKE:close()else | |
return false,"Failed to open config file for writing: "..tostring(L)end end;local X,zLtWO09=io.open(U2,"r") | |
if X then local KTVmRC=X:read("*all")X:close() | |
local Pa={};(load(KTVmRC,"config","t",Pa))() | |
local bmK | |
bmK=function(OJPc3R)if OJPc3R==nil then OJPc3R={}end | |
return | |
setmetatable(OJPc3R,{__index={get=function(j,vMgKnGj,M9K)if | |
type(OJPc3R[j])~="nil"then | |
if type(OJPc3R[j])=="table"then return bmK(OJPc3R[j])end;return OJPc3R[j]end | |
Zg.error( | |
"Attempt to access undeclared config field '"..tostring(j).."'!")if not M9K then return vMgKnGj else return bmK(vMgKnGj)end end}})end;RkGFh6=bmK(Pa)nvCiFt7r=RkGFh6.get("modules",nvCiFt7r) | |
xSebv5Jc=RkGFh6.get("dist",xSebv5Jc)return RkGFh6 else return false, | |
"Failed to open config file for reading: "..tostring(zLtWO09)end end;local cR6rJlAl | |
cR6rJlAl=function()if not(LfEJbh_("internet"))then | |
Zg.fatal("This command requires an internet card to run!")end;Qlmlet=Qlmlet or | |
require("internet").request end;local M6ilzGJ | |
M6ilzGJ=function(Zeu)cR6rJlAl()return pcall(Qlmlet,Zeu)end;local iW6CD | |
iW6CD=function() | |
if not tE(nvCiFt7r)then local W0iTcMIt,N=o5sms(nvCiFt7r)if not W0iTcMIt then | |
return false, | |
"Failed to create '".. | |
tostring(nvCiFt7r).."' directory for custom modules: "..tostring(N)end end;local Q2_d=iPL3B4cr(w(nvCiFt7r)) | |
for Hald6SO in Q2_d do | |
hw18.name=Hald6SO:match("^(.+)%..+$") | |
local Dq=iPL3B4cr(loadfile(JQi1jg(nvCiFt7r,Hald6SO),"t",hw18))Dq()hw18.name=nil end;return true end;local wZdg | |
wZdg=function(y3Ur)local GL70F7uL=y3Ur;local lqANrrJA;do local WUFTXBy6=y3Ur:find(':') | |
if WUFTXBy6 then | |
GL70F7uL=y3Ur:sub(WUFTXBy6+1)lqANrrJA=y3Ur:sub(1,WUFTXBy6-1)end end | |
if not lqANrrJA then | |
local aEZf={} | |
for QjQ_o,lqANrrJA in pairs(_)do | |
if lqANrrJA[GL70F7uL]then if type(lqANrrJA[GL70F7uL])=="table"and | |
lqANrrJA[GL70F7uL].__public==true then | |
el(aEZf,{class=lqANrrJA,module=QjQ_o,method=lqANrrJA[GL70F7uL]})end end end | |
if#aEZf>1 then local wDiq_=nil;for QYA5WJOY,lqANrrJA in pairs(aEZf)do | |
if lqANrrJA.module=="hel"then wDiq_=QYA5WJOY;break end end;if wDiq_ then | |
aEZf={aEZf[wDiq_]}end end | |
if#aEZf>1 then | |
Zg.print("Ambiguous choice: method ".. | |
tostring(GL70F7uL).." is implemented in the following modules:")for yliV8=1,#aEZf do local lqANrrJA=aEZf[yliV8] | |
Zg.print(" * "..tostring(lqANrrJA.module))end | |
Zg.print( | |
"Choose a specific module by prepending its name with a colon, e.g., ".. | |
tostring(aEZf[1].module)..":"..tostring(GL70F7uL)..".")return false elseif#aEZf==0 then | |
Zg.error("Unknown command: "..tostring(GL70F7uL))return false else lqANrrJA=aEZf[1].module | |
Zg.info("Note, using "..tostring(lqANrrJA)..":".. | |
tostring(GL70F7uL)..".")return | |
function(...)return aEZf[1].method(aEZf[1].class,...)end end else | |
if _[lqANrrJA]and N5UjTN(GL70F7uL)then local rjpKFl={} | |
for YUGQovw,XZt7GyF in pairs(_[lqANrrJA])do if | |
type(XZt7GyF)=="table"and XZt7GyF.__public==true then | |
el(rjpKFl,tostring(YUGQovw))end end | |
Zg.print("Available module-specific commands: "..tostring(table.concat(rjpKFl,", ")))return false end | |
if | |
not _[lqANrrJA]or not _[lqANrrJA][GL70F7uL]or _[lqANrrJA][GL70F7uL]and | |
( | |
type(_[lqANrrJA][GL70F7uL])~="table"or _[lqANrrJA][GL70F7uL].__public~=true)then | |
Zg.error("Unknown command: ".. | |
tostring(lqANrrJA)..":"..tostring(GL70F7uL))return false else return function(...) | |
return _[lqANrrJA][GL70F7uL](_[lqANrrJA],...)end end end end;local BaX | |
BaX=function(Zn3SC) | |
if not Zn3SC or Zn3SC==""then Zn3SC="hel"else Zn3SC=Zn3SC end;return _[Zn3SC]or _.default end;local SJsW11k | |
SJsW11k=function(D4,crA9EKx,...)if D4 ==nil then D4=_.default end | |
if D4[crA9EKx]then return | |
D4[crA9EKx](D4,...)else return _.default[crA9EKx](_.default,...)end end;local Ki1HJT | |
Ki1HJT=function(IcsJ,A,Wp9xT,P)if A==nil then A="hel"end | |
if Wp9xT==nil then Wp9xT=JQi1jg(xSebv5Jc,A)end;if P==nil then P=IcsJ.name end | |
if not IcsJ then return false,"'nil' given"end | |
if not tE(Wp9xT)then local x,AXNfV=o5sms(Wp9xT)if not x then | |
return false,"Failed to create '".. | |
tostring(JQi1jg(Wp9xT,A)).."' directory for manifest files: "..tostring(AXNfV)end end;local o0_XG8FI,jLsxpw=io.open(JQi1jg(Wp9xT,P),"w") | |
if o0_XG8FI then | |
o0_XG8FI:write(RSjapQ(IcsJ))o0_XG8FI:close()return true else return false, | |
"Failed to open file for writing: "..tostring(jLsxpw)end end;local wjim8xCV | |
wjim8xCV=function(cX,iyx,bxvn)if bxvn==nil then bxvn="hel"end | |
iyx=iyx or JQi1jg(xSebv5Jc,bxvn,cX) | |
if VcV0EuD(iyx)then local mWYrzB,O7kX=io.open(iyx,"rb") | |
if mWYrzB then | |
local Q4XSpdY=iPL3B4cr(QJf(mWYrzB:read("*all")))mWYrzB:close()return Q4XSpdY else return false, | |
"Failed to open manifest for '"..tostring(cX).."' package: ".. | |
tostring(O7kX)end else | |
return false,"No manifest found for '"..tostring(cX).."' package"end end;local EQLam | |
EQLam=function(fzTyrQ9F,fAumJ0i)if fAumJ0i==nil then fAumJ0i="hel"end | |
local i0=JQi1jg(xSebv5Jc,fAumJ0i,fzTyrQ9F) | |
if VcV0EuD(i0)then return OO(i0)else return false, | |
"No manifest found for '"..tostring(fzTyrQ9F).."' package"end end;local qTDt | |
qTDt=function(tZliF4)return | |
setmetatable({__public=true},{__call=function(jlmopoj,...)return tZliF4(...)end})end;local v | |
v=function(R,uS_N6) | |
return | |
function()local o5SLRA,ztwXaCR=pcall(R)if not(o5SLRA)then | |
return false,"Could not download '"..tostring(uS_N6).."': ".. | |
tostring(ztwXaCR)else return ztwXaCR end end end;local Ta | |
Ta=function(M2WtMgiq,FgfME,ylH9o) | |
if FgfME==nil then FgfME="Could not download '%s': %s"end;if ylH9o==nil then ylH9o="Could not download '%s': %s"end | |
local CC4Kfjh,k,eUQ0x=M6ilzGJ(M2WtMgiq)if not(CC4Kfjh and k)then | |
return false,FgfME:format(M2WtMgiq,eUQ0x)end;local r0OR="" | |
for pYHkv,eUQ0x in v(k)do if pYHkv then r0OR=r0OR..pYHkv else return false, | |
ylH9o:format(M2WtMgiq,eUQ0x)end end;return r0OR end;local unArcvQl | |
unArcvQl=function() | |
if not(sgeP.y)then | |
io.write("Press [ENTER] to continue...")local hxZHlgP=select(3,zC("key_down"))if hxZHlgP==13 then pfZ3SPy_() | |
return true else io.write("\n")return false end else | |
return true end end;local h6Ub7U | |
h6Ub7U=function(zct)local WQk6Wkd=0;local t={} | |
if not(N5UjTN(zct.install))then | |
local pRCHPl={"Packages to INSTALL:",table.concat(zct.install," ")}el(t,pRCHPl)WQk6Wkd=WQk6Wkd+#zct.install else | |
zct.install={}end | |
if not(N5UjTN(zct.reinstall))then | |
local sCffg4HK={"Packages to REINSTALL:",table.concat(zct.reinstall," ")}el(t,sCffg4HK)WQk6Wkd=WQk6Wkd+#zct.reinstall else | |
zct.reinstall={}end | |
if not(N5UjTN(zct.upgrade))then | |
local EyljhkFp={"Packages to UPGRADE:",table.concat(zct.upgrade," ")}el(t,EyljhkFp)WQk6Wkd=WQk6Wkd+#zct.upgrade else | |
zct.upgrade={}end | |
if not(N5UjTN(zct.remove))then | |
local uGDn542={"Packages to REMOVE:",table.concat(zct.remove," ")}el(t,uGDn542)WQk6Wkd=WQk6Wkd+#zct.remove else zct.remove={}end | |
do | |
local DQ={tostring(#zct.install).. | |
" to INSTALL, "..tostring(#zct.reinstall).. | |
" to REINSTALL, "..tostring( | |
#zct.upgrade).." to UPGRADE, ".. | |
tostring(#zct.remove).." to REMOVE."}el(t,DQ)end | |
for s6Ahlni_,T6dNu in pairs(t)do | |
for s6Ahlni_,H in pairs(T6dNu)do if s6Ahlni_==1 then Zg.print(H)else | |
Zg.print(" "..tostring(H))end end;if s6Ahlni_~=#t then Zg.print("")end end | |
if WQk6Wkd>0 then if not(unArcvQl())then return y06X3k(7)end end end | |
do local YlzZm;local vj9879b5={}vj9879b5.__index=vj9879b5 | |
YlzZm=setmetatable({__init=function()end,__base=vj9879b5,__name="default"},{__index=vj9879b5,__call=function(FRcmT,...) | |
local zfl=setmetatable({},vj9879b5)FRcmT.__init(zfl,...)return zfl end})vj9879b5.__class=YlzZm;local cotcYZ1f=YlzZm | |
cotcYZ1f.install=function()return | |
Zg.fatal("Incorrect source is provided! No default 'install' implementation.")end | |
cotcYZ1f.remove=function(cotcYZ1f,itxD,JPHs7A)if JPHs7A==nil then JPHs7A="hel"end | |
if itxD then | |
if itxD.files then | |
for yzYgnMtr,o in | |
pairs(itxD.files)do local wmkJ=JQi1jg(o.dir,o.name)local I1,gXu5hG=OO(wmkJ) | |
if not(I1)then return false, | |
"Failed to remove '".. | |
tostring(wmkJ).."': "..tostring(gXu5hG)end end end;return EQLam(itxD.name,JPHs7A)else | |
return false,"Package can't be removed: the manifest is empty."end end | |
cotcYZ1f.save=function()return | |
Zg.fatal("Incorrect source is provided! No default 'save' implementation.")end;_.default=YlzZm end | |
do local R60Ru4bj;local eQWRf=_.default;local WT2AX={}WT2AX.__index=WT2AX | |
setmetatable(WT2AX,eQWRf.__base) | |
R60Ru4bj=setmetatable({__init=function(qEO,...)return R60Ru4bj.__parent.__init(qEO,...)end,__base=WT2AX,__name="hel",__parent=eQWRf},{__index=function(q,WUY7) | |
local _puepou=rawget(WT2AX,WUY7)if _puepou==nil then local DYLeJ=rawget(q,"__parent") | |
if DYLeJ then return DYLeJ[WUY7]end else return _puepou end end,__call=function(udbF,...) | |
local dt1=setmetatable({},WT2AX)udbF.__init(dt1,...)return dt1 end})WT2AX.__class=R60Ru4bj;local _AvO=R60Ru4bj | |
_AvO.URL="https://hel-roottree.rhcloud.com/" | |
_AvO.parsePackageJSON=function(_AvO,V7eMEiVW,Co1tUVas) | |
if Co1tUVas==nil then Co1tUVas=YAtG_LV3.Spec("*")end;local B=nil;local UjlBMb={} | |
for IPPy,zYGA2q2 in pairs(V7eMEiVW.versions)do | |
local I9Mw=YAtG_LV3.Version(IPPy)if not(I9Mw)then | |
Zg.fatal("Could not parse the version in package: "..tostring(I9Mw))end;UjlBMb[I9Mw]=zYGA2q2 end | |
local PKWIJ9,rQYWEt=pcall(function()return | |
Co1tUVas:select((function()local e={}local BUtIET=1 | |
for NvAj,Icg in pairs(UjlBMb)do e[BUtIET]=NvAj;BUtIET=BUtIET+1 end;return e end)())end)if not(PKWIJ9)then | |
Zg.fatal("Could not select the best version: "..tostring(rQYWEt))end;B=tostring(rQYWEt)if | |
not(rQYWEt)then | |
Zg.fatal("No candidate for version specification '"..tostring(Co1tUVas).."' found!")end | |
local nCwsa={name=V7eMEiVW.name,version=B,files={},dependencies={}}for PzMsk,axLuO in pairs(UjlBMb[rQYWEt].files)do local j=axLuO.dir;local As=axLuO.name | |
el(nCwsa.files,{url=PzMsk,dir=j,name=As})end | |
for JmCzKm,Mwhc in | |
pairs(UjlBMb[rQYWEt].depends)do local A6z=Mwhc.version;local _Mk=Mwhc.type | |
el(nCwsa.dependencies,{name=JmCzKm,version=A6z,type=_Mk})end;return nCwsa end | |
_AvO.getPackageSpec=function(_AvO,PXrrrSid) | |
Zg.info("Downloading package data for "..tostring(PXrrrSid).." ...") | |
local L9,_KZPScl=M6ilzGJ(_AvO.URL.."packages/"..PXrrrSid)if not(L9)then | |
Zg.fatal("HTTP request error: ".._KZPScl)end;local dbTwy="" | |
for Kj1I in _KZPScl do dbTwy=dbTwy..Kj1I end;local R4f819q=s:decode(dbTwy)if not(R4f819q)then | |
Zg.fatal("Incorrect JSON format!\n"..tostring(dbTwy))end;return R4f819q.data end | |
_AvO.rawInstall=function(_AvO,nTUMgqomA,Id5sIM,gZM2ANLt)if Id5sIM==nil then Id5sIM=false end | |
if gZM2ANLt==nil then gZM2ANLt=false end;local aC72qEnu | |
if gZM2ANLt then aC72qEnu=JQi1jg(u(),nTUMgqomA.name)else aC72qEnu="/"end | |
if gZM2ANLt and not tE(aC72qEnu)then local B60J,Y4=o5sms(aC72qEnu)if | |
not(B60J)then | |
Zg.fatal("Failed creating '"..tostring(aC72qEnu).. | |
"' directory for package '"..tostring(nTUMgqomA.name).. | |
"'! \n"..tostring(Y4))end elseif not | |
gZM2ANLt then local f=wjim8xCV(nTUMgqomA.name,nil,"hel") | |
if f then | |
if f.version== | |
tostring(nTUMgqomA.version)then | |
Zg.print("'".. | |
tostring(nTUMgqomA.name).."@"..tostring(f.version).. | |
"' is already installed, skipping...")return f else | |
Zg.fatal("'".. | |
tostring(nTUMgqomA.name).. | |
"@".. | |
tostring(nTUMgqomA.version).. | |
"' was attempted to install, however, another version of the same package is already installed: '"..tostring(nTUMgqomA.name).. | |
"@"..tostring(f.version).."'")end end end | |
for yeCnvcd6,Iq93c6cA in pairs(nTUMgqomA.files)do | |
Zg.info("Fetching '".. | |
tostring(Iq93c6cA.name).."' ...")local nsM0h=iPL3B4cr(Ta(Iq93c6cA.url)) | |
local Czi=JQi1jg(aC72qEnu,Iq93c6cA.dir) | |
if not tE(Czi)then local IlxN,EA_3x01A=o5sms(Czi)if not(IlxN)then | |
Zg.fatal("Failed to create '".. | |
tostring(Czi).. | |
"' directory for '".. | |
tostring(Iq93c6cA.name).."'! \n"..tostring(EA_3x01A))end end | |
do local m54tY2 | |
Iq93c6cA,m54tY2=io.open(JQi1jg(Czi,Iq93c6cA.name),"w")if not(Iq93c6cA)then | |
Zg.fatal("Could not open '".. | |
tostring(JQi1jg(Czi,Iq93c6cA.name)).."' for writing: "..tostring(m54tY2))end | |
Iq93c6cA:write(nsM0h)Iq93c6cA:close()end end;return | |
{name=nTUMgqomA.name,version=tostring(nTUMgqomA.version),files=nTUMgqomA.files,dependencies=nTUMgqomA.dependencies,manual=Id5sIM}end | |
_AvO.resolveDependencies=function(_AvO,WJWMdKI,AhbP,QHFgYUN,RoEsr7So)if AhbP==nil then AhbP={}end | |
if QHFgYUN==nil then QHFgYUN={}end;if RoEsr7So==nil then RoEsr7So={}end | |
for dX=1,#WJWMdKI do local Rz=WJWMdKI[dX]local j177r,j | |
j177r,j=Rz.name,Rz.version;local qCaFw=false | |
for syvPi=1,#AhbP do local NrgSK2=AhbP[syvPi]if NrgSK2.pkg.name==j177r then | |
qCaFw=true;break end end | |
if not(qCaFw)then el(QHFgYUN,{name=j177r,version=""}) | |
local wIH=wjim8xCV(j177r,nil,"hel") | |
if not wIH or | |
not j:match(YAtG_LV3.Version(wIH.version))then local TYWkpc=_AvO:getPackageSpec(j177r) | |
local k=_AvO:parsePackageJSON(TYWkpc,j)QHFgYUN[#QHFgYUN].version=k.version;local J=k.dependencies | |
for gtlO9=1,#J do | |
local Lun=J[gtlO9]qCaFw=false | |
for beUJXhjw=1,#AhbP do local zY7adu=AhbP[beUJXhjw]if | |
zY7adu.pkg.name==Lun.name then qCaFw=true;break end end | |
if not qCaFw then local Nlvw=nil;for K55,BJcMTdMi in pairs(QHFgYUN)do | |
if BJcMTdMi.name==Lun.name then Nlvw=K55;break end end | |
if Nlvw then | |
if QHFgYUN[Nlvw].version== | |
Lun.version then | |
Zg.fatal("Circular dependencies detected: '".. | |
tostring(j177r).. | |
"@".. | |
tostring(k.version).. | |
"' depends on '".. | |
tostring(Lun.name).. | |
"@".. | |
tostring(Lun.version).. | |
"', and '".. | |
tostring(QHFgYUN[Nlvw].name).. | |
"@"..tostring(QHFgYUN[Nlvw].version).. | |
"' depends on '"..tostring(j177r).."@".. | |
tostring(k.version).."'.")else | |
Zg.fatal("Attempted to install two versions of the same package: '".. | |
tostring(Lun.name).. | |
"@".. | |
tostring(Lun.version).. | |
"' and '".. | |
tostring(QHFgYUN[Nlvw].name).."@".. | |
tostring(QHFgYUN[Nlvw].version).."' when resolving dependencies for '"..tostring(j177r).. | |
"@"..tostring(k.version).."'.")end end | |
_AvO:resolveDependencies({{name=Lun.name,version=YAtG_LV3.Spec(Lun.version)}},AhbP,QHFgYUN,RoEsr7So)end end;el(AhbP,{pkg=k})el(RoEsr7So,{pkg=k})else | |
el(AhbP,{pkg=wIH})end;QHFgYUN[#QHFgYUN]=nil end end;return RoEsr7So end | |
_AvO.getPackageDependants=function(_AvO,f1MKKJ,nFf,EIqL41)if nFf==nil then nFf={}end | |
if EIqL41 ==nil then EIqL41={}end | |
for iv=1,#f1MKKJ do local rfmMR4=f1MKKJ[iv]local Tq2I=false;for GNo=1,#nFf do local e5x=nFf[GNo]if e5x.name==rfmMR4 then | |
Tq2I=true;break end end | |
if | |
not(Tq2I)then el(EIqL41,{name=rfmMR4}) | |
local QrONvWGq=wjim8xCV(rfmMR4,nil,"hel") | |
if QrONvWGq then el(nFf,{name=rfmMR4,manifest=QrONvWGq}) | |
local D94fnZaa=iPL3B4cr(w(JQi1jg(xSebv5Jc,"hel"))) | |
for XI in D94fnZaa do QrONvWGq=iPL3B4cr(wjim8xCV(XI,nil,"hel")) | |
local FNi=QrONvWGq.dependencies | |
for pRW2nEmK=1,#FNi do local OR=FNi[pRW2nEmK] | |
if OR.name==rfmMR4 then Tq2I=false | |
for Arww=1,#nFf do local BYH=nFf[Arww]if | |
BYH.name==XI then Tq2I=true;break end end | |
if not Tq2I then | |
for o7E8TLH=1,#EIqL41 do local N5N27Jd=EIqL41[o7E8TLH]if N5N27Jd.name==XI then | |
Zg.fatal( | |
"Circular dependencies detected: "..tostring(XI))end end;_AvO:getPackageDependants({XI},nFf,EIqL41)end end end end else | |
Zg.fatal("Package ".. | |
tostring(rfmMR4).." is referenced as a dependant of another package, however, this package isn't installed.")end;EIqL41[#EIqL41]=nil end end;return nFf end | |
_AvO.install=qTDt(function(_AvO,...) | |
if sgeP.l or sgeP["local"]then | |
local F4AWvI=pzDMZwG.resolve(...) | |
local GYVN=iPL3B4cr(wjim8xCV(F4AWvI,JQi1jg(F4AWvI,"manifest"))) | |
local DNlB1V=_AvO:resolveDependencies((function()local xNPDtul={}local k8=1;local HmgRk=GYVN.dependencies | |
for UuCdpVi=1,#HmgRk do | |
local fghe=HmgRk[UuCdpVi]local vFXf,CA0uX7n;vFXf,CA0uX7n=fghe.name,fghe.version | |
xNPDtul[k8]={name=vFXf,version=YAtG_LV3.Spec(CA0uX7n)}k8=k8+1 end;return xNPDtul end)())local erb6G_E=sgeP.d or sgeP.onlyDeps;local QFUU10K={}for ze5Vpc3=1,#DNlB1V do | |
local vwK8=DNlB1V[ze5Vpc3] | |
el(QFUU10K,tostring(vwK8.pkg.name).. | |
"@"..tostring(vwK8.pkg.version))end;if | |
not(erb6G_E)then | |
el(QFUU10K,tostring(GYVN.name).."@"..tostring(GYVN.version))end | |
h6Ub7U({install=QFUU10K}) | |
for Sk_SiC=1,#DNlB1V,1 do local X0bgPvA=DNlB1V[Sk_SiC] | |
Zg.print("Installing '".. | |
tostring(X0bgPvA.pkg.name).. | |
"@"..tostring(X0bgPvA.pkg.version).."'...")local M9CyqH=_AvO:rawInstall(X0bgPvA.pkg,false,false) | |
local z0x4qSAN,X0GTupeV=Ki1HJT(M9CyqH,"hel") | |
if z0x4qSAN then | |
Zg.info("Saved the manifest of '"..tostring(M9CyqH.name).."'.")else | |
Zg.fatal("Couldn't save the manifest of '"..tostring(M9CyqH.name).."': ".. | |
tostring(X0GTupeV)..".")end end | |
if not erb6G_E then | |
Zg.print("Installing '"..tostring(GYVN.name).."@".. | |
tostring(GYVN.version).."'...") | |
for Oc,IHovU in pairs(GYVN.files)do if | |
not tE(JQi1jg(IHovU.dir,IHovU.name))then o5sms(IHovU.dir)end | |
local e_wDQjk,ClglY=wVzn(JQi1jg(F4AWvI,IHovU.url),JQi1jg(IHovU.dir,IHovU.name))if not(e_wDQjk)then | |
Zg.fatal("Cannot copy file '"..tostring(IHovU.name).. | |
"': "..tostring(ClglY))end end;local rQ,k=Ki1HJT(GYVN,"hel") | |
if rQ then | |
Zg.info("Saved the manifest of '".. | |
tostring(GYVN.name).."'.")else | |
Zg.fatal("Couldn't save the manifest of '".. | |
tostring(GYVN.name).."': "..tostring(k)..".")end end;return true end;local m={}local nK={...} | |
for S=1,#nK do local NKetZhs=nK[S] | |
local EFLZ0N1,gL=NKetZhs:match("^(.+)@(.+)$")or NKetZhs;if N5UjTN(gL)then gL="*"end | |
Zg.info("Creating version specification for "..tostring(gL).." ...") | |
local m4,rNOL8G=pcall(function()return YAtG_LV3.Spec(gL)end)if not(m4)then | |
Zg.fatal("Could not parse the version specification: "..tostring(rNOL8G).."!")end | |
el(m,{name=EFLZ0N1,version=rNOL8G})end;local _zr=sgeP.r or sgeP.reinstall | |
local f5=sgeP.s or sgeP.save;local UAc=_AvO:resolveDependencies(m)local Ef={}local P={} | |
for q=1,#UAc do local lKO=false | |
repeat | |
local hcwgu=UAc[q] | |
if _zr then local omgCdqp8=false | |
for X17eHTx=1,#m do local SGF=m[X17eHTx]if SGF.name==hcwgu.pkg.name then | |
omgCdqp8=true;break end end;if omgCdqp8 then | |
el(Ef,tostring(hcwgu.pkg.name).. | |
"@"..tostring(hcwgu.pkg.version))lKO=true;break end end | |
el(P,tostring(hcwgu.pkg.name).. | |
"@"..tostring(hcwgu.pkg.version))lKO=true until true;if not lKO then break end end;h6Ub7U({install=P,reinstall=Ef}) | |
if _zr then local myIHU | |
do local xxNCdF={}local _cl1b=1;for Xz18nk=1,#m do | |
local PsTX4=m[Xz18nk] | |
xxNCdF[_cl1b]=iPL3B4cr(wjim8xCV(PsTX4.name,nil,"hel"))_cl1b=_cl1b+1 end | |
myIHU=xxNCdF end;_AvO:_remove(myIHU,true,false)end | |
for A0TJx=1,#UAc do local Nqdkw=UAc[A0TJx] | |
Zg.print("Installing '"..tostring(Nqdkw.pkg.name).."@".. | |
tostring(Nqdkw.pkg.version).."'...")local t=false;for o0pf=1,#m do local tx1LD=m[o0pf] | |
if tx1LD.name==Nqdkw.pkg.name then t=true;break end end | |
local QbMO=_AvO:rawInstall(Nqdkw.pkg,t,f5)local wYZ,aMd=Ki1HJT(QbMO,"hel") | |
if wYZ then | |
Zg.info("Saved the manifest of '".. | |
tostring(QbMO.name).."'.")else | |
Zg.fatal("Couldn't save the manifest of '"..tostring(QbMO.name).. | |
"': "..tostring(aMd)..".")end end end) | |
_AvO.remove=qTDt(function(_AvO,...)local N3ROeR={...}local I1oQVnUd={} | |
for oTX=1,#N3ROeR do local WZlF4=N3ROeR[oTX] | |
local IxqPDOWH=iPL3B4cr(wjim8xCV(WZlF4,nil,"hel"))el(I1oQVnUd,IxqPDOWH)end;return _AvO:_remove(I1oQVnUd,false)end) | |
_AvO._remove=function(_AvO,GZqV,OVubrDw_,G2_TeR8)if OVubrDw_==nil then OVubrDw_=false end;if G2_TeR8 ==nil then | |
G2_TeR8=true end;local yk | |
if not | |
RkGFh6.get("hel",{},true).get("remove_dependants",true)or not G2_TeR8 then | |
do | |
local OPSPMfr_={}local QnNOl=1;for aQs=1,#GZqV do local uow_0tb=GZqV[aQs] | |
OPSPMfr_[QnNOl]={name=uow_0tb.name,manifest=uow_0tb}QnNOl=QnNOl+1 end | |
yk=OPSPMfr_ end else | |
yk=_AvO:getPackageDependants((function()local tykg={}local C_pPyW=1;for mgb4b=1,#GZqV do local LOBqxO=GZqV[mgb4b] | |
tykg[C_pPyW]=LOBqxO.name;C_pPyW=C_pPyW+1 end;return tykg end)())end | |
if not(OVubrDw_)then | |
h6Ub7U({remove=(function()local m8={}local mcoAHO=1 | |
for d3gFWO=1,#yk do local D=yk[d3gFWO] | |
m8[mcoAHO]="hel:".. | |
tostring(D.manifest.name).."@"..tostring(D.manifest.version)mcoAHO=mcoAHO+1 end;return m8 end)()})end | |
for obodPKnu=1,#yk do local kgdzk=yk[obodPKnu] | |
Zg.print("Removing '"..tostring(kgdzk.manifest.name).. | |
"@"..tostring(kgdzk.manifest.version).."' ...") | |
iPL3B4cr(R60Ru4bj.__parent.remove(_AvO,kgdzk.manifest,"hel"))end;return true end | |
_AvO.upgrade=qTDt(function(_AvO)local oVSp={} | |
for uKSj in iPL3B4cr(w(JQi1jg(xSebv5Jc,"hel")))do if not | |
(XPoQB(JQi1jg(xSebv5Jc,"hel",uKSj)))then | |
el(oVSp,iPL3B4cr(wjim8xCV(uKSj,nil,"hel")))end end;local uBJ={} | |
for YXgXQB=1,#oVSp do local bvL1X4=oVSp[YXgXQB] | |
local PPNahh,z2g=pcall(_AvO.getPackageSpec,_AvO,bvL1X4.name) | |
if PPNahh then local m9JTkVv6=_AvO:parsePackageJSON(z2g) | |
bvL1X4.latest={spec=z2g,data=m9JTkVv6} | |
if YAtG_LV3.Version(bvL1X4.latest.data.version)> | |
YAtG_LV3.Version(bvL1X4.version)then el(uBJ,bvL1X4)end end end | |
local A=_AvO:resolveDependencies((function()local Q={}local bWkP=1;for JtFj=1,#uBJ do local PQ3=uBJ[JtFj] | |
Q[bWkP]={name=PQ3.name,version=YAtG_LV3.Spec(PQ3.latest.data.version)}bWkP=bWkP+1 end;return | |
Q end)())local MP | |
do local _xCtN={}local JVpe=1 | |
for nG36XmZC=1,#uBJ do local Vf26=uBJ[nG36XmZC] | |
_xCtN[JVpe]= | |
tostring(Vf26.name).."@{".. | |
tostring(Vf26.version).." => ".. | |
tostring(Vf26.latest.data.version).."}"JVpe=JVpe+1 end;MP=_xCtN end;local jb={} | |
for xUGt=1,#A do local _U=A[xUGt]local hkI39=true | |
for MwwN=1,#uBJ do local oZ9=uBJ[MwwN]if | |
oZ9.name==_U.pkg.name then hkI39=false;break end end;if hkI39 then | |
el(jb,tostring(_U.pkg.name).."@"..tostring(_U.pkg.version))end end;h6Ub7U({upgrade=MP,install=jb}) | |
for OXlT0=1,#A do local V=A[OXlT0] | |
local zIYNIXy1=false;local c=false | |
for nqBfKL=1,#uBJ do local gs3a=uBJ[nqBfKL]if gs3a.name==V.pkg.name then zIYNIXy1=gs3a | |
c=gs3a.manual;break end end | |
if zIYNIXy1 then _AvO:_remove({zIYNIXy1},true,false)end | |
Zg.print("Installing '"..tostring(V.pkg.name).."@".. | |
tostring(V.pkg.version).."'...")local mReHt4h=_AvO:rawInstall(V.pkg,c,false) | |
local I7,Upw=Ki1HJT(mReHt4h,"hel") | |
if I7 then | |
Zg.info("Saved the manifest of '"..tostring(mReHt4h.name).."'.")else | |
Zg.fatal("Couldn't save the manifest of '"..tostring(mReHt4h.name).. | |
"': "..tostring(Upw)..".")end end end) | |
_AvO.info=qTDt(function(_AvO,AkKaBC,OmRH8)if OmRH8 ==nil then OmRH8="*"end;if N5UjTN(AkKaBC)then | |
Zg.fatal("Usage: hpm hel:info <package name> [<version specification>]")end | |
if N5UjTN(OmRH8)then OmRH8="*"end | |
Zg.print("Creating version specification for "..tostring(OmRH8).." ...") | |
local GY,oukM79R=pcall(function()return YAtG_LV3.Spec(OmRH8)end)if not(GY)then | |
Zg.fatal("Could not parse the version specification: "..tostring(oukM79R).."!")end | |
local D_j=_AvO:getPackageSpec(AkKaBC)local mZPe4w=_AvO:parsePackageJSON(D_j,oukM79R)local OvZ={} | |
el(OvZ, | |
"- Package name: "..tostring(D_j.name)) | |
el(OvZ,"- Description:\n"..tostring(D_j.description)) | |
el(OvZ,"- Package owners: "..tostring(table.concat(D_j.owners,", "))) | |
el(OvZ,"- Authors:\n".. | |
tostring(table.concat((function()local cBOpf={}local KZYA5y=1;local YoCAN7OU=D_j.authors;for FoP=1,#YoCAN7OU do | |
local jqtWXY=YoCAN7OU[FoP]cBOpf[KZYA5y]=" - "..tostring(jqtWXY) | |
KZYA5y=KZYA5y+1 end;return cBOpf end)(),"\n"))) | |
el(OvZ,"- License: "..tostring(D_j.license)) | |
el(OvZ,"- Versions: "..tostring(O(D_j.versions))..", latest: ".. | |
tostring(mZPe4w.version)) | |
el(OvZ," - Files: "..tostring(#mZPe4w.files)) | |
el(OvZ," - Depends: ".. | |
tostring(table.concat((function()local XgRb={}local G3e=1;local GoP6=mZPe4w.dependencies;for cZ_=1,#GoP6 do | |
local NYc8=GoP6[cZ_] | |
XgRb[G3e]=tostring(NYc8.name).."@"..tostring(NYc8.version)G3e=G3e+1 end;return XgRb end)()))) | |
el(OvZ," - Changes:\n".. | |
tostring(D_j.versions[mZPe4w.version].changes))el(OvZ,"- Stats:") | |
el(OvZ," - Views: "..tostring(D_j.stats.views)) | |
el(OvZ,"- Creation date: ".. | |
tostring(D_j.stats.date.created).." UTC") | |
el(OvZ,"- Last updated: ".. | |
tostring(D_j.stats.date["last-updated"]).." UTC")return Zg.print(table.concat(OvZ,"\n"))end) | |
_AvO.search=qTDt(function(_AvO,...)local Dff8=0 | |
while true do local lEYwsOG9={}local M=_AvO.URL.."packages" | |
if...then | |
M=M.. | |
("?q=".. | |
table.concat((function(...) | |
local N={}local v9mB_RUi=1;local hX={...}for AVU=1,#hX do local I=hX[AVU] | |
N[v9mB_RUi]='"'..I:gsub("\"","")..'"'v9mB_RUi=v9mB_RUi+1 end;return N end)(...)," "):gsub("&",""))end;M=M.."?offset="..tostring(Dff8) | |
local Vt95q2G,jsPbwU=M6ilzGJ(M)if not(Vt95q2G)then | |
Zg.fatal("HTTP request error: "..jsPbwU)end;local Wvs3rd6o="" | |
for _x5O1 in jsPbwU do Wvs3rd6o=Wvs3rd6o.._x5O1 end;local UdVlP=s:decode(Wvs3rd6o)if not(UdVlP)then | |
Zg.fatal("Incorrect JSON format!\n".. | |
tostring(Wvs3rd6o))end;lEYwsOG9=UdVlP.data.list;for eFI8dI3=1,#lEYwsOG9 | |
do local i=lEYwsOG9[eFI8dI3] | |
Zg.print(tostring(i.name)..": ".. | |
tostring(i.short_description))end | |
if | |
#lEYwsOG9 ==0 and Dff8 ==0 then Zg.print("No packages found.")break end | |
if UdVlP.data.truncated and UdVlP.data.sent+UdVlP.data.offset< | |
UdVlP.data.total then Dff8= | |
UdVlP.data.offset+UdVlP.data.sent else break end end end) | |
if eQWRf.__inherited then eQWRf.__inherited(eQWRf,R60Ru4bj)end;_.hel=R60Ru4bj end | |
do local l6xUetCb;local lOb_Sv=_.default;local VspvGB9V={}VspvGB9V.__index=VspvGB9V | |
setmetatable(VspvGB9V,lOb_Sv.__base) | |
l6xUetCb=setmetatable({__init=function(GfB7,...) | |
return l6xUetCb.__parent.__init(GfB7,...)end,__base=VspvGB9V,__name="oppm",__parent=lOb_Sv},{__index=function(Iz_w1j,G) | |
local X7YKzX=rawget(VspvGB9V,G)if X7YKzX==nil then local od0VOF=rawget(Iz_w1j,"__parent") | |
if od0VOF then return od0VOF[G]end else return X7YKzX end end,__call=function(oO6SbZ,...) | |
local UE_vrsNx=setmetatable({},VspvGB9V)oO6SbZ.__init(UE_vrsNx,...)return UE_vrsNx end})VspvGB9V.__class=l6xUetCb;local LrFLp5=l6xUetCb | |
LrFLp5.REPOS="https://raw.githubusercontent.com/OpenPrograms/openprograms.github.io/master/repos.cfg" | |
LrFLp5.PACKAGES="https://raw.githubusercontent.com/%s/master/programs.cfg"LrFLp5.FILES="https://raw.githubusercontent.com/%s/%s" | |
LrFLp5.DIRECTORY="https://api.github.com/repos/%s/contents/%s?ref=%s"LrFLp5.DEFAULT_CACHE_FILE="/var/cache/hpm/oppm" | |
LrFLp5.cacheFile=function(LrFLp5) | |
local kef2zBS=RkGFh6.get("oppm",{},true).get("cache_file",LrFLp5.DEFAULT_CACHE_FILE) | |
if not(tE(pE.path(kef2zBS)))then | |
local Z,ze0=o5sms(pE.path(kef2zBS))if not(Z)then | |
Zg.fatal("Could not create the cache directory at "..tostring(pE.path(kef2zBS))..": ".. | |
tostring(ze0))end end | |
if not(VcV0EuD(kef2zBS))then local ylW3uC0,N_G1=io.open(kef2zBS,"w")if not | |
(ylW3uC0)then | |
Zg.fatal("Could not open '".. | |
tostring(kef2zBS).."' for writing: "..tostring(N_G1))end | |
ylW3uC0:write("{}")ylW3uC0:close()end;return kef2zBS end | |
LrFLp5.listCache=function(LrFLp5)local wkGNE;local ccK=LrFLp5:cacheFile() | |
do | |
local BV,HnLY=io.open(ccK,"r")if not(BV)then | |
return false,"Could not open '".. | |
tostring(ccK).."' for reading: "..tostring(HnLY)end | |
qLH5=BV:read("*all")wkGNE,HnLY=QJf(qLH5)if not(wkGNE)then return false, | |
"Cache is malformed: "..tostring(HnLY)end | |
BV:close()end;return wkGNE end | |
LrFLp5.resolveDirectory=function(LrFLp5,cm51CH1n,iWrSgT,C) | |
local YK1=iPL3B4cr(Ta(LrFLp5.DIRECTORY:format(cm51CH1n,C,iWrSgT)))YK1=s:decode(YK1)if YK1.message then | |
return false,"Could not fetch ".. | |
tostring(cm51CH1n)..":"..tostring(iWrSgT).. | |
"/"..tostring(C)..": "..tostring(YK1.message)end | |
local t96Qtz={}local HjKNi=1 | |
for Ub9iqg=1,#YK1 do local r_S8HFRo=YK1[Ub9iqg] | |
if r_S8HFRo.type=="file"then | |
t96Qtz[HjKNi]={name=r_S8HFRo.name,url=r_S8HFRo.download_url,path=r_S8HFRo.path}HjKNi=HjKNi+1 end end;return t96Qtz end | |
LrFLp5.updateCache=function(LrFLp5)local qIF4RFBv=LrFLp5:cacheFile() | |
local wNbC65Ta=iPL3B4cr(LrFLp5:listCache())local xOiPW,Z9j=Ta(LrFLp5.REPOS) | |
if not(xOiPW)then return false, | |
"Could not fetch ".. | |
tostring(LrFLp5.REPOS)..": "..tostring(Z9j)end;xOiPW=QJf(xOiPW)local r={} | |
for lOpDJ,YLe in pairs(xOiPW)do local lTH=false | |
repeat | |
if YLe.repo then | |
Zg.info("Fetching '".. | |
tostring(lOpDJ).."' at '"..tostring(YLe.repo).."' ...")local JL,FpU_E | |
JL,FpU_E,Z9j=M6ilzGJ(LrFLp5.PACKAGES:format(YLe.repo)) | |
if not(JL and FpU_E)then | |
Zg.error("Could not fetch '".. | |
tostring(lOpDJ).."' at '".. | |
tostring(YLe.repo).."': "..tostring(Z9j))lTH=true;break end;local JWtwnQ2t="" | |
for JL,aYO4NN in function()return pcall(FpU_E)end do | |
if not JL then | |
Zg.error("Could not fetch '".. | |
tostring(lOpDJ).. | |
"' at '"..tostring(YLe.repo).."': "..tostring(aYO4NN))JWtwnQ2t=false;break else if not aYO4NN then break end;JWtwnQ2t=JWtwnQ2t..aYO4NN end end;if JWtwnQ2t==false then lTH=true;break end;if N5UjTN(JWtwnQ2t)then | |
Zg.error("Could not fetch '".. | |
tostring(lOpDJ).."' at '"..tostring(YLe.repo).."'")lTH=true;break end | |
local uEKPPpj_;uEKPPpj_,Z9j=QJf(JWtwnQ2t) | |
if not uEKPPpj_ then | |
Zg.error("Manifest '"..tostring(lOpDJ).. | |
"' at '".. | |
tostring(YLe.repo).."' is malformed: "..tostring(Z9j))lTH=true;break end | |
for CtG9nSQL,uZtK5yX in pairs(uEKPPpj_)do local kr2CYaS=false | |
repeat | |
if CtG9nSQL:match("[^A-Za-z0-9._-]")then | |
Zg.error( | |
"Package name contains illegal characters: ".. | |
tostring(lOpDJ)..":"..tostring(CtG9nSQL).."!")kr2CYaS=true;break end | |
el(r,{repo=YLe.repo,name=CtG9nSQL,data=uZtK5yX})kr2CYaS=true until true;if not kr2CYaS then break end end end;lTH=true until true;if not lTH then break end end;local OnJ1={}local KFU0={} | |
for hXgSzEI=1,#r do local AUQ=r[hXgSzEI]local B,J,coSiE | |
B,J,coSiE=AUQ.name,AUQ.repo,AUQ.data;if n(JQi1jg(J,B),OnJ1)then | |
Zg.error("There're multiple packages under the same name: "..tostring(B).."!")end | |
el(KFU0,{pkg=B,repo=J,data={name=B,repo=J,data=coSiE}})local wm | |
do for _O,smj in pairs(wNbC65Ta)do | |
if smj.repo==J and smj.pkg==B then wm=_O;break end end end | |
if wm then table.remove(wNbC65Ta,wm)else el(OnJ1,JQi1jg(J,B))end end;local Pvuq;Pvuq,Z9j=io.open(qIF4RFBv,"w") | |
if not(Pvuq)then return false, | |
"Could not open '".. | |
tostring(qIF4RFBv).."' for writing: "..tostring(Z9j)end | |
do Pvuq:write(RSjapQ(KFU0))Pvuq:close()end | |
Zg.print("- "..tostring(#r).. | |
" program"..tostring(pX4gCR(#r)).." cached.") | |
Zg.print("- "..tostring(#OnJ1).. | |
" package"..tostring(pX4gCR(#OnJ1)).." ".. | |
tostring(dk(#OnJ1)).." new.") | |
Zg.print("- "..tostring(#wNbC65Ta).. | |
" package"..tostring(pX4gCR(#wNbC65Ta)).. | |
" no longer exist"..tostring(gad4ZcL(#wNbC65Ta))..".")return true end | |
LrFLp5.parseLocalPath=function(LrFLp5,obBu,cbQlG) | |
if cbQlG:sub(1,2)=="//"then | |
return JQi1jg(obBu,cbQlG:sub(3))else return JQi1jg(obBu,"usr",cbQlG)end end | |
LrFLp5.rawInstall=function(LrFLp5,YZQu1DR4,kza,CvGDk_2,EGpun)if kza==nil then kza="/"end | |
if CvGDk_2 ==nil then CvGDk_2=false end;if EGpun==nil then EGpun=false end;local LNlhK=LrFLp5:listCache() | |
local cnx_1g={filesInstalled=0,packagesInstalled=0} | |
if EGpun and not tE(kza)then local k6,m=o5sms(kza)if not(k6)then | |
Zg.fatal("Failed to create '".. | |
tostring(kza).. | |
"' directory for package '"..tostring(YZQu1DR4).."'! \n"..tostring(m))end elseif not EGpun then local rvNhq6v=wjim8xCV(YZQu1DR4, | |
nil,"oppm")if rvNhq6v then | |
Zg.print("'"..tostring(YZQu1DR4).. | |
"' is already installed, skipping...")return rvNhq6v,cnx_1g end end;local eV | |
for gC=1,#LNlhK do local QO=LNlhK[gC]local VvzMQHj,fSYJX,WV | |
VvzMQHj,fSYJX,WV=QO.pkg,QO.repo,QO.data;if VvzMQHj==YZQu1DR4 then eV=QO;break end end;if not(eV)then | |
Zg.fatal("No such package: "..tostring(YZQu1DR4))end;local DGQnw={}local yLgHuF=eV.repo | |
for yUho4MXRx,J2 in | |
pairs(eV.data.data.files)do local hgrBfz0w={} | |
if yUho4MXRx:sub(1,1)==":"then | |
hgrBfz0w=LrFLp5:resolveDirectory(yLgHuF,yUho4MXRx:sub(2, | |
yUho4MXRx:find("/")-1,nil),yUho4MXRx:sub(yUho4MXRx:find("/")+1))else | |
hgrBfz0w={{name=pE.name(yUho4MXRx),path=yUho4MXRx,url=LrFLp5.FILES:format(yLgHuF,yUho4MXRx)}}end;local YZQu1DR4 | |
for Gi=1,#hgrBfz0w do local wpv1=hgrBfz0w[Gi]local I9IMuWm,a | |
YZQu1DR4,I9IMuWm,a=wpv1.name,wpv1.path,wpv1.url;local rZ=iPL3B4cr(Ta(a)) | |
local VKTNfzUf=LrFLp5:parseLocalPath(kza,J2)if not(tE(VKTNfzUf))then o5sms(VKTNfzUf)end | |
do | |
local Oms4,JfA=io.open(JQi1jg(VKTNfzUf,YZQu1DR4),"w")if not Oms4 then | |
Zg.fatal("Could not open file for writing: "..tostring(JfA))end;Oms4:write(rZ) | |
Oms4:close()end;cnx_1g.filesInstalled=cnx_1g.filesInstalled+1 | |
el(DGQnw,{name=YZQu1DR4,url=a,dir=VKTNfzUf})end end;local fpL={} | |
if eV.data.data.dependencies then for CPu1 in pairs(eV.data.data.dependencies)do | |
el(fpL,{name=CPu1})end end;cnx_1g.packagesInstalled=cnx_1g.packagesInstalled+1;return | |
{name=YZQu1DR4,files=DGQnw,dependencies=fpL,manual=CvGDk_2},cnx_1g end | |
LrFLp5.resolveDependencies=function(LrFLp5,pfyhF,pglFz82w,RkeCL,LoW_7e)if pglFz82w==nil then pglFz82w={}end | |
if RkeCL==nil then RkeCL={}end;if LoW_7e==nil then LoW_7e={}end;local mLgQ=LrFLp5:listCache() | |
for ng=1,#pfyhF do | |
local Pp_NboV=pfyhF[ng]local owAp3u2G=false | |
for OH0C=1,#pglFz82w do local kmQkm9cr=pglFz82w[OH0C]if kmQkm9cr==Pp_NboV then | |
owAp3u2G=true;break end end | |
if not(owAp3u2G)then RkeCL[Pp_NboV]=true | |
local IE97m=wjim8xCV(Pp_NboV,nil,"oppm") | |
if not IE97m then local wey | |
for hThO6=1,#mLgQ do local zXU=mLgQ[hThO6]local HmJym2;HmJym2=zXU.pkg;if HmJym2 ==Pp_NboV then | |
wey=zXU;break end end;if not(wey)then | |
return false,"Unknown package: "..tostring(Pp_NboV)end | |
if wey.data.data.dependencies then | |
for Jjb7Am5 in | |
pairs(wey.data.data.dependencies)do owAp3u2G=false;for UwqY7A=1,#pglFz82w do local k=pglFz82w[UwqY7A] | |
if k==Jjb7Am5 then owAp3u2G=true;break end end | |
if not(owAp3u2G)then | |
if | |
RkeCL[Jjb7Am5]then | |
Zg.fatal("Circular dependencies detected: '".. | |
tostring(Pp_NboV).."' depends on '".. | |
tostring(Jjb7Am5).."', and '".. | |
tostring(Jjb7Am5).."' depends on '"..tostring(Pp_NboV).."'.")end | |
LrFLp5:resolveDependencies({Jjb7Am5},pglFz82w,RkeCL,LoW_7e)end end end;el(LoW_7e,Pp_NboV)end;el(pglFz82w,Pp_NboV)RkeCL[Pp_NboV]=nil end end;return LoW_7e end | |
LrFLp5.getPackageDependants=function(LrFLp5,d7gPKcw,naeNp,gA)if naeNp==nil then naeNp={}end;if gA==nil then gA={}end | |
for r=1,#d7gPKcw | |
do local LWe=d7gPKcw[r]local _3Tq=false;for Rq1hByv=1,#naeNp do local iFk=naeNp[Rq1hByv]if iFk.name==LWe then | |
_3Tq=true;break end end | |
if | |
not(_3Tq)then el(gA,{name=LWe})local sEFtmNgB=wjim8xCV(LWe,nil,"oppm") | |
if sEFtmNgB then | |
el(naeNp,{name=LWe,manifest=sEFtmNgB}) | |
local qxiez0Cn=iPL3B4cr(w(JQi1jg(xSebv5Jc,"oppm"))) | |
for Ck_H in qxiez0Cn do sEFtmNgB=iPL3B4cr(wjim8xCV(Ck_H,nil,"oppm")) | |
local Sc=sEFtmNgB.dependencies | |
for _QFw_It=1,#Sc do local WLqHf=Sc[_QFw_It] | |
if WLqHf.name==LWe then _3Tq=false | |
for vN=1,#naeNp do | |
local BIwW6_=naeNp[vN]if BIwW6_.name==Ck_H then _3Tq=true;break end end | |
if not _3Tq then | |
for Vdfc3=1,#gA do local CzM7PG=gA[Vdfc3]if CzM7PG.name==Ck_H then | |
Zg.fatal("Circular dependencies detected: ".. | |
tostring(Ck_H))end end;LrFLp5:getPackageDependants({Ck_H},naeNp,gA)end end end end else | |
Zg.fatal("Package ".. | |
tostring(LWe).." is referenced as a dependant of another package, however, this package isn't installed.")end;gA[#gA]=nil end end;return naeNp end | |
LrFLp5.whatDependsOn=function(LrFLp5,RKf6s5) | |
local tP9E_=iPL3B4cr(wjim8xCV(RKf6s5,nil,"oppm"))local Y1WX={} | |
local G06Z2=iPL3B4cr(w(JQi1jg(xSebv5Jc,"oppm"))) | |
for K in G06Z2 do tP9E_=iPL3B4cr(wjim8xCV(K,nil,"oppm")) | |
local tQx9TV=tP9E_.dependencies;for FL7g2o=1,#tQx9TV do local dkh7Tt9=tQx9TV[FL7g2o] | |
if dkh7Tt9.name==RKf6s5 then el(Y1WX,K)end end end;return Y1WX end | |
LrFLp5.install=qTDt(function(LrFLp5,...)local XiNd_H={...}local Q_c4px86=sgeP.r or sgeP.reinstall;local _F6VYt= | |
sgeP.s or sgeP.save | |
local ITv3PH1i=iPL3B4cr(LrFLp5:resolveDependencies(XiNd_H)) | |
h6Ub7U({install=(function()local OUQqQp={}local OyOfzTWn=1 | |
for rx=1,#ITv3PH1i do local ijvSrZA1=ITv3PH1i[rx]if not Q_c4px86 or not | |
n(ijvSrZA1,XiNd_H)then OUQqQp[OyOfzTWn]=ijvSrZA1 | |
OyOfzTWn=OyOfzTWn+1 end end;return OUQqQp end)(),reinstall= | |
Q_c4px86 and | |
(function()local STNuSN6={}local PYOeGnAZ=1 | |
for s10ar5XH=1,#ITv3PH1i do local YoKhvIs=ITv3PH1i[s10ar5XH]if n(YoKhvIs,XiNd_H)then | |
STNuSN6[PYOeGnAZ]=YoKhvIs;PYOeGnAZ=PYOeGnAZ+1 end end;return STNuSN6 end)()or nil})local _5fF={filesInstalled=0,packagesInstalled=0} | |
if Q_c4px86 then local I2ipE | |
do local qS730I={}local PYEbnua=1 | |
for Um4ZYiT=1,#XiNd_H | |
do local AF=XiNd_H[Um4ZYiT] | |
qS730I[PYEbnua]=iPL3B4cr(wjim8xCV(AF,nil,"oppm"))PYEbnua=PYEbnua+1 end;I2ipE=qS730I end;LrFLp5:_remove(I2ipE,true,false)end | |
for shIHW=1,#ITv3PH1i do local H5=ITv3PH1i[shIHW] | |
Zg.print("Installing '"..tostring(H5).."'...")local HYY | |
if _F6VYt then HYY="./"..tostring(H5).."/"else HYY="/"end | |
local C3,SkCMMH=LrFLp5:rawInstall(H5,HYY,n(H5,XiNd_H),_F6VYt) | |
_5fF.filesInstalled=_5fF.filesInstalled+SkCMMH.filesInstalled | |
_5fF.packagesInstalled=_5fF.packagesInstalled+SkCMMH.packagesInstalled | |
if _5fF.packagesInstalled~=0 then local kvvs,_yTx3S94=Ki1HJT(C3,"oppm") | |
if kvvs then | |
Zg.info( | |
"Saved the manifest of '"..tostring(C3.name).."'.")else | |
Zg.fatal("Couldn't save the manifest of '"..tostring(C3.name).. | |
"': "..tostring(_yTx3S94)..".")end end end | |
Zg.print("- ".. | |
tostring(_5fF.packagesInstalled).." package".. | |
tostring(pX4gCR(_5fF.packagesInstalled)).." installed.")return | |
Zg.print("- ".. | |
tostring(_5fF.filesInstalled).." file".. | |
tostring(pX4gCR(_5fF.filesInstalled)).." installed.")end) | |
LrFLp5.remove=qTDt(function(LrFLp5,...)local Mm={...}local g524={} | |
for WUdVeYc=1,#Mm do local lHep6wo=Mm[WUdVeYc] | |
local BKZsJ=iPL3B4cr(wjim8xCV(lHep6wo,nil,"oppm"))el(g524,BKZsJ)end;return LrFLp5:_remove(g524,false)end) | |
LrFLp5._remove=function(LrFLp5,Sw,W67mm9p6,oBxdTi6u)if W67mm9p6 ==nil then W67mm9p6=false end;if oBxdTi6u==nil then | |
oBxdTi6u=true end;local T7hLe5j | |
if | |
not | |
RkGFh6.get("oppm",{},true).get("remove_dependants",true)or not oBxdTi6u then | |
do local I_={}local J2Jin=1;for Rvg=1,#Sw do local HpdA=Sw[Rvg] | |
I_[J2Jin]={name=HpdA.name,manifest=HpdA}J2Jin=J2Jin+1 end;T7hLe5j=I_ end else | |
T7hLe5j=LrFLp5:getPackageDependants((function()local DsAJbW={}local AXfX=1;for btcUUhB=1,#Sw do local iw0S=Sw[btcUUhB] | |
DsAJbW[AXfX]=iw0S.name;AXfX=AXfX+1 end;return DsAJbW end)())end | |
if not(W67mm9p6)then | |
h6Ub7U({remove=(function()local Tjg={}local n2srE7H=1;for Rf=1,#T7hLe5j do local X9ZjrTz=T7hLe5j[Rf] | |
Tjg[n2srE7H]=tostring(X9ZjrTz.name)n2srE7H=n2srE7H+1 end | |
return Tjg end)()})end | |
for tYFIuD=1,#T7hLe5j do local Ht5Ge=T7hLe5j[tYFIuD] | |
Zg.print("Removing '".. | |
tostring(Ht5Ge.manifest.name).."' ...") | |
iPL3B4cr(l6xUetCb.__parent.remove(LrFLp5,Ht5Ge.manifest,"oppm"))end;return true end | |
LrFLp5.cache=qTDt(function(LrFLp5,l,...)local IO=l | |
if"update"==IO then | |
Zg.print("Updating OpenPrograms program cache ...")iPL3B4cr(LrFLp5:updateCache()) | |
return Zg.print("Done.")else Zg.error("Unknown command.")return | |
Zg.print("Usage: hpm oppm:cache update")end end) | |
LrFLp5.autoremove=qTDt(function(LrFLp5)local YDJY={}local t={} | |
local Rdi8NIft=iPL3B4cr(w(JQi1jg(xSebv5Jc,"oppm"))) | |
for J0uTkQ9 in Rdi8NIft do | |
local sd6k=iPL3B4cr(wjim8xCV(J0uTkQ9,nil,"oppm")) | |
if not(sd6k.manual)then | |
local a=LrFLp5:getPackageDependants(J0uTkQ9)if#a==1 then el(YDJY,J0uTkQ9)el(t,J0uTkQ9)end end end | |
while true do local lK7=false | |
Rdi8NIft=iPL3B4cr(w(JQi1jg(xSebv5Jc,"oppm"))) | |
for KWMxs7a in Rdi8NIft do | |
if not(n(KWMxs7a,YDJY))then | |
local T=iPL3B4cr(wjim8xCV(KWMxs7a,nil,"oppm")) | |
if not(T.manual)then | |
local LBIp4=LrFLp5:getPackageDependants(KWMxs7a)table.remove(LBIp4,1) | |
if | |
qLH5((function()local A5={}local PV168s0f=1 | |
for bjK=1,#LBIp4 do | |
local Us1Xh=LBIp4[bjK]A5[PV168s0f]=n(Us1Xh.name,YDJY)PV168s0f=PV168s0f+1 end;return A5 end)())then for rs59=1,#LBIp4 do local R=LBIp4[rs59]local rGa2MaGH,i6=n(R.name,t)if i6 then | |
table.remove(t,i6)end end | |
el(YDJY,KWMxs7a)el(t,KWMxs7a)lK7=true end end end end;if not(lK7)then break end end | |
h6Ub7U({remove=(function() | |
if#YDJY>0 then local u33wPQT={}local aNrMnPZ=1 | |
for fC=1,#YDJY do local Kl=YDJY[fC]u33wPQT[aNrMnPZ]="oppm:".. | |
tostring(Kl)aNrMnPZ=aNrMnPZ+1 end;return u33wPQT else return nil end end)()})for EmJGBwA=1,#t do local _E3=t[EmJGBwA] | |
LrFLp5:_remove({iPL3B4cr(wjim8xCV(_E3,nil,"oppm"))},false)end | |
Zg.print("Done.")return true end) | |
LrFLp5.search=qTDt(function(LrFLp5,...)local j3=iPL3B4cr(LrFLp5:listCache())local f={} | |
if | |
...then | |
for jy=1,#j3 do local Ifev2bUE=j3[jy]local ZY;ZY=Ifev2bUE.data;local KCpJbzHT=ZY.data;local g={...} | |
for dQl0xvy2=#g,1,-1 do | |
local hX=g[dQl0xvy2] | |
if ZY.name:find(hX)then table.remove(g,dQl0xvy2)break end;if KCpJbzHT.name and KCpJbzHT.name:find(hX)then | |
table.remove(g,dQl0xvy2)break end | |
if KCpJbzHT.description and | |
KCpJbzHT.description:find(hX)then table.remove(g,dQl0xvy2)break end;if KCpJbzHT.note and KCpJbzHT.note:find(hX)then | |
table.remove(g,dQl0xvy2)break end end;if#g==0 then el(f,ZY)end end else do local wYTrvPn={}local pB6K=1 | |
for YV=1,#j3 do local zPm=j3[YV]wYTrvPn[pB6K]=zPm.data;pB6K=pB6K+1 end;f=wYTrvPn end end | |
for JmEyZ5=1,#f do local FGvy=f[JmEyZ5] | |
Zg.print(tostring(FGvy.name).." - ".. | |
tostring(FGvy.data.name or FGvy.name)..": "..tostring(FGvy.data.description))end end) | |
LrFLp5.info=qTDt(function(LrFLp5,KpnA)if N5UjTN(KpnA)then | |
Zg.fatal("Usage: hpm oppm:info <package name>")end;local j_F9c=LrFLp5:listCache() | |
local q=nil;for b7G0ciz=1,#j_F9c do local rF2te=j_F9c[b7G0ciz] | |
if rF2te.pkg==KpnA then q=rF2te;break end end;if not(q)then | |
Zg.fatal("No such package.")end | |
Zg.print("- Package name: "..tostring(q.pkg))if q.data.data.name then | |
Zg.print(" "..tostring(q.data.data.name))end;if q.data.data.description then | |
Zg.print( | |
"- Description:\n"..tostring(q.data.data.description))end;if q.data.data.authors then | |
Zg.print( | |
"- Authors:\n"..tostring(q.data.data.authors))end;if q.data.data.files then | |
Zg.print("- Files: ".. | |
tostring(O(q.data.data.files)))end | |
if q.data.data.dependencies then | |
Zg.print( | |
"- Depends: ".. | |
tostring(table.concat((function()local KG_EjN={}local aIrjXeB=1;for sZdri in pairs(q.data.data.dependencies)do | |
KG_EjN[aIrjXeB]=sZdri;aIrjXeB=aIrjXeB+1 end;return KG_EjN end)())))end;if q.data.data.note then | |
Zg.print("- Note:\n"..tostring(q.data.data.note))end | |
return Zg.print("- Repository: https://github.com/".. | |
tostring(q.repo))end) | |
if lOb_Sv.__inherited then lOb_Sv.__inherited(lOb_Sv,l6xUetCb)end;_.oppm=l6xUetCb end;local Gm | |
Gm=function()local pT=iPL3B4cr(w(xSebv5Jc))N5UjTN=true | |
for XgkgIR9 in pT do | |
local sm2=pE.name(XgkgIR9) | |
if XPoQB(JQi1jg(xSebv5Jc,sm2))then | |
local cz=iPL3B4cr(w(JQi1jg(xSebv5Jc,sm2))) | |
for pSL in cz do | |
if | |
not(XPoQB(JQi1jg(xSebv5Jc,sm2,pSL)))then local ifrP9=iPL3B4cr(wjim8xCV(pSL,nil,sm2)) | |
Zg.print(sm2 ..":"..pSL.. | |
( | |
ifrP9.version and" @ "..ifrP9.version or""))N5UjTN=false end end end end | |
if N5UjTN then return Zg.print("No packages installed.")end end;local YKA7cU | |
YKA7cU=function(...)CM,sgeP=JD(...)if#CM<1 then return y36Aetn()end end;local mCsewfX | |
mCsewfX=function()local Iynmp=CM[1] | |
if"list"==Iynmp then return Gm()elseif"help"==Iynmp then return y36Aetn()else | |
do | |
local PFvHX=wZdg(CM[1]) | |
if PFvHX then return | |
PFvHX(Wu_uIt((function()local sP={}local Y=1 | |
for QHxdp58D=2,#CM do local efdknL=CM[QHxdp58D]sP[Y]=efdknL;Y=Y+1 end;return sP end)()))end end end end | |
hw18.semver={Version=YAtG_LV3.Version,Spec=YAtG_LV3.Spec,SpecItem=YAtG_LV3.SpecItem,compare=YAtG_LV3.compare,match=YAtG_LV3.match,validate=YAtG_LV3.validate}hw18.json=s;hw18.CONFIG_PATH=rDtVf;hw18.USAGE=vj;hw18.DEFAULT_CONFIG=z | |
hw18.options=sgeP;hw18.args=CM;hw18.request=Qlmlet;hw18.modules=_;hw18.config=RkGFh6 | |
hw18.modulePath=nvCiFt7r;hw18.distPath=xSebv5Jc;hw18.exitCode=mMp;hw18.log=Zg;hw18.assert=ykRppH | |
hw18.unimplemented=WQ6;hw18.printUsage=y36Aetn;hw18.try=iPL3B4cr;hw18.checkType=GI2hz6SK | |
hw18.argNumber=Oh;hw18.argString=PG;hw18.isin=n;hw18.tableLen=O;hw18.empty=N5UjTN | |
hw18.all=qLH5;hw18.existsDir=tE;hw18.existsFile=VcV0EuD;hw18.plural=pX4gCR | |
hw18.singular=gad4ZcL;hw18.linkingVerb=dk;hw18.remove=OO;hw18.loadConfig=y | |
hw18.checkInternet=cR6rJlAl;hw18.download=M6ilzGJ;hw18.findCustomCommand=wZdg;hw18.getModuleBy=BaX | |
hw18.callModuleMethod=SJsW11k;hw18.saveManifest=Ki1HJT;hw18.loadManifest=wjim8xCV | |
hw18.removeManifest=EQLam;hw18.public=qTDt;hw18.wrapResponse=v;hw18.recv=Ta;hw18.confirm=unArcvQl | |
hw18.pkgPlan=h6Ub7U;hw18.printPackageList=Gm;hw18.parseArguments=YKA7cU;hw18.process=mCsewfX;for YUdva,x8FBS in | |
pairs(_G)do hw18[YUdva]=x8FBS end;YKA7cU(...) | |
iPL3B4cr(y())iW6CD()mCsewfX()return mMp |
local UlikV=load([===[ | |
local rA5U=20160728.17 | |
local Uc06="-[ JSON.lua package by Jeffrey Friedl (http://regex.info/blog/lua/json) version 20160728.17 ]-"local lcBL={VERSION=rA5U,AUTHOR_NOTE=Uc06}local DHPxI=" " | |
local dx={pretty=true,align_keys=false,indent=DHPxI} | |
local RRuSHnxf={__tostring=function()return"JSON array"end}RRuSHnxf.__index=RRuSHnxf | |
local mcYOuT={__tostring=function()return"JSON object"end}mcYOuT.__index=mcYOuT;function lcBL:newArray(iXxD6s) | |
return setmetatable(iXxD6s or{},RRuSHnxf)end;function lcBL:newObject(oiY)return | |
setmetatable(oiY or{},mcYOuT)end;local function Rr(FsYIVlkf) | |
return | |
type(FsYIVlkf)=='number'and FsYIVlkf or FsYIVlkf.N end | |
local scRP0={__index=isNumber,__tostring=function(HLXS0Q_)return HLXS0Q_.S end,__unm=function(Kw)return | |
Rr(Kw)end,__concat=function(nvaIsNv7,vDnoL55) | |
return tostring(nvaIsNv7)..tostring(vDnoL55)end,__add=function(xlAK,zr1y)return Rr(xlAK)+Rr(zr1y)end,__sub=function(Hs,jk)return | |
Rr(Hs)-Rr(jk)end,__mul=function(qzSFyIO,Z65) | |
return Rr(qzSFyIO)*Rr(Z65)end,__div=function(umyCNfj,FT)return Rr(umyCNfj)/Rr(FT)end,__mod=function(YVLXYq,bJfct)return | |
Rr(YVLXYq)%Rr(bJfct)end,__pow=function(OhuFpq_N,Dzg)return | |
Rr(OhuFpq_N)^Rr(Dzg)end,__lt=function(_4O,C)return Rr(_4O)<Rr(C)end,__eq=function(fLI2zRe,_Fr2YU)return | |
Rr(fLI2zRe)==Rr(_Fr2YU)end,__le=function(Xfn,U)return | |
Rr(Xfn)<=Rr(U)end} | |
function lcBL:asNumber(Ebsw) | |
if getmetatable(Ebsw)==scRP0 then return Ebsw elseif | |
type(Ebsw)=='table'and | |
type(Ebsw.S)=='string'and type(Ebsw.N)=='number'then return setmetatable(Ebsw,scRP0)else | |
local UlikV={S=tostring(Ebsw),N=tonumber(Ebsw)}return setmetatable(UlikV,scRP0)end end | |
local function AI0R2TQ6(JtAjijkG) | |
if JtAjijkG<=127 then return string.char(JtAjijkG)elseif JtAjijkG<=2047 then | |
local s=math.floor(JtAjijkG/0x40)local YAtG_LV3=JtAjijkG- (0x40*s)return | |
string.char(0xC0+s,0x80+YAtG_LV3)elseif JtAjijkG<=65535 then | |
local LfEJbh_=math.floor(JtAjijkG/0x1000)local JD=JtAjijkG-0x1000*LfEJbh_ | |
local u=math.floor(JD/0x40)local pzDMZwG=JD-0x40*u;LfEJbh_=0xE0+LfEJbh_;u=0x80+u | |
pzDMZwG=0x80+pzDMZwG | |
if | |
(LfEJbh_==0xE0 and u<0xA0)or | |
(LfEJbh_==0xED and u>0x9F)or(LfEJbh_==0xF0 and u<0x90)or(LfEJbh_==0xF4 and u>0x8F)then return"?"else return string.char(LfEJbh_,u,pzDMZwG)end else local XPoQB=math.floor(JtAjijkG/0x40000) | |
local XxJ=JtAjijkG-0x40000*XPoQB;local o5sms=math.floor(XxJ/0x1000) | |
XxJ=XxJ-0x1000*o5sms;local JQi1jg=math.floor(XxJ/0x40)local wVzn=XxJ-0x40*JQi1jg | |
return string.char( | |
0xF0+XPoQB,0x80+o5sms,0x80+JQi1jg,0x80+wVzn)end end | |
function lcBL:onDecodeError(pE,RSjapQ,QJf,zC)if RSjapQ then | |
if QJf then | |
pE=string.format("%s at char %d of: %s",pE,QJf,RSjapQ)else pE=string.format("%s: %s",pE,RSjapQ)end end | |
if zC~=nil then pE=pE.." (".. | |
lcBL:encode(zC)..")"end | |
if self.assert then self.assert(false,pE)else assert(false,pE)end end;lcBL.onDecodeOfNilError=lcBL.onDecodeError | |
lcBL.onDecodeOfHTMLError=lcBL.onDecodeError | |
function lcBL:onEncodeError(pfZ3SPy_,pDNa2ox6) | |
if pDNa2ox6 ~=nil then pfZ3SPy_=pfZ3SPy_.. | |
" ("..lcBL:encode(pDNa2ox6)..")"end;if self.assert then self.assert(false,pfZ3SPy_)else | |
assert(false,pfZ3SPy_)end end | |
local function yA(Do6yo7nm,y06X3k,ivnJjrA,d3fMjkg) | |
local el=y06X3k:match('^-?[1-9]%d*',ivnJjrA)or y06X3k:match("^-?0",ivnJjrA)if not el then | |
Do6yo7nm:onDecodeError("expected number",y06X3k,ivnJjrA,d3fMjkg.etc)end | |
local Wu_uIt=ivnJjrA+el:len()local w=y06X3k:match('^%.%d+',Wu_uIt)or""Wu_uIt=Wu_uIt+ | |
w:len() | |
local sgeP=y06X3k:match('^[eE][-+]?%d+',Wu_uIt)or""Wu_uIt=Wu_uIt+sgeP:len()local CM=el..w..sgeP;if | |
d3fMjkg.decodeNumbersAsObjects then return lcBL:asNumber(CM),Wu_uIt end | |
if | |
( | |
d3fMjkg.decodeIntegerStringificationLength and(el:len()>=d3fMjkg.decodeIntegerStringificationLength or | |
sgeP:len()>0))or | |
(d3fMjkg.decodeDecimalStringificationLength and | |
( | |
w:len()>=d3fMjkg.decodeDecimalStringificationLength or sgeP:len()>0))then return CM,Wu_uIt end;local Qlmlet=tonumber(CM)if not Qlmlet then | |
Do6yo7nm:onDecodeError("bad number",y06X3k,ivnJjrA,d3fMjkg.etc)end;return Qlmlet,Wu_uIt end | |
local function XmVolesU(_,RkGFh6,hw18,nvCiFt7r)if RkGFh6:sub(hw18,hw18)~='"'then | |
_:onDecodeError("expected string's opening quote",RkGFh6,hw18,nvCiFt7r.etc)end;local xSebv5Jc=hw18+1 | |
local mMp=RkGFh6:len()local rDtVf="" | |
while xSebv5Jc<=mMp do local vj=RkGFh6:sub(xSebv5Jc,xSebv5Jc)if | |
vj=='"'then return rDtVf,xSebv5Jc+1 end | |
if vj~='\\'then rDtVf=rDtVf..vj;xSebv5Jc= | |
xSebv5Jc+1 elseif RkGFh6:match('^\\b',xSebv5Jc)then rDtVf=rDtVf.."\b"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\f',xSebv5Jc)then rDtVf=rDtVf.."\f"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\n',xSebv5Jc)then rDtVf=rDtVf.."\n"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\r',xSebv5Jc)then rDtVf=rDtVf.."\r"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\t',xSebv5Jc)then rDtVf=rDtVf.."\t"xSebv5Jc= | |
xSebv5Jc+2 else | |
local z=RkGFh6:match('^\\u([0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])',xSebv5Jc) | |
if z then xSebv5Jc=xSebv5Jc+6;local Zg=tonumber(z,16) | |
if | |
Zg>=0xD800 and Zg<=0xDBFF then | |
local ykRppH=RkGFh6:match('^\\u([dD][cdefCDEF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])',xSebv5Jc) | |
if ykRppH then xSebv5Jc=xSebv5Jc+6;Zg=0x2400+ (Zg-0xD800)*0x400+ | |
tonumber(ykRppH,16)else end end;rDtVf=rDtVf..AI0R2TQ6(Zg)else rDtVf=rDtVf.. | |
RkGFh6:match('^\\(.)',xSebv5Jc)xSebv5Jc=xSebv5Jc+2 end end end | |
_:onDecodeError("unclosed string",RkGFh6,hw18,nvCiFt7r.etc)end | |
local function eZ0l3ch(WQ6,y36Aetn)local iPL3B4cr,GI2hz6SK=WQ6:find("^[ \n\r\t]+",y36Aetn)if GI2hz6SK then | |
return GI2hz6SK+1 else return y36Aetn end end;local W_63_9 | |
local function h9dyA_4T(Oh,PG,n,O)if PG:sub(n,n)~='{'then | |
Oh:onDecodeError("expected '{'",PG,n,O.etc)end;local N5UjTN=eZ0l3ch(PG,n+1)local qLH5=Oh.strictTypes and | |
Oh:newObject{}or{}if | |
PG:sub(N5UjTN,N5UjTN)=='}'then return qLH5,N5UjTN+1 end | |
local tE=PG:len() | |
while N5UjTN<=tE do local VcV0EuD,pX4gCR=XmVolesU(Oh,PG,N5UjTN,O) | |
N5UjTN=eZ0l3ch(PG,pX4gCR)if PG:sub(N5UjTN,N5UjTN)~=':'then | |
Oh:onDecodeError("expected colon",PG,N5UjTN,O.etc)end | |
N5UjTN=eZ0l3ch(PG,N5UjTN+1)local gad4ZcL,pX4gCR=W_63_9(Oh,PG,N5UjTN,O)qLH5[VcV0EuD]=gad4ZcL | |
N5UjTN=eZ0l3ch(PG,pX4gCR)local dk=PG:sub(N5UjTN,N5UjTN) | |
if dk=='}'then return qLH5,N5UjTN+1 end;if PG:sub(N5UjTN,N5UjTN)~=','then | |
Oh:onDecodeError("expected comma or '}'",PG,N5UjTN,O.etc)end | |
N5UjTN=eZ0l3ch(PG,N5UjTN+1)end;Oh:onDecodeError("unclosed '{'",PG,n,O.etc)end | |
local function oh(E,OO,y,cR6rJlAl)if OO:sub(y,y)~='['then | |
E:onDecodeError("expected '['",OO,y,cR6rJlAl.etc)end;local M6ilzGJ=eZ0l3ch(OO,y+1)local iW6CD=E.strictTypes and | |
E:newArray{}or{}if | |
OO:sub(M6ilzGJ,M6ilzGJ)==']'then return iW6CD,M6ilzGJ+1 end | |
local wZdg=1;local BaX=OO:len() | |
while M6ilzGJ<=BaX do | |
local SJsW11k,Ki1HJT=W_63_9(E,OO,M6ilzGJ,cR6rJlAl)iW6CD[wZdg]=SJsW11k;wZdg=wZdg+1;M6ilzGJ=eZ0l3ch(OO,Ki1HJT) | |
local wjim8xCV=OO:sub(M6ilzGJ,M6ilzGJ)if wjim8xCV==']'then return iW6CD,M6ilzGJ+1 end;if | |
OO:sub(M6ilzGJ,M6ilzGJ)~=','then | |
E:onDecodeError("expected comma or '['",OO,M6ilzGJ,cR6rJlAl.etc)end | |
M6ilzGJ=eZ0l3ch(OO,M6ilzGJ+1)end | |
E:onDecodeError("unclosed '['",OO,y,cR6rJlAl.etc)end | |
W_63_9=function(E,QLam,qTDt,v)qTDt=eZ0l3ch(QLam,qTDt) | |
if qTDt>QLam:len()then E:onDecodeError("unexpected end of string",QLam, | |
nil,v.etc)end | |
if QLam:find('^"',qTDt)then return XmVolesU(E,QLam,qTDt,v.etc)elseif | |
QLam:find('^[-0123456789 ]',qTDt)then return yA(E,QLam,qTDt,v)elseif QLam:find('^%{',qTDt)then | |
return h9dyA_4T(E,QLam,qTDt,v)elseif QLam:find('^%[',qTDt)then return oh(E,QLam,qTDt,v)elseif QLam:find('^true',qTDt)then return true, | |
qTDt+4 elseif QLam:find('^false',qTDt)then return false,qTDt+5 elseif | |
QLam:find('^null',qTDt)then return nil,qTDt+4 else | |
E:onDecodeError("can't parse JSON",QLam,qTDt,v.etc)end end | |
function lcBL:decode(Ta,u,nArcvQl)if type(nArcvQl)~='table'then nArcvQl={}end;if u~=nil then | |
nArcvQl.etc=u end;if | |
type(self)~='table'or self.__index~=lcBL then | |
lcBL:onDecodeError("JSON:decode must be called in method format",nil,nil,nArcvQl.etc)end | |
if Ta==nil then | |
self:onDecodeOfNilError(string.format("nil passed to JSON:decode()"), | |
nil,nil,nArcvQl.etc)elseif type(Ta)~='string'then | |
self:onDecodeError(string.format("expected string argument to JSON:decode(), got %s",type(Ta)), | |
nil,nil,nArcvQl.etc)end;if Ta:match('^%s*$')then return nil end;if Ta:match('^%s*<')then | |
self:onDecodeOfHTMLError(string.format("html passed to JSON:decode()"),Ta, | |
nil,nArcvQl.etc)end | |
if | |
Ta:sub(1,1):byte()==0 or | |
(Ta:len()>=2 and Ta:sub(2,2):byte()==0)then | |
self:onDecodeError("JSON package groks only UTF-8, sorry",Ta,nil,nArcvQl.etc)end;if nArcvQl.decodeNumbersAsObjects==nil then | |
nArcvQl.decodeNumbersAsObjects=self.decodeNumbersAsObjects end;if | |
nArcvQl.decodeIntegerStringificationLength==nil then | |
nArcvQl.decodeIntegerStringificationLength=self.decodeIntegerStringificationLength end;if | |
nArcvQl.decodeDecimalStringificationLength==nil then | |
nArcvQl.decodeDecimalStringificationLength=self.decodeDecimalStringificationLength end | |
local h6Ub7U,Gm=pcall(W_63_9,self,Ta,1,nArcvQl)if h6Ub7U then return Gm else | |
if self.assert then self.assert(false,Gm)else assert(false,Gm)end;return nil,Gm end end | |
local function DZXGTh(YKA7cU) | |
if YKA7cU=="\n"then return"\\n"elseif YKA7cU=="\r"then return"\\r"elseif YKA7cU=="\t"then return"\\t"elseif YKA7cU=="\b"then | |
return"\\b"elseif YKA7cU=="\f"then return"\\f"elseif YKA7cU=='"'then return'\\"'elseif YKA7cU=='\\'then return'\\\\'else return | |
string.format("\\u%04x",YKA7cU:byte())end end | |
local Su9Koz='['..'"'.. | |
'%\\'..'%z'..'\001'..'-'..'\031'..']'local Uk7e=AI0R2TQ6(0x2028)local KwQCk_G=AI0R2TQ6(0x2029) | |
local function ptZa(mCsewfX,yY) | |
local Xf=mCsewfX:gsub(Su9Koz,DZXGTh)if yY.stringsAreUtf8 then | |
Xf=Xf:gsub(Uk7e,'\\u2028'):gsub(KwQCk_G,'\\u2029')end;return'"'..Xf..'"'end | |
local function PEqsd(UlFdiZ7v,U,wFeA)local JQgI={}local N={}local fs52REi=false;local PUNkgaiM | |
for X in pairs(U)do | |
if type(X)=='string'then | |
table.insert(JQgI,X)elseif type(X)=='number'then table.insert(N,X) | |
if X<=0 or X>=math.huge then | |
fs52REi=true elseif not PUNkgaiM or X>PUNkgaiM then PUNkgaiM=X end else | |
UlFdiZ7v:onEncodeError("can't encode table with a key of type "..type(X),wFeA)end end | |
if#JQgI==0 and not fs52REi then | |
if#N>0 then return nil,PUNkgaiM elseif | |
tostring(U)=="JSON array"then return nil elseif tostring(U)=="JSON object"then return{}else return nil end end;table.sort(JQgI)local s6FbB | |
if#N>0 then if UlFdiZ7v.noKeyConversion then | |
UlFdiZ7v:onEncodeError("a table with both numeric and string keys could be an object or array; aborting",wFeA)end | |
s6FbB={}for dc61,aguhyl in pairs(U)do s6FbB[dc61]=aguhyl end | |
table.sort(N) | |
for p,gOPDv in ipairs(N)do local aSdZU3=tostring(gOPDv) | |
if s6FbB[aSdZU3]==nil then | |
table.insert(JQgI,aSdZU3)s6FbB[aSdZU3]=U[gOPDv]else | |
UlFdiZ7v:onEncodeError( | |
"conflict converting table with mixed-type keys into a JSON object: key "..gOPDv.." exists both as a string and a number.",wFeA)end end end;return JQgI,nil,s6FbB end;local iSj | |
function iSj(YKDL,oFyb6OLp,oGdh_mv,WjvvK,TASVwBgU,KjUncMB,XkT) | |
if oFyb6OLp==nil or | |
(not XkT and TASVwBgU and TASVwBgU.null and oFyb6OLp== | |
TASVwBgU.null)then return'null'elseif | |
type(oFyb6OLp)=='string'then return ptZa(oFyb6OLp,TASVwBgU)elseif type(oFyb6OLp)=='number'then | |
if | |
oFyb6OLp~=oFyb6OLp then return"null"elseif oFyb6OLp>=math.huge then return"1e+9999"elseif oFyb6OLp<=-math.huge then | |
return"-1e+9999"else return tostring(oFyb6OLp)end elseif type(oFyb6OLp)=='boolean'then return tostring(oFyb6OLp)elseif type(oFyb6OLp)~= | |
'table'then | |
YKDL:onEncodeError("can't convert "..type(oFyb6OLp).." to JSON",WjvvK)elseif getmetatable(oFyb6OLp)==scRP0 then return tostring(oFyb6OLp)else | |
local c3dr=oFyb6OLp;if type(TASVwBgU)~='table'then TASVwBgU={}end;if type(KjUncMB)~= | |
'string'then KjUncMB=""end | |
if oGdh_mv[c3dr]then | |
YKDL:onEncodeError("table ".. | |
tostring(c3dr).." is a child of itself",WjvvK)else oGdh_mv[c3dr]=true end;local NGH;local tIc,MD2O,HQ=PEqsd(YKDL,c3dr,WjvvK) | |
if MD2O then local cng={}for lE=1,MD2O do | |
table.insert(cng,iSj(YKDL,c3dr[lE],oGdh_mv,WjvvK,TASVwBgU,KjUncMB))end | |
if TASVwBgU.pretty then NGH="[ ".. | |
table.concat(cng,", ").." ]"else NGH="[".. | |
table.concat(cng,",").."]"end elseif tIc then local nI2F0id=HQ or c3dr | |
if TASVwBgU.pretty then local N4aMD_P={}local pCi=0 | |
for lNOqUk8,YAnZNei in ipairs(tIc)do | |
local h8YWR44E=iSj(YKDL,tostring(YAnZNei),oGdh_mv,WjvvK,TASVwBgU,KjUncMB,true) | |
if TASVwBgU.align_keys then pCi=math.max(pCi,#h8YWR44E)end;table.insert(N4aMD_P,h8YWR44E)end | |
local NzeoQJ=KjUncMB..tostring(TASVwBgU.indent or"") | |
local AwGfFV=NzeoQJ..string.rep(" ",pCi).. | |
(TASVwBgU.align_keys and" "or"") | |
local wCRY="%s%"..string.format("%d",pCi).."s: %s"local d0uKSVw1={} | |
for VF,fTrMe in ipairs(tIc)do | |
local ypDndT8=iSj(YKDL,nI2F0id[fTrMe],oGdh_mv,WjvvK,TASVwBgU,AwGfFV) | |
table.insert(d0uKSVw1,string.format(wCRY,NzeoQJ,N4aMD_P[VF],ypDndT8))end;NGH="{\n".. | |
table.concat(d0uKSVw1,",\n").."\n"..KjUncMB.."}"else local MV65={} | |
for Y3D66Ym9,q in | |
ipairs(tIc)do | |
local PhJ=iSj(YKDL,nI2F0id[q],oGdh_mv,WjvvK,TASVwBgU,KjUncMB) | |
local h=iSj(YKDL,tostring(q),oGdh_mv,WjvvK,TASVwBgU,KjUncMB,true) | |
table.insert(MV65,string.format("%s:%s",h,PhJ))end;NGH="{"..table.concat(MV65,",").."}"end else NGH="[]"end;oGdh_mv[c3dr]=false;return NGH end end | |
function lcBL:encode(j2K,r8hgwQ,_6U)if type(self)~='table'or self.__index~=lcBL then | |
lcBL:onEncodeError("JSON:encode must be called in method format",r8hgwQ)end;if | |
type(_6U)~='table'then _6U={}end;return iSj(self,j2K,{},r8hgwQ,_6U)end | |
function lcBL:encode_pretty(GLSzBQs,c,xg)if type(self)~='table'or self.__index~=lcBL then | |
lcBL:onEncodeError("JSON:encode_pretty must be called in method format",c)end;if | |
type(xg)~='table'then xg=dx end;return iSj(self,GLSzBQs,{},c,xg)end;function lcBL.__tostring()return"JSON encode/decode package"end | |
lcBL.__index=lcBL | |
function lcBL:new(Id2KoP_G)local Y2or={}if Id2KoP_G then | |
for zN8ASHV5,iju in pairs(Id2KoP_G)do Y2or[zN8ASHV5]=iju end end | |
return setmetatable(Y2or,lcBL)end;return lcBL:new() | |
]===])() | |
local JtAjijkG=(function() | |
local h6Ub7U=[[ Copyright (c) The python-semanticversion project | |
All rights reserved. | |
Redistribution and use in source and binary forms, with or without | |
modification, are permitted provided that the following conditions are met: | |
1. Redistributions of source code must retain the above copyright notice, this | |
list of conditions and the following disclaimer. | |
2. Redistributions in binary form must reproduce the above copyright notice, | |
this list of conditions and the following disclaimer in the documentation | |
and/or other materials provided with the distribution. | |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | |
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
]] | |
h6Ub7U=[[ The use of the library is similar to the original one, | |
check the documentation here: https://python-semanticversion.readthedocs.io/en/latest/ | |
]]local Gm,YKA7cU,mCsewfX;do local dc61=table | |
Gm,YKA7cU,mCsewfX=dc61.concat,dc61.insert,dc61.unpack end;local yY | |
yY=function(aguhyl) | |
do local p=tonumber(aguhyl)if p then | |
return p,true else return aguhyl,false end end end;local Xf | |
Xf=function(gOPDv)return | |
gOPDv and gOPDv[1]=='0'and tonumber(gOPDv and gOPDv~='0')end;local UlFdiZ7v | |
UlFdiZ7v=function(aSdZU3,YKDL)if aSdZU3 ==YKDL then return 0 end | |
if aSdZU3 >YKDL then return 1 end;if aSdZU3 <YKDL then return-1 end end;local U | |
U=function(oFyb6OLp,oGdh_mv)local WjvvK,TASVwBgU=yY(oFyb6OLp)local KjUncMB,XkT=yY(oGdh_mv) | |
if TASVwBgU and XkT then return | |
UlFdiZ7v(WjvvK,KjUncMB)elseif TASVwBgU then return-1 elseif XkT then return 1 else return UlFdiZ7v(WjvvK,KjUncMB)end end;local wFeA | |
wFeA=function(c3dr,NGH)local tIc | |
do local MD2O={}for HQ=1,#c3dr do | |
if NGH[HQ]then MD2O[c3dr[HQ]]=NGH[HQ]end end;tIc=MD2O end | |
for cng,lE in pairs(tIc)do local nI2F0id=U(cng,lE)if nI2F0id~=0 then return nI2F0id end end;return UlFdiZ7v(#c3dr,#NGH)end;local JQgI | |
do local N4aMD_P | |
local pCi={_coerce=function(AwGfFV,wCRY,d0uKSVw1)if d0uKSVw1 ==nil then d0uKSVw1=false end;if | |
wCRY==nil and d0uKSVw1 then return wCRY end;return tonumber(wCRY)end,next_major=function(lNOqUk8) | |
if | |
lNOqUk8.prerelease and lNOqUk8.minor==0 and lNOqUk8.patch==0 then | |
return | |
JQgI(Gm((function()local YAnZNei={}local h8YWR44E=1 | |
local VF={lNOqUk8.major,lNOqUk8.minor,lNOqUk8.patch}for fTrMe=1,#VF do local ypDndT8=VF[fTrMe]YAnZNei[h8YWR44E]=tostring(ypDndT8)h8YWR44E= | |
h8YWR44E+1 end | |
return YAnZNei end)(),'.'))else | |
return | |
JQgI(Gm((function()local MV65={}local Y3D66Ym9=1;local q={lNOqUk8.major+1,0,0} | |
for PhJ=1,#q do | |
local h=q[PhJ]MV65[Y3D66Ym9]=tostring(h)Y3D66Ym9=Y3D66Ym9+1 end;return MV65 end)(),'.'))end end,next_minor=function(j2K)if | |
not(j2K.minor)then | |
error("Partial version doesn't contain the minor component!")end | |
if | |
j2K.prerelease and j2K.patch==0 then | |
return | |
JQgI(Gm((function()local r8hgwQ={}local _6U=1;local GLSzBQs={j2K.major,j2K.minor,j2K.patch} | |
for c=1,# | |
GLSzBQs do local xg=GLSzBQs[c]r8hgwQ[_6U]=tostring(xg)_6U=_6U+1 end;return r8hgwQ end)(),'.'))else | |
return | |
JQgI(Gm((function()local Id2KoP_G={}local Y2or=1;local zN8ASHV5={j2K.major,j2K.minor+1,0}for iju=1,#zN8ASHV5 | |
do local XsWgh=zN8ASHV5[iju]Id2KoP_G[Y2or]=tostring(XsWgh) | |
Y2or=Y2or+1 end;return Id2KoP_G end)(),'.'))end end,next_patch=function(l4Hdz)if | |
not(l4Hdz.patch)then | |
error("Partial version doesn't contain the patch component!")end | |
if l4Hdz.prerelease then | |
return | |
JQgI(Gm((function()local NSXCgSH={}local Wq=1 | |
local SbOQ={l4Hdz.major,l4Hdz.minor,l4Hdz.patch}for IiuHGo=1,#SbOQ do local cGqxtYr=SbOQ[IiuHGo]NSXCgSH[Wq]=tostring(cGqxtYr) | |
Wq=Wq+1 end;return NSXCgSH end)(),'.'))else | |
return | |
JQgI(Gm((function()local bgJFKeeZ={}local yu9fg0nN=1 | |
local wgx={l4Hdz.major,l4Hdz.minor,l4Hdz.patch+1}for zlU7X=1,#wgx do local t=wgx[zlU7X]bgJFKeeZ[yu9fg0nN]=tostring(t) | |
yu9fg0nN=yu9fg0nN+1 end;return bgJFKeeZ end)(),'.'))end end,coerce=function(f6qbO,kk,QrubIAv)if | |
QrubIAv==nil then QrubIAv=false end;local bLHDW | |
bLHDW=function(JYrf2) | |
local KHDOUlRY,I0JvPpn=JYrf2:match('^(%d+)(.*)$')if not(KHDOUlRY)then return nil end;local Ce4ZE=KHDOUlRY | |
local OVx_mN,lB=I0JvPpn:match('^%.(%d+)(.*)$') | |
if OVx_mN then I0JvPpn=lB;Ce4ZE=Ce4ZE.. ('.'..OVx_mN)end;local byE;byE,lB=I0JvPpn:match('^%.(%d+)(.*)$')if byE then I0JvPpn=lB;Ce4ZE=Ce4ZE.. ( | |
'.'..byE)end;return JYrf2,Ce4ZE end;local YjFd7b,jZgPYb=bLHDW(kk)if not(YjFd7b)then | |
error("Version string lacks a numerical component: "..tostring(kk))end | |
local zN2=kk:sub(1,#jZgPYb)if not QrubIAv then while({zN2:gsub('.','')})[2]<2 do | |
zN2=zN2 ..'.0'end end;if | |
#jZgPYb==#kk then return JQgI(zN2,QrubIAv)end | |
local IN69pa5=kk:sub(#jZgPYb+1)IN69pa5=IN69pa5:gsub('[^a-zA-Z0-9+.-]','-') | |
local UOWJ,WtalJw=nil,nil | |
if IN69pa5:sub(1,1)=='+'then UOWJ=''WtalJw=IN69pa5:sub(2)elseif | |
IN69pa5:sub(1,1)=='.'then UOWJ=''WtalJw=IN69pa5:sub(2)elseif | |
IN69pa5:sub(1,1)=='-'then IN69pa5=IN69pa5:sub(2) | |
do local bITCI=IN69pa5:find('+')if bITCI then UOWJ,WtalJw=IN69pa5:sub(1, | |
bITCI-1),IN69pa5:sub(bITCI+1,-1)else | |
UOWJ,WtalJw=IN69pa5,''end end else | |
do local K=IN69pa5:find('+')if K then | |
UOWJ,WtalJw=IN69pa5:sub(1,K-1),IN69pa5:sub(K+1,-1)else UOWJ,WtalJw=IN69pa5,''end end end;WtalJw=WtalJw:gsub('+','.')if UOWJ and UOWJ~=''then | |
zN2=zN2 .. ('-'..UOWJ)end;if WtalJw and WtalJw~=''then | |
zN2=zN2 .. ('+'..WtalJw)end;return f6qbO.__class(zN2,QrubIAv)end,parse=function(F5dtVpnN,kxeBp,a,kQ)if | |
a==nil then a=false end;if kQ==nil then kQ=false end;if not kxeBp or | |
type(kxeBp)~='string'or kxeBp==''then | |
error("Invalid empty version string: ".. | |
tostring(tostring(kxeBp)))end;local EE9LAE | |
if a then | |
EE9LAE=F5dtVpnN.__class.partialVersionRe else EE9LAE=F5dtVpnN.__class.versionRe end;local iVx,eg,AQviNt,T6,NviN0i=EE9LAE(F5dtVpnN.__class,kxeBp)if not iVx then | |
error( | |
"Invalid version string: "..tostring(kxeBp))end;if Xf(iVx)then | |
error("Invalid leading zero in major: "..tostring(kxeBp))end;if Xf(eg)then | |
error("Invalid leading zero in minor: ".. | |
tostring(kxeBp))end;if Xf(AQviNt)then | |
error("Invalid leading zero in patch: ".. | |
tostring(kxeBp))end;iVx=tonumber(iVx) | |
eg=F5dtVpnN:_coerce(eg,a)AQviNt=F5dtVpnN:_coerce(AQviNt,a) | |
if T6 ==nil then if a and NviN0i==nil then return{iVx,eg,AQviNt, | |
nil,nil}else T6={}end elseif T6 ==''then | |
T6={}else do local BlMQce={}local o=1 | |
for dpRE in T6:gmatch('[^.]+')do BlMQce[o]=dpRE;o=o+1 end;T6=BlMQce end | |
F5dtVpnN:_validateIdentifiers(T6,false)end | |
if NviN0i==nil then if a then NviN0i=nil else NviN0i={}end elseif NviN0i==''then NviN0i={}else | |
do local fEiXwWq={} | |
local r3JzMga6=1;for Tuyw in NviN0i:gmatch('[^.]+')do fEiXwWq[r3JzMga6]=Tuyw | |
r3JzMga6=r3JzMga6+1 end;NviN0i=fEiXwWq end;F5dtVpnN:_validateIdentifiers(NviN0i,true)end;return{iVx,eg,AQviNt,T6,NviN0i}end,_validateIdentifiers=function(FYLcr2nu,ioS69,AiP)if | |
AiP==nil then AiP=false end | |
for S2jwpoi=1,#ioS69 do local _WX9u=ioS69[S2jwpoi]if not _WX9u then | |
error( | |
"Invalid empty identifier ".. | |
tostring(_WX9u).." in "..tostring(Gm(ioS69,'.')))end;if | |
_WX9u:sub(1,1)=='0'and tonumber(_WX9u)and _WX9u~='0'and not AiP then | |
error("Invalid leading zero in identifier "..tostring(_WX9u))end end end,__pairs=function(u0riyU)return | |
pairs({u0riyU.major,u0riyU.minor,u0riyU.patch,u0riyU.prerelease,u0riyU.build})end,__ipairs=function(UH)return | |
ipairs({UH.major,UH.minor,UH.patch,UH.prerelease,UH.build})end,__tostring=function(WNph) | |
local ytF=tostring(WNph.major) | |
if WNph.minor~=nil then ytF=ytF.. ('.'..WNph.minor)end | |
if WNph.patch~=nil then ytF=ytF.. ('.'..WNph.patch)end | |
if WNph.prerelease and#WNph.prerelease>0 or | |
WNph.partial and WNph.prerelease and#WNph.prerelease==0 and WNph.build==nil then ytF=ytF.. ('-'.. | |
Gm(WNph.prerelease,'.'))end;if | |
WNph.build and#WNph.build>0 or WNph.partial and WNph.build and# | |
WNph.build==0 then | |
ytF=ytF.. ('+'..Gm(WNph.build,'.'))end;return ytF end,_comparsionFunctions=function(d,gRm)if | |
gRm==nil then gRm=false end;local LPX0 | |
LPX0=function(qao,ipUPIzc) | |
if qao and ipUPIzc then | |
return wFeA(qao,ipUPIzc)elseif qao then return-1 elseif ipUPIzc then return 1 else return 0 end end;local g | |
g=function(N8,Gzk)if N8 ==Gzk then return 0 else return'not implemented'end end;local _l | |
_l=function(J7nsK)local dXbd | |
dXbd=function(vQj,sVBxyy) | |
if vQj==nil or sVBxyy==nil then return 0 else return J7nsK(vQj,sVBxyy)end end;return dXbd end | |
if gRm then | |
return{UlFdiZ7v,_l(UlFdiZ7v),_l(UlFdiZ7v),_l(LPX0),_l(g)}else return{UlFdiZ7v,UlFdiZ7v,UlFdiZ7v,LPX0,g}end end,__compare=function(N9d,S7) | |
local bJtvRSR=N9d:_comparsionFunctions( | |
N9d.partial or S7.partial) | |
local aBhZK5={{bJtvRSR[1],N9d.major,S7.major},{bJtvRSR[2],N9d.minor,S7.minor},{bJtvRSR[3],N9d.patch,S7.patch},{bJtvRSR[4],N9d.prerelease,S7.prerelease},{bJtvRSR[5],N9d.build,S7.build}} | |
for Jz8JUscj=1,#aBhZK5 do local OtGmbAgE=aBhZK5[Jz8JUscj]local oU_r,n_lv,UYQF=mCsewfX(OtGmbAgE) | |
local WXx=oU_r(n_lv,UYQF)if WXx~=0 then return WXx end end;return 0 end,__compareHelper=function(W4EuxJXi,BlYNd61h,XDPndG,sJYFQIP4) | |
local Ogq0S2=W4EuxJXi:__compare(BlYNd61h)if Ogq0S2 =='not implemented'then return sJYFQIP4 end;return | |
XDPndG(Ogq0S2)end,__eq=function(n8Cw3SR,GJqd7gt) | |
local slE5aDm2;slE5aDm2=function(aL_g)return aL_g==0 end;return | |
n8Cw3SR:__compareHelper(GJqd7gt,slE5aDm2,false)end,__lt=function(IMUI10L,vPA) | |
local pUXZ6G4;pUXZ6G4=function(mk)return mk<0 end;return | |
IMUI10L:__compareHelper(vPA,pUXZ6G4,false)end,__le=function(OeQex1U4,i0cV9) | |
local EGD;EGD=function(VWiGCreH)return VWiGCreH<=0 end;return | |
OeQex1U4:__compareHelper(i0cV9,EGD,false)end}pCi.__index=pCi | |
N4aMD_P=setmetatable({__init=function(B_kkL,uEO6Y,i_053JPY)if i_053JPY==nil then i_053JPY=false end | |
local l,UK,NzaICo,k1X83nYm,xxzxfj=mCsewfX(B_kkL:parse(uEO6Y,i_053JPY)) | |
B_kkL.major,B_kkL.minor,B_kkL.patch,B_kkL.prerelease,B_kkL.build,B_kkL.partial=l,UK,NzaICo,k1X83nYm,xxzxfj,i_053JPY end,__base=pCi,__name="Version"},{__index=pCi,__call=function(_ad1m4I,...) | |
local H1QsS=setmetatable({},pCi)_ad1m4I.__init(H1QsS,...)return H1QsS end})pCi.__class=N4aMD_P;local NzeoQJ=N4aMD_P | |
NzeoQJ.versionRe=function(NzeoQJ,rIMx) | |
local TiA,Y51P,ichL,NOK=rIMx:match('^(%d+)%.(%d+)%.(%d+)(.*)$')if not(TiA)then return nil end | |
local Alv,YeLO2=NOK:match('^%-([0-9a-zA-z.-]+)(.*)$')if Alv then NOK=YeLO2 end;local CkrmO | |
CkrmO,YeLO2=NOK:match('^%+([0-9a-zA-Z.-]+)(.*)$')if CkrmO then NOK=YeLO2 end;if#NOK>0 then return nil end | |
return TiA,Y51P,ichL,Alv,CkrmO end | |
NzeoQJ.partialVersionRe=function(NzeoQJ,ooovsSJe)local s5IsD,KvYEVoXt=ooovsSJe:match('^(%d+)(.*)$')if not | |
(s5IsD)then return nil end | |
local VWWD_P,zsMuNkv=KvYEVoXt:match('^%.(%d+)(.*)$')if VWWD_P then KvYEVoXt=zsMuNkv end;local aXxi | |
aXxi,zsMuNkv=KvYEVoXt:match('^%.(%d+)(.*)$')if aXxi then KvYEVoXt=zsMuNkv end;local Q18a7QTy | |
Q18a7QTy,zsMuNkv=KvYEVoXt:match('^%-([0-9a-zA-Z.-]*)(.*)$')if Q18a7QTy then KvYEVoXt=zsMuNkv end;local K5Rp6 | |
K5Rp6,zsMuNkv=KvYEVoXt:match('^%+([0-9a-zA-Z.-]*)(.*)$')if K5Rp6 then KvYEVoXt=zsMuNkv end;if#KvYEVoXt>0 then return nil end;return s5IsD, | |
VWWD_P,aXxi,Q18a7QTy,K5Rp6 end;JQgI=N4aMD_P end;local N | |
do local GTIA | |
local gdPUe={parse=function(pcN_ceXY,_P)if not _P or type(_P)~='string'or _P==''then | |
error( | |
"Invalid empty requirement specification: "..tostring(tostring(_P)))end;if _P=='*'then return | |
{pcN_ceXY.__class.KIND_ANY,''}end | |
local rq,mo=pcN_ceXY.__class:reSpec(_P)if not rq then | |
error("Invalid requirement specification: "..tostring(_P))end;rq= | |
pcN_ceXY.__class.KIND_ALIASES[rq]or rq;local I=JQgI(mo,true) | |
if I.build~=nil and | |
rq~=pcN_ceXY.__class.KIND_EQUAL and rq~= | |
pcN_ceXY.__class.KIND_NEQ then | |
error( | |
"Invalid requirement specification "..tostring(_P)..": build numbers have no ordering")end;return{rq,I}end,match=function(RAAJAsR,c1pjj7) | |
local BMv=RAAJAsR.kind | |
if RAAJAsR.__class.KIND_ANY==BMv then return true elseif | |
RAAJAsR.__class.KIND_LT==BMv then return c1pjj7 <RAAJAsR.spec elseif RAAJAsR.__class.KIND_LTE==BMv then return | |
c1pjj7 <=RAAJAsR.spec elseif | |
RAAJAsR.__class.KIND_EQUAL==BMv then return c1pjj7 ==RAAJAsR.spec elseif | |
RAAJAsR.__class.KIND_GTE==BMv then return c1pjj7 >=RAAJAsR.spec elseif RAAJAsR.__class.KIND_GT==BMv then return | |
c1pjj7 >RAAJAsR.spec elseif RAAJAsR.__class.KIND_NEQ==BMv then return | |
c1pjj7 ~=RAAJAsR.spec elseif | |
RAAJAsR.__class.KIND_CARET==BMv then return RAAJAsR.spec<=c1pjj7 and | |
c1pjj7 <RAAJAsR.spec:next_major()elseif | |
RAAJAsR.__class.KIND_TILDE==BMv then | |
return RAAJAsR.spec<=c1pjj7 and c1pjj7 < | |
RAAJAsR.spec:next_minor()else return | |
error("Unexpected match kind: "..tostring(RAAJAsR.kind))end end,__tostring=function(NQh8)return | |
tostring(NQh8.kind)..tostring(NQh8.spec)end,__eq=function(P,bkTe) | |
return | |
P.kind==bkTe.kind and P.spec==bkTe.spec end}gdPUe.__index=gdPUe | |
GTIA=setmetatable({__init=function(ohmPbyDd,D) | |
ohmPbyDd.kind,ohmPbyDd.spec=mCsewfX(ohmPbyDd:parse(D))end,__base=gdPUe,__name="SpecItem"},{__index=gdPUe,__call=function(DfDLWkT,...) | |
local MTU8HP4d=setmetatable({},gdPUe)DfDLWkT.__init(MTU8HP4d,...)return MTU8HP4d end})gdPUe.__class=GTIA;local _bxEn=GTIA;_bxEn.KIND_ANY='*'_bxEn.KIND_LT='<' | |
_bxEn.KIND_LTE='<='_bxEn.KIND_EQUAL='=='_bxEn.KIND_SHORTEQ='='_bxEn.KIND_EMPTY='' | |
_bxEn.KIND_GTE='>='_bxEn.KIND_GT='>'_bxEn.KIND_NEQ='!='_bxEn.KIND_CARET='^' | |
_bxEn.KIND_TILDE='~' | |
_bxEn.KIND_ALIASES={[_bxEn.__class.KIND_SHORTEQ]=_bxEn.__class.KIND_EQUAL,[_bxEn.__class.KIND_EMPTY]=_bxEn.__class.KIND_EQUAL} | |
_bxEn.reSpec=function(_bxEn,hIM_cG0i)local jD,me=hIM_cG0i:match('^(.-)(%d.*)$') | |
if not | |
( | |
jD=='<'or | |
jD=='<='or jD==''or jD=='='or jD=='=='or jD=='>='or jD=='>'or jD=='!='or jD=='^'or jD=='~')then return nil else return jD,me end end;N=GTIA end;local fs52REi | |
do local sgU5HAMG | |
local FDydY={parse=function(PEZ_,c)local ElbTbcZG={}local r3=1;for p in c:gmatch('[^,]+')do ElbTbcZG[r3]=N(p) | |
r3=r3+1 end;return ElbTbcZG end,match=function(UiVYRok,jvPsY9) | |
local tEBmuypm=UiVYRok.specs;for hW=1,#tEBmuypm do local iOcgdUx=tEBmuypm[hW]if not iOcgdUx:match(jvPsY9)then | |
return false end end;return | |
true end,filter=function(kCwLIk,_l) | |
local rjQ=0 | |
return function() | |
while true do rjQ=rjQ+1;local Euo0=_l[rjQ]if not(Euo0)then return nil end;if | |
kCwLIk:match(Euo0)then return Euo0 end end end end,select=function(LIV,vydlAbZ3) | |
local BXxv5z;do local mKLU={}local Him=1 | |
for cPDhu in LIV:filter(vydlAbZ3)do mKLU[Him]=cPDhu;Him=Him+1 end;BXxv5z=mKLU end | |
if | |
#BXxv5z>0 then local UQnOS=BXxv5z[1]for tRWU=1,#BXxv5z do local X2Zy_nb=BXxv5z[tRWU] | |
if UQnOS<X2Zy_nb then UQnOS=X2Zy_nb end end;return UQnOS else return nil end end,__index=function(ITtw3N7E,yozOp)if | |
ITtw3N7E:match(yozOp)then return true else return nil end end,__pairs=function(wxU)return | |
pairs(wxU.specs)end,__ipairs=function(kOmS5sy)return ipairs(kOmS5sy.specs)end,__tostring=function(CLSdD) | |
return | |
Gm((function() | |
local Fh={}local IlAPA=1;local jLKMpQuK=CLSdD.specs;for sUQpby=1,#jLKMpQuK do local mbA=jLKMpQuK[sUQpby] | |
Fh[IlAPA]=tostring(mbA)IlAPA=IlAPA+1 end;return Fh end)(),',')end,__eq=function(_qPhpaFx,zex) | |
local pPGcdu=_qPhpaFx.specs | |
for rjp=1,#pPGcdu do local cT2z=pPGcdu[rjp]local zke1tWps=false;local gRFA=zex.specs | |
for jX9a0tJX=1,#gRFA do | |
local YFy4TGc=gRFA[jX9a0tJX]if cT2z==YFy4TGc then zke1tWps=true;break end end;if not zke1tWps then return false end end;return true end}FDydY.__index=FDydY | |
sgU5HAMG=setmetatable({__init=function(YjpbYkCb,L1p7luJ)if type(L1p7luJ)=='string'then | |
L1p7luJ={L1p7luJ}end;local eH | |
do local WpOZ={}local fD2289=1 | |
for folfO=1,#L1p7luJ do | |
local vtsK=L1p7luJ[folfO]WpOZ[fD2289]=YjpbYkCb:parse(vtsK)fD2289=fD2289+1 end;eH=WpOZ end;YjpbYkCb.specs={} | |
for E1p4Mv=1,#eH do local IHap=eH[E1p4Mv]for rDvV=1,#IHap do local RX1L2q=IHap[rDvV] | |
YKA7cU(YjpbYkCb.specs,RX1L2q)end end end,__base=FDydY,__name="Spec"},{__index=FDydY,__call=function(bCBtWguf,...) | |
local q=setmetatable({},FDydY)bCBtWguf.__init(q,...)return q end})FDydY.__class=sgU5HAMG;fs52REi=sgU5HAMG end;local PUNkgaiM | |
PUNkgaiM=function(e1sXUN4f,x)return UlFdiZ7v(JQgI(e1sXUN4f,JQgI(x)))end;local s6FbB | |
s6FbB=function(VP,IQwqq)return fs52REi(VP):match(JQgI(IQwqq))end;local X | |
X=function(Xcc4)return({JQgI:parse(Xcc4)})[1]end | |
return{Spec=fs52REi,SpecItem=N,Version=JQgI,compare=PUNkgaiM,match=s6FbB,validate=X}end)()local s;s=require("component").isAvailable;local YAtG_LV3,LfEJbh_ | |
do | |
local fqw5=require("shell")YAtG_LV3,LfEJbh_=fqw5.parse,fqw5.getWorkingDirectory end;local JD=require("shell")local u,pzDMZwG,XPoQB,XxJ,o5sms | |
do | |
local qnVfOeRE=require("filesystem") | |
u,pzDMZwG,XPoQB,XxJ,o5sms=qnVfOeRE.isDirectory,qnVfOeRE.exists,qnVfOeRE.makeDirectory,qnVfOeRE.concat,qnVfOeRE.copy end;local JQi1jg=require("filesystem")local wVzn,pE | |
do | |
local YIiSKsxK=require("serialization")wVzn,pE=YIiSKsxK.serialize,YIiSKsxK.unserialize end;local RSjapQ;RSjapQ=require("event").pull;local QJf,zC;do | |
local Ua=require("term")QJf,zC=Ua.clearLine,Ua.getCursor end;local pfZ3SPy_ | |
pfZ3SPy_=os.exit;local pDNa2ox6,Do6yo7nm | |
do local qeJtG=io;pDNa2ox6,Do6yo7nm=qeJtG.write,qeJtG.stderr end;local y06X3k,ivnJjrA | |
do local pdpNgBcZ=table;y06X3k,ivnJjrA=pdpNgBcZ.insert,pdpNgBcZ.unpack end;local d3fMjkg=JQi1jg.list;local el,Wu_uIt={},{}local w=nil;local sgeP={}local CM={} | |
local Qlmlet="/etc/hpm/module/"local _="/var/lib/hpm/dist/"local RkGFh6=0;local hw18="/etc/hpm/hpm.cfg" | |
local nvCiFt7r=[[Usage: hpm OPTIONS COMMAND | |
See `man hpm` for more info.]] | |
local xSebv5Jc=[[-- << Global settings >> ------------------------------------------------------- | |
-- A directory where package manifests will be placed. | |
-- It will be created if it doesn't exist. | |
dist = "/var/lib/hpm/dist" | |
-- A place where to search for custom hpm modules. | |
-- It will be created if it doesn't exist. | |
modules = "/etc/hpm/module" | |
-- << Settings related to the hel module >> ------------------------------------ | |
hel = {} | |
-- If set to `false`, hpm will *only* remove a package that hpm is told to | |
-- remove. Otherwise, all of its dependants will be also removed. | |
hel.remove_dependants = true | |
-- << Settings related to the oppm module >> ----------------------------------- | |
oppm = {} | |
-- A directory where package manifests will be stored for faster access. | |
oppm.cache_directory = "/var/cache/hpm/oppm" | |
-- See hel.remove_dependants above. | |
oppm.remove_dependants = true]] | |
local mMp={info=function(...) | |
if el.v then | |
return | |
print(table.concat((function(...)local wV={}local rLd=1;local z8oF={...}for DB6A7N=1,#z8oF do local VhYX=z8oF[DB6A7N] | |
wV[rLd]=tostring(VhYX)rLd=rLd+1 end;return wV end)(...),"\t"))end end,print=function(...) | |
if | |
not(el.q)then | |
return | |
print(table.concat((function(...)local Ha7ErH={}local rjU95v=1;local sxBl={...}for m=1,#sxBl do local nD4LhX6z=sxBl[m] | |
Ha7ErH[rjU95v]=tostring(nD4LhX6z)rjU95v=rjU95v+1 end;return Ha7ErH end)(...),"\t"))end end,error=function(...) | |
if | |
not(el.q)then | |
return | |
Do6yo7nm:write( | |
table.concat((function(...)local iN={}local Lq=1;local s9tW={...} | |
for R61K=1,#s9tW do | |
local Jf4os=s9tW[R61K]iN[Lq]=tostring(Jf4os)Lq=Lq+1 end;return iN end)(...),"\t")..'\n')end end,fatal=function(...) | |
if | |
not(el.q)then | |
Do6yo7nm:write( | |
table.concat((function(...)local a4xc={}local e=1;local la5={...}for i=1,#la5 do local R=la5[i] | |
a4xc[e]=tostring(R)e=e+1 end;return a4xc end)(...),"\t")..'\n')end;return pfZ3SPy_(1)end}local rDtVf | |
rDtVf=function(xWVu,Yw8Yxix)if not(xWVu)then return mMp.fatal(Yw8Yxix)end end;local vj | |
vj=function(i)return | |
mMp.fatal((tostring(i))..": Not implemented yet!")end;local z | |
z=function()pDNa2ox6(nvCiFt7r)return pfZ3SPy_(0)end;local Zg | |
Zg=function(VoXG,JL0I04c)if not(VoXG)then mMp.fatal(JL0I04c)end;return VoXG end;local ykRppH | |
ykRppH=function(En6r_K97,T4AA,VnuCKTdu) | |
if not(type(En6r_K97 ==T4AA))then | |
mMp.fatal("Value '".. | |
tostring(En6r_K97).. | |
"' is "..tostring(type(VnuCKTdu))..", however, a ".. | |
tostring(T4AA).." is expected.")end;return VnuCKTdu end;local WQ6 | |
WQ6=function(XnNgn)return ykRppH(XnNgn,"number",tonumber(XnNgn))end;local y36Aetn | |
y36Aetn=function(H1JD)return ykRppH(H1JD,"string",tostring(H1JD))end;local iPL3B4cr | |
iPL3B4cr=function(gEEa9I,ULLLDUm) | |
for e4F3,GsfNt7 in pairs(ULLLDUm)do if GsfNt7 ==gEEa9I then return true,e4F3 end end;return false end;local GI2hz6SK | |
GI2hz6SK=function(fF0)local YWPfQKb2=0 | |
for r,OS0Zp3i in pairs(fF0)do YWPfQKb2=YWPfQKb2+1 end;return YWPfQKb2 end;local Oh | |
Oh=function(BK) | |
if type(BK)=="nil"then return true elseif type(BK)=="string"then | |
return not BK or#BK<1 elseif type(BK)=="table"then return not BK or GI2hz6SK(BK)<1 else | |
return true end end;local PG | |
PG=function(Idjbe70) | |
for B=1,#Idjbe70 do local nDjt=Idjbe70[B]if not nDjt then return false end end;return true end;local n | |
n=function(NVWt)return pzDMZwG(NVWt)and u(NVWt)end;local O | |
O=function(efuUGMh)return pzDMZwG(efuUGMh)and not u(efuUGMh)end;local N5UjTN | |
N5UjTN=function(p4nNp)return p4nNp==1 and""or"s"end;local qLH5 | |
qLH5=function(VW)return VW~=1 and""or"s"end;local tE | |
tE=function(Zt)return Zt==1 and"is"or"are"end;local VcV0EuD | |
VcV0EuD=function(V)return V:match("^([^:]-):?([^:@]+)@?([^:@]*)$")end;local pX4gCR | |
pX4gCR=function(mzeTI) | |
if | |
JQi1jg.get(JD.resolve(mzeTI)).isReadOnly()then return false,"the path is readonly!"elseif not pzDMZwG(mzeTI)then | |
return false,"the filesystem node doesn't exist."else | |
if | |
not(u(mzeTI)or JQi1jg.isLink(mzeTI))then return JQi1jg.remove(mzeTI)else for sy4J in Zg(d3fMjkg(mzeTI))do | |
pX4gCR(XxJ(mzeTI,sy4J))end;return JQi1jg.remove(mzeTI)end end end;local gad4ZcL | |
gad4ZcL=function()local ztJhP_u8=el.c or el.config or hw18 | |
if | |
not O(ztJhP_u8)then local ys=JQi1jg.path(ztJhP_u8) | |
if not n(ys)then local X,zLtWO09=XPoQB(ys)if not X then | |
return false, | |
"Failed to create '".. | |
tostring(ys).."' directory for the config file: "..tostring(zLtWO09)end end;local rMQ1um8,U2=io.open(ztJhP_u8,"w") | |
if rMQ1um8 then | |
rMQ1um8:write(xSebv5Jc)rMQ1um8:close()else return false, | |
"Failed to open config file for writing: "..tostring(U2)end end;local D,XIcl=io.open(ztJhP_u8,"r") | |
if D then local Z=D:read("*all") | |
D:close()local ZDICnKE={} | |
(load(Z,"config","t",ZDICnKE))()local L | |
L=function(B58)if B58 ==nil then B58={}end | |
return | |
setmetatable(B58,{__index={get=function(PYVzrNl,KTVmRC,Pa) | |
if type(B58[PYVzrNl])~="nil"then | |
if | |
type(B58[PYVzrNl])=="table"then return L(B58[PYVzrNl])end;return B58[PYVzrNl]end | |
mMp.error("Attempt to access undeclared config field '"..tostring(PYVzrNl).."'!")if not Pa then return KTVmRC else return L(KTVmRC)end end}})end;CM=L(ZDICnKE)Qlmlet=CM.get("modules",Qlmlet) | |
_=CM.get("dist",_)return CM else | |
return false,"Failed to open config file for reading: "..tostring(XIcl)end end;local dk | |
dk=function()if not(s("internet"))then | |
mMp.fatal("This command requires an internet card to run!")end;w=w or | |
require("internet").request end;local E;E=function(bmK)dk()return pcall(w,bmK)end;local OO | |
OO=function() | |
if not | |
n(Qlmlet)then local j,vMgKnGj=XPoQB(Qlmlet)if not j then | |
return false,"Failed to create '".. | |
tostring(Qlmlet).. | |
"' directory for custom modules: "..tostring(vMgKnGj)end end;local OJPc3R=Zg(d3fMjkg(Qlmlet)) | |
for M9K in OJPc3R do | |
local Zeu=M9K:match("^(.+)%..+$") | |
local Q2_d=(loadfile(XxJ(Qlmlet,M9K),"t",_ENV))()if Q2_d then sgeP[Zeu]=Q2_d end end;return true end;local y | |
y=function(W0iTcMIt)local N=W0iTcMIt;local Hald6SO | |
do local Dq=W0iTcMIt:find(':')if Dq then | |
N=W0iTcMIt:sub(Dq+1)Hald6SO=W0iTcMIt:sub(1,Dq-1)end end | |
if not Hald6SO then local y3Ur={} | |
for GL70F7uL,Hald6SO in pairs(sgeP)do | |
if Hald6SO[N]then if type(Hald6SO[N])=="table"and | |
Hald6SO[N].__public==true then | |
y06X3k(y3Ur,{class=Hald6SO,module=GL70F7uL,method=Hald6SO[N]})end end end | |
if#y3Ur>1 then local lqANrrJA=nil;for WUFTXBy6,Hald6SO in pairs(y3Ur)do | |
if Hald6SO.module=="hel"then lqANrrJA=WUFTXBy6;break end end;if lqANrrJA then | |
y3Ur={y3Ur[lqANrrJA]}end end | |
if#y3Ur>1 then | |
mMp.print("Ambiguous choice: method ".. | |
tostring(N).." is implemented in the following modules:")for aEZf=1,#y3Ur do local Hald6SO=y3Ur[aEZf] | |
mMp.print(" * "..tostring(Hald6SO.module))end | |
mMp.print( | |
"Choose a specific module by prepending its name with a colon, e.g., ".. | |
tostring(y3Ur[1].module)..":"..tostring(N)..".")return false elseif#y3Ur==0 then | |
mMp.error("Unknown command: "..tostring(N))return false else Hald6SO=y3Ur[1].module | |
mMp.info("Note, using "..tostring(Hald6SO)..":".. | |
tostring(N)..".")return | |
function(...)return y3Ur[1].method(y3Ur[1].class,...)end end else | |
if sgeP[Hald6SO]and Oh(N)then local QjQ_o={} | |
for wDiq_,QYA5WJOY in pairs(sgeP[Hald6SO])do if type(QYA5WJOY)== | |
"table"and QYA5WJOY.__public==true then | |
y06X3k(QjQ_o,tostring(wDiq_))end end | |
mMp.print("Available module-specific commands: "..tostring(table.concat(QjQ_o,", ")))return false end | |
if | |
not sgeP[Hald6SO]or not sgeP[Hald6SO][N]or | |
sgeP[Hald6SO][N]and | |
(type(sgeP[Hald6SO][N])~="table"or | |
sgeP[Hald6SO][N].__public~=true)then | |
mMp.error("Unknown command: "..tostring(Hald6SO)..":"..tostring(N))return false else return function(...) | |
return sgeP[Hald6SO][N](sgeP[Hald6SO],...)end end end end;local cR6rJlAl | |
cR6rJlAl=function(yliV8) | |
if not yliV8 or yliV8 ==""then yliV8="hel"else yliV8=yliV8 end;return sgeP[yliV8]or sgeP.default end;local M6ilzGJ | |
M6ilzGJ=function(rjpKFl,YUGQovw,...)if rjpKFl==nil then rjpKFl=sgeP.default end | |
if | |
rjpKFl[YUGQovw]then return rjpKFl[YUGQovw](rjpKFl,...)else return | |
sgeP.default[YUGQovw](sgeP.default,...)end end;local iW6CD | |
iW6CD=function(XZt7GyF,Zn3SC,D4,crA9EKx)if Zn3SC==nil then Zn3SC="hel"end | |
if D4 ==nil then D4=XxJ(_,Zn3SC)end;if crA9EKx==nil then crA9EKx=XZt7GyF.name end;if not XZt7GyF then | |
return false,"'nil' given"end | |
if not n(D4)then local Wp9xT,P=XPoQB(D4)if not Wp9xT then | |
return false,"Failed to create '".. | |
tostring(XxJ(D4,Zn3SC)).."' directory for manifest files: "..tostring(P)end end;local IcsJ,A=io.open(XxJ(D4,crA9EKx),"w") | |
if IcsJ then | |
IcsJ:write(wVzn(XZt7GyF))IcsJ:close()return true else return false, | |
"Failed to open file for writing: "..tostring(A)end end;local wZdg | |
wZdg=function(o0_XG8FI,jLsxpw,x)if x==nil then x="hel"end | |
jLsxpw=jLsxpw or XxJ(_,x,o0_XG8FI) | |
if O(jLsxpw)then local AXNfV,cX=io.open(jLsxpw,"rb") | |
if AXNfV then | |
local iyx=Zg(pE(AXNfV:read("*all")))AXNfV:close()return iyx else return false, | |
"Failed to open manifest for '"..tostring(o0_XG8FI).."' package: ".. | |
tostring(cX)end else return false, | |
"No manifest found for '"..tostring(o0_XG8FI).."' package"end end;local BaX | |
BaX=function(bxvn,mWYrzB)if mWYrzB==nil then mWYrzB="hel"end | |
local O7kX=XxJ(_,mWYrzB,bxvn) | |
if O(O7kX)then return pX4gCR(O7kX)else return false, | |
"No manifest found for '"..tostring(bxvn).."' package"end end;local SJsW11k | |
SJsW11k=function(Q4XSpdY)return | |
setmetatable({__public=true},{__call=function(fzTyrQ9F,...)return Q4XSpdY(...)end})end;local Ki1HJT | |
Ki1HJT=function(fAumJ0i,i0) | |
return | |
function()local tZliF4,jlmopoj=pcall(fAumJ0i) | |
if not(tZliF4)then return false, | |
"Could not download '".. | |
tostring(i0).."': "..tostring(jlmopoj)else return jlmopoj end end end;local wjim8xCV | |
wjim8xCV=function(R,uS_N6,o5SLRA) | |
if uS_N6 ==nil then uS_N6="Could not download '%s': %s"end;if o5SLRA==nil then o5SLRA="Could not download '%s': %s"end | |
local ztwXaCR,M2WtMgiq,FgfME=E(R)if not(ztwXaCR and M2WtMgiq)then | |
return false,uS_N6:format(R,FgfME)end;local ylH9o=""for CC4Kfjh,FgfME in Ki1HJT(M2WtMgiq)do | |
if CC4Kfjh then | |
ylH9o=ylH9o..CC4Kfjh else return false,o5SLRA:format(R,FgfME)end end;return ylH9o end;local EQLam | |
EQLam=function() | |
if not(el.y)then | |
io.write("Press [ENTER] to continue...")local k=select(3,RSjapQ("key_down"))if k==13 then QJf()return true else | |
io.write("\n")return false end else return true end end;local qTDt | |
qTDt=function(eUQ0x)local r0OR=0;local pYHkv={} | |
if not(Oh(eUQ0x.install))then | |
local hxZHlgP={"Packages to INSTALL:",table.concat(eUQ0x.install," ")}y06X3k(pYHkv,hxZHlgP)r0OR=r0OR+#eUQ0x.install else | |
eUQ0x.install={}end | |
if not(Oh(eUQ0x.reinstall))then | |
local zct={"Packages to REINSTALL:",table.concat(eUQ0x.reinstall," ")}y06X3k(pYHkv,zct)r0OR=r0OR+#eUQ0x.reinstall else | |
eUQ0x.reinstall={}end | |
if not(Oh(eUQ0x.upgrade))then | |
local WQk6Wkd={"Packages to UPGRADE:",table.concat(eUQ0x.upgrade," ")}y06X3k(pYHkv,WQk6Wkd)r0OR=r0OR+#eUQ0x.upgrade else | |
eUQ0x.upgrade={}end | |
if not(Oh(eUQ0x.remove))then | |
local t={"Packages to REMOVE:",table.concat(eUQ0x.remove," ")}y06X3k(pYHkv,t)r0OR=r0OR+#eUQ0x.remove else | |
eUQ0x.remove={}end | |
do | |
local pRCHPl={tostring(#eUQ0x.install).." to INSTALL, ".. | |
tostring(#eUQ0x.reinstall).. | |
" to REINSTALL, ".. | |
tostring(#eUQ0x.upgrade).." to UPGRADE, "..tostring(#eUQ0x.remove).. | |
" to REMOVE."}y06X3k(pYHkv,pRCHPl)end | |
for sCffg4HK,EyljhkFp in pairs(pYHkv)do for sCffg4HK,uGDn542 in pairs(EyljhkFp)do | |
if sCffg4HK==1 then mMp.print(uGDn542)else mMp.print(" ".. | |
tostring(uGDn542))end end;if | |
sCffg4HK~=#pYHkv then mMp.print("")end end | |
if r0OR>0 then if not(EQLam())then return pfZ3SPy_(7)end end end | |
do local DQ;local s6Ahlni_={}s6Ahlni_.__index=s6Ahlni_ | |
DQ=setmetatable({__init=function()end,__base=s6Ahlni_,__name="default"},{__index=s6Ahlni_,__call=function(H,...) | |
local YlzZm=setmetatable({},s6Ahlni_)H.__init(YlzZm,...)return YlzZm end})s6Ahlni_.__class=DQ;local T6dNu=DQ | |
T6dNu.install=function()return | |
mMp.fatal("Incorrect source is provided! No default 'install' implementation.")end | |
T6dNu.remove=function(T6dNu,vj9879b5,cotcYZ1f)if cotcYZ1f==nil then cotcYZ1f="hel"end | |
if vj9879b5 then | |
if vj9879b5.files then | |
for FRcmT,zfl in | |
pairs(vj9879b5.files)do local itxD=XxJ(zfl.dir,zfl.name)local JPHs7A,yzYgnMtr=pX4gCR(itxD) | |
if | |
not(JPHs7A)then return false,"Failed to remove '".. | |
tostring(itxD).."': "..tostring(yzYgnMtr)end end end;return BaX(vj9879b5.name,cotcYZ1f)else | |
return false,"Package can't be removed: the manifest is empty."end end | |
T6dNu.save=function()return | |
mMp.fatal("Incorrect source is provided! No default 'save' implementation.")end;sgeP.default=DQ end | |
do local o;local wmkJ=sgeP.default;local I1={}I1.__index=I1 | |
setmetatable(I1,wmkJ.__base) | |
o=setmetatable({__init=function(R60Ru4bj,...)return o.__parent.__init(R60Ru4bj,...)end,__base=I1,__name="hel",__parent=wmkJ},{__index=function(eQWRf,WT2AX) | |
local _AvO=rawget(I1,WT2AX)if _AvO==nil then local qEO=rawget(eQWRf,"__parent") | |
if qEO then return qEO[WT2AX]end else return _AvO end end,__call=function(q,...) | |
local WUY7=setmetatable({},I1)q.__init(WUY7,...)return WUY7 end})I1.__class=o;local gXu5hG=o;gXu5hG.URL="https://hel-roottree.rhcloud.com/" | |
gXu5hG.parsePackageJSON=function(gXu5hG,_puepou,DYLeJ)if | |
DYLeJ==nil then DYLeJ=JtAjijkG.Spec("*")end;local udbF=nil | |
local dt1={} | |
for UjlBMb,PKWIJ9 in pairs(_puepou.versions)do local rQYWEt=JtAjijkG.Version(UjlBMb)if not | |
(rQYWEt)then | |
mMp.fatal("Could not parse the version in package: "..tostring(rQYWEt))end;dt1[rQYWEt]=PKWIJ9 end | |
local V7eMEiVW,Co1tUVas=pcall(function()return | |
DYLeJ:select((function()local nCwsa={}local IPPy=1 | |
for zYGA2q2,I9Mw in pairs(dt1)do nCwsa[IPPy]=zYGA2q2;IPPy=IPPy+1 end;return nCwsa end)())end)if not(V7eMEiVW)then | |
mMp.fatal("Could not select the best version: "..tostring(Co1tUVas))end | |
udbF=tostring(Co1tUVas)if not(Co1tUVas)then | |
mMp.fatal("No candidate for version specification '"..tostring(DYLeJ).."' found!")end | |
local B={name=_puepou.name,version=udbF,files={},dependencies={}}for e,BUtIET in pairs(dt1[Co1tUVas].files)do local NvAj=BUtIET.dir;local Icg=BUtIET.name | |
y06X3k(B.files,{url=e,dir=NvAj,name=Icg})end;for PzMsk,axLuO in | |
pairs(dt1[Co1tUVas].depends)do local j=axLuO.version;local As=axLuO.type | |
y06X3k(B.dependencies,{name=PzMsk,version=j,type=As})end | |
return B end | |
gXu5hG.getPackageSpec=function(gXu5hG,JmCzKm) | |
mMp.info("Downloading package data for "..tostring(JmCzKm).." ...") | |
local Mwhc,A6z=E(gXu5hG.URL.."packages/"..JmCzKm)if not(Mwhc)then | |
mMp.fatal("HTTP request error: "..A6z)end;local _Mk=""for L9 in A6z do _Mk=_Mk..L9 end | |
local PXrrrSid=UlikV:decode(_Mk)if not(PXrrrSid)then | |
mMp.fatal("Incorrect JSON format!\n"..tostring(_Mk))end;return PXrrrSid.data end | |
gXu5hG.rawInstall=function(gXu5hG,_KZPScl,dbTwy,R4f819q)if dbTwy==nil then dbTwy=false end | |
if R4f819q==nil then R4f819q=false end;local Kj1I | |
if R4f819q then Kj1I=XxJ(LfEJbh_(),_KZPScl.name)else Kj1I="/"end | |
if R4f819q and not n(Kj1I)then local nTUMgqomA,Id5sIM=XPoQB(Kj1I) | |
if not(nTUMgqomA)then | |
mMp.fatal( | |
"Failed creating '".. | |
tostring(Kj1I).."' directory for package '"..tostring(_KZPScl.name).. | |
"'! \n"..tostring(Id5sIM))end elseif not R4f819q then local gZM2ANLt=wZdg(_KZPScl.name,nil,"hel") | |
if gZM2ANLt then | |
if | |
gZM2ANLt.version==tostring(_KZPScl.version)then | |
mMp.print("'".. | |
tostring(_KZPScl.name).."@".. | |
tostring(gZM2ANLt.version).."' is already installed, skipping...")return gZM2ANLt else | |
mMp.fatal("'".. | |
tostring(_KZPScl.name).. | |
"@".. | |
tostring(_KZPScl.version).. | |
"' was attempted to install, however, another version of the same package is already installed: '"..tostring(_KZPScl.name).. | |
"@"..tostring(gZM2ANLt.version).."'")end end end | |
for aC72qEnu,B60J in pairs(_KZPScl.files)do | |
mMp.info("Fetching '"..tostring(B60J.name).."' ...")local Y4=Zg(wjim8xCV(B60J.url)) | |
local f=XxJ(Kj1I,B60J.dir) | |
if not n(f)then local yeCnvcd6,Iq93c6cA=XPoQB(f)if not(yeCnvcd6)then | |
mMp.fatal("Failed to create '".. | |
tostring(f).. | |
"' directory for '".. | |
tostring(B60J.name).."'! \n"..tostring(Iq93c6cA))end end | |
do local nsM0h;B60J,nsM0h=io.open(XxJ(f,B60J.name),"w")if | |
not(B60J)then | |
mMp.fatal("Could not open '"..tostring(XxJ(f,B60J.name)).. | |
"' for writing: "..tostring(nsM0h))end | |
B60J:write(Y4)B60J:close()end end;return | |
{name=_KZPScl.name,version=tostring(_KZPScl.version),files=_KZPScl.files,dependencies=_KZPScl.dependencies,manual=dbTwy}end | |
gXu5hG.resolveDependencies=function(gXu5hG,Czi,IlxN,EA_3x01A,m54tY2)if IlxN==nil then IlxN={}end | |
if EA_3x01A==nil then EA_3x01A={}end;if m54tY2 ==nil then m54tY2={}end | |
for WJWMdKI=1,#Czi do local AhbP=Czi[WJWMdKI]local QHFgYUN,RoEsr7So | |
QHFgYUN,RoEsr7So=AhbP.name,AhbP.version;local dX=false;for Rz=1,#IlxN do local j177r=IlxN[Rz] | |
if j177r.pkg.name==QHFgYUN then dX=true;break end end | |
if not(dX)then | |
y06X3k(EA_3x01A,{name=QHFgYUN,version=""})local j=wZdg(QHFgYUN,nil,"hel") | |
if not j or not | |
RoEsr7So:match(JtAjijkG.Version(j.version))then | |
local qCaFw=gXu5hG:getPackageSpec(QHFgYUN)local syvPi=gXu5hG:parsePackageJSON(qCaFw,RoEsr7So) | |
EA_3x01A[#EA_3x01A].version=syvPi.version;local NrgSK2=syvPi.dependencies | |
for wIH=1,#NrgSK2 do local TYWkpc=NrgSK2[wIH]dX=false | |
for k=1,#IlxN do | |
local J=IlxN[k]if J.pkg.name==TYWkpc.name then dX=true;break end end | |
if not dX then local gtlO9=nil;for Lun,beUJXhjw in pairs(EA_3x01A)do | |
if beUJXhjw.name==TYWkpc.name then gtlO9=Lun;break end end | |
if gtlO9 then | |
if | |
EA_3x01A[gtlO9].version==TYWkpc.version then | |
mMp.fatal("Circular dependencies detected: '".. | |
tostring(QHFgYUN).. | |
"@".. | |
tostring(syvPi.version).. | |
"' depends on '".. | |
tostring(TYWkpc.name).. | |
"@".. | |
tostring(TYWkpc.version).. | |
"', and '".. | |
tostring(EA_3x01A[gtlO9].name).. | |
"@"..tostring(EA_3x01A[gtlO9].version).. | |
"' depends on '"..tostring(QHFgYUN).."@".. | |
tostring(syvPi.version).."'.")else | |
mMp.fatal("Attempted to install two versions of the same package: '".. | |
tostring(TYWkpc.name).. | |
"@".. | |
tostring(TYWkpc.version).. | |
"' and '".. | |
tostring(EA_3x01A[gtlO9].name).. | |
"@".. | |
tostring(EA_3x01A[gtlO9].version).. | |
"' when resolving dependencies for '"..tostring(QHFgYUN).."@".. | |
tostring(syvPi.version).."'.")end end | |
gXu5hG:resolveDependencies({{name=TYWkpc.name,version=JtAjijkG.Spec(TYWkpc.version)}},IlxN,EA_3x01A,m54tY2)end end;y06X3k(IlxN,{pkg=syvPi}) | |
y06X3k(m54tY2,{pkg=syvPi})else y06X3k(IlxN,{pkg=j})end;EA_3x01A[#EA_3x01A]=nil end end;return m54tY2 end | |
gXu5hG.getPackageDependants=function(gXu5hG,zY7adu,Nlvw,K55)if Nlvw==nil then Nlvw={}end;if K55 ==nil then K55={}end | |
for BJcMTdMi=1,#zY7adu | |
do local f1MKKJ=zY7adu[BJcMTdMi]local nFf=false | |
for EIqL41=1,#Nlvw do local iv=Nlvw[EIqL41]if | |
iv.name==f1MKKJ then nFf=true;break end end | |
if not(nFf)then y06X3k(K55,{name=f1MKKJ}) | |
local rfmMR4=wZdg(f1MKKJ,nil,"hel") | |
if rfmMR4 then y06X3k(Nlvw,{name=f1MKKJ,manifest=rfmMR4}) | |
local Tq2I=Zg(d3fMjkg(XxJ(_,"hel"))) | |
for GNo in Tq2I do rfmMR4=Zg(wZdg(GNo,nil,"hel")) | |
local e5x=rfmMR4.dependencies | |
for QrONvWGq=1,#e5x do local D94fnZaa=e5x[QrONvWGq] | |
if D94fnZaa.name==f1MKKJ then nFf=false | |
for XI=1,#Nlvw do | |
local FNi=Nlvw[XI]if FNi.name==GNo then nFf=true;break end end | |
if not nFf then | |
for pRW2nEmK=1,#K55 do local OR=K55[pRW2nEmK]if OR.name==GNo then | |
mMp.fatal("Circular dependencies detected: ".. | |
tostring(GNo))end end;gXu5hG:getPackageDependants({GNo},Nlvw,K55)end end end end else | |
mMp.fatal("Package ".. | |
tostring(f1MKKJ).." is referenced as a dependant of another package, however, this package isn't installed.")end;K55[#K55]=nil end end;return Nlvw end | |
gXu5hG.install=SJsW11k(function(gXu5hG,...) | |
if el.l or el["local"]then local f5=JD.resolve(...) | |
local UAc=Zg(wZdg(f5,XxJ(f5,"manifest")))local Ef=gXu5hG:resolveDependencies(UAc.depends,nil)local P=el.d or | |
el.onlyDeps;local F4AWvI={}for GYVN=1,#Ef do local DNlB1V=Ef[GYVN] | |
y06X3k(F4AWvI, | |
tostring(DNlB1V.pkg.name).."@"..tostring(DNlB1V.pkg.version))end;if not(P)then | |
y06X3k(F4AWvI, | |
tostring(UAc.name).."@"..tostring(UAc.version))end;qTDt({install=F4AWvI}) | |
for erb6G_E=1,# | |
Ef,1 do local QFUU10K=Ef[erb6G_E] | |
mMp.print("Installing '".. | |
tostring(QFUU10K.pkg.name).."@".. | |
tostring(QFUU10K.pkg.version).."'...")UAc=gXu5hG:rawInstall(QFUU10K.pkg,false,false) | |
local xNPDtul,k8=iW6CD(UAc,"hel") | |
if xNPDtul then | |
mMp.info("Saved the manifest of '"..tostring(UAc.name).."'.")else | |
mMp.fatal("Couldn't save the manifest of '"..tostring(UAc.name).. | |
"': "..tostring(k8)..".")end end | |
if not P then | |
mMp.print("Installing '"..tostring(UAc.name).. | |
"@"..tostring(UAc.version).."'...") | |
for fghe,vFXf in pairs(UAc.files)do if not n(XxJ(vFXf.dir,vFXf.name))then | |
XPoQB(vFXf.dir)end | |
local CA0uX7n,ze5Vpc3=o5sms(XxJ(f5,vFXf.url),XxJ(vFXf.dir,vFXf.name))if not(CA0uX7n)then | |
mMp.fatal("Cannot copy file '"..tostring(vFXf.name).. | |
"': "..tostring(ze5Vpc3))end end;local HmgRk,UuCdpVi=iW6CD(UAc,"hel") | |
if HmgRk then | |
mMp.info("Saved the manifest of '".. | |
tostring(UAc.name).."'.")else | |
mMp.fatal("Couldn't save the manifest of '"..tostring(UAc.name).. | |
"': "..tostring(UuCdpVi)..".")end end end;local Arww={}local BYH={...} | |
for vwK8=1,#BYH do local Sk_SiC=BYH[vwK8] | |
local X0bgPvA,M9CyqH=Sk_SiC:match("^(.+)@(.+)$"or Sk_SiC)if Oh(M9CyqH)then M9CyqH="*"end | |
mMp.info("Creating version specification for "..tostring(M9CyqH).. | |
" ...") | |
local z0x4qSAN,X0GTupeV=pcall(function()return JtAjijkG.Spec(M9CyqH)end)if not(z0x4qSAN)then | |
mMp.fatal("Could not parse the version specification: "..tostring(X0GTupeV).."!")end | |
y06X3k(Arww,{name=X0bgPvA,version=X0GTupeV})end;local o7E8TLH=el.r or el.reinstall;local N5N27Jd=el.s or el.save | |
local m=gXu5hG:resolveDependencies(Arww)local nK={}local _zr={} | |
for rQ=1,#m do local k=false | |
repeat local Oc=m[rQ] | |
if o7E8TLH then local IHovU=false | |
for e_wDQjk=1,#Arww do | |
local ClglY=Arww[e_wDQjk]if ClglY.name==Oc.pkg.name then IHovU=true;break end end;if IHovU then | |
y06X3k(nK,tostring(Oc.pkg.name).."@"..tostring(Oc.pkg.version))k=true;break end end | |
y06X3k(_zr,tostring(Oc.pkg.name).."@"..tostring(Oc.pkg.version))k=true until true;if not k then break end end;qTDt({install=_zr,reinstall=nK}) | |
if o7E8TLH then local S | |
do local NKetZhs={}local EFLZ0N1=1;for gL=1,# | |
Arww do local m4=Arww[gL] | |
NKetZhs[EFLZ0N1]=Zg(wZdg(m4.name,nil,"hel"))EFLZ0N1=EFLZ0N1+1 end | |
S=NKetZhs end;gXu5hG:_remove(S,true,false)end | |
for rNOL8G=1,#m do local q=m[rNOL8G] | |
mMp.print("Installing '"..tostring(q.pkg.name).."@".. | |
tostring(q.pkg.version).."'...")local lKO=false;for SGF=1,#Arww do local myIHU=Arww[SGF] | |
if myIHU.name==q.pkg.name then lKO=true;break end end | |
local hcwgu=gXu5hG:rawInstall(q.pkg,lKO,N5N27Jd)local omgCdqp8,X17eHTx=iW6CD(hcwgu,"hel") | |
if omgCdqp8 then | |
mMp.info("Saved the manifest of '".. | |
tostring(hcwgu.name).."'.")else | |
mMp.fatal("Couldn't save the manifest of '"..tostring(hcwgu.name).. | |
"': "..tostring(X17eHTx)..".")end end end) | |
gXu5hG.remove=SJsW11k(function(gXu5hG,...)local xxNCdF={...}local _cl1b={} | |
for Xz18nk=1,#xxNCdF do local P=xxNCdF[Xz18nk] | |
local sTX4=Zg(wZdg(P,nil,"hel"))y06X3k(_cl1b,sTX4)end;return gXu5hG:_remove(_cl1b,false)end) | |
gXu5hG._remove=function(gXu5hG,A0TJx,Nqdkw,t)if Nqdkw==nil then Nqdkw=false end;if t==nil then t=true end;local QbMO | |
if not | |
CM.get("hel",{},true).get("remove_dependants",true)or not t then | |
do local wYZ={}local aMd=1;for o0pf=1, | |
#A0TJx do local tx1LD=A0TJx[o0pf] | |
wYZ[aMd]={name=tx1LD.name,manifest=tx1LD}aMd=aMd+1 end;QbMO=wYZ end else | |
QbMO=gXu5hG:getPackageDependants((function()local N3ROeR={}local I1oQVnUd=1;for oTX=1,#A0TJx do local WZlF4=A0TJx[oTX] | |
N3ROeR[I1oQVnUd]=WZlF4.name;I1oQVnUd=I1oQVnUd+1 end | |
return N3ROeR end)())end | |
if not(Nqdkw)then | |
qTDt({remove=(function()local IxqPDOWH={}local GZqV=1 | |
for OVubrDw_=1,#QbMO do local G2_TeR8=QbMO[OVubrDw_] | |
IxqPDOWH[GZqV]= | |
"hel:"..tostring(G2_TeR8.manifest.name).."@".. | |
tostring(G2_TeR8.manifest.version)GZqV=GZqV+1 end;return IxqPDOWH end)()})end | |
for yk=1,#QbMO do local OPSPMfr_=QbMO[yk] | |
mMp.print("Removing '".. | |
tostring(OPSPMfr_.manifest.name).. | |
"@"..tostring(OPSPMfr_.manifest.version).."' ...") | |
Zg(o.__parent.remove(gXu5hG,OPSPMfr_.manifest,"hel"))end;return true end | |
gXu5hG.upgrade=SJsW11k(function(gXu5hG)local QnNOl={} | |
for tykg in Zg(d3fMjkg(XxJ(_,"hel")))do if not | |
(u(XxJ(_,"hel",tykg)))then | |
y06X3k(QnNOl,Zg(wZdg(tykg,nil,"hel")))end end;local aQs={} | |
for C_pPyW=1,#QnNOl do local mgb4b=QnNOl[C_pPyW] | |
local LOBqxO=gXu5hG:getPackageSpec(mgb4b.name)local m8=gXu5hG:parsePackageJSON(LOBqxO) | |
mgb4b.latest={spec=LOBqxO,data=m8} | |
if JtAjijkG.Version(mgb4b.latest.data.version)> | |
JtAjijkG.Version(mgb4b.version)then y06X3k(aQs,mgb4b)end end | |
gXu5hG:resolveDependencies((function()local mcoAHO={}local d3gFWO=1 | |
for D=1,#aQs do local obodPKnu=aQs[D] | |
mcoAHO[d3gFWO]={name=obodPKnu.name,version=JtAjijkG.Spec(obodPKnu.latest.data.version)}d3gFWO=d3gFWO+1 end;return mcoAHO end)())local uow_0tb | |
do local kgdzk={}local oVSp=1 | |
for uBJ=1,#aQs do local A=aQs[uBJ] | |
kgdzk[oVSp]=tostring(A.name).."@{".. | |
tostring(A.version).. | |
" => "..tostring(A.latest.data.version).."}"oVSp=oVSp+1 end;uow_0tb=kgdzk end;qTDt({upgrade=uow_0tb}) | |
for MP=1,#aQs do local jb=aQs[MP] | |
gXu5hG:_remove({jb},true,false) | |
mMp.print("Installing '".. | |
tostring(jb.name).."@"..tostring(jb.latest.data.version).. | |
"'...") | |
local uKSj=gXu5hG:rawInstall(jb.latest.data,jb.manual,false)local YXgXQB,bvL1X4=iW6CD(uKSj,"hel") | |
if YXgXQB then | |
mMp.info("Saved the manifest of '"..tostring(uKSj.name).. | |
"'.")else | |
mMp.fatal("Couldn't save the manifest of '"..tostring(uKSj.name).. | |
"': "..tostring(bvL1X4)..".")end end end) | |
gXu5hG.info=SJsW11k(function(gXu5hG,PPNahh,z2g)if z2g==nil then z2g="*"end;if Oh(PPNahh)then | |
mMp.fatal("Usage: hpm hel:info <package name> [<version specification>]")end;if Oh(z2g)then z2g="*"end | |
mMp.print( | |
"Creating version specification for "..tostring(z2g).." ...") | |
local m9JTkVv6,Q=pcall(function()return JtAjijkG.Spec(z2g)end)if not(m9JTkVv6)then | |
mMp.fatal("Could not parse the version specification: "..tostring(Q).."!")end | |
local bWkP=gXu5hG:getPackageSpec(PPNahh)local JtFj=gXu5hG:parsePackageJSON(bWkP,Q)local PQ3={}y06X3k(PQ3,"- Package name: ".. | |
tostring(bWkP.name)) | |
y06X3k(PQ3, | |
"- Description:\n"..tostring(bWkP.description)) | |
y06X3k(PQ3,"- Package owners: "..tostring(table.concat(bWkP.owners,", "))) | |
y06X3k(PQ3,"- Authors:\n".. | |
tostring(table.concat((function()local _xCtN={}local JVpe=1;local nG36XmZC=bWkP.authors | |
for Vf26=1,#nG36XmZC do | |
local xUGt=nG36XmZC[Vf26]_xCtN[JVpe]=" - "..tostring(xUGt)JVpe=JVpe+1 end;return _xCtN end)(),"\n"))) | |
y06X3k(PQ3,"- License: "..tostring(bWkP.license)) | |
y06X3k(PQ3,"- Versions: "..tostring(GI2hz6SK(bWkP.versions))..", latest: ".. | |
tostring(JtFj.version)) | |
y06X3k(PQ3," - Files: "..tostring(#JtFj.files)) | |
y06X3k(PQ3," - Depends: ".. | |
tostring(table.concat((function()local _U={}local hkI39=1;local MwwN=JtFj.dependencies;for oZ9=1,#MwwN do | |
local OXlT0=MwwN[oZ9] | |
_U[hkI39]=tostring(OXlT0.name).."@"..tostring(OXlT0.version)hkI39=hkI39+1 end;return | |
_U end)()))) | |
y06X3k(PQ3," - Changes:\n".. | |
tostring(bWkP.versions[JtFj.version].changes))y06X3k(PQ3,"- Stats:") | |
y06X3k(PQ3," - Views: ".. | |
tostring(bWkP.stats.views)) | |
y06X3k(PQ3,"- Creation date: ".. | |
tostring(bWkP.stats.date.created).." UTC") | |
y06X3k(PQ3,"- Last updated: ".. | |
tostring(bWkP.stats.date["last-updated"]).." UTC")return mMp.print(table.concat(PQ3,"\n"))end)if wmkJ.__inherited then wmkJ.__inherited(wmkJ,o)end | |
sgeP.hel=o end | |
do local V;local zIYNIXy1=sgeP.default;local c={}c.__index=c | |
setmetatable(c,zIYNIXy1.__base) | |
V=setmetatable({__init=function(I7,...)return V.__parent.__init(I7,...)end,__base=c,__name="oppm",__parent=zIYNIXy1},{__index=function(Upw,nqBfKL) | |
local gs3a=rawget(c,nqBfKL)if gs3a==nil then local AkKaBC=rawget(Upw,"__parent") | |
if AkKaBC then return AkKaBC[nqBfKL]end else return gs3a end end,__call=function(OmRH8,...) | |
local GY=setmetatable({},c)OmRH8.__init(GY,...)return GY end})c.__class=V;local mReHt4h=V | |
mReHt4h.REPOS="https://raw.githubusercontent.com/OpenPrograms/openprograms.github.io/master/repos.cfg" | |
mReHt4h.PACKAGES="https://raw.githubusercontent.com/%s/master/programs.cfg"mReHt4h.FILES="https://raw.githubusercontent.com/%s/%s" | |
mReHt4h.DIRECTORY="https://api.github.com/repos/%s/contents/%s?ref=%s"mReHt4h.DEFAULT_CACHE_DIRECTORY="/var/cache/hpm/oppm" | |
mReHt4h.cacheDirectory=function(mReHt4h) | |
local oukM79R=CM.get("oppm",{},true).get("cache_directory",mReHt4h.DEFAULT_CACHE_DIRECTORY) | |
if not(n(oukM79R))then local D_j,mZPe4w=XPoQB(oukM79R)if not(D_j)then | |
mMp.fatal( | |
"Could not create the cache directory at "..tostring(oukM79R)..": "..tostring(mZPe4w))end end;return oukM79R end | |
mReHt4h.listCache=function(mReHt4h)local OvZ={}local cBOpf=mReHt4h:cacheDirectory() | |
local KZYA5y=Zg(d3fMjkg(cBOpf)) | |
for YoCAN7OU in KZYA5y do | |
if u(XxJ(cBOpf,YoCAN7OU))then | |
local FoP=Zg(d3fMjkg(XxJ(cBOpf,YoCAN7OU))) | |
for jqtWXY in FoP do | |
if u(XxJ(cBOpf,YoCAN7OU,jqtWXY))then | |
local XgRb=Zg(d3fMjkg(XxJ(cBOpf,YoCAN7OU,jqtWXY))) | |
for G3e in XgRb do local GoP6=XxJ(cBOpf,YoCAN7OU,jqtWXY,G3e) | |
if not(u(GoP6))then local cZ_ | |
do | |
local Dff8,lEYwsOG9=io.open(GoP6,"r")if not Dff8 then | |
return false,"Could not open '".. | |
tostring(GoP6).."' for reading: "..tostring(lEYwsOG9)end | |
PG=Dff8:read("*all")cZ_=pE(PG)Dff8:close()end;local NYc8=XxJ(YoCAN7OU,jqtWXY) | |
y06X3k(OvZ,{path=GoP6,repo=NYc8,pkg=G3e,data=cZ_})end end end end end end;return OvZ end | |
mReHt4h.fixCache=function(mReHt4h)local M=mReHt4h:cacheDirectory() | |
local Vt95q2G=Zg(d3fMjkg(M)) | |
for jsPbwU in Vt95q2G do local Wvs3rd6o=true;local UdVlP=XxJ(M,jsPbwU) | |
if u(UdVlP)then | |
local N=Zg(d3fMjkg(UdVlP)) | |
for v9mB_RUi in N do local hX=true;local AVU=XxJ(UdVlP,v9mB_RUi) | |
if u(AVU)then | |
local I=Zg(d3fMjkg(AVU)) | |
for _x5O1 in I do local eFI8dI3=true;local i=XxJ(AVU,_x5O1)if not(u(i))then | |
eFI8dI3,hX,Wvs3rd6o=false,false,false end;if eFI8dI3 then pX4gCR(i)end end end;if hX then pX4gCR(AVU)end end end;if Wvs3rd6o then pX4gCR(UdVlP)end end;return true end | |
mReHt4h.resolveDirectory=function(mReHt4h,l6xUetCb,lOb_Sv,VspvGB9V) | |
local LrFLp5=Zg(wjim8xCV(mReHt4h.DIRECTORY:format(l6xUetCb,VspvGB9V,lOb_Sv)))LrFLp5=UlikV:decode(LrFLp5) | |
if LrFLp5.message then | |
return false,"Could not fetch ".. | |
tostring(l6xUetCb)..":".. | |
tostring(lOb_Sv).."/"..tostring(VspvGB9V).. | |
": "..tostring(LrFLp5.message)end;local GfB7={}local Iz_w1j=1 | |
for G=1,#LrFLp5 do local X7YKzX=LrFLp5[G] | |
if X7YKzX.type=="file"then | |
GfB7[Iz_w1j]={name=X7YKzX.name,url=X7YKzX.download_url,path=X7YKzX.path}Iz_w1j=Iz_w1j+1 end end;return GfB7 end | |
mReHt4h.updateCache=function(mReHt4h)local od0VOF=mReHt4h:cacheDirectory() | |
local oO6SbZ=Zg(mReHt4h:listCache())local UE_vrsNx,kef2zBS=wjim8xCV(mReHt4h.REPOS)if not(UE_vrsNx)then | |
return false, | |
"Could not fetch ".. | |
tostring(mReHt4h.REPOS)..": "..tostring(kef2zBS)end | |
UE_vrsNx=pE(UE_vrsNx)local Z={} | |
for ylW3uC0,N_G1 in pairs(UE_vrsNx)do local wkGNE=false | |
repeat | |
if N_G1.repo then | |
mMp.info("Fetching '"..tostring(ylW3uC0).."' at '".. | |
tostring(N_G1.repo).."' ...")local ccK,BV | |
ccK,BV,kef2zBS=E(mReHt4h.PACKAGES:format(N_G1.repo)) | |
if not(ccK and BV)then | |
mMp.error("Could not fetch '"..tostring(ylW3uC0).. | |
"' at '".. | |
tostring(N_G1.repo).."': "..tostring(kef2zBS))wkGNE=true;break end;local HnLY="" | |
for ccK,iWrSgT in function()return pcall(BV)end do | |
if not ccK then | |
mMp.error("Could not fetch '"..tostring(ylW3uC0).. | |
"' at '"..tostring(N_G1.repo).."': "..tostring(iWrSgT))HnLY=false;break else if not iWrSgT then break end;HnLY=HnLY..iWrSgT end end;if HnLY==false then wkGNE=true;break end;if Oh(HnLY)then | |
mMp.error("Could not fetch '".. | |
tostring(ylW3uC0).."' at '"..tostring(N_G1.repo).."'")wkGNE=true;break end | |
local cm51CH1n;cm51CH1n,kef2zBS=pE(HnLY) | |
if not cm51CH1n then | |
mMp.error("Manifest '"..tostring(ylW3uC0).. | |
"' at '".. | |
tostring(N_G1.repo).."' is malformed: "..tostring(kef2zBS))wkGNE=true;break end | |
for C,YK1 in pairs(cm51CH1n)do local t96Qtz=false | |
repeat | |
if C:match("[^A-Za-z0-9._-]")then | |
mMp.error( | |
"Package name contains illegal characters: "..tostring(ylW3uC0)..":"..tostring(C).."!")t96Qtz=true;break end;y06X3k(Z,{repo=N_G1.repo,name=C,data=YK1}) | |
t96Qtz=true until true;if not t96Qtz then break end end end;wkGNE=true until true;if not wkGNE then break end end;local ze0={} | |
for HjKNi=1,#Z do local Ub9iqg=Z[HjKNi]local r_S8HFRo,qIF4RFBv,wNbC65Ta | |
r_S8HFRo,qIF4RFBv,wNbC65Ta=Ub9iqg.name,Ub9iqg.repo,Ub9iqg.data;if iPL3B4cr(XxJ(qIF4RFBv,r_S8HFRo),ze0)then | |
mMp.error("There're multiple packages under the same name: ".. | |
tostring(r_S8HFRo).."!")end | |
if not | |
(n(XxJ(od0VOF,qIF4RFBv)))then local r;r,kef2zBS=XPoQB(XxJ(od0VOF,qIF4RFBv)) | |
if not | |
(r)then return false, | |
"Could not create directory '"..tostring(XxJ(od0VOF,qIF4RFBv)).."': ".. | |
tostring(kef2zBS)end end;local xOiPW | |
xOiPW,kef2zBS=io.open(XxJ(od0VOF,qIF4RFBv,r_S8HFRo),"w") | |
if not(xOiPW)then return false, | |
"Could not open '"..tostring(XxJ(od0VOF,qIF4RFBv,r_S8HFRo)).. | |
"' for writing: "..tostring(kef2zBS)end;do | |
xOiPW:write(wVzn({name=r_S8HFRo,repo=qIF4RFBv,data=wNbC65Ta}))xOiPW:close()end;local Z9j | |
do for OnJ1,KFU0 in | |
pairs(oO6SbZ)do | |
if KFU0.repo==qIF4RFBv and KFU0.pkg==r_S8HFRo then Z9j=OnJ1;break end end end;if Z9j then table.remove(oO6SbZ,Z9j)else | |
y06X3k(ze0,XxJ(qIF4RFBv,r_S8HFRo))end end;mMp.print("Removing old cache files ...") | |
for Pvuq=1,#oO6SbZ do | |
local lOpDJ=oO6SbZ[Pvuq]local YLe;YLe=lOpDJ.path;pX4gCR(YLe)end;mMp.print("Fixing bad cache nodes ...") | |
mReHt4h:fixCache() | |
mMp.print("- "..tostring(#Z).. | |
" program"..tostring(N5UjTN(#Z)).." cached.") | |
mMp.print("- "..tostring(#ze0).. | |
" package"..tostring(N5UjTN(#ze0)).." ".. | |
tostring(tE(#ze0)).." new.") | |
mMp.print("- ".. | |
tostring(#oO6SbZ).." package".. | |
tostring(N5UjTN(#oO6SbZ)).." no longer exist"..tostring(qLH5( | |
#oO6SbZ))..".")return true end | |
mReHt4h.parseLocalPath=function(mReHt4h,lTH,JL)if JL:sub(1,2)=="//"then return XxJ(lTH,JL:sub(3))else return | |
XxJ(lTH,"usr",JL)end end | |
mReHt4h.rawInstall=function(mReHt4h,FpU_E,JWtwnQ2t,uEKPPpj_,aYO4NN)if JWtwnQ2t==nil then JWtwnQ2t="/"end;if uEKPPpj_==nil then | |
uEKPPpj_=false end;if aYO4NN==nil then aYO4NN=false end | |
local CtG9nSQL=mReHt4h:listCache()local uZtK5yX={filesInstalled=0,packagesInstalled=0} | |
if | |
aYO4NN and not n(JWtwnQ2t)then local J,coSiE=XPoQB(JWtwnQ2t)if not(J)then | |
mMp.fatal("Failed to create '"..tostring(JWtwnQ2t).. | |
"' directory for package '"..tostring(FpU_E).."'! \n"..tostring(coSiE))end elseif | |
not aYO4NN then local wm=wZdg(FpU_E,nil,"oppm")if wm then | |
mMp.print("'"..tostring(FpU_E).. | |
"' is already installed, skipping...")return wm,uZtK5yX end end;local kr2CYaS | |
for _O=1,#CtG9nSQL do local smj=CtG9nSQL[_O]local obBu,cbQlG,YZQu1DR4,kza | |
obBu,cbQlG,YZQu1DR4,kza=smj.path,smj.pkg,smj.repo,smj.data;if cbQlG==FpU_E then kr2CYaS=smj;break end end;if not(kr2CYaS)then | |
mMp.fatal("No such package: "..tostring(FpU_E))end;local hXgSzEI={}local AUQ=kr2CYaS.repo | |
for CvGDk_2,EGpun in | |
pairs(kr2CYaS.data.data.files)do local LNlhK={} | |
if CvGDk_2:sub(1,1)==":"then | |
LNlhK=mReHt4h:resolveDirectory(AUQ,CvGDk_2:sub(2, | |
CvGDk_2:find("/")-1,nil),CvGDk_2:sub(CvGDk_2:find("/")+1))else | |
LNlhK={{name=JQi1jg.name(CvGDk_2),path=CvGDk_2,url=mReHt4h.FILES:format(AUQ,CvGDk_2)}}end;local FpU_E | |
for cnx_1g=1,#LNlhK do local eV=LNlhK[cnx_1g]local DGQnw,yLgHuF | |
FpU_E,DGQnw,yLgHuF=eV.name,eV.path,eV.url;local fpL=Zg(wjim8xCV(yLgHuF)) | |
local k6=mReHt4h:parseLocalPath(JWtwnQ2t,EGpun)if not(n(k6))then XPoQB(k6)end | |
do | |
local m,rvNhq6v=io.open(XxJ(k6,FpU_E),"w")if not m then | |
mMp.fatal("Could not open file for writing: "..tostring(rvNhq6v))end;m:write(fpL)m:close()end;uZtK5yX.filesInstalled=uZtK5yX.filesInstalled+1 | |
y06X3k(hXgSzEI,{name=FpU_E,url=yLgHuF,dir=k6})end end;local B={} | |
if kr2CYaS.data.data.dependencies then for gC in | |
pairs(kr2CYaS.data.data.dependencies)do y06X3k(B,{name=gC})end end;uZtK5yX.packagesInstalled=uZtK5yX.packagesInstalled+1;return | |
{name=FpU_E,files=hXgSzEI,dependencies=B,manual=uEKPPpj_},uZtK5yX end | |
mReHt4h.resolveDependencies=function(mReHt4h,QO,VvzMQHj,fSYJX,WV)if VvzMQHj==nil then VvzMQHj={}end | |
if fSYJX==nil then fSYJX={}end;if WV==nil then WV={}end;local yUho4MXRx=mReHt4h:listCache() | |
for J2=1,#QO do | |
local hgrBfz0w=QO[J2]local Gi=false;for wpv1=1,#VvzMQHj do local I9IMuWm=VvzMQHj[wpv1] | |
if I9IMuWm==hgrBfz0w then Gi=true;break end end | |
if not(Gi)then | |
fSYJX[hgrBfz0w]=true;local a=wZdg(hgrBfz0w,nil,"oppm") | |
if not a then local rZ | |
for VKTNfzUf=1,#yUho4MXRx do | |
local Oms4=yUho4MXRx[VKTNfzUf]local JfA;JfA=Oms4.pkg;if JfA==hgrBfz0w then rZ=Oms4;break end end;if not(rZ)then | |
return false,"Unknown package: "..tostring(hgrBfz0w)end | |
if rZ.data.data.dependencies then | |
for CPu1 in | |
pairs(rZ.data.data.dependencies)do Gi=false;for pfyhF=1,#VvzMQHj do local pglFz82w=VvzMQHj[pfyhF] | |
if pglFz82w==CPu1 then Gi=true;break end end | |
if not(Gi)then | |
if fSYJX[CPu1]then | |
mMp.fatal( | |
"Circular dependencies detected: '"..tostring(hgrBfz0w).. | |
"' depends on '"..tostring(CPu1).. | |
"', and '"..tostring(CPu1).."' depends on '".. | |
tostring(hgrBfz0w).."'.")end | |
mReHt4h:resolveDependencies({CPu1},VvzMQHj,fSYJX,WV)end end end;y06X3k(WV,hgrBfz0w)end;y06X3k(VvzMQHj,hgrBfz0w)fSYJX[hgrBfz0w]=nil end end;return WV end | |
mReHt4h.getPackageDependants=function(mReHt4h,RkeCL,LoW_7e,mLgQ)if LoW_7e==nil then LoW_7e={}end | |
if mLgQ==nil then mLgQ={}end | |
for ng=1,#RkeCL do local Pp_NboV=RkeCL[ng]local owAp3u2G=false | |
for OH0C=1,#LoW_7e do local kmQkm9cr=LoW_7e[OH0C]if | |
kmQkm9cr.name==Pp_NboV then owAp3u2G=true;break end end | |
if not(owAp3u2G)then y06X3k(mLgQ,{name=Pp_NboV}) | |
local IE97m=wZdg(Pp_NboV,nil,"oppm") | |
if IE97m then y06X3k(LoW_7e,{name=Pp_NboV,manifest=IE97m}) | |
local wey=Zg(d3fMjkg(XxJ(_,"oppm"))) | |
for hThO6 in wey do IE97m=Zg(wZdg(hThO6,nil,"oppm")) | |
local zXU=IE97m.dependencies | |
for HmJym2=1,#zXU do local Jjb7Am5=zXU[HmJym2] | |
if Jjb7Am5.name==Pp_NboV then owAp3u2G=false | |
for UwqY7A=1,#LoW_7e do | |
local k=LoW_7e[UwqY7A]if k.name==hThO6 then owAp3u2G=true;break end end | |
if not owAp3u2G then | |
for d7gPKcw=1,#mLgQ do local naeNp=mLgQ[d7gPKcw]if naeNp.name==hThO6 then | |
mMp.fatal( | |
"Circular dependencies detected: "..tostring(hThO6))end end | |
mReHt4h:getPackageDependants({hThO6},LoW_7e,mLgQ)end end end end else | |
mMp.fatal("Package ".. | |
tostring(Pp_NboV).." is referenced as a dependant of another package, however, this package isn't installed.")end;mLgQ[#mLgQ]=nil end end;return LoW_7e end | |
mReHt4h.whatDependsOn=function(mReHt4h,gA)local r=Zg(wZdg(gA,nil,"oppm"))local LWe={} | |
local _3Tq=Zg(d3fMjkg(XxJ(_,"oppm"))) | |
for Rq1hByv in _3Tq do r=Zg(wZdg(Rq1hByv,nil,"oppm"))local iFk=r.dependencies | |
for sEFtmNgB=1,# | |
iFk do local qxiez0Cn=iFk[sEFtmNgB]if qxiez0Cn.name==gA then | |
y06X3k(LWe,Rq1hByv)end end end;return LWe end | |
mReHt4h.install=SJsW11k(function(mReHt4h,...)local Ck_H={...}local Sc=el.r or el.reinstall | |
local _QFw_It=el.s or el.save | |
local WLqHf=Zg(mReHt4h:resolveDependencies(Ck_H)) | |
qTDt({install=(function()local BIwW6_={}local Vdfc3=1;for CzM7PG=1,#WLqHf do local RKf6s5=WLqHf[CzM7PG] | |
if not Sc or | |
not iPL3B4cr(RKf6s5,Ck_H)then BIwW6_[Vdfc3]=RKf6s5;Vdfc3=Vdfc3+1 end end | |
return BIwW6_ end)(),reinstall= | |
Sc and | |
(function()local tP9E_={}local Y1WX=1 | |
for G06Z2=1,#WLqHf do local K=WLqHf[G06Z2]if iPL3B4cr(K,Ck_H)then tP9E_[Y1WX]=K;Y1WX= | |
Y1WX+1 end end;return tP9E_ end)()or nil})local vN={filesInstalled=0,packagesInstalled=0} | |
if Sc then local tQx9TV | |
do local FL7g2o={}local dkh7Tt9=1;for XiNd_H=1,#Ck_H do | |
local Q_c4px86=Ck_H[XiNd_H]FL7g2o[dkh7Tt9]=Zg(wZdg(Q_c4px86,nil,"oppm"))dkh7Tt9= | |
dkh7Tt9+1 end | |
tQx9TV=FL7g2o end;mReHt4h:_remove(tQx9TV,true,false)end | |
for _F6VYt=1,#WLqHf do local ITv3PH1i=WLqHf[_F6VYt] | |
mMp.print("Installing '".. | |
tostring(ITv3PH1i).."'...")local _5fF;if _QFw_It then _5fF="./"..tostring(ITv3PH1i).."/"else | |
_5fF="/"end | |
local OUQqQp,OyOfzTWn=mReHt4h:rawInstall(ITv3PH1i,_5fF,iPL3B4cr(ITv3PH1i,Ck_H),_QFw_It) | |
vN.filesInstalled=vN.filesInstalled+OyOfzTWn.filesInstalled | |
vN.packagesInstalled=vN.packagesInstalled+OyOfzTWn.packagesInstalled | |
if vN.packagesInstalled~=0 then local rx,ijvSrZA1=iW6CD(OUQqQp,"oppm") | |
if rx then | |
mMp.info( | |
"Saved the manifest of '"..tostring(OUQqQp.name).."'.")else | |
mMp.fatal("Couldn't save the manifest of '"..tostring(OUQqQp.name).."': ".. | |
tostring(ijvSrZA1)..".")end end end | |
mMp.print("- ".. | |
tostring(vN.packagesInstalled).." package".. | |
tostring(N5UjTN(vN.packagesInstalled)).." installed.")return | |
mMp.print("- ".. | |
tostring(vN.filesInstalled).." file".. | |
tostring(N5UjTN(vN.filesInstalled)).." installed.")end) | |
mReHt4h.remove=SJsW11k(function(mReHt4h,...)local STNuSN6={...}local PYOeGnAZ={}for s10ar5XH=1,#STNuSN6 do | |
local YoKhvIs=STNuSN6[s10ar5XH]local I2ipE=Zg(wZdg(YoKhvIs,nil,"oppm")) | |
y06X3k(PYOeGnAZ,I2ipE)end;return | |
mReHt4h:_remove(PYOeGnAZ,false)end) | |
mReHt4h._remove=function(mReHt4h,qS730I,PYEbnua,Um4ZYiT)if PYEbnua==nil then PYEbnua=false end;if Um4ZYiT==nil then | |
Um4ZYiT=true end;local AF | |
if not | |
CM.get("oppm",{},true).get("remove_dependants",true)or not Um4ZYiT then | |
do | |
local shIHW={}local H5=1;for HYY=1,#qS730I do local C3=qS730I[HYY] | |
shIHW[H5]={name=C3.name,manifest=C3}H5=H5+1 end;AF=shIHW end else | |
AF=mReHt4h:getPackageDependants((function()local SkCMMH={}local kvvs=1;for _yTx3S94=1,#qS730I do local Mm=qS730I[_yTx3S94] | |
SkCMMH[kvvs]=Mm.name;kvvs=kvvs+1 end;return SkCMMH end)())end | |
if not(PYEbnua)then | |
qTDt({remove=(function()local g524={}local WUdVeYc=1;for lHep6wo=1,#AF do local BKZsJ=AF[lHep6wo] | |
g524[WUdVeYc]=tostring(BKZsJ.name)WUdVeYc=WUdVeYc+1 end | |
return g524 end)()})end | |
for Sw=1,#AF do local W67mm9p6=AF[Sw] | |
mMp.print("Removing '"..tostring(W67mm9p6.manifest.name).. | |
"' ...") | |
Zg(V.__parent.remove(mReHt4h,W67mm9p6.manifest,"oppm"))end;return true end | |
mReHt4h.cache=SJsW11k(function(mReHt4h,oBxdTi6u,...)local T7hLe5j=oBxdTi6u | |
if"update"==T7hLe5j then | |
mMp.print("Updating OpenPrograms program cache ...")Zg(mReHt4h:updateCache()) | |
return mMp.print("Done.")elseif"fix"==T7hLe5j then | |
mMp.print("Fixing OpenPrograms program cache ...")Zg(mReHt4h:fixCache())return mMp.print("Done.")else | |
mMp.error("Unknown command.")return mMp.print("Usage: hpm oppm:cache {update|fix}")end end) | |
mReHt4h.autoremove=SJsW11k(function(mReHt4h)local I_={}local J2Jin={} | |
local Rvg=Zg(d3fMjkg(XxJ(_,"oppm"))) | |
for HpdA in Rvg do local DsAJbW=Zg(wZdg(HpdA,nil,"oppm")) | |
if | |
not(DsAJbW.manual)then local AXfX=mReHt4h:getPackageDependants(HpdA)if#AXfX==1 then | |
y06X3k(I_,HpdA)y06X3k(J2Jin,HpdA)end end end | |
while true do local btcUUhB=false;Rvg=Zg(d3fMjkg(XxJ(_,"oppm"))) | |
for iw0S in Rvg do | |
if not | |
(iPL3B4cr(iw0S,I_))then local Tjg=Zg(wZdg(iw0S,nil,"oppm")) | |
if | |
not(Tjg.manual)then local n2srE7H=mReHt4h:getPackageDependants(iw0S) | |
table.remove(n2srE7H,1) | |
if | |
PG((function()local Rf={}local X9ZjrTz=1;for tYFIuD=1,#n2srE7H do local Ht5Ge=n2srE7H[tYFIuD] | |
Rf[X9ZjrTz]=iPL3B4cr(Ht5Ge.name,I_)X9ZjrTz=X9ZjrTz+1 end;return | |
Rf end)())then for l=1,#n2srE7H do local IO=n2srE7H[l]local YDJY,t=iPL3B4cr(IO.name,J2Jin)if t then | |
table.remove(J2Jin,t)end end | |
y06X3k(I_,iw0S)y06X3k(J2Jin,iw0S)btcUUhB=true end end end end;if not(btcUUhB)then break end end | |
qTDt({remove=(function() | |
if#I_>0 then local Rdi8NIft={}local J0uTkQ9=1;for sd6k=1,#I_ do local a=I_[sd6k] | |
Rdi8NIft[J0uTkQ9]="oppm:"..tostring(a)J0uTkQ9=J0uTkQ9+1 end | |
return Rdi8NIft else return nil end end)()})for lK7=1,#J2Jin do local KWMxs7a=J2Jin[lK7] | |
mReHt4h:_remove({Zg(wZdg(KWMxs7a,nil,"oppm"))},false)end | |
mMp.print("Done.")return true end) | |
if zIYNIXy1.__inherited then zIYNIXy1.__inherited(zIYNIXy1,V)end;sgeP.oppm=V end;local v | |
v=function()local T=Zg(d3fMjkg(_))Oh=true | |
for LBIp4 in T do local A5=JQi1jg.name(LBIp4) | |
if | |
u(XxJ(_,A5))then local PV168s0f=Zg(d3fMjkg(XxJ(_,A5))) | |
for bjK in PV168s0f do | |
if not | |
(u(XxJ(_,A5,bjK)))then local Us1Xh=Zg(wZdg(bjK,nil,A5)) | |
mMp.print(A5 ..":".. | |
bjK.. (Us1Xh.version and" @ ".. | |
Us1Xh.version or""))Oh=false end end end end | |
if Oh then return mMp.print("No packages installed.")end end;local Ta | |
Ta=function(...)Wu_uIt,el=YAtG_LV3(...)if#Wu_uIt<1 then return z()end end;local unArcvQl | |
unArcvQl=function()local rs59=Wu_uIt[1] | |
if"list"==rs59 then return v()elseif"help"==rs59 then return z()else | |
do | |
local R=y(Wu_uIt[1]) | |
if R then | |
return | |
R(ivnJjrA((function()local rGa2MaGH={}local i6=1;for u33wPQT=2,#Wu_uIt do local aNrMnPZ=Wu_uIt[u33wPQT] | |
rGa2MaGH[i6]=aNrMnPZ;i6=i6+1 end;return rGa2MaGH end)()))end end end end;Ta(...)Zg(gad4ZcL())OO()unArcvQl()return RkGFh6; |
local s=load([===[ | |
local rA5U=20160728.17 | |
local Uc06="-[ JSON.lua package by Jeffrey Friedl (http://regex.info/blog/lua/json) version 20160728.17 ]-"local lcBL={VERSION=rA5U,AUTHOR_NOTE=Uc06}local DHPxI=" " | |
local dx={pretty=true,align_keys=false,indent=DHPxI} | |
local RRuSHnxf={__tostring=function()return"JSON array"end}RRuSHnxf.__index=RRuSHnxf | |
local mcYOuT={__tostring=function()return"JSON object"end}mcYOuT.__index=mcYOuT;function lcBL:newArray(iXxD6s) | |
return setmetatable(iXxD6s or{},RRuSHnxf)end;function lcBL:newObject(oiY)return | |
setmetatable(oiY or{},mcYOuT)end;local function Rr(FsYIVlkf) | |
return | |
type(FsYIVlkf)=='number'and FsYIVlkf or FsYIVlkf.N end | |
local scRP0={__index=isNumber,__tostring=function(HLXS0Q_)return HLXS0Q_.S end,__unm=function(Kw)return | |
Rr(Kw)end,__concat=function(nvaIsNv7,vDnoL55) | |
return tostring(nvaIsNv7)..tostring(vDnoL55)end,__add=function(xlAK,zr1y)return Rr(xlAK)+Rr(zr1y)end,__sub=function(Hs,jk)return | |
Rr(Hs)-Rr(jk)end,__mul=function(qzSFyIO,Z65) | |
return Rr(qzSFyIO)*Rr(Z65)end,__div=function(umyCNfj,FT)return Rr(umyCNfj)/Rr(FT)end,__mod=function(YVLXYq,bJfct)return | |
Rr(YVLXYq)%Rr(bJfct)end,__pow=function(OhuFpq_N,Dzg)return | |
Rr(OhuFpq_N)^Rr(Dzg)end,__lt=function(_4O,C)return Rr(_4O)<Rr(C)end,__eq=function(fLI2zRe,_Fr2YU)return | |
Rr(fLI2zRe)==Rr(_Fr2YU)end,__le=function(Xfn,U)return | |
Rr(Xfn)<=Rr(U)end} | |
function lcBL:asNumber(Ebsw) | |
if getmetatable(Ebsw)==scRP0 then return Ebsw elseif | |
type(Ebsw)=='table'and | |
type(Ebsw.S)=='string'and type(Ebsw.N)=='number'then return setmetatable(Ebsw,scRP0)else | |
local UlikV={S=tostring(Ebsw),N=tonumber(Ebsw)}return setmetatable(UlikV,scRP0)end end | |
local function AI0R2TQ6(JtAjijkG) | |
if JtAjijkG<=127 then return string.char(JtAjijkG)elseif JtAjijkG<=2047 then | |
local s=math.floor(JtAjijkG/0x40)local YAtG_LV3=JtAjijkG- (0x40*s)return | |
string.char(0xC0+s,0x80+YAtG_LV3)elseif JtAjijkG<=65535 then | |
local LfEJbh_=math.floor(JtAjijkG/0x1000)local JD=JtAjijkG-0x1000*LfEJbh_ | |
local u=math.floor(JD/0x40)local pzDMZwG=JD-0x40*u;LfEJbh_=0xE0+LfEJbh_;u=0x80+u | |
pzDMZwG=0x80+pzDMZwG | |
if | |
(LfEJbh_==0xE0 and u<0xA0)or | |
(LfEJbh_==0xED and u>0x9F)or(LfEJbh_==0xF0 and u<0x90)or(LfEJbh_==0xF4 and u>0x8F)then return"?"else return string.char(LfEJbh_,u,pzDMZwG)end else local XPoQB=math.floor(JtAjijkG/0x40000) | |
local XxJ=JtAjijkG-0x40000*XPoQB;local o5sms=math.floor(XxJ/0x1000) | |
XxJ=XxJ-0x1000*o5sms;local JQi1jg=math.floor(XxJ/0x40)local wVzn=XxJ-0x40*JQi1jg | |
return string.char( | |
0xF0+XPoQB,0x80+o5sms,0x80+JQi1jg,0x80+wVzn)end end | |
function lcBL:onDecodeError(pE,RSjapQ,QJf,zC)if RSjapQ then | |
if QJf then | |
pE=string.format("%s at char %d of: %s",pE,QJf,RSjapQ)else pE=string.format("%s: %s",pE,RSjapQ)end end | |
if zC~=nil then pE=pE.." (".. | |
lcBL:encode(zC)..")"end | |
if self.assert then self.assert(false,pE)else assert(false,pE)end end;lcBL.onDecodeOfNilError=lcBL.onDecodeError | |
lcBL.onDecodeOfHTMLError=lcBL.onDecodeError | |
function lcBL:onEncodeError(pfZ3SPy_,pDNa2ox6) | |
if pDNa2ox6 ~=nil then pfZ3SPy_=pfZ3SPy_.. | |
" ("..lcBL:encode(pDNa2ox6)..")"end;if self.assert then self.assert(false,pfZ3SPy_)else | |
assert(false,pfZ3SPy_)end end | |
local function yA(Do6yo7nm,y06X3k,ivnJjrA,d3fMjkg) | |
local el=y06X3k:match('^-?[1-9]%d*',ivnJjrA)or y06X3k:match("^-?0",ivnJjrA)if not el then | |
Do6yo7nm:onDecodeError("expected number",y06X3k,ivnJjrA,d3fMjkg.etc)end | |
local Wu_uIt=ivnJjrA+el:len()local w=y06X3k:match('^%.%d+',Wu_uIt)or""Wu_uIt=Wu_uIt+ | |
w:len() | |
local sgeP=y06X3k:match('^[eE][-+]?%d+',Wu_uIt)or""Wu_uIt=Wu_uIt+sgeP:len()local CM=el..w..sgeP;if | |
d3fMjkg.decodeNumbersAsObjects then return lcBL:asNumber(CM),Wu_uIt end | |
if | |
( | |
d3fMjkg.decodeIntegerStringificationLength and(el:len()>=d3fMjkg.decodeIntegerStringificationLength or | |
sgeP:len()>0))or | |
(d3fMjkg.decodeDecimalStringificationLength and | |
( | |
w:len()>=d3fMjkg.decodeDecimalStringificationLength or sgeP:len()>0))then return CM,Wu_uIt end;local Qlmlet=tonumber(CM)if not Qlmlet then | |
Do6yo7nm:onDecodeError("bad number",y06X3k,ivnJjrA,d3fMjkg.etc)end;return Qlmlet,Wu_uIt end | |
local function XmVolesU(_,RkGFh6,hw18,nvCiFt7r)if RkGFh6:sub(hw18,hw18)~='"'then | |
_:onDecodeError("expected string's opening quote",RkGFh6,hw18,nvCiFt7r.etc)end;local xSebv5Jc=hw18+1 | |
local mMp=RkGFh6:len()local rDtVf="" | |
while xSebv5Jc<=mMp do local vj=RkGFh6:sub(xSebv5Jc,xSebv5Jc)if | |
vj=='"'then return rDtVf,xSebv5Jc+1 end | |
if vj~='\\'then rDtVf=rDtVf..vj;xSebv5Jc= | |
xSebv5Jc+1 elseif RkGFh6:match('^\\b',xSebv5Jc)then rDtVf=rDtVf.."\b"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\f',xSebv5Jc)then rDtVf=rDtVf.."\f"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\n',xSebv5Jc)then rDtVf=rDtVf.."\n"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\r',xSebv5Jc)then rDtVf=rDtVf.."\r"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\t',xSebv5Jc)then rDtVf=rDtVf.."\t"xSebv5Jc= | |
xSebv5Jc+2 else | |
local z=RkGFh6:match('^\\u([0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])',xSebv5Jc) | |
if z then xSebv5Jc=xSebv5Jc+6;local Zg=tonumber(z,16) | |
if | |
Zg>=0xD800 and Zg<=0xDBFF then | |
local ykRppH=RkGFh6:match('^\\u([dD][cdefCDEF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])',xSebv5Jc) | |
if ykRppH then xSebv5Jc=xSebv5Jc+6;Zg=0x2400+ (Zg-0xD800)*0x400+ | |
tonumber(ykRppH,16)else end end;rDtVf=rDtVf..AI0R2TQ6(Zg)else rDtVf=rDtVf.. | |
RkGFh6:match('^\\(.)',xSebv5Jc)xSebv5Jc=xSebv5Jc+2 end end end | |
_:onDecodeError("unclosed string",RkGFh6,hw18,nvCiFt7r.etc)end | |
local function eZ0l3ch(WQ6,y36Aetn)local iPL3B4cr,GI2hz6SK=WQ6:find("^[ \n\r\t]+",y36Aetn)if GI2hz6SK then | |
return GI2hz6SK+1 else return y36Aetn end end;local W_63_9 | |
local function h9dyA_4T(Oh,PG,n,O)if PG:sub(n,n)~='{'then | |
Oh:onDecodeError("expected '{'",PG,n,O.etc)end;local N5UjTN=eZ0l3ch(PG,n+1)local qLH5=Oh.strictTypes and | |
Oh:newObject{}or{}if | |
PG:sub(N5UjTN,N5UjTN)=='}'then return qLH5,N5UjTN+1 end | |
local tE=PG:len() | |
while N5UjTN<=tE do local VcV0EuD,pX4gCR=XmVolesU(Oh,PG,N5UjTN,O) | |
N5UjTN=eZ0l3ch(PG,pX4gCR)if PG:sub(N5UjTN,N5UjTN)~=':'then | |
Oh:onDecodeError("expected colon",PG,N5UjTN,O.etc)end | |
N5UjTN=eZ0l3ch(PG,N5UjTN+1)local gad4ZcL,pX4gCR=W_63_9(Oh,PG,N5UjTN,O)qLH5[VcV0EuD]=gad4ZcL | |
N5UjTN=eZ0l3ch(PG,pX4gCR)local dk=PG:sub(N5UjTN,N5UjTN) | |
if dk=='}'then return qLH5,N5UjTN+1 end;if PG:sub(N5UjTN,N5UjTN)~=','then | |
Oh:onDecodeError("expected comma or '}'",PG,N5UjTN,O.etc)end | |
N5UjTN=eZ0l3ch(PG,N5UjTN+1)end;Oh:onDecodeError("unclosed '{'",PG,n,O.etc)end | |
local function oh(E,OO,y,cR6rJlAl)if OO:sub(y,y)~='['then | |
E:onDecodeError("expected '['",OO,y,cR6rJlAl.etc)end;local M6ilzGJ=eZ0l3ch(OO,y+1)local iW6CD=E.strictTypes and | |
E:newArray{}or{}if | |
OO:sub(M6ilzGJ,M6ilzGJ)==']'then return iW6CD,M6ilzGJ+1 end | |
local wZdg=1;local BaX=OO:len() | |
while M6ilzGJ<=BaX do | |
local SJsW11k,Ki1HJT=W_63_9(E,OO,M6ilzGJ,cR6rJlAl)iW6CD[wZdg]=SJsW11k;wZdg=wZdg+1;M6ilzGJ=eZ0l3ch(OO,Ki1HJT) | |
local wjim8xCV=OO:sub(M6ilzGJ,M6ilzGJ)if wjim8xCV==']'then return iW6CD,M6ilzGJ+1 end;if | |
OO:sub(M6ilzGJ,M6ilzGJ)~=','then | |
E:onDecodeError("expected comma or '['",OO,M6ilzGJ,cR6rJlAl.etc)end | |
M6ilzGJ=eZ0l3ch(OO,M6ilzGJ+1)end | |
E:onDecodeError("unclosed '['",OO,y,cR6rJlAl.etc)end | |
W_63_9=function(E,QLam,qTDt,v)qTDt=eZ0l3ch(QLam,qTDt) | |
if qTDt>QLam:len()then E:onDecodeError("unexpected end of string",QLam, | |
nil,v.etc)end | |
if QLam:find('^"',qTDt)then return XmVolesU(E,QLam,qTDt,v.etc)elseif | |
QLam:find('^[-0123456789 ]',qTDt)then return yA(E,QLam,qTDt,v)elseif QLam:find('^%{',qTDt)then | |
return h9dyA_4T(E,QLam,qTDt,v)elseif QLam:find('^%[',qTDt)then return oh(E,QLam,qTDt,v)elseif QLam:find('^true',qTDt)then return true, | |
qTDt+4 elseif QLam:find('^false',qTDt)then return false,qTDt+5 elseif | |
QLam:find('^null',qTDt)then return nil,qTDt+4 else | |
E:onDecodeError("can't parse JSON",QLam,qTDt,v.etc)end end | |
function lcBL:decode(Ta,u,nArcvQl)if type(nArcvQl)~='table'then nArcvQl={}end;if u~=nil then | |
nArcvQl.etc=u end;if | |
type(self)~='table'or self.__index~=lcBL then | |
lcBL:onDecodeError("JSON:decode must be called in method format",nil,nil,nArcvQl.etc)end | |
if Ta==nil then | |
self:onDecodeOfNilError(string.format("nil passed to JSON:decode()"), | |
nil,nil,nArcvQl.etc)elseif type(Ta)~='string'then | |
self:onDecodeError(string.format("expected string argument to JSON:decode(), got %s",type(Ta)), | |
nil,nil,nArcvQl.etc)end;if Ta:match('^%s*$')then return nil end;if Ta:match('^%s*<')then | |
self:onDecodeOfHTMLError(string.format("html passed to JSON:decode()"),Ta, | |
nil,nArcvQl.etc)end | |
if | |
Ta:sub(1,1):byte()==0 or | |
(Ta:len()>=2 and Ta:sub(2,2):byte()==0)then | |
self:onDecodeError("JSON package groks only UTF-8, sorry",Ta,nil,nArcvQl.etc)end;if nArcvQl.decodeNumbersAsObjects==nil then | |
nArcvQl.decodeNumbersAsObjects=self.decodeNumbersAsObjects end;if | |
nArcvQl.decodeIntegerStringificationLength==nil then | |
nArcvQl.decodeIntegerStringificationLength=self.decodeIntegerStringificationLength end;if | |
nArcvQl.decodeDecimalStringificationLength==nil then | |
nArcvQl.decodeDecimalStringificationLength=self.decodeDecimalStringificationLength end | |
local h6Ub7U,Gm=pcall(W_63_9,self,Ta,1,nArcvQl)if h6Ub7U then return Gm else | |
if self.assert then self.assert(false,Gm)else assert(false,Gm)end;return nil,Gm end end | |
local function DZXGTh(YKA7cU) | |
if YKA7cU=="\n"then return"\\n"elseif YKA7cU=="\r"then return"\\r"elseif YKA7cU=="\t"then return"\\t"elseif YKA7cU=="\b"then | |
return"\\b"elseif YKA7cU=="\f"then return"\\f"elseif YKA7cU=='"'then return'\\"'elseif YKA7cU=='\\'then return'\\\\'else return | |
string.format("\\u%04x",YKA7cU:byte())end end | |
local Su9Koz='['..'"'.. | |
'%\\'..'%z'..'\001'..'-'..'\031'..']'local Uk7e=AI0R2TQ6(0x2028)local KwQCk_G=AI0R2TQ6(0x2029) | |
local function ptZa(mCsewfX,yY) | |
local Xf=mCsewfX:gsub(Su9Koz,DZXGTh)if yY.stringsAreUtf8 then | |
Xf=Xf:gsub(Uk7e,'\\u2028'):gsub(KwQCk_G,'\\u2029')end;return'"'..Xf..'"'end | |
local function PEqsd(UlFdiZ7v,U,wFeA)local JQgI={}local N={}local fs52REi=false;local PUNkgaiM | |
for X in pairs(U)do | |
if type(X)=='string'then | |
table.insert(JQgI,X)elseif type(X)=='number'then table.insert(N,X) | |
if X<=0 or X>=math.huge then | |
fs52REi=true elseif not PUNkgaiM or X>PUNkgaiM then PUNkgaiM=X end else | |
UlFdiZ7v:onEncodeError("can't encode table with a key of type "..type(X),wFeA)end end | |
if#JQgI==0 and not fs52REi then | |
if#N>0 then return nil,PUNkgaiM elseif | |
tostring(U)=="JSON array"then return nil elseif tostring(U)=="JSON object"then return{}else return nil end end;table.sort(JQgI)local s6FbB | |
if#N>0 then if UlFdiZ7v.noKeyConversion then | |
UlFdiZ7v:onEncodeError("a table with both numeric and string keys could be an object or array; aborting",wFeA)end | |
s6FbB={}for dc61,aguhyl in pairs(U)do s6FbB[dc61]=aguhyl end | |
table.sort(N) | |
for p,gOPDv in ipairs(N)do local aSdZU3=tostring(gOPDv) | |
if s6FbB[aSdZU3]==nil then | |
table.insert(JQgI,aSdZU3)s6FbB[aSdZU3]=U[gOPDv]else | |
UlFdiZ7v:onEncodeError( | |
"conflict converting table with mixed-type keys into a JSON object: key "..gOPDv.." exists both as a string and a number.",wFeA)end end end;return JQgI,nil,s6FbB end;local iSj | |
function iSj(YKDL,oFyb6OLp,oGdh_mv,WjvvK,TASVwBgU,KjUncMB,XkT) | |
if oFyb6OLp==nil or | |
(not XkT and TASVwBgU and TASVwBgU.null and oFyb6OLp== | |
TASVwBgU.null)then return'null'elseif | |
type(oFyb6OLp)=='string'then return ptZa(oFyb6OLp,TASVwBgU)elseif type(oFyb6OLp)=='number'then | |
if | |
oFyb6OLp~=oFyb6OLp then return"null"elseif oFyb6OLp>=math.huge then return"1e+9999"elseif oFyb6OLp<=-math.huge then | |
return"-1e+9999"else return tostring(oFyb6OLp)end elseif type(oFyb6OLp)=='boolean'then return tostring(oFyb6OLp)elseif type(oFyb6OLp)~= | |
'table'then | |
YKDL:onEncodeError("can't convert "..type(oFyb6OLp).." to JSON",WjvvK)elseif getmetatable(oFyb6OLp)==scRP0 then return tostring(oFyb6OLp)else | |
local c3dr=oFyb6OLp;if type(TASVwBgU)~='table'then TASVwBgU={}end;if type(KjUncMB)~= | |
'string'then KjUncMB=""end | |
if oGdh_mv[c3dr]then | |
YKDL:onEncodeError("table ".. | |
tostring(c3dr).." is a child of itself",WjvvK)else oGdh_mv[c3dr]=true end;local NGH;local tIc,MD2O,HQ=PEqsd(YKDL,c3dr,WjvvK) | |
if MD2O then local cng={}for lE=1,MD2O do | |
table.insert(cng,iSj(YKDL,c3dr[lE],oGdh_mv,WjvvK,TASVwBgU,KjUncMB))end | |
if TASVwBgU.pretty then NGH="[ ".. | |
table.concat(cng,", ").." ]"else NGH="[".. | |
table.concat(cng,",").."]"end elseif tIc then local nI2F0id=HQ or c3dr | |
if TASVwBgU.pretty then local N4aMD_P={}local pCi=0 | |
for lNOqUk8,YAnZNei in ipairs(tIc)do | |
local h8YWR44E=iSj(YKDL,tostring(YAnZNei),oGdh_mv,WjvvK,TASVwBgU,KjUncMB,true) | |
if TASVwBgU.align_keys then pCi=math.max(pCi,#h8YWR44E)end;table.insert(N4aMD_P,h8YWR44E)end | |
local NzeoQJ=KjUncMB..tostring(TASVwBgU.indent or"") | |
local AwGfFV=NzeoQJ..string.rep(" ",pCi).. | |
(TASVwBgU.align_keys and" "or"") | |
local wCRY="%s%"..string.format("%d",pCi).."s: %s"local d0uKSVw1={} | |
for VF,fTrMe in ipairs(tIc)do | |
local ypDndT8=iSj(YKDL,nI2F0id[fTrMe],oGdh_mv,WjvvK,TASVwBgU,AwGfFV) | |
table.insert(d0uKSVw1,string.format(wCRY,NzeoQJ,N4aMD_P[VF],ypDndT8))end;NGH="{\n".. | |
table.concat(d0uKSVw1,",\n").."\n"..KjUncMB.."}"else local MV65={} | |
for Y3D66Ym9,q in | |
ipairs(tIc)do | |
local PhJ=iSj(YKDL,nI2F0id[q],oGdh_mv,WjvvK,TASVwBgU,KjUncMB) | |
local h=iSj(YKDL,tostring(q),oGdh_mv,WjvvK,TASVwBgU,KjUncMB,true) | |
table.insert(MV65,string.format("%s:%s",h,PhJ))end;NGH="{"..table.concat(MV65,",").."}"end else NGH="[]"end;oGdh_mv[c3dr]=false;return NGH end end | |
function lcBL:encode(j2K,r8hgwQ,_6U)if type(self)~='table'or self.__index~=lcBL then | |
lcBL:onEncodeError("JSON:encode must be called in method format",r8hgwQ)end;if | |
type(_6U)~='table'then _6U={}end;return iSj(self,j2K,{},r8hgwQ,_6U)end | |
function lcBL:encode_pretty(GLSzBQs,c,xg)if type(self)~='table'or self.__index~=lcBL then | |
lcBL:onEncodeError("JSON:encode_pretty must be called in method format",c)end;if | |
type(xg)~='table'then xg=dx end;return iSj(self,GLSzBQs,{},c,xg)end;function lcBL.__tostring()return"JSON encode/decode package"end | |
lcBL.__index=lcBL | |
function lcBL:new(Id2KoP_G)local Y2or={}if Id2KoP_G then | |
for zN8ASHV5,iju in pairs(Id2KoP_G)do Y2or[zN8ASHV5]=iju end end | |
return setmetatable(Y2or,lcBL)end;return lcBL:new() | |
]===])() | |
local YAtG_LV3=(function() | |
local yY=[[ Copyright (c) The python-semanticversion project | |
All rights reserved. | |
Redistribution and use in source and binary forms, with or without | |
modification, are permitted provided that the following conditions are met: | |
1. Redistributions of source code must retain the above copyright notice, this | |
list of conditions and the following disclaimer. | |
2. Redistributions in binary form must reproduce the above copyright notice, | |
this list of conditions and the following disclaimer in the documentation | |
and/or other materials provided with the distribution. | |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | |
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
]] | |
yY=[[ The use of the library is similar to the original one, | |
check the documentation here: https://python-semanticversion.readthedocs.io/en/latest/ | |
]]local Xf,UlFdiZ7v,U;do local aSdZU3=table | |
Xf,UlFdiZ7v,U=aSdZU3.concat,aSdZU3.insert,aSdZU3.unpack end;local wFeA | |
wFeA=function(YKDL) | |
do local oFyb6OLp=tonumber(YKDL)if | |
oFyb6OLp then return oFyb6OLp,true else return YKDL,false end end end;local JQgI | |
JQgI=function(oGdh_mv)return oGdh_mv and oGdh_mv[1]=='0'and | |
tonumber(oGdh_mv and oGdh_mv~='0')end;local N | |
N=function(WjvvK,TASVwBgU)if WjvvK==TASVwBgU then return 0 end | |
if WjvvK>TASVwBgU then return 1 end;if WjvvK<TASVwBgU then return-1 end end;local fs52REi | |
fs52REi=function(KjUncMB,XkT)local c3dr,NGH=wFeA(KjUncMB)local tIc,MD2O=wFeA(XkT) | |
if NGH and MD2O then | |
return N(c3dr,tIc)elseif NGH then return-1 elseif MD2O then return 1 else return N(c3dr,tIc)end end;local PUNkgaiM | |
PUNkgaiM=function(HQ,cng)local lE;do local nI2F0id={}for N4aMD_P=1,#HQ do if cng[N4aMD_P]then | |
nI2F0id[HQ[N4aMD_P]]=cng[N4aMD_P]end end | |
lE=nI2F0id end | |
for pCi,NzeoQJ in pairs(lE)do | |
local AwGfFV=fs52REi(pCi,NzeoQJ)if AwGfFV~=0 then return AwGfFV end end;return N(#HQ,#cng)end;local s6FbB | |
do local wCRY | |
local d0uKSVw1={_coerce=function(YAnZNei,h8YWR44E,VF)if VF==nil then VF=false end | |
if h8YWR44E==nil and VF then return h8YWR44E end;return tonumber(h8YWR44E)end,next_major=function(fTrMe) | |
if | |
fTrMe.prerelease and fTrMe.minor==0 and fTrMe.patch==0 then | |
return | |
s6FbB(Xf((function()local ypDndT8={}local MV65=1 | |
local Y3D66Ym9={fTrMe.major,fTrMe.minor,fTrMe.patch}for q=1,#Y3D66Ym9 do local PhJ=Y3D66Ym9[q]ypDndT8[MV65]=tostring(PhJ) | |
MV65=MV65+1 end;return ypDndT8 end)(),'.'))else | |
return | |
s6FbB(Xf((function()local h={}local j2K=1;local r8hgwQ={fTrMe.major+1,0,0} | |
for _6U=1,#r8hgwQ do | |
local GLSzBQs=r8hgwQ[_6U]h[j2K]=tostring(GLSzBQs)j2K=j2K+1 end;return h end)(),'.'))end end,next_minor=function(c)if | |
not(c.minor)then | |
error("Partial version doesn't contain the minor component!")end | |
if c.prerelease and c.patch==0 then | |
return | |
s6FbB(Xf((function() | |
local xg={}local Id2KoP_G=1;local Y2or={c.major,c.minor,c.patch} | |
for zN8ASHV5=1,#Y2or do | |
local iju=Y2or[zN8ASHV5]xg[Id2KoP_G]=tostring(iju)Id2KoP_G=Id2KoP_G+1 end;return xg end)(),'.'))else | |
return | |
s6FbB(Xf((function()local XsWgh={}local l4Hdz=1;local NSXCgSH={c.major,c.minor+1,0} | |
for Wq=1,#NSXCgSH do | |
local SbOQ=NSXCgSH[Wq]XsWgh[l4Hdz]=tostring(SbOQ)l4Hdz=l4Hdz+1 end;return XsWgh end)(),'.'))end end,next_patch=function(IiuHGo)if | |
not(IiuHGo.patch)then | |
error("Partial version doesn't contain the patch component!")end | |
if IiuHGo.prerelease then | |
return | |
s6FbB(Xf((function()local cGqxtYr={} | |
local bgJFKeeZ=1;local yu9fg0nN={IiuHGo.major,IiuHGo.minor,IiuHGo.patch} | |
for wgx=1,# | |
yu9fg0nN do local zlU7X=yu9fg0nN[wgx] | |
cGqxtYr[bgJFKeeZ]=tostring(zlU7X)bgJFKeeZ=bgJFKeeZ+1 end;return cGqxtYr end)(),'.'))else | |
return | |
s6FbB(Xf((function()local t={}local f6qbO=1 | |
local kk={IiuHGo.major,IiuHGo.minor,IiuHGo.patch+1} | |
for QrubIAv=1,#kk do local bLHDW=kk[QrubIAv]t[f6qbO]=tostring(bLHDW)f6qbO=f6qbO+1 end;return t end)(),'.'))end end,coerce=function(YjFd7b,jZgPYb,zN2)if | |
zN2 ==nil then zN2=false end;local IN69pa5 | |
IN69pa5=function(OVx_mN) | |
local lB,byE=OVx_mN:match('^(%d+)(.*)$')if not(lB)then return nil end;local bITCI=lB | |
local K,F5dtVpnN=byE:match('^%.(%d+)(.*)$')if K then byE=F5dtVpnN;bITCI=bITCI.. ('.'..K)end;local kxeBp | |
kxeBp,F5dtVpnN=byE:match('^%.(%d+)(.*)$') | |
if kxeBp then byE=F5dtVpnN;bITCI=bITCI.. ('.'..kxeBp)end;return OVx_mN,bITCI end;local UOWJ,WtalJw=IN69pa5(jZgPYb)if not(UOWJ)then | |
error("Version string lacks a numerical component: ".. | |
tostring(jZgPYb))end | |
local JYrf2=jZgPYb:sub(1,#WtalJw) | |
if not zN2 then while({JYrf2:gsub('.','')})[2]<2 do JYrf2= | |
JYrf2 ..'.0'end end;if#WtalJw==#jZgPYb then return s6FbB(JYrf2,zN2)end;local KHDOUlRY=jZgPYb:sub( | |
#WtalJw+1) | |
KHDOUlRY=KHDOUlRY:gsub('[^a-zA-Z0-9+.-]','-')local I0JvPpn,Ce4ZE=nil,nil | |
if KHDOUlRY:sub(1,1)=='+'then I0JvPpn='' | |
Ce4ZE=KHDOUlRY:sub(2)elseif KHDOUlRY:sub(1,1)=='.'then I0JvPpn=''Ce4ZE=KHDOUlRY:sub(2)elseif | |
KHDOUlRY:sub(1,1)=='-'then KHDOUlRY=KHDOUlRY:sub(2) | |
do | |
local a=KHDOUlRY:find('+')if a then | |
I0JvPpn,Ce4ZE=KHDOUlRY:sub(1,a-1),KHDOUlRY:sub(a+1,-1)else I0JvPpn,Ce4ZE=KHDOUlRY,''end end else do local kQ=KHDOUlRY:find('+') | |
if kQ then I0JvPpn,Ce4ZE=KHDOUlRY:sub(1,kQ-1),KHDOUlRY:sub( | |
kQ+1,-1)else I0JvPpn,Ce4ZE=KHDOUlRY,''end end end;Ce4ZE=Ce4ZE:gsub('+','.')if I0JvPpn and I0JvPpn~=''then JYrf2=JYrf2 .. | |
('-'..I0JvPpn)end;if | |
Ce4ZE and Ce4ZE~=''then JYrf2=JYrf2 .. ('+'..Ce4ZE)end;return | |
YjFd7b.__class(JYrf2,zN2)end,parse=function(EE9LAE,iVx,eg,AQviNt)if | |
eg==nil then eg=false end;if AQviNt==nil then AQviNt=false end;if not iVx or | |
type(iVx)~='string'or iVx==''then | |
error("Invalid empty version string: ".. | |
tostring(tostring(iVx)))end;local T6 | |
if eg then | |
T6=EE9LAE.__class.partialVersionRe else T6=EE9LAE.__class.versionRe end;local NviN0i,BlMQce,o,dpRE,fEiXwWq=T6(EE9LAE.__class,iVx)if not NviN0i then | |
error( | |
"Invalid version string: "..tostring(iVx))end;if JQgI(NviN0i)then | |
error("Invalid leading zero in major: ".. | |
tostring(iVx))end;if JQgI(BlMQce)then | |
error("Invalid leading zero in minor: ".. | |
tostring(iVx))end;if JQgI(o)then | |
error("Invalid leading zero in patch: ".. | |
tostring(iVx))end;NviN0i=tonumber(NviN0i) | |
BlMQce=EE9LAE:_coerce(BlMQce,eg)o=EE9LAE:_coerce(o,eg) | |
if dpRE==nil then if eg and fEiXwWq==nil then return | |
{NviN0i,BlMQce,o,nil,nil}else dpRE={}end elseif dpRE==''then dpRE={}else | |
do | |
local r3JzMga6={}local Tuyw=1 | |
for FYLcr2nu in dpRE:gmatch('[^.]+')do r3JzMga6[Tuyw]=FYLcr2nu;Tuyw=Tuyw+1 end;dpRE=r3JzMga6 end;EE9LAE:_validateIdentifiers(dpRE,false)end | |
if fEiXwWq==nil then if eg then fEiXwWq=nil else fEiXwWq={}end elseif fEiXwWq==''then fEiXwWq={}else do | |
local ioS69={}local AiP=1 | |
for S2jwpoi in fEiXwWq:gmatch('[^.]+')do ioS69[AiP]=S2jwpoi;AiP=AiP+1 end;fEiXwWq=ioS69 end | |
EE9LAE:_validateIdentifiers(fEiXwWq,true)end;return{NviN0i,BlMQce,o,dpRE,fEiXwWq}end,_validateIdentifiers=function(_WX9u,u0riyU,UH)if | |
UH==nil then UH=false end | |
for WNph=1,#u0riyU do local ytF=u0riyU[WNph]if not ytF then | |
error( | |
"Invalid empty identifier ".. | |
tostring(ytF).." in "..tostring(Xf(u0riyU,'.')))end;if | |
ytF:sub(1,1)=='0'and | |
tonumber(ytF)and ytF~='0'and not UH then | |
error("Invalid leading zero in identifier "..tostring(ytF))end end end,__pairs=function(d)return | |
pairs({d.major,d.minor,d.patch,d.prerelease,d.build})end,__ipairs=function(gRm)return | |
ipairs({gRm.major,gRm.minor,gRm.patch,gRm.prerelease,gRm.build})end,__tostring=function(LPX0) | |
local g=tostring(LPX0.major) | |
if LPX0.minor~=nil then g=g.. ('.'..LPX0.minor)end | |
if LPX0.patch~=nil then g=g.. ('.'..LPX0.patch)end | |
if LPX0.prerelease and#LPX0.prerelease>0 or | |
LPX0.partial and LPX0.prerelease and#LPX0.prerelease==0 and LPX0.build==nil then g=g.. ('-'.. | |
Xf(LPX0.prerelease,'.'))end | |
if | |
LPX0.build and#LPX0.build>0 or LPX0.partial and LPX0.build and# | |
LPX0.build==0 then g=g.. ('+'..Xf(LPX0.build,'.'))end;return g end,_comparsionFunctions=function(_l,qao)if | |
qao==nil then qao=false end;local ipUPIzc | |
ipUPIzc=function(J7nsK,dXbd) | |
if J7nsK and dXbd then | |
return PUNkgaiM(J7nsK,dXbd)elseif J7nsK then return-1 elseif dXbd then return 1 else return 0 end end;local N8 | |
N8=function(vQj,sVBxyy)if vQj==sVBxyy then return 0 else return'not implemented'end end;local Gzk | |
Gzk=function(N9d)local S7 | |
S7=function(bJtvRSR,aBhZK5)if bJtvRSR==nil or aBhZK5 ==nil then return 0 else | |
return N9d(bJtvRSR,aBhZK5)end end;return S7 end;if qao then return{N,Gzk(N),Gzk(N),Gzk(ipUPIzc),Gzk(N8)}else return | |
{N,N,N,ipUPIzc,N8}end end,__compare=function(Jz8JUscj,OtGmbAgE) | |
local oU_r=Jz8JUscj:_comparsionFunctions( | |
Jz8JUscj.partial or OtGmbAgE.partial) | |
local n_lv={{oU_r[1],Jz8JUscj.major,OtGmbAgE.major},{oU_r[2],Jz8JUscj.minor,OtGmbAgE.minor},{oU_r[3],Jz8JUscj.patch,OtGmbAgE.patch},{oU_r[4],Jz8JUscj.prerelease,OtGmbAgE.prerelease},{oU_r[5],Jz8JUscj.build,OtGmbAgE.build}} | |
for UYQF=1,#n_lv do local WXx=n_lv[UYQF]local W4EuxJXi,BlYNd61h,XDPndG=U(WXx) | |
local sJYFQIP4=W4EuxJXi(BlYNd61h,XDPndG)if sJYFQIP4 ~=0 then return sJYFQIP4 end end;return 0 end,__compareHelper=function(Ogq0S2,n8Cw3SR,GJqd7gt,slE5aDm2) | |
local aL_g=Ogq0S2:__compare(n8Cw3SR)if aL_g=='not implemented'then return slE5aDm2 end | |
return GJqd7gt(aL_g)end,__eq=function(IMUI10L,vPA) | |
local pUXZ6G4;pUXZ6G4=function(mk)return mk==0 end;return | |
IMUI10L:__compareHelper(vPA,pUXZ6G4,false)end,__lt=function(OeQex1U4,i0cV9) | |
local EGD;EGD=function(VWiGCreH)return VWiGCreH<0 end;return | |
OeQex1U4:__compareHelper(i0cV9,EGD,false)end,__le=function(B_kkL,uEO6Y) | |
local i_053JPY;i_053JPY=function(l)return l<=0 end;return | |
B_kkL:__compareHelper(uEO6Y,i_053JPY,false)end}d0uKSVw1.__index=d0uKSVw1 | |
wCRY=setmetatable({__init=function(UK,NzaICo,k1X83nYm) | |
if k1X83nYm==nil then k1X83nYm=false end;local xxzxfj,_ad1m4I,H1QsS,rIMx,TiA=U(UK:parse(NzaICo,k1X83nYm)) | |
UK.major,UK.minor,UK.patch,UK.prerelease,UK.build,UK.partial=xxzxfj,_ad1m4I,H1QsS,rIMx,TiA,k1X83nYm end,__base=d0uKSVw1,__name="Version"},{__index=d0uKSVw1,__call=function(Y51P,...) | |
local ichL=setmetatable({},d0uKSVw1)Y51P.__init(ichL,...)return ichL end})d0uKSVw1.__class=wCRY;local lNOqUk8=wCRY | |
lNOqUk8.versionRe=function(lNOqUk8,NOK) | |
local Alv,YeLO2,CkrmO,ooovsSJe=NOK:match('^(%d+)%.(%d+)%.(%d+)(.*)$')if not(Alv)then return nil end | |
local s5IsD,KvYEVoXt=ooovsSJe:match('^%-([0-9a-zA-z.-]+)(.*)$')if s5IsD then ooovsSJe=KvYEVoXt end;local VWWD_P | |
VWWD_P,KvYEVoXt=ooovsSJe:match('^%+([0-9a-zA-Z.-]+)(.*)$')if VWWD_P then ooovsSJe=KvYEVoXt end;if#ooovsSJe>0 then return nil end;return | |
Alv,YeLO2,CkrmO,s5IsD,VWWD_P end | |
lNOqUk8.partialVersionRe=function(lNOqUk8,zsMuNkv)local aXxi,Q18a7QTy=zsMuNkv:match('^(%d+)(.*)$')if | |
not(aXxi)then return nil end | |
local K5Rp6,GTIA=Q18a7QTy:match('^%.(%d+)(.*)$')if K5Rp6 then Q18a7QTy=GTIA end;local gdPUe | |
gdPUe,GTIA=Q18a7QTy:match('^%.(%d+)(.*)$')if gdPUe then Q18a7QTy=GTIA end;local _bxEn | |
_bxEn,GTIA=Q18a7QTy:match('^%-([0-9a-zA-Z.-]*)(.*)$')if _bxEn then Q18a7QTy=GTIA end;local pcN_ceXY | |
pcN_ceXY,GTIA=Q18a7QTy:match('^%+([0-9a-zA-Z.-]*)(.*)$')if pcN_ceXY then Q18a7QTy=GTIA end;if#Q18a7QTy>0 then return nil end;return aXxi, | |
K5Rp6,gdPUe,_bxEn,pcN_ceXY end;s6FbB=wCRY end;local X | |
do local _P | |
local rq={parse=function(I,RAAJAsR)if | |
not RAAJAsR or type(RAAJAsR)~='string'or RAAJAsR==''then | |
error("Invalid empty requirement specification: "..tostring(tostring(RAAJAsR)))end;if RAAJAsR== | |
'*'then return{I.__class.KIND_ANY,''}end | |
local c1pjj7,BMv=I.__class:reSpec(RAAJAsR)if not c1pjj7 then | |
error("Invalid requirement specification: "..tostring(RAAJAsR))end;c1pjj7= | |
I.__class.KIND_ALIASES[c1pjj7]or c1pjj7;local NQh8=s6FbB(BMv,true) | |
if | |
NQh8.build~=nil and c1pjj7 ~=I.__class.KIND_EQUAL and c1pjj7 ~= | |
I.__class.KIND_NEQ then | |
error( | |
"Invalid requirement specification "..tostring(RAAJAsR)..": build numbers have no ordering")end;return{c1pjj7,NQh8}end,match=function(P,bkTe) | |
local ohmPbyDd=P.kind | |
if P.__class.KIND_ANY==ohmPbyDd then return true elseif P.__class.KIND_LT==ohmPbyDd then return bkTe< | |
P.spec elseif P.__class.KIND_LTE==ohmPbyDd then return bkTe<=P.spec elseif | |
P.__class.KIND_EQUAL==ohmPbyDd then return bkTe==P.spec elseif P.__class.KIND_GTE==ohmPbyDd then return bkTe>= | |
P.spec elseif P.__class.KIND_GT==ohmPbyDd then return bkTe>P.spec elseif | |
P.__class.KIND_NEQ==ohmPbyDd then return bkTe~=P.spec elseif P.__class.KIND_CARET==ohmPbyDd then | |
return | |
P.spec<=bkTe and bkTe<P.spec:next_major()elseif P.__class.KIND_TILDE==ohmPbyDd then return P.spec<=bkTe and | |
bkTe<P.spec:next_minor()else return | |
error("Unexpected match kind: "..tostring(P.kind))end end,__tostring=function(D)return | |
tostring(D.kind)..tostring(D.spec)end,__eq=function(DfDLWkT,MTU8HP4d)return | |
DfDLWkT.kind==MTU8HP4d.kind and DfDLWkT.spec==MTU8HP4d.spec end}rq.__index=rq | |
_P=setmetatable({__init=function(hIM_cG0i,jD) | |
hIM_cG0i.kind,hIM_cG0i.spec=U(hIM_cG0i:parse(jD))end,__base=rq,__name="SpecItem"},{__index=rq,__call=function(me,...) | |
local sgU5HAMG=setmetatable({},rq)me.__init(sgU5HAMG,...)return sgU5HAMG end})rq.__class=_P;local mo=_P;mo.KIND_ANY='*'mo.KIND_LT='<'mo.KIND_LTE='<=' | |
mo.KIND_EQUAL='=='mo.KIND_SHORTEQ='='mo.KIND_EMPTY=''mo.KIND_GTE='>='mo.KIND_GT='>' | |
mo.KIND_NEQ='!='mo.KIND_CARET='^'mo.KIND_TILDE='~' | |
mo.KIND_ALIASES={[mo.__class.KIND_SHORTEQ]=mo.__class.KIND_EQUAL,[mo.__class.KIND_EMPTY]=mo.__class.KIND_EQUAL} | |
mo.reSpec=function(mo,FDydY)local PEZ_,c=FDydY:match('^(.-)(%d.*)$') | |
if not | |
( | |
PEZ_=='<'or PEZ_=='<='or PEZ_==''or PEZ_=='='or PEZ_=='=='or PEZ_=='>='or PEZ_=='>'or PEZ_=='!='or PEZ_=='^'or PEZ_=='~')then return nil else | |
return PEZ_,c end end;X=_P end;local dc61 | |
do local ElbTbcZG | |
local r3={parse=function(pUiVYRok,jvPsY9)local tEBmuypm={}local hW=1;for iOcgdUx in jvPsY9:gmatch('[^,]+')do | |
tEBmuypm[hW]=X(iOcgdUx)hW=hW+1 end;return tEBmuypm end,match=function(kCwLIk,_l) | |
local rjQ=kCwLIk.specs | |
for Euo0=1,#rjQ do local LIV=rjQ[Euo0]if not LIV:match(_l)then return false end end;return true end,filter=function(vydlAbZ3,BXxv5z) | |
local mKLU=0 | |
return function() | |
while true do mKLU=mKLU+1;local Him=BXxv5z[mKLU]if not(Him)then return nil end;if | |
vydlAbZ3:match(Him)then return Him end end end end,select=function(cPDhu,UQnOS) | |
local tRWU | |
do local X2Zy_nb={}local ITtw3N7E=1;for yozOp in cPDhu:filter(UQnOS)do X2Zy_nb[ITtw3N7E]=yozOp;ITtw3N7E= | |
ITtw3N7E+1 end;tRWU=X2Zy_nb end | |
if#tRWU>0 then local wxU=tRWU[1]for kOmS5sy=1,#tRWU do local CLSdD=tRWU[kOmS5sy] | |
if wxU<CLSdD then wxU=CLSdD end end;return wxU else return nil end end,__index=function(Fh,IlAPA)if | |
Fh:match(IlAPA)then return true else return nil end end,__pairs=function(jLKMpQuK)return | |
pairs(jLKMpQuK.specs)end,__ipairs=function(sUQpby)return ipairs(sUQpby.specs)end,__tostring=function(mbA) | |
return | |
Xf((function() | |
local _qPhpaFx={}local zex=1;local pPGcdu=mbA.specs;for rjp=1,#pPGcdu do local cT2z=pPGcdu[rjp] | |
_qPhpaFx[zex]=tostring(cT2z)zex=zex+1 end;return _qPhpaFx end)(),',')end,__eq=function(zke1tWps,gRFA) | |
local jX9a0tJX=zke1tWps.specs | |
for YFy4TGc=1,#jX9a0tJX do local YjpbYkCb=jX9a0tJX[YFy4TGc]local L1p7luJ=false;local eH=gRFA.specs | |
for WpOZ=1,#eH do | |
local fD2289=eH[WpOZ]if YjpbYkCb==fD2289 then L1p7luJ=true;break end end;if not L1p7luJ then return false end end;return true end}r3.__index=r3 | |
ElbTbcZG=setmetatable({__init=function(folfO,vtsK) | |
if type(vtsK)=='string'then vtsK={vtsK}end;local E1p4Mv | |
do local IHap={}local rDvV=1;for RX1L2q=1,#vtsK do local bCBtWguf=vtsK[RX1L2q] | |
IHap[rDvV]=folfO:parse(bCBtWguf)rDvV=rDvV+1 end;E1p4Mv=IHap end;folfO.specs={} | |
for q=1,#E1p4Mv do local e1sXUN4f=E1p4Mv[q]for x=1,#e1sXUN4f do local VP=e1sXUN4f[x] | |
UlFdiZ7v(folfO.specs,VP)end end end,__base=r3,__name="Spec"},{__index=r3,__call=function(IQwqq,...) | |
local Xcc4=setmetatable({},r3)IQwqq.__init(Xcc4,...)return Xcc4 end})r3.__class=ElbTbcZG;dc61=ElbTbcZG end;local aguhyl | |
aguhyl=function(fqw5,qnVfOeRE)return N(s6FbB(fqw5,s6FbB(qnVfOeRE)))end;local p | |
p=function(YIiSKsxK,Ua)return dc61(YIiSKsxK):match(s6FbB(Ua))end;local gOPDv;gOPDv=function(qeJtG) | |
return({s6FbB:parse(qeJtG)})[1]end;return | |
{Spec=dc61,SpecItem=X,Version=s6FbB,compare=aguhyl,match=p,validate=gOPDv}end)()local LfEJbh_;LfEJbh_=require("component").isAvailable;local JD,u | |
do | |
local pdpNgBcZ=require("shell")JD,u=pdpNgBcZ.parse,pdpNgBcZ.getWorkingDirectory end;local pzDMZwG=require("shell")local XPoQB,XxJ,o5sms,JQi1jg,wVzn;do | |
local wV=require("filesystem") | |
XPoQB,XxJ,o5sms,JQi1jg,wVzn=wV.isDirectory,wV.exists,wV.makeDirectory,wV.concat,wV.copy end | |
local pE=require("filesystem")local RSjapQ,QJf;do local rLd=require("serialization") | |
RSjapQ,QJf=rLd.serialize,rLd.unserialize end;local zC | |
zC=require("event").pull;local pfZ3SPy_,pDNa2ox6,Do6yo7nm;do local z8oF=require("term") | |
pfZ3SPy_,pDNa2ox6,Do6yo7nm=z8oF.clearLine,z8oF.getCursor,z8oF.clear end;local y06X3k;y06X3k=os.exit | |
local ivnJjrA,d3fMjkg | |
do local DB6A7N=io;ivnJjrA,d3fMjkg=DB6A7N.write,DB6A7N.stderr end;local el,Wu_uIt | |
do local VhYX=table;el,Wu_uIt=VhYX.insert,VhYX.unpack end;local w=pE.list;local sgeP,CM={},{}local Qlmlet=nil;local _={}local RkGFh6={}local hw18={} | |
local nvCiFt7r="/etc/hpm/module/"local xSebv5Jc="/var/lib/hpm/dist/"local mMp=0;local rDtVf="/etc/hpm/hpm.cfg" | |
local vj=[[Usage: hpm OPTIONS COMMAND | |
See `man hpm` for more info.]] | |
local z=[[-- << Global settings >> ------------------------------------------------------- | |
-- A directory where package manifests will be placed. | |
-- It will be created if it doesn't exist. | |
dist = "/var/lib/hpm/dist" | |
-- A place where to search for custom hpm modules. | |
-- It will be created if it doesn't exist. | |
modules = "/etc/hpm/module" | |
-- << Settings related to the hel module >> ------------------------------------ | |
hel = {} | |
-- If set to `false`, hpm will *only* remove a package that hpm is told to | |
-- remove. Otherwise, all of its dependants will be also removed. | |
hel.remove_dependants = true | |
-- << Settings related to the oppm module >> ----------------------------------- | |
oppm = {} | |
-- A directory where package manifests will be stored for faster access. | |
oppm.cache_directory = "/var/cache/hpm/oppm" | |
-- See hel.remove_dependants above. | |
oppm.remove_dependants = true]] | |
local Zg={info=function(...) | |
if sgeP.v then | |
return | |
print(table.concat((function(...)local Ha7ErH={}local rjU95v=1;local sxBl={...}for m=1,#sxBl do local nD4LhX6z=sxBl[m] | |
Ha7ErH[rjU95v]=tostring(nD4LhX6z)rjU95v=rjU95v+1 end;return Ha7ErH end)(...),"\t"))end end,print=function(...) | |
if | |
not(sgeP.q)then | |
return | |
print(table.concat((function(...)local iN={}local Lq=1;local s9tW={...}for R61K=1,#s9tW do local Jf4os=s9tW[R61K] | |
iN[Lq]=tostring(Jf4os)Lq=Lq+1 end;return iN end)(...),"\t"))end end,error=function(...) | |
if | |
not(sgeP.q)then | |
return | |
d3fMjkg:write( | |
table.concat((function(...)local a4xc={}local e=1;local la5={...}for i=1,#la5 do local R=la5[i] | |
a4xc[e]=tostring(R)e=e+1 end;return a4xc end)(...),"\t")..'\n')end end,fatal=function(...) | |
if | |
not(sgeP.q)then | |
d3fMjkg:write( | |
table.concat((function(...)local xWVu={}local Yw8Yxix=1;local i={...} | |
for VoXG=1,#i do | |
local JL0I04c=i[VoXG]xWVu[Yw8Yxix]=tostring(JL0I04c)Yw8Yxix=Yw8Yxix+1 end;return xWVu end)(...),"\t")..'\n')end;return y06X3k(1)end}local ykRppH | |
ykRppH=function(En6r_K97,T4AA)if not(En6r_K97)then return Zg.fatal(T4AA)end end;local WQ6 | |
WQ6=function(VnuCKTdu)return | |
Zg.fatal((tostring(VnuCKTdu))..": Not implemented yet!")end;local y36Aetn | |
y36Aetn=function()ivnJjrA(vj)return y06X3k(0)end;local iPL3B4cr | |
iPL3B4cr=function(XnNgn,H1JD)if not(XnNgn)then Zg.fatal(H1JD)end;return XnNgn end;local GI2hz6SK | |
GI2hz6SK=function(gEEa9I,ULLLDUm,e4F3) | |
if not(type(gEEa9I==ULLLDUm))then | |
Zg.fatal("Value '".. | |
tostring(gEEa9I).. | |
"' is "..tostring(type(e4F3)).. | |
", however, a "..tostring(ULLLDUm).." is expected.")end;return e4F3 end;local Oh;Oh=function(GsfNt7) | |
return GI2hz6SK(GsfNt7,"number",tonumber(GsfNt7))end;local PG | |
PG=function(fF0)return | |
GI2hz6SK(fF0,"string",tostring(fF0))end;local n | |
n=function(YWPfQKb2,r) | |
for OS0Zp3i,BK in pairs(r)do if BK==YWPfQKb2 then return true,OS0Zp3i end end;return false end;local O | |
O=function(Idjbe70)local B=0;for nDjt,NVWt in pairs(Idjbe70)do B=B+1 end;return B end;local N5UjTN | |
N5UjTN=function(efuUGMh) | |
if type(efuUGMh)=="nil"then return true elseif type(efuUGMh)=="string"then return | |
not efuUGMh or#efuUGMh<1 elseif type(efuUGMh)=="table"then return | |
not efuUGMh or O(efuUGMh)<1 else return true end end;local qLH5 | |
qLH5=function(p4nNp) | |
for VW=1,#p4nNp do local Zt=p4nNp[VW]if not Zt then return false end end;return true end;local tE | |
tE=function(V)return XxJ(V)and XPoQB(V)end;local VcV0EuD | |
VcV0EuD=function(mzeTI)return XxJ(mzeTI)and not XPoQB(mzeTI)end;local pX4gCR | |
pX4gCR=function(sy4J)return sy4J==1 and""or"s"end;local gad4ZcL | |
gad4ZcL=function(ztJhP_u8)return ztJhP_u8 ~=1 and""or"s"end;local dk | |
dk=function(D)return D==1 and"is"or"are"end;local E | |
E=function(XIcl)return XIcl:match("^([^:]-):?([^:@]+)@?([^:@]*)$")end;local OO | |
OO=function(ys) | |
if | |
pE.get(pzDMZwG.resolve(ys)).isReadOnly()then return false,"the path is readonly!"elseif not XxJ(ys)then | |
return false,"the filesystem node doesn't exist."else | |
if not(XPoQB(ys)or pE.isLink(ys))then | |
return pE.remove(ys)else | |
for rMQ1um8 in iPL3B4cr(w(ys))do OO(JQi1jg(ys,rMQ1um8))end;return pE.remove(ys)end end end;local y | |
y=function()local U2=sgeP.c or sgeP.config or rDtVf | |
if | |
not VcV0EuD(U2)then local Z=pE.path(U2) | |
if not tE(Z)then local B58,PYVzrNl=o5sms(Z)if not B58 then | |
return false,"Failed to create '".. | |
tostring(Z).."' directory for the config file: "..tostring(PYVzrNl)end end;local ZDICnKE,L=io.open(U2,"w")if ZDICnKE then ZDICnKE:write(z) | |
ZDICnKE:close()else | |
return false,"Failed to open config file for writing: "..tostring(L)end end;local X,zLtWO09=io.open(U2,"r") | |
if X then local KTVmRC=X:read("*all")X:close() | |
local Pa={};(load(KTVmRC,"config","t",Pa))() | |
local bmK | |
bmK=function(OJPc3R)if OJPc3R==nil then OJPc3R={}end | |
return | |
setmetatable(OJPc3R,{__index={get=function(j,vMgKnGj,M9K)if | |
type(OJPc3R[j])~="nil"then | |
if type(OJPc3R[j])=="table"then return bmK(OJPc3R[j])end;return OJPc3R[j]end | |
Zg.error( | |
"Attempt to access undeclared config field '"..tostring(j).."'!")if not M9K then return vMgKnGj else return bmK(vMgKnGj)end end}})end;RkGFh6=bmK(Pa)nvCiFt7r=RkGFh6.get("modules",nvCiFt7r) | |
xSebv5Jc=RkGFh6.get("dist",xSebv5Jc)return RkGFh6 else return false, | |
"Failed to open config file for reading: "..tostring(zLtWO09)end end;local cR6rJlAl | |
cR6rJlAl=function()if not(LfEJbh_("internet"))then | |
Zg.fatal("This command requires an internet card to run!")end;Qlmlet=Qlmlet or | |
require("internet").request end;local M6ilzGJ | |
M6ilzGJ=function(Zeu)cR6rJlAl()return pcall(Qlmlet,Zeu)end;local iW6CD | |
iW6CD=function() | |
if not tE(nvCiFt7r)then local W0iTcMIt,N=o5sms(nvCiFt7r)if not W0iTcMIt then | |
return false, | |
"Failed to create '".. | |
tostring(nvCiFt7r).."' directory for custom modules: "..tostring(N)end end;local Q2_d=iPL3B4cr(w(nvCiFt7r)) | |
for Hald6SO in Q2_d do | |
hw18.name=Hald6SO:match("^(.+)%..+$") | |
local Dq=iPL3B4cr(loadfile(JQi1jg(nvCiFt7r,Hald6SO),"t",hw18))Dq()hw18.name=nil end;return true end;local wZdg | |
wZdg=function(y3Ur)local GL70F7uL=y3Ur;local lqANrrJA;do local WUFTXBy6=y3Ur:find(':') | |
if WUFTXBy6 then | |
GL70F7uL=y3Ur:sub(WUFTXBy6+1)lqANrrJA=y3Ur:sub(1,WUFTXBy6-1)end end | |
if not lqANrrJA then | |
local aEZf={} | |
for QjQ_o,lqANrrJA in pairs(_)do | |
if lqANrrJA[GL70F7uL]then if type(lqANrrJA[GL70F7uL])=="table"and | |
lqANrrJA[GL70F7uL].__public==true then | |
el(aEZf,{class=lqANrrJA,module=QjQ_o,method=lqANrrJA[GL70F7uL]})end end end | |
if#aEZf>1 then local wDiq_=nil;for QYA5WJOY,lqANrrJA in pairs(aEZf)do | |
if lqANrrJA.module=="hel"then wDiq_=QYA5WJOY;break end end;if wDiq_ then | |
aEZf={aEZf[wDiq_]}end end | |
if#aEZf>1 then | |
Zg.print("Ambiguous choice: method ".. | |
tostring(GL70F7uL).." is implemented in the following modules:")for yliV8=1,#aEZf do local lqANrrJA=aEZf[yliV8] | |
Zg.print(" * "..tostring(lqANrrJA.module))end | |
Zg.print( | |
"Choose a specific module by prepending its name with a colon, e.g., ".. | |
tostring(aEZf[1].module)..":"..tostring(GL70F7uL)..".")return false elseif#aEZf==0 then | |
Zg.error("Unknown command: "..tostring(GL70F7uL))return false else lqANrrJA=aEZf[1].module | |
Zg.info("Note, using "..tostring(lqANrrJA)..":".. | |
tostring(GL70F7uL)..".")return | |
function(...)return aEZf[1].method(aEZf[1].class,...)end end else | |
if _[lqANrrJA]and N5UjTN(GL70F7uL)then local rjpKFl={} | |
for YUGQovw,XZt7GyF in pairs(_[lqANrrJA])do if | |
type(XZt7GyF)=="table"and XZt7GyF.__public==true then | |
el(rjpKFl,tostring(YUGQovw))end end | |
Zg.print("Available module-specific commands: "..tostring(table.concat(rjpKFl,", ")))return false end | |
if | |
not _[lqANrrJA]or not _[lqANrrJA][GL70F7uL]or _[lqANrrJA][GL70F7uL]and | |
( | |
type(_[lqANrrJA][GL70F7uL])~="table"or _[lqANrrJA][GL70F7uL].__public~=true)then | |
Zg.error("Unknown command: ".. | |
tostring(lqANrrJA)..":"..tostring(GL70F7uL))return false else return function(...) | |
return _[lqANrrJA][GL70F7uL](_[lqANrrJA],...)end end end end;local BaX | |
BaX=function(Zn3SC) | |
if not Zn3SC or Zn3SC==""then Zn3SC="hel"else Zn3SC=Zn3SC end;return _[Zn3SC]or _.default end;local SJsW11k | |
SJsW11k=function(D4,crA9EKx,...)if D4 ==nil then D4=_.default end | |
if D4[crA9EKx]then return | |
D4[crA9EKx](D4,...)else return _.default[crA9EKx](_.default,...)end end;local Ki1HJT | |
Ki1HJT=function(IcsJ,A,Wp9xT,P)if A==nil then A="hel"end | |
if Wp9xT==nil then Wp9xT=JQi1jg(xSebv5Jc,A)end;if P==nil then P=IcsJ.name end | |
if not IcsJ then return false,"'nil' given"end | |
if not tE(Wp9xT)then local x,AXNfV=o5sms(Wp9xT)if not x then | |
return false,"Failed to create '".. | |
tostring(JQi1jg(Wp9xT,A)).."' directory for manifest files: "..tostring(AXNfV)end end;local o0_XG8FI,jLsxpw=io.open(JQi1jg(Wp9xT,P),"w") | |
if o0_XG8FI then | |
o0_XG8FI:write(RSjapQ(IcsJ))o0_XG8FI:close()return true else return false, | |
"Failed to open file for writing: "..tostring(jLsxpw)end end;local wjim8xCV | |
wjim8xCV=function(cX,iyx,bxvn)if bxvn==nil then bxvn="hel"end | |
iyx=iyx or JQi1jg(xSebv5Jc,bxvn,cX) | |
if VcV0EuD(iyx)then local mWYrzB,O7kX=io.open(iyx,"rb") | |
if mWYrzB then | |
local Q4XSpdY=iPL3B4cr(QJf(mWYrzB:read("*all")))mWYrzB:close()return Q4XSpdY else return false, | |
"Failed to open manifest for '"..tostring(cX).."' package: ".. | |
tostring(O7kX)end else | |
return false,"No manifest found for '"..tostring(cX).."' package"end end;local EQLam | |
EQLam=function(fzTyrQ9F,fAumJ0i)if fAumJ0i==nil then fAumJ0i="hel"end | |
local i0=JQi1jg(xSebv5Jc,fAumJ0i,fzTyrQ9F) | |
if VcV0EuD(i0)then return OO(i0)else return false, | |
"No manifest found for '"..tostring(fzTyrQ9F).."' package"end end;local qTDt | |
qTDt=function(tZliF4)return | |
setmetatable({__public=true},{__call=function(jlmopoj,...)return tZliF4(...)end})end;local v | |
v=function(R,uS_N6) | |
return | |
function()local o5SLRA,ztwXaCR=pcall(R)if not(o5SLRA)then | |
return false,"Could not download '"..tostring(uS_N6).."': ".. | |
tostring(ztwXaCR)else return ztwXaCR end end end;local Ta | |
Ta=function(M2WtMgiq,FgfME,ylH9o) | |
if FgfME==nil then FgfME="Could not download '%s': %s"end;if ylH9o==nil then ylH9o="Could not download '%s': %s"end | |
local CC4Kfjh,k,eUQ0x=M6ilzGJ(M2WtMgiq)if not(CC4Kfjh and k)then | |
return false,FgfME:format(M2WtMgiq,eUQ0x)end;local r0OR="" | |
for pYHkv,eUQ0x in v(k)do if pYHkv then r0OR=r0OR..pYHkv else return false, | |
ylH9o:format(M2WtMgiq,eUQ0x)end end;return r0OR end;local unArcvQl | |
unArcvQl=function() | |
if not(sgeP.y)then | |
io.write("Press [ENTER] to continue...")local hxZHlgP=select(3,zC("key_down"))if hxZHlgP==13 then pfZ3SPy_() | |
return true else io.write("\n")return false end else | |
return true end end;local h6Ub7U | |
h6Ub7U=function(zct)local WQk6Wkd=0;local t={} | |
if not(N5UjTN(zct.install))then | |
local pRCHPl={"Packages to INSTALL:",table.concat(zct.install," ")}el(t,pRCHPl)WQk6Wkd=WQk6Wkd+#zct.install else | |
zct.install={}end | |
if not(N5UjTN(zct.reinstall))then | |
local sCffg4HK={"Packages to REINSTALL:",table.concat(zct.reinstall," ")}el(t,sCffg4HK)WQk6Wkd=WQk6Wkd+#zct.reinstall else | |
zct.reinstall={}end | |
if not(N5UjTN(zct.upgrade))then | |
local EyljhkFp={"Packages to UPGRADE:",table.concat(zct.upgrade," ")}el(t,EyljhkFp)WQk6Wkd=WQk6Wkd+#zct.upgrade else | |
zct.upgrade={}end | |
if not(N5UjTN(zct.remove))then | |
local uGDn542={"Packages to REMOVE:",table.concat(zct.remove," ")}el(t,uGDn542)WQk6Wkd=WQk6Wkd+#zct.remove else zct.remove={}end | |
do | |
local DQ={tostring(#zct.install).. | |
" to INSTALL, "..tostring(#zct.reinstall).. | |
" to REINSTALL, "..tostring( | |
#zct.upgrade).." to UPGRADE, ".. | |
tostring(#zct.remove).." to REMOVE."}el(t,DQ)end | |
for s6Ahlni_,T6dNu in pairs(t)do | |
for s6Ahlni_,H in pairs(T6dNu)do if s6Ahlni_==1 then Zg.print(H)else | |
Zg.print(" "..tostring(H))end end;if s6Ahlni_~=#t then Zg.print("")end end | |
if WQk6Wkd>0 then if not(unArcvQl())then return y06X3k(7)end end end | |
do local YlzZm;local vj9879b5={}vj9879b5.__index=vj9879b5 | |
YlzZm=setmetatable({__init=function()end,__base=vj9879b5,__name="default"},{__index=vj9879b5,__call=function(FRcmT,...) | |
local zfl=setmetatable({},vj9879b5)FRcmT.__init(zfl,...)return zfl end})vj9879b5.__class=YlzZm;local cotcYZ1f=YlzZm | |
cotcYZ1f.install=function()return | |
Zg.fatal("Incorrect source is provided! No default 'install' implementation.")end | |
cotcYZ1f.remove=function(cotcYZ1f,itxD,JPHs7A)if JPHs7A==nil then JPHs7A="hel"end | |
if itxD then | |
if itxD.files then | |
for yzYgnMtr,o in | |
pairs(itxD.files)do local wmkJ=JQi1jg(o.dir,o.name)local I1,gXu5hG=OO(wmkJ) | |
if not(I1)then return false, | |
"Failed to remove '".. | |
tostring(wmkJ).."': "..tostring(gXu5hG)end end end;return EQLam(itxD.name,JPHs7A)else | |
return false,"Package can't be removed: the manifest is empty."end end | |
cotcYZ1f.save=function()return | |
Zg.fatal("Incorrect source is provided! No default 'save' implementation.")end;_.default=YlzZm end | |
do local R60Ru4bj;local eQWRf=_.default;local WT2AX={}WT2AX.__index=WT2AX | |
setmetatable(WT2AX,eQWRf.__base) | |
R60Ru4bj=setmetatable({__init=function(qEO,...)return R60Ru4bj.__parent.__init(qEO,...)end,__base=WT2AX,__name="hel",__parent=eQWRf},{__index=function(q,WUY7) | |
local _puepou=rawget(WT2AX,WUY7)if _puepou==nil then local DYLeJ=rawget(q,"__parent") | |
if DYLeJ then return DYLeJ[WUY7]end else return _puepou end end,__call=function(udbF,...) | |
local dt1=setmetatable({},WT2AX)udbF.__init(dt1,...)return dt1 end})WT2AX.__class=R60Ru4bj;local _AvO=R60Ru4bj | |
_AvO.URL="https://hel-roottree.rhcloud.com/" | |
_AvO.parsePackageJSON=function(_AvO,V7eMEiVW,Co1tUVas) | |
if Co1tUVas==nil then Co1tUVas=YAtG_LV3.Spec("*")end;local B=nil;local UjlBMb={} | |
for IPPy,zYGA2q2 in pairs(V7eMEiVW.versions)do | |
local I9Mw=YAtG_LV3.Version(IPPy)if not(I9Mw)then | |
Zg.fatal("Could not parse the version in package: "..tostring(I9Mw))end;UjlBMb[I9Mw]=zYGA2q2 end | |
local PKWIJ9,rQYWEt=pcall(function()return | |
Co1tUVas:select((function()local e={}local BUtIET=1 | |
for NvAj,Icg in pairs(UjlBMb)do e[BUtIET]=NvAj;BUtIET=BUtIET+1 end;return e end)())end)if not(PKWIJ9)then | |
Zg.fatal("Could not select the best version: "..tostring(rQYWEt))end;B=tostring(rQYWEt)if | |
not(rQYWEt)then | |
Zg.fatal("No candidate for version specification '"..tostring(Co1tUVas).."' found!")end | |
local nCwsa={name=V7eMEiVW.name,version=B,files={},dependencies={}}for PzMsk,axLuO in pairs(UjlBMb[rQYWEt].files)do local j=axLuO.dir;local As=axLuO.name | |
el(nCwsa.files,{url=PzMsk,dir=j,name=As})end | |
for JmCzKm,Mwhc in | |
pairs(UjlBMb[rQYWEt].depends)do local A6z=Mwhc.version;local _Mk=Mwhc.type | |
el(nCwsa.dependencies,{name=JmCzKm,version=A6z,type=_Mk})end;return nCwsa end | |
_AvO.getPackageSpec=function(_AvO,PXrrrSid) | |
Zg.info("Downloading package data for "..tostring(PXrrrSid).." ...") | |
local L9,_KZPScl=M6ilzGJ(_AvO.URL.."packages/"..PXrrrSid)if not(L9)then | |
Zg.fatal("HTTP request error: ".._KZPScl)end;local dbTwy="" | |
for Kj1I in _KZPScl do dbTwy=dbTwy..Kj1I end;local R4f819q=s:decode(dbTwy)if not(R4f819q)then | |
Zg.fatal("Incorrect JSON format!\n"..tostring(dbTwy))end;return R4f819q.data end | |
_AvO.rawInstall=function(_AvO,nTUMgqomA,Id5sIM,gZM2ANLt)if Id5sIM==nil then Id5sIM=false end | |
if gZM2ANLt==nil then gZM2ANLt=false end;local aC72qEnu | |
if gZM2ANLt then aC72qEnu=JQi1jg(u(),nTUMgqomA.name)else aC72qEnu="/"end | |
if gZM2ANLt and not tE(aC72qEnu)then local B60J,Y4=o5sms(aC72qEnu)if | |
not(B60J)then | |
Zg.fatal("Failed creating '"..tostring(aC72qEnu).. | |
"' directory for package '"..tostring(nTUMgqomA.name).. | |
"'! \n"..tostring(Y4))end elseif not | |
gZM2ANLt then local f=wjim8xCV(nTUMgqomA.name,nil,"hel") | |
if f then | |
if f.version== | |
tostring(nTUMgqomA.version)then | |
Zg.print("'".. | |
tostring(nTUMgqomA.name).."@"..tostring(f.version).. | |
"' is already installed, skipping...")return f else | |
Zg.fatal("'".. | |
tostring(nTUMgqomA.name).. | |
"@".. | |
tostring(nTUMgqomA.version).. | |
"' was attempted to install, however, another version of the same package is already installed: '"..tostring(nTUMgqomA.name).. | |
"@"..tostring(f.version).."'")end end end | |
for yeCnvcd6,Iq93c6cA in pairs(nTUMgqomA.files)do | |
Zg.info("Fetching '".. | |
tostring(Iq93c6cA.name).."' ...")local nsM0h=iPL3B4cr(Ta(Iq93c6cA.url)) | |
local Czi=JQi1jg(aC72qEnu,Iq93c6cA.dir) | |
if not tE(Czi)then local IlxN,EA_3x01A=o5sms(Czi)if not(IlxN)then | |
Zg.fatal("Failed to create '".. | |
tostring(Czi).. | |
"' directory for '".. | |
tostring(Iq93c6cA.name).."'! \n"..tostring(EA_3x01A))end end | |
do local m54tY2 | |
Iq93c6cA,m54tY2=io.open(JQi1jg(Czi,Iq93c6cA.name),"w")if not(Iq93c6cA)then | |
Zg.fatal("Could not open '".. | |
tostring(JQi1jg(Czi,Iq93c6cA.name)).."' for writing: "..tostring(m54tY2))end | |
Iq93c6cA:write(nsM0h)Iq93c6cA:close()end end;return | |
{name=nTUMgqomA.name,version=tostring(nTUMgqomA.version),files=nTUMgqomA.files,dependencies=nTUMgqomA.dependencies,manual=Id5sIM}end | |
_AvO.resolveDependencies=function(_AvO,WJWMdKI,AhbP,QHFgYUN,RoEsr7So)if AhbP==nil then AhbP={}end | |
if QHFgYUN==nil then QHFgYUN={}end;if RoEsr7So==nil then RoEsr7So={}end | |
for dX=1,#WJWMdKI do local Rz=WJWMdKI[dX]local j177r,j | |
j177r,j=Rz.name,Rz.version;local qCaFw=false | |
for syvPi=1,#AhbP do local NrgSK2=AhbP[syvPi]if NrgSK2.pkg.name==j177r then | |
qCaFw=true;break end end | |
if not(qCaFw)then el(QHFgYUN,{name=j177r,version=""}) | |
local wIH=wjim8xCV(j177r,nil,"hel") | |
if not wIH or | |
not j:match(YAtG_LV3.Version(wIH.version))then local TYWkpc=_AvO:getPackageSpec(j177r) | |
local k=_AvO:parsePackageJSON(TYWkpc,j)QHFgYUN[#QHFgYUN].version=k.version;local J=k.dependencies | |
for gtlO9=1,#J do | |
local Lun=J[gtlO9]qCaFw=false | |
for beUJXhjw=1,#AhbP do local zY7adu=AhbP[beUJXhjw]if | |
zY7adu.pkg.name==Lun.name then qCaFw=true;break end end | |
if not qCaFw then local Nlvw=nil;for K55,BJcMTdMi in pairs(QHFgYUN)do | |
if BJcMTdMi.name==Lun.name then Nlvw=K55;break end end | |
if Nlvw then | |
if QHFgYUN[Nlvw].version== | |
Lun.version then | |
Zg.fatal("Circular dependencies detected: '".. | |
tostring(j177r).. | |
"@".. | |
tostring(k.version).. | |
"' depends on '".. | |
tostring(Lun.name).. | |
"@".. | |
tostring(Lun.version).. | |
"', and '".. | |
tostring(QHFgYUN[Nlvw].name).. | |
"@"..tostring(QHFgYUN[Nlvw].version).. | |
"' depends on '"..tostring(j177r).."@".. | |
tostring(k.version).."'.")else | |
Zg.fatal("Attempted to install two versions of the same package: '".. | |
tostring(Lun.name).. | |
"@".. | |
tostring(Lun.version).. | |
"' and '".. | |
tostring(QHFgYUN[Nlvw].name).."@".. | |
tostring(QHFgYUN[Nlvw].version).."' when resolving dependencies for '"..tostring(j177r).. | |
"@"..tostring(k.version).."'.")end end | |
_AvO:resolveDependencies({{name=Lun.name,version=YAtG_LV3.Spec(Lun.version)}},AhbP,QHFgYUN,RoEsr7So)end end;el(AhbP,{pkg=k})el(RoEsr7So,{pkg=k})else | |
el(AhbP,{pkg=wIH})end;QHFgYUN[#QHFgYUN]=nil end end;return RoEsr7So end | |
_AvO.getPackageDependants=function(_AvO,f1MKKJ,nFf,EIqL41)if nFf==nil then nFf={}end | |
if EIqL41 ==nil then EIqL41={}end | |
for iv=1,#f1MKKJ do local rfmMR4=f1MKKJ[iv]local Tq2I=false;for GNo=1,#nFf do local e5x=nFf[GNo]if e5x.name==rfmMR4 then | |
Tq2I=true;break end end | |
if | |
not(Tq2I)then el(EIqL41,{name=rfmMR4}) | |
local QrONvWGq=wjim8xCV(rfmMR4,nil,"hel") | |
if QrONvWGq then el(nFf,{name=rfmMR4,manifest=QrONvWGq}) | |
local D94fnZaa=iPL3B4cr(w(JQi1jg(xSebv5Jc,"hel"))) | |
for XI in D94fnZaa do QrONvWGq=iPL3B4cr(wjim8xCV(XI,nil,"hel")) | |
local FNi=QrONvWGq.dependencies | |
for pRW2nEmK=1,#FNi do local OR=FNi[pRW2nEmK] | |
if OR.name==rfmMR4 then Tq2I=false | |
for Arww=1,#nFf do local BYH=nFf[Arww]if | |
BYH.name==XI then Tq2I=true;break end end | |
if not Tq2I then | |
for o7E8TLH=1,#EIqL41 do local N5N27Jd=EIqL41[o7E8TLH]if N5N27Jd.name==XI then | |
Zg.fatal( | |
"Circular dependencies detected: "..tostring(XI))end end;_AvO:getPackageDependants({XI},nFf,EIqL41)end end end end else | |
Zg.fatal("Package ".. | |
tostring(rfmMR4).." is referenced as a dependant of another package, however, this package isn't installed.")end;EIqL41[#EIqL41]=nil end end;return nFf end | |
_AvO.install=qTDt(function(_AvO,...) | |
if sgeP.l or sgeP["local"]then | |
local F4AWvI=pzDMZwG.resolve(...) | |
local GYVN=iPL3B4cr(wjim8xCV(F4AWvI,JQi1jg(F4AWvI,"manifest"))) | |
local DNlB1V=_AvO:resolveDependencies((function()local xNPDtul={}local k8=1;local HmgRk=GYVN.dependencies | |
for UuCdpVi=1,#HmgRk do | |
local fghe=HmgRk[UuCdpVi]local vFXf,CA0uX7n;vFXf,CA0uX7n=fghe.name,fghe.version | |
xNPDtul[k8]={name=vFXf,version=YAtG_LV3.Spec(CA0uX7n)}k8=k8+1 end;return xNPDtul end)())local erb6G_E=sgeP.d or sgeP.onlyDeps;local QFUU10K={}for ze5Vpc3=1,#DNlB1V do | |
local vwK8=DNlB1V[ze5Vpc3] | |
el(QFUU10K,tostring(vwK8.pkg.name).. | |
"@"..tostring(vwK8.pkg.version))end;if | |
not(erb6G_E)then | |
el(QFUU10K,tostring(GYVN.name).."@"..tostring(GYVN.version))end | |
h6Ub7U({install=QFUU10K}) | |
for Sk_SiC=1,#DNlB1V,1 do local X0bgPvA=DNlB1V[Sk_SiC] | |
Zg.print("Installing '".. | |
tostring(X0bgPvA.pkg.name).. | |
"@"..tostring(X0bgPvA.pkg.version).."'...")local M9CyqH=_AvO:rawInstall(X0bgPvA.pkg,false,false) | |
local z0x4qSAN,X0GTupeV=Ki1HJT(M9CyqH,"hel") | |
if z0x4qSAN then | |
Zg.info("Saved the manifest of '"..tostring(M9CyqH.name).."'.")else | |
Zg.fatal("Couldn't save the manifest of '"..tostring(M9CyqH.name).."': ".. | |
tostring(X0GTupeV)..".")end end | |
if not erb6G_E then | |
Zg.print("Installing '"..tostring(GYVN.name).."@".. | |
tostring(GYVN.version).."'...") | |
for Oc,IHovU in pairs(GYVN.files)do if | |
not tE(JQi1jg(IHovU.dir,IHovU.name))then o5sms(IHovU.dir)end | |
local e_wDQjk,ClglY=wVzn(JQi1jg(F4AWvI,IHovU.url),JQi1jg(IHovU.dir,IHovU.name))if not(e_wDQjk)then | |
Zg.fatal("Cannot copy file '"..tostring(IHovU.name).. | |
"': "..tostring(ClglY))end end;local rQ,k=Ki1HJT(GYVN,"hel") | |
if rQ then | |
Zg.info("Saved the manifest of '".. | |
tostring(GYVN.name).."'.")else | |
Zg.fatal("Couldn't save the manifest of '".. | |
tostring(GYVN.name).."': "..tostring(k)..".")end end;return true end;local m={}local nK={...} | |
for S=1,#nK do local NKetZhs=nK[S] | |
local EFLZ0N1,gL=NKetZhs:match("^(.+)@(.+)$")or NKetZhs;if N5UjTN(gL)then gL="*"end | |
Zg.info("Creating version specification for "..tostring(gL).." ...") | |
local m4,rNOL8G=pcall(function()return YAtG_LV3.Spec(gL)end)if not(m4)then | |
Zg.fatal("Could not parse the version specification: "..tostring(rNOL8G).."!")end | |
el(m,{name=EFLZ0N1,version=rNOL8G})end;local _zr=sgeP.r or sgeP.reinstall | |
local f5=sgeP.s or sgeP.save;local UAc=_AvO:resolveDependencies(m)local Ef={}local P={} | |
for q=1,#UAc do local lKO=false | |
repeat | |
local hcwgu=UAc[q] | |
if _zr then local omgCdqp8=false | |
for X17eHTx=1,#m do local SGF=m[X17eHTx]if SGF.name==hcwgu.pkg.name then | |
omgCdqp8=true;break end end;if omgCdqp8 then | |
el(Ef,tostring(hcwgu.pkg.name).. | |
"@"..tostring(hcwgu.pkg.version))lKO=true;break end end | |
el(P,tostring(hcwgu.pkg.name).. | |
"@"..tostring(hcwgu.pkg.version))lKO=true until true;if not lKO then break end end;h6Ub7U({install=P,reinstall=Ef}) | |
if _zr then local myIHU | |
do local xxNCdF={}local _cl1b=1;for Xz18nk=1,#m do | |
local PsTX4=m[Xz18nk] | |
xxNCdF[_cl1b]=iPL3B4cr(wjim8xCV(PsTX4.name,nil,"hel"))_cl1b=_cl1b+1 end | |
myIHU=xxNCdF end;_AvO:_remove(myIHU,true,false)end | |
for A0TJx=1,#UAc do local Nqdkw=UAc[A0TJx] | |
Zg.print("Installing '"..tostring(Nqdkw.pkg.name).."@".. | |
tostring(Nqdkw.pkg.version).."'...")local t=false;for o0pf=1,#m do local tx1LD=m[o0pf] | |
if tx1LD.name==Nqdkw.pkg.name then t=true;break end end | |
local QbMO=_AvO:rawInstall(Nqdkw.pkg,t,f5)local wYZ,aMd=Ki1HJT(QbMO,"hel") | |
if wYZ then | |
Zg.info("Saved the manifest of '".. | |
tostring(QbMO.name).."'.")else | |
Zg.fatal("Couldn't save the manifest of '"..tostring(QbMO.name).. | |
"': "..tostring(aMd)..".")end end end) | |
_AvO.remove=qTDt(function(_AvO,...)local N3ROeR={...}local I1oQVnUd={} | |
for oTX=1,#N3ROeR do local WZlF4=N3ROeR[oTX] | |
local IxqPDOWH=iPL3B4cr(wjim8xCV(WZlF4,nil,"hel"))el(I1oQVnUd,IxqPDOWH)end;return _AvO:_remove(I1oQVnUd,false)end) | |
_AvO._remove=function(_AvO,GZqV,OVubrDw_,G2_TeR8)if OVubrDw_==nil then OVubrDw_=false end;if G2_TeR8 ==nil then | |
G2_TeR8=true end;local yk | |
if not | |
RkGFh6.get("hel",{},true).get("remove_dependants",true)or not G2_TeR8 then | |
do | |
local OPSPMfr_={}local QnNOl=1;for aQs=1,#GZqV do local uow_0tb=GZqV[aQs] | |
OPSPMfr_[QnNOl]={name=uow_0tb.name,manifest=uow_0tb}QnNOl=QnNOl+1 end | |
yk=OPSPMfr_ end else | |
yk=_AvO:getPackageDependants((function()local tykg={}local C_pPyW=1;for mgb4b=1,#GZqV do local LOBqxO=GZqV[mgb4b] | |
tykg[C_pPyW]=LOBqxO.name;C_pPyW=C_pPyW+1 end;return tykg end)())end | |
if not(OVubrDw_)then | |
h6Ub7U({remove=(function()local m8={}local mcoAHO=1 | |
for d3gFWO=1,#yk do local D=yk[d3gFWO] | |
m8[mcoAHO]="hel:".. | |
tostring(D.manifest.name).."@"..tostring(D.manifest.version)mcoAHO=mcoAHO+1 end;return m8 end)()})end | |
for obodPKnu=1,#yk do local kgdzk=yk[obodPKnu] | |
Zg.print("Removing '"..tostring(kgdzk.manifest.name).. | |
"@"..tostring(kgdzk.manifest.version).."' ...") | |
iPL3B4cr(R60Ru4bj.__parent.remove(_AvO,kgdzk.manifest,"hel"))end;return true end | |
_AvO.upgrade=qTDt(function(_AvO)local oVSp={} | |
for uKSj in iPL3B4cr(w(JQi1jg(xSebv5Jc,"hel")))do if not | |
(XPoQB(JQi1jg(xSebv5Jc,"hel",uKSj)))then | |
el(oVSp,iPL3B4cr(wjim8xCV(uKSj,nil,"hel")))end end;local uBJ={} | |
for YXgXQB=1,#oVSp do local bvL1X4=oVSp[YXgXQB] | |
local PPNahh,z2g=pcall(_AvO.getPackageSpec,_AvO,bvL1X4.name) | |
if PPNahh then local m9JTkVv6=_AvO:parsePackageJSON(z2g) | |
bvL1X4.latest={spec=z2g,data=m9JTkVv6} | |
if YAtG_LV3.Version(bvL1X4.latest.data.version)> | |
YAtG_LV3.Version(bvL1X4.version)then el(uBJ,bvL1X4)end end end | |
local A=_AvO:resolveDependencies((function()local Q={}local bWkP=1;for JtFj=1,#uBJ do local PQ3=uBJ[JtFj] | |
Q[bWkP]={name=PQ3.name,version=YAtG_LV3.Spec(PQ3.latest.data.version)}bWkP=bWkP+1 end;return | |
Q end)())local MP | |
do local _xCtN={}local JVpe=1 | |
for nG36XmZC=1,#uBJ do local Vf26=uBJ[nG36XmZC] | |
_xCtN[JVpe]= | |
tostring(Vf26.name).."@{".. | |
tostring(Vf26.version).." => ".. | |
tostring(Vf26.latest.data.version).."}"JVpe=JVpe+1 end;MP=_xCtN end;local jb={} | |
for xUGt=1,#A do local _U=A[xUGt]local hkI39=true | |
for MwwN=1,#uBJ do local oZ9=uBJ[MwwN]if | |
oZ9.name==_U.pkg.name then hkI39=false;break end end;if hkI39 then | |
el(jb,tostring(_U.pkg.name).."@"..tostring(_U.pkg.version))end end;h6Ub7U({upgrade=MP,install=jb}) | |
for OXlT0=1,#A do local V=A[OXlT0] | |
local zIYNIXy1=false;local c=false | |
for nqBfKL=1,#uBJ do local gs3a=uBJ[nqBfKL]if gs3a.name==V.pkg.name then zIYNIXy1=gs3a | |
c=gs3a.manual;break end end | |
if zIYNIXy1 then _AvO:_remove({zIYNIXy1},true,false)end | |
Zg.print("Installing '"..tostring(V.pkg.name).."@".. | |
tostring(V.pkg.version).."'...")local mReHt4h=_AvO:rawInstall(V.pkg,c,false) | |
local I7,Upw=Ki1HJT(mReHt4h,"hel") | |
if I7 then | |
Zg.info("Saved the manifest of '"..tostring(mReHt4h.name).."'.")else | |
Zg.fatal("Couldn't save the manifest of '"..tostring(mReHt4h.name).. | |
"': "..tostring(Upw)..".")end end end) | |
_AvO.info=qTDt(function(_AvO,AkKaBC,OmRH8)if OmRH8 ==nil then OmRH8="*"end;if N5UjTN(AkKaBC)then | |
Zg.fatal("Usage: hpm hel:info <package name> [<version specification>]")end | |
if N5UjTN(OmRH8)then OmRH8="*"end | |
Zg.print("Creating version specification for "..tostring(OmRH8).." ...") | |
local GY,oukM79R=pcall(function()return YAtG_LV3.Spec(OmRH8)end)if not(GY)then | |
Zg.fatal("Could not parse the version specification: "..tostring(oukM79R).."!")end | |
local D_j=_AvO:getPackageSpec(AkKaBC)local mZPe4w=_AvO:parsePackageJSON(D_j,oukM79R)local OvZ={} | |
el(OvZ, | |
"- Package name: "..tostring(D_j.name)) | |
el(OvZ,"- Description:\n"..tostring(D_j.description)) | |
el(OvZ,"- Package owners: "..tostring(table.concat(D_j.owners,", "))) | |
el(OvZ,"- Authors:\n".. | |
tostring(table.concat((function()local cBOpf={}local KZYA5y=1;local YoCAN7OU=D_j.authors;for FoP=1,#YoCAN7OU do | |
local jqtWXY=YoCAN7OU[FoP]cBOpf[KZYA5y]=" - "..tostring(jqtWXY) | |
KZYA5y=KZYA5y+1 end;return cBOpf end)(),"\n"))) | |
el(OvZ,"- License: "..tostring(D_j.license)) | |
el(OvZ,"- Versions: "..tostring(O(D_j.versions))..", latest: ".. | |
tostring(mZPe4w.version)) | |
el(OvZ," - Files: "..tostring(#mZPe4w.files)) | |
el(OvZ," - Depends: ".. | |
tostring(table.concat((function()local XgRb={}local G3e=1;local GoP6=mZPe4w.dependencies;for cZ_=1,#GoP6 do | |
local NYc8=GoP6[cZ_] | |
XgRb[G3e]=tostring(NYc8.name).."@"..tostring(NYc8.version)G3e=G3e+1 end;return XgRb end)()))) | |
el(OvZ," - Changes:\n".. | |
tostring(D_j.versions[mZPe4w.version].changes))el(OvZ,"- Stats:") | |
el(OvZ," - Views: "..tostring(D_j.stats.views)) | |
el(OvZ,"- Creation date: ".. | |
tostring(D_j.stats.date.created).." UTC") | |
el(OvZ,"- Last updated: ".. | |
tostring(D_j.stats.date["last-updated"]).." UTC")return Zg.print(table.concat(OvZ,"\n"))end) | |
_AvO.search=qTDt(function(_AvO,...)local Dff8=0 | |
while true do local lEYwsOG9={}local M=_AvO.URL.."packages" | |
if...then | |
M=M.. | |
("?q=".. | |
table.concat((function(...) | |
local N={}local v9mB_RUi=1;local hX={...}for AVU=1,#hX do local I=hX[AVU] | |
N[v9mB_RUi]='"'..I:gsub("\"","")..'"'v9mB_RUi=v9mB_RUi+1 end;return N end)(...)," "):gsub("&",""))end;M=M.."?offset="..tostring(Dff8) | |
local Vt95q2G,jsPbwU=M6ilzGJ(M)if not(Vt95q2G)then | |
Zg.fatal("HTTP request error: "..jsPbwU)end;local Wvs3rd6o="" | |
for _x5O1 in jsPbwU do Wvs3rd6o=Wvs3rd6o.._x5O1 end;local UdVlP=s:decode(Wvs3rd6o)if not(UdVlP)then | |
Zg.fatal("Incorrect JSON format!\n".. | |
tostring(Wvs3rd6o))end;lEYwsOG9=UdVlP.data.list;for eFI8dI3=1,#lEYwsOG9 | |
do local i=lEYwsOG9[eFI8dI3] | |
Zg.print(tostring(i.name)..": ".. | |
tostring(i.short_description))end | |
if | |
#lEYwsOG9 ==0 and Dff8 ==0 then Zg.print("No packages found.")break end | |
if UdVlP.data.truncated and UdVlP.data.sent+UdVlP.data.offset< | |
UdVlP.data.total then Dff8= | |
UdVlP.data.offset+UdVlP.data.sent else break end end end) | |
if eQWRf.__inherited then eQWRf.__inherited(eQWRf,R60Ru4bj)end;_.hel=R60Ru4bj end | |
do local l6xUetCb;local lOb_Sv=_.default;local VspvGB9V={}VspvGB9V.__index=VspvGB9V | |
setmetatable(VspvGB9V,lOb_Sv.__base) | |
l6xUetCb=setmetatable({__init=function(GfB7,...) | |
return l6xUetCb.__parent.__init(GfB7,...)end,__base=VspvGB9V,__name="oppm",__parent=lOb_Sv},{__index=function(Iz_w1j,G) | |
local X7YKzX=rawget(VspvGB9V,G)if X7YKzX==nil then local od0VOF=rawget(Iz_w1j,"__parent") | |
if od0VOF then return od0VOF[G]end else return X7YKzX end end,__call=function(oO6SbZ,...) | |
local UE_vrsNx=setmetatable({},VspvGB9V)oO6SbZ.__init(UE_vrsNx,...)return UE_vrsNx end})VspvGB9V.__class=l6xUetCb;local LrFLp5=l6xUetCb | |
LrFLp5.REPOS="https://raw.githubusercontent.com/OpenPrograms/openprograms.github.io/master/repos.cfg" | |
LrFLp5.PACKAGES="https://raw.githubusercontent.com/%s/master/programs.cfg"LrFLp5.FILES="https://raw.githubusercontent.com/%s/%s" | |
LrFLp5.DIRECTORY="https://api.github.com/repos/%s/contents/%s?ref=%s"LrFLp5.DEFAULT_CACHE_DIRECTORY="/var/cache/hpm/oppm" | |
LrFLp5.cacheDirectory=function(LrFLp5) | |
local kef2zBS=RkGFh6.get("oppm",{},true).get("cache_directory",LrFLp5.DEFAULT_CACHE_DIRECTORY) | |
if not(tE(kef2zBS))then local Z,ze0=o5sms(kef2zBS)if not(Z)then | |
Zg.fatal( | |
"Could not create the cache directory at "..tostring(kef2zBS)..": "..tostring(ze0))end end;return kef2zBS end | |
LrFLp5.listCache=function(LrFLp5)local ylW3uC0={}local N_G1=LrFLp5:cacheDirectory() | |
local wkGNE=iPL3B4cr(w(N_G1)) | |
for ccK in wkGNE do | |
if XPoQB(JQi1jg(N_G1,ccK))then | |
local BV=iPL3B4cr(w(JQi1jg(N_G1,ccK))) | |
for HnLY in BV do | |
if XPoQB(JQi1jg(N_G1,ccK,HnLY))then | |
local cm51CH1n=iPL3B4cr(w(JQi1jg(N_G1,ccK,HnLY))) | |
for iWrSgT in cm51CH1n do local C=JQi1jg(N_G1,ccK,HnLY,iWrSgT) | |
if not(XPoQB(C))then local YK1 | |
do | |
local HjKNi,Ub9iqg=io.open(C,"r")if not HjKNi then | |
return false,"Could not open '".. | |
tostring(C).."' for reading: "..tostring(Ub9iqg)end | |
qLH5=HjKNi:read("*all")YK1=QJf(qLH5)HjKNi:close()end;local t96Qtz=JQi1jg(ccK,HnLY) | |
el(ylW3uC0,{path=C,repo=t96Qtz,pkg=iWrSgT,data=YK1})end end end end end end;return ylW3uC0 end | |
LrFLp5.fixCache=function(LrFLp5)local r_S8HFRo=LrFLp5:cacheDirectory() | |
local qIF4RFBv=iPL3B4cr(w(r_S8HFRo)) | |
for wNbC65Ta in qIF4RFBv do local xOiPW=true;local Z9j=JQi1jg(r_S8HFRo,wNbC65Ta) | |
if XPoQB(Z9j)then | |
local r=iPL3B4cr(w(Z9j)) | |
for OnJ1 in r do local KFU0=true;local Pvuq=JQi1jg(Z9j,OnJ1) | |
if XPoQB(Pvuq)then | |
local lOpDJ=iPL3B4cr(w(Pvuq)) | |
for YLe in lOpDJ do local lTH=true;local JL=JQi1jg(Pvuq,YLe)if not(XPoQB(JL))then | |
lTH,KFU0,xOiPW=false,false,false end;if lTH then OO(JL)end end end;if KFU0 then OO(Pvuq)end end end;if xOiPW then OO(Z9j)end end;return true end | |
LrFLp5.resolveDirectory=function(LrFLp5,FpU_E,JWtwnQ2t,uEKPPpj_) | |
local aYO4NN=iPL3B4cr(Ta(LrFLp5.DIRECTORY:format(FpU_E,uEKPPpj_,JWtwnQ2t)))aYO4NN=s:decode(aYO4NN) | |
if aYO4NN.message then return false, | |
"Could not fetch "..tostring(FpU_E).. | |
":".. | |
tostring(JWtwnQ2t).."/".. | |
tostring(uEKPPpj_)..": "..tostring(aYO4NN.message)end;local CtG9nSQL={}local uZtK5yX=1 | |
for kr2CYaS=1,#aYO4NN do local hXgSzEI=aYO4NN[kr2CYaS] | |
if | |
hXgSzEI.type=="file"then | |
CtG9nSQL[uZtK5yX]={name=hXgSzEI.name,url=hXgSzEI.download_url,path=hXgSzEI.path}uZtK5yX=uZtK5yX+1 end end;return CtG9nSQL end | |
LrFLp5.updateCache=function(LrFLp5)local AUQ=LrFLp5:cacheDirectory() | |
local B=iPL3B4cr(LrFLp5:listCache())local J,coSiE=Ta(LrFLp5.REPOS) | |
if not(J)then return false, | |
"Could not fetch "..tostring(LrFLp5.REPOS).. | |
": "..tostring(coSiE)end;J=QJf(J)local wm={} | |
for smj,obBu in pairs(J)do local cbQlG=false | |
repeat | |
if obBu.repo then | |
Zg.info("Fetching '"..tostring(smj).."' at '".. | |
tostring(obBu.repo).."' ...")local YZQu1DR4,kza | |
YZQu1DR4,kza,coSiE=M6ilzGJ(LrFLp5.PACKAGES:format(obBu.repo)) | |
if not(YZQu1DR4 and kza)then | |
Zg.error("Could not fetch '"..tostring(smj).. | |
"' at '".. | |
tostring(obBu.repo).."': "..tostring(coSiE))cbQlG=true;break end;local CvGDk_2="" | |
for YZQu1DR4,LNlhK in function()return pcall(kza)end do | |
if not YZQu1DR4 then | |
Zg.error("Could not fetch '".. | |
tostring(smj).. | |
"' at '"..tostring(obBu.repo).."': "..tostring(LNlhK))CvGDk_2=false;break else if not LNlhK then break end;CvGDk_2=CvGDk_2 ..LNlhK end end;if CvGDk_2 ==false then cbQlG=true;break end;if N5UjTN(CvGDk_2)then | |
Zg.error( | |
"Could not fetch '".. | |
tostring(smj).."' at '"..tostring(obBu.repo).."'")cbQlG=true;break end | |
local EGpun;EGpun,coSiE=QJf(CvGDk_2) | |
if not EGpun then | |
Zg.error("Manifest '"..tostring(smj).. | |
"' at '".. | |
tostring(obBu.repo).."' is malformed: "..tostring(coSiE))cbQlG=true;break end | |
for cnx_1g,eV in pairs(EGpun)do local DGQnw=false | |
repeat | |
if cnx_1g:match("[^A-Za-z0-9._-]")then | |
Zg.error( | |
"Package name contains illegal characters: "..tostring(smj)..":"..tostring(cnx_1g).."!")DGQnw=true;break end;el(wm,{repo=obBu.repo,name=cnx_1g,data=eV}) | |
DGQnw=true until true;if not DGQnw then break end end end;cbQlG=true until true;if not cbQlG then break end end;local _O={} | |
for yLgHuF=1,#wm do local fpL=wm[yLgHuF]local k6,m,rvNhq6v | |
k6,m,rvNhq6v=fpL.name,fpL.repo,fpL.data;if n(JQi1jg(m,k6),_O)then | |
Zg.error("There're multiple packages under the same name: "..tostring(k6).."!")end | |
if not | |
(tE(JQi1jg(AUQ,m)))then local VvzMQHj;VvzMQHj,coSiE=o5sms(JQi1jg(AUQ,m))if | |
not(VvzMQHj)then | |
return false,"Could not create directory '".. | |
tostring(JQi1jg(AUQ,m)).."': "..tostring(coSiE)end end;local gC;gC,coSiE=io.open(JQi1jg(AUQ,m,k6),"w")if not(gC)then | |
return false, | |
"Could not open '".. | |
tostring(JQi1jg(AUQ,m,k6)).."' for writing: "..tostring(coSiE)end;do | |
gC:write(RSjapQ({name=k6,repo=m,data=rvNhq6v}))gC:close()end;local QO;do | |
for fSYJX,WV in pairs(B)do if WV.repo==m and | |
WV.pkg==k6 then QO=fSYJX;break end end end;if QO then table.remove(B,QO)else | |
el(_O,JQi1jg(m,k6))end end;Zg.print("Removing old cache files ...") | |
for yUho4MXRx=1,#B do | |
local J2=B[yUho4MXRx]local hgrBfz0w;hgrBfz0w=J2.path;OO(hgrBfz0w)end;Zg.print("Fixing bad cache nodes ...") | |
LrFLp5:fixCache() | |
Zg.print("- "..tostring(#wm).. | |
" program"..tostring(pX4gCR(#wm)).." cached.") | |
Zg.print("- "..tostring(#_O).. | |
" package"..tostring(pX4gCR(#_O)).." ".. | |
tostring(dk(#_O)).." new.") | |
Zg.print("- "..tostring(#B).. | |
" package"..tostring(pX4gCR(#B)).." no longer exist".. | |
tostring(gad4ZcL(#B))..".")return true end | |
LrFLp5.parseLocalPath=function(LrFLp5,Gi,wpv1) | |
if wpv1:sub(1,2)=="//"then | |
return JQi1jg(Gi,wpv1:sub(3))else return JQi1jg(Gi,"usr",wpv1)end end | |
LrFLp5.rawInstall=function(LrFLp5,I9IMuWm,a,rZ,VKTNfzUf)if a==nil then a="/"end;if rZ==nil then rZ=false end;if VKTNfzUf==nil then | |
VKTNfzUf=false end;local Oms4=LrFLp5:listCache() | |
local JfA={filesInstalled=0,packagesInstalled=0} | |
if VKTNfzUf and not tE(a)then local LoW_7e,mLgQ=o5sms(a)if not(LoW_7e)then | |
Zg.fatal("Failed to create '".. | |
tostring(a).."' directory for package '".. | |
tostring(I9IMuWm).."'! \n"..tostring(mLgQ))end elseif | |
not VKTNfzUf then local ng=wjim8xCV(I9IMuWm,nil,"oppm")if ng then | |
Zg.print("'"..tostring(I9IMuWm).. | |
"' is already installed, skipping...")return ng,JfA end end;local CPu1 | |
for Pp_NboV=1,#Oms4 do local owAp3u2G=Oms4[Pp_NboV]local OH0C,kmQkm9cr,IE97m,wey | |
OH0C,kmQkm9cr,IE97m,wey=owAp3u2G.path,owAp3u2G.pkg,owAp3u2G.repo,owAp3u2G.data;if kmQkm9cr==I9IMuWm then CPu1=owAp3u2G;break end end;if not(CPu1)then | |
Zg.fatal("No such package: "..tostring(I9IMuWm))end;local pfyhF={}local pglFz82w=CPu1.repo | |
for hThO6,zXU in | |
pairs(CPu1.data.data.files)do local HmJym2={} | |
if hThO6:sub(1,1)==":"then | |
HmJym2=LrFLp5:resolveDirectory(pglFz82w,hThO6:sub(2, | |
hThO6:find("/")-1,nil),hThO6:sub(hThO6:find("/")+1))else | |
HmJym2={{name=pE.name(hThO6),path=hThO6,url=LrFLp5.FILES:format(pglFz82w,hThO6)}}end;local I9IMuWm | |
for Jjb7Am5=1,#HmJym2 do local UwqY7A=HmJym2[Jjb7Am5]local k,d7gPKcw | |
I9IMuWm,k,d7gPKcw=UwqY7A.name,UwqY7A.path,UwqY7A.url;local naeNp=iPL3B4cr(Ta(d7gPKcw)) | |
local gA=LrFLp5:parseLocalPath(a,zXU)if not(tE(gA))then o5sms(gA)end | |
do | |
local r,LWe=io.open(JQi1jg(gA,I9IMuWm),"w")if not r then | |
Zg.fatal("Could not open file for writing: "..tostring(LWe))end;r:write(naeNp)r:close()end;JfA.filesInstalled=JfA.filesInstalled+1 | |
el(pfyhF,{name=I9IMuWm,url=d7gPKcw,dir=gA})end end;local RkeCL={} | |
if CPu1.data.data.dependencies then for _3Tq in | |
pairs(CPu1.data.data.dependencies)do el(RkeCL,{name=_3Tq})end end;JfA.packagesInstalled=JfA.packagesInstalled+1;return | |
{name=I9IMuWm,files=pfyhF,dependencies=RkeCL,manual=rZ},JfA end | |
LrFLp5.resolveDependencies=function(LrFLp5,Rq1hByv,iFk,sEFtmNgB,qxiez0Cn)if iFk==nil then iFk={}end | |
if sEFtmNgB==nil then sEFtmNgB={}end;if qxiez0Cn==nil then qxiez0Cn={}end;local Ck_H=LrFLp5:listCache() | |
for Sc=1, | |
#Rq1hByv do local _QFw_It=Rq1hByv[Sc]local WLqHf=false | |
for vN=1,#iFk do local BIwW6_=iFk[vN]if | |
BIwW6_==_QFw_It then WLqHf=true;break end end | |
if not(WLqHf)then sEFtmNgB[_QFw_It]=true | |
local Vdfc3=wjim8xCV(_QFw_It,nil,"oppm") | |
if not Vdfc3 then local CzM7PG | |
for RKf6s5=1,#Ck_H do local tP9E_=Ck_H[RKf6s5]local Y1WX;Y1WX=tP9E_.pkg;if Y1WX==_QFw_It then | |
CzM7PG=tP9E_;break end end;if not(CzM7PG)then | |
return false,"Unknown package: "..tostring(_QFw_It)end | |
if CzM7PG.data.data.dependencies then | |
for G06Z2 in | |
pairs(CzM7PG.data.data.dependencies)do WLqHf=false | |
for K=1,#iFk do local tQx9TV=iFk[K]if tQx9TV==G06Z2 then WLqHf=true;break end end | |
if not(WLqHf)then | |
if sEFtmNgB[G06Z2]then | |
Zg.fatal("Circular dependencies detected: '".. | |
tostring(_QFw_It).."' depends on '".. | |
tostring(G06Z2).."', and '"..tostring(G06Z2).. | |
"' depends on '"..tostring(_QFw_It).."'.")end | |
LrFLp5:resolveDependencies({G06Z2},iFk,sEFtmNgB,qxiez0Cn)end end end;el(qxiez0Cn,_QFw_It)end;el(iFk,_QFw_It)sEFtmNgB[_QFw_It]=nil end end;return qxiez0Cn end | |
LrFLp5.getPackageDependants=function(LrFLp5,FL7g2o,dkh7Tt9,XiNd_H)if dkh7Tt9 ==nil then dkh7Tt9={}end | |
if XiNd_H==nil then XiNd_H={}end | |
for Q_c4px86=1,#FL7g2o do local _F6VYt=FL7g2o[Q_c4px86]local ITv3PH1i=false | |
for _5fF=1,#dkh7Tt9 do | |
local OUQqQp=dkh7Tt9[_5fF]if OUQqQp.name==_F6VYt then ITv3PH1i=true;break end end | |
if not(ITv3PH1i)then el(XiNd_H,{name=_F6VYt}) | |
local OyOfzTWn=wjim8xCV(_F6VYt,nil,"oppm") | |
if OyOfzTWn then el(dkh7Tt9,{name=_F6VYt,manifest=OyOfzTWn}) | |
local rx=iPL3B4cr(w(JQi1jg(xSebv5Jc,"oppm"))) | |
for ijvSrZA1 in rx do | |
OyOfzTWn=iPL3B4cr(wjim8xCV(ijvSrZA1,nil,"oppm"))local STNuSN6=OyOfzTWn.dependencies | |
for PYOeGnAZ=1,#STNuSN6 do local s10ar5XH=STNuSN6[PYOeGnAZ] | |
if | |
s10ar5XH.name==_F6VYt then ITv3PH1i=false | |
for YoKhvIs=1,#dkh7Tt9 do local I2ipE=dkh7Tt9[YoKhvIs]if I2ipE.name== | |
ijvSrZA1 then ITv3PH1i=true;break end end | |
if not ITv3PH1i then | |
for qS730I=1,#XiNd_H do local PYEbnua=XiNd_H[qS730I]if PYEbnua.name==ijvSrZA1 then | |
Zg.fatal( | |
"Circular dependencies detected: "..tostring(ijvSrZA1))end end | |
LrFLp5:getPackageDependants({ijvSrZA1},dkh7Tt9,XiNd_H)end end end end else | |
Zg.fatal("Package ".. | |
tostring(_F6VYt).." is referenced as a dependant of another package, however, this package isn't installed.")end;XiNd_H[#XiNd_H]=nil end end;return dkh7Tt9 end | |
LrFLp5.whatDependsOn=function(LrFLp5,Um4ZYiT) | |
local AF=iPL3B4cr(wjim8xCV(Um4ZYiT,nil,"oppm"))local shIHW={} | |
local H5=iPL3B4cr(w(JQi1jg(xSebv5Jc,"oppm"))) | |
for HYY in H5 do AF=iPL3B4cr(wjim8xCV(HYY,nil,"oppm")) | |
local C3=AF.dependencies;for SkCMMH=1,#C3 do local kvvs=C3[SkCMMH] | |
if kvvs.name==Um4ZYiT then el(shIHW,HYY)end end end;return shIHW end | |
LrFLp5.install=qTDt(function(LrFLp5,...)local _yTx3S94={...}local Mm=sgeP.r or sgeP.reinstall;local g524=sgeP.s or | |
sgeP.save | |
local WUdVeYc=iPL3B4cr(LrFLp5:resolveDependencies(_yTx3S94)) | |
h6Ub7U({install=(function()local BKZsJ={}local Sw=1;for W67mm9p6=1,#WUdVeYc do local oBxdTi6u=WUdVeYc[W67mm9p6] | |
if not Mm or not | |
n(oBxdTi6u,_yTx3S94)then BKZsJ[Sw]=oBxdTi6u;Sw=Sw+1 end end | |
return BKZsJ end)(),reinstall= | |
Mm and | |
(function()local T7hLe5j={}local I_=1 | |
for J2Jin=1,#WUdVeYc do local Rvg=WUdVeYc[J2Jin]if n(Rvg,_yTx3S94)then | |
T7hLe5j[I_]=Rvg;I_=I_+1 end end;return T7hLe5j end)()or nil})local lHep6wo={filesInstalled=0,packagesInstalled=0} | |
if Mm then local HpdA | |
do local DsAJbW={}local AXfX=1;for btcUUhB=1,#_yTx3S94 | |
do local iw0S=_yTx3S94[btcUUhB] | |
DsAJbW[AXfX]=iPL3B4cr(wjim8xCV(iw0S,nil,"oppm"))AXfX=AXfX+1 end | |
HpdA=DsAJbW end;LrFLp5:_remove(HpdA,true,false)end | |
for Tjg=1,#WUdVeYc do local n2srE7H=WUdVeYc[Tjg]Zg.print("Installing '".. | |
tostring(n2srE7H).."'...") | |
local Rf | |
if g524 then Rf="./"..tostring(n2srE7H).."/"else Rf="/"end | |
local X9ZjrTz,tYFIuD=LrFLp5:rawInstall(n2srE7H,Rf,n(n2srE7H,_yTx3S94),g524) | |
lHep6wo.filesInstalled=lHep6wo.filesInstalled+tYFIuD.filesInstalled | |
lHep6wo.packagesInstalled=lHep6wo.packagesInstalled+tYFIuD.packagesInstalled | |
if lHep6wo.packagesInstalled~=0 then local Ht5Ge,l=Ki1HJT(X9ZjrTz,"oppm") | |
if Ht5Ge then | |
Zg.info( | |
"Saved the manifest of '"..tostring(X9ZjrTz.name).."'.")else | |
Zg.fatal("Couldn't save the manifest of '"..tostring(X9ZjrTz.name).. | |
"': "..tostring(l)..".")end end end | |
Zg.print("- ".. | |
tostring(lHep6wo.packagesInstalled).." package".. | |
tostring(pX4gCR(lHep6wo.packagesInstalled)).." installed.")return | |
Zg.print("- ".. | |
tostring(lHep6wo.filesInstalled).." file".. | |
tostring(pX4gCR(lHep6wo.filesInstalled)).." installed.")end) | |
LrFLp5.remove=qTDt(function(LrFLp5,...)local IO={...}local YDJY={} | |
for t=1,#IO do local Rdi8NIft=IO[t] | |
local J0uTkQ9=iPL3B4cr(wjim8xCV(Rdi8NIft,nil,"oppm"))el(YDJY,J0uTkQ9)end;return LrFLp5:_remove(YDJY,false)end) | |
LrFLp5._remove=function(LrFLp5,sd6k,a,lK7)if a==nil then a=false end;if lK7 ==nil then lK7=true end;local KWMxs7a | |
if not | |
RkGFh6.get("oppm",{},true).get("remove_dependants",true)or not lK7 then do | |
local T={}local LBIp4=1;for A5=1,#sd6k do local PV168s0f=sd6k[A5] | |
T[LBIp4]={name=PV168s0f.name,manifest=PV168s0f}LBIp4=LBIp4+1 end | |
KWMxs7a=T end else | |
KWMxs7a=LrFLp5:getPackageDependants((function() | |
local bjK={}local Us1Xh=1 | |
for rs59=1,#sd6k do local R=sd6k[rs59]bjK[Us1Xh]=R.name;Us1Xh=Us1Xh+1 end;return bjK end)())end | |
if not(a)then | |
h6Ub7U({remove=(function()local rGa2MaGH={}local i6=1;for u33wPQT=1,#KWMxs7a do local aNrMnPZ=KWMxs7a[u33wPQT] | |
rGa2MaGH[i6]=tostring(aNrMnPZ.name)i6=i6+1 end;return rGa2MaGH end)()})end | |
for fC=1,#KWMxs7a do local Kl=KWMxs7a[fC] | |
Zg.print("Removing '".. | |
tostring(Kl.manifest.name).."' ...") | |
iPL3B4cr(l6xUetCb.__parent.remove(LrFLp5,Kl.manifest,"oppm"))end;return true end | |
LrFLp5.cache=qTDt(function(LrFLp5,EmJGBwA,...)local _E3=EmJGBwA | |
if"update"==_E3 then | |
Zg.print("Updating OpenPrograms program cache ...")iPL3B4cr(LrFLp5:updateCache()) | |
return Zg.print("Done.")elseif"fix"==_E3 then | |
Zg.print("Fixing OpenPrograms program cache ...")iPL3B4cr(LrFLp5:fixCache()) | |
return Zg.print("Done.")else Zg.error("Unknown command.")return | |
Zg.print("Usage: hpm oppm:cache {update|fix}")end end) | |
LrFLp5.autoremove=qTDt(function(LrFLp5)local j3={}local f={} | |
local jy=iPL3B4cr(w(JQi1jg(xSebv5Jc,"oppm"))) | |
for Ifev2bUE in jy do | |
local ZY=iPL3B4cr(wjim8xCV(Ifev2bUE,nil,"oppm"))if not(ZY.manual)then | |
local KCpJbzHT=LrFLp5:getPackageDependants(Ifev2bUE) | |
if#KCpJbzHT==1 then el(j3,Ifev2bUE)el(f,Ifev2bUE)end end end | |
while true do local g=false | |
jy=iPL3B4cr(w(JQi1jg(xSebv5Jc,"oppm"))) | |
for dQl0xvy2 in jy do | |
if not(n(dQl0xvy2,j3))then | |
local hX=iPL3B4cr(wjim8xCV(dQl0xvy2,nil,"oppm")) | |
if not(hX.manual)then | |
local wYTrvPn=LrFLp5:getPackageDependants(dQl0xvy2)table.remove(wYTrvPn,1) | |
if | |
qLH5((function()local pB6K={}local YV=1 | |
for zPm=1,#wYTrvPn do | |
local JmEyZ5=wYTrvPn[zPm]pB6K[YV]=n(JmEyZ5.name,j3)YV=YV+1 end;return pB6K end)())then for FGvy=1,#wYTrvPn do local KpnA=wYTrvPn[FGvy]local j_F9c,q=n(KpnA.name,f)if q then | |
table.remove(f,q)end end | |
el(j3,dQl0xvy2)el(f,dQl0xvy2)g=true end end end end;if not(g)then break end end | |
h6Ub7U({remove=(function() | |
if#j3 >0 then local b7G0ciz={}local rF2te=1 | |
for KG_EjN=1,#j3 do local aIrjXeB=j3[KG_EjN]b7G0ciz[rF2te]="oppm:".. | |
tostring(aIrjXeB)rF2te=rF2te+1 end;return b7G0ciz else return nil end end)()})for sZdri=1,#f do local pT=f[sZdri] | |
LrFLp5:_remove({iPL3B4cr(wjim8xCV(pT,nil,"oppm"))},false)end;Zg.print("Done.")return | |
true end) | |
LrFLp5.search=qTDt(function(LrFLp5,...)local XgkgIR9=LrFLp5:listCache()local sm2={} | |
if...then | |
for cz=1,#XgkgIR9 do | |
local pSL=XgkgIR9[cz]local ifrP9;ifrP9=pSL.data;local Iynmp=ifrP9.data;local PFvHX={...} | |
for sP=#PFvHX,1,-1 do | |
local Y=PFvHX[sP] | |
if ifrP9.name:find(Y)then table.remove(PFvHX,sP)break end;if Iynmp.name and Iynmp.name:find(Y)then | |
table.remove(PFvHX,sP)break end | |
if Iynmp.description and | |
Iynmp.description:find(Y)then table.remove(PFvHX,sP)break end;if Iynmp.note and Iynmp.note:find(Y)then | |
table.remove(PFvHX,sP)break end end;if#PFvHX==0 then el(sm2,ifrP9)end end else do local QHxdp58D={}local efdknL=1;for YUdva=1,#XgkgIR9 do local x8FBS=XgkgIR9[YUdva] | |
QHxdp58D[efdknL]=x8FBS.data;efdknL=efdknL+1 end | |
sm2=QHxdp58D end end;for LGBr=1,#sm2 do local M=sm2[LGBr] | |
Zg.print(tostring(M.name).." - ".. | |
tostring(M.data.name or M.name)..": "..tostring(M.data.description))end end) | |
LrFLp5.info=qTDt(function(LrFLp5,I)if N5UjTN(I)then | |
Zg.fatal("Usage: hpm oppm:info <package name>")end;local W=LrFLp5:listCache() | |
local Dx5GC=nil | |
for kwZhI=1,#W do local T0h=W[kwZhI]if T0h.pkg==I then Dx5GC=T0h;break end end | |
if not(Dx5GC)then Zg.fatal("No such package.")end | |
Zg.print("- Package name: "..tostring(Dx5GC.pkg))if Dx5GC.data.data.name then | |
Zg.print(" ".. | |
tostring(Dx5GC.data.data.name))end;if Dx5GC.data.data.description then | |
Zg.print( | |
"- Description:\n"..tostring(Dx5GC.data.data.description))end;if | |
Dx5GC.data.data.authors then | |
Zg.print("- Authors:\n"..tostring(Dx5GC.data.data.authors))end;if Dx5GC.data.data.files then | |
Zg.print( | |
"- Files: "..tostring(O(Dx5GC.data.data.files)))end | |
if | |
Dx5GC.data.data.dependencies then | |
Zg.print("- Depends: ".. | |
tostring(table.concat((function()local H0={}local Mrz66=1;for A in | |
pairs(Dx5GC.data.data.dependencies)do H0[Mrz66]=A;Mrz66=Mrz66+1 end;return H0 end)())))end;if Dx5GC.data.data.note then | |
Zg.print("- Note:\n".. | |
tostring(Dx5GC.data.data.note))end | |
return Zg.print("- Repository: https://github.com/".. | |
tostring(Dx5GC.repo))end) | |
if lOb_Sv.__inherited then lOb_Sv.__inherited(lOb_Sv,l6xUetCb)end;_.oppm=l6xUetCb end;local Gm | |
Gm=function()local RR=iPL3B4cr(w(xSebv5Jc))N5UjTN=true | |
for Oj4B in RR do | |
local aT=pE.name(Oj4B) | |
if XPoQB(JQi1jg(xSebv5Jc,aT))then | |
local ZN0brC=iPL3B4cr(w(JQi1jg(xSebv5Jc,aT))) | |
for g in ZN0brC do | |
if not(XPoQB(JQi1jg(xSebv5Jc,aT,g)))then local iYIip_rt=iPL3B4cr(wjim8xCV(g, | |
nil,aT)) | |
Zg.print(aT..":"..g.. | |
(iYIip_rt.version and" @ ".. | |
iYIip_rt.version or""))N5UjTN=false end end end end | |
if N5UjTN then return Zg.print("No packages installed.")end end;local YKA7cU | |
YKA7cU=function(...)CM,sgeP=JD(...)if#CM<1 then return y36Aetn()end end;local mCsewfX | |
mCsewfX=function()local WoJla=CM[1] | |
if"list"==WoJla then return Gm()elseif"help"==WoJla then return y36Aetn()else | |
do | |
local jk=wZdg(CM[1]) | |
if jk then return | |
jk(Wu_uIt((function()local Y={}local sM=1 | |
for MMJEx=2,#CM do local EB=CM[MMJEx]Y[sM]=EB;sM=sM+1 end;return Y end)()))end end end end | |
hw18.semver={Version=YAtG_LV3.Version,Spec=YAtG_LV3.Spec,SpecItem=YAtG_LV3.SpecItem,compare=YAtG_LV3.compare,match=YAtG_LV3.match,validate=YAtG_LV3.validate}hw18.json=s;hw18.CONFIG_PATH=rDtVf;hw18.USAGE=vj;hw18.DEFAULT_CONFIG=z | |
hw18.options=sgeP;hw18.args=CM;hw18.request=Qlmlet;hw18.modules=_;hw18.config=RkGFh6 | |
hw18.modulePath=nvCiFt7r;hw18.distPath=xSebv5Jc;hw18.exitCode=mMp;hw18.log=Zg;hw18.assert=ykRppH | |
hw18.unimplemented=WQ6;hw18.printUsage=y36Aetn;hw18.try=iPL3B4cr;hw18.checkType=GI2hz6SK | |
hw18.argNumber=Oh;hw18.argString=PG;hw18.isin=n;hw18.tableLen=O;hw18.empty=N5UjTN | |
hw18.all=qLH5;hw18.existsDir=tE;hw18.existsFile=VcV0EuD;hw18.plural=pX4gCR | |
hw18.singular=gad4ZcL;hw18.linkingVerb=dk;hw18.remove=OO;hw18.loadConfig=y | |
hw18.checkInternet=cR6rJlAl;hw18.download=M6ilzGJ;hw18.findCustomCommand=wZdg;hw18.getModuleBy=BaX | |
hw18.callModuleMethod=SJsW11k;hw18.saveManifest=Ki1HJT;hw18.loadManifest=wjim8xCV | |
hw18.removeManifest=EQLam;hw18.public=qTDt;hw18.wrapResponse=v;hw18.recv=Ta;hw18.confirm=unArcvQl | |
hw18.pkgPlan=h6Ub7U;hw18.printPackageList=Gm;hw18.parseArguments=YKA7cU;hw18.process=mCsewfX;for Qy,rCWKBim in | |
pairs(_G)do hw18[Qy]=rCWKBim end;YKA7cU(...) | |
iPL3B4cr(y())iW6CD()mCsewfX()return mMp |
local JtAjijkG=load([===[ | |
local rA5U=20160728.17 | |
local Uc06="-[ JSON.lua package by Jeffrey Friedl (http://regex.info/blog/lua/json) version 20160728.17 ]-"local lcBL={VERSION=rA5U,AUTHOR_NOTE=Uc06}local DHPxI=" " | |
local dx={pretty=true,align_keys=false,indent=DHPxI} | |
local RRuSHnxf={__tostring=function()return"JSON array"end}RRuSHnxf.__index=RRuSHnxf | |
local mcYOuT={__tostring=function()return"JSON object"end}mcYOuT.__index=mcYOuT;function lcBL:newArray(iXxD6s) | |
return setmetatable(iXxD6s or{},RRuSHnxf)end;function lcBL:newObject(oiY)return | |
setmetatable(oiY or{},mcYOuT)end;local function Rr(FsYIVlkf) | |
return | |
type(FsYIVlkf)=='number'and FsYIVlkf or FsYIVlkf.N end | |
local scRP0={__index=isNumber,__tostring=function(HLXS0Q_)return HLXS0Q_.S end,__unm=function(Kw)return | |
Rr(Kw)end,__concat=function(nvaIsNv7,vDnoL55) | |
return tostring(nvaIsNv7)..tostring(vDnoL55)end,__add=function(xlAK,zr1y)return Rr(xlAK)+Rr(zr1y)end,__sub=function(Hs,jk)return | |
Rr(Hs)-Rr(jk)end,__mul=function(qzSFyIO,Z65) | |
return Rr(qzSFyIO)*Rr(Z65)end,__div=function(umyCNfj,FT)return Rr(umyCNfj)/Rr(FT)end,__mod=function(YVLXYq,bJfct)return | |
Rr(YVLXYq)%Rr(bJfct)end,__pow=function(OhuFpq_N,Dzg)return | |
Rr(OhuFpq_N)^Rr(Dzg)end,__lt=function(_4O,C)return Rr(_4O)<Rr(C)end,__eq=function(fLI2zRe,_Fr2YU)return | |
Rr(fLI2zRe)==Rr(_Fr2YU)end,__le=function(Xfn,U)return | |
Rr(Xfn)<=Rr(U)end} | |
function lcBL:asNumber(Ebsw) | |
if getmetatable(Ebsw)==scRP0 then return Ebsw elseif | |
type(Ebsw)=='table'and | |
type(Ebsw.S)=='string'and type(Ebsw.N)=='number'then return setmetatable(Ebsw,scRP0)else | |
local UlikV={S=tostring(Ebsw),N=tonumber(Ebsw)}return setmetatable(UlikV,scRP0)end end | |
local function AI0R2TQ6(JtAjijkG) | |
if JtAjijkG<=127 then return string.char(JtAjijkG)elseif JtAjijkG<=2047 then | |
local s=math.floor(JtAjijkG/0x40)local YAtG_LV3=JtAjijkG- (0x40*s)return | |
string.char(0xC0+s,0x80+YAtG_LV3)elseif JtAjijkG<=65535 then | |
local LfEJbh_=math.floor(JtAjijkG/0x1000)local JD=JtAjijkG-0x1000*LfEJbh_ | |
local u=math.floor(JD/0x40)local pzDMZwG=JD-0x40*u;LfEJbh_=0xE0+LfEJbh_;u=0x80+u | |
pzDMZwG=0x80+pzDMZwG | |
if | |
(LfEJbh_==0xE0 and u<0xA0)or | |
(LfEJbh_==0xED and u>0x9F)or(LfEJbh_==0xF0 and u<0x90)or(LfEJbh_==0xF4 and u>0x8F)then return"?"else return string.char(LfEJbh_,u,pzDMZwG)end else local XPoQB=math.floor(JtAjijkG/0x40000) | |
local XxJ=JtAjijkG-0x40000*XPoQB;local o5sms=math.floor(XxJ/0x1000) | |
XxJ=XxJ-0x1000*o5sms;local JQi1jg=math.floor(XxJ/0x40)local wVzn=XxJ-0x40*JQi1jg | |
return string.char( | |
0xF0+XPoQB,0x80+o5sms,0x80+JQi1jg,0x80+wVzn)end end | |
function lcBL:onDecodeError(pE,RSjapQ,QJf,zC)if RSjapQ then | |
if QJf then | |
pE=string.format("%s at char %d of: %s",pE,QJf,RSjapQ)else pE=string.format("%s: %s",pE,RSjapQ)end end | |
if zC~=nil then pE=pE.." (".. | |
lcBL:encode(zC)..")"end | |
if self.assert then self.assert(false,pE)else assert(false,pE)end end;lcBL.onDecodeOfNilError=lcBL.onDecodeError | |
lcBL.onDecodeOfHTMLError=lcBL.onDecodeError | |
function lcBL:onEncodeError(pfZ3SPy_,pDNa2ox6) | |
if pDNa2ox6 ~=nil then pfZ3SPy_=pfZ3SPy_.. | |
" ("..lcBL:encode(pDNa2ox6)..")"end;if self.assert then self.assert(false,pfZ3SPy_)else | |
assert(false,pfZ3SPy_)end end | |
local function yA(Do6yo7nm,y06X3k,ivnJjrA,d3fMjkg) | |
local el=y06X3k:match('^-?[1-9]%d*',ivnJjrA)or y06X3k:match("^-?0",ivnJjrA)if not el then | |
Do6yo7nm:onDecodeError("expected number",y06X3k,ivnJjrA,d3fMjkg.etc)end | |
local Wu_uIt=ivnJjrA+el:len()local w=y06X3k:match('^%.%d+',Wu_uIt)or""Wu_uIt=Wu_uIt+ | |
w:len() | |
local sgeP=y06X3k:match('^[eE][-+]?%d+',Wu_uIt)or""Wu_uIt=Wu_uIt+sgeP:len()local CM=el..w..sgeP;if | |
d3fMjkg.decodeNumbersAsObjects then return lcBL:asNumber(CM),Wu_uIt end | |
if | |
( | |
d3fMjkg.decodeIntegerStringificationLength and(el:len()>=d3fMjkg.decodeIntegerStringificationLength or | |
sgeP:len()>0))or | |
(d3fMjkg.decodeDecimalStringificationLength and | |
( | |
w:len()>=d3fMjkg.decodeDecimalStringificationLength or sgeP:len()>0))then return CM,Wu_uIt end;local Qlmlet=tonumber(CM)if not Qlmlet then | |
Do6yo7nm:onDecodeError("bad number",y06X3k,ivnJjrA,d3fMjkg.etc)end;return Qlmlet,Wu_uIt end | |
local function XmVolesU(_,RkGFh6,hw18,nvCiFt7r)if RkGFh6:sub(hw18,hw18)~='"'then | |
_:onDecodeError("expected string's opening quote",RkGFh6,hw18,nvCiFt7r.etc)end;local xSebv5Jc=hw18+1 | |
local mMp=RkGFh6:len()local rDtVf="" | |
while xSebv5Jc<=mMp do local vj=RkGFh6:sub(xSebv5Jc,xSebv5Jc)if | |
vj=='"'then return rDtVf,xSebv5Jc+1 end | |
if vj~='\\'then rDtVf=rDtVf..vj;xSebv5Jc= | |
xSebv5Jc+1 elseif RkGFh6:match('^\\b',xSebv5Jc)then rDtVf=rDtVf.."\b"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\f',xSebv5Jc)then rDtVf=rDtVf.."\f"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\n',xSebv5Jc)then rDtVf=rDtVf.."\n"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\r',xSebv5Jc)then rDtVf=rDtVf.."\r"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\t',xSebv5Jc)then rDtVf=rDtVf.."\t"xSebv5Jc= | |
xSebv5Jc+2 else | |
local z=RkGFh6:match('^\\u([0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])',xSebv5Jc) | |
if z then xSebv5Jc=xSebv5Jc+6;local Zg=tonumber(z,16) | |
if | |
Zg>=0xD800 and Zg<=0xDBFF then | |
local ykRppH=RkGFh6:match('^\\u([dD][cdefCDEF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])',xSebv5Jc) | |
if ykRppH then xSebv5Jc=xSebv5Jc+6;Zg=0x2400+ (Zg-0xD800)*0x400+ | |
tonumber(ykRppH,16)else end end;rDtVf=rDtVf..AI0R2TQ6(Zg)else rDtVf=rDtVf.. | |
RkGFh6:match('^\\(.)',xSebv5Jc)xSebv5Jc=xSebv5Jc+2 end end end | |
_:onDecodeError("unclosed string",RkGFh6,hw18,nvCiFt7r.etc)end | |
local function eZ0l3ch(WQ6,y36Aetn)local iPL3B4cr,GI2hz6SK=WQ6:find("^[ \n\r\t]+",y36Aetn)if GI2hz6SK then | |
return GI2hz6SK+1 else return y36Aetn end end;local W_63_9 | |
local function h9dyA_4T(Oh,PG,n,O)if PG:sub(n,n)~='{'then | |
Oh:onDecodeError("expected '{'",PG,n,O.etc)end;local N5UjTN=eZ0l3ch(PG,n+1)local qLH5=Oh.strictTypes and | |
Oh:newObject{}or{}if | |
PG:sub(N5UjTN,N5UjTN)=='}'then return qLH5,N5UjTN+1 end | |
local tE=PG:len() | |
while N5UjTN<=tE do local VcV0EuD,pX4gCR=XmVolesU(Oh,PG,N5UjTN,O) | |
N5UjTN=eZ0l3ch(PG,pX4gCR)if PG:sub(N5UjTN,N5UjTN)~=':'then | |
Oh:onDecodeError("expected colon",PG,N5UjTN,O.etc)end | |
N5UjTN=eZ0l3ch(PG,N5UjTN+1)local gad4ZcL,pX4gCR=W_63_9(Oh,PG,N5UjTN,O)qLH5[VcV0EuD]=gad4ZcL | |
N5UjTN=eZ0l3ch(PG,pX4gCR)local dk=PG:sub(N5UjTN,N5UjTN) | |
if dk=='}'then return qLH5,N5UjTN+1 end;if PG:sub(N5UjTN,N5UjTN)~=','then | |
Oh:onDecodeError("expected comma or '}'",PG,N5UjTN,O.etc)end | |
N5UjTN=eZ0l3ch(PG,N5UjTN+1)end;Oh:onDecodeError("unclosed '{'",PG,n,O.etc)end | |
local function oh(E,OO,y,cR6rJlAl)if OO:sub(y,y)~='['then | |
E:onDecodeError("expected '['",OO,y,cR6rJlAl.etc)end;local M6ilzGJ=eZ0l3ch(OO,y+1)local iW6CD=E.strictTypes and | |
E:newArray{}or{}if | |
OO:sub(M6ilzGJ,M6ilzGJ)==']'then return iW6CD,M6ilzGJ+1 end | |
local wZdg=1;local BaX=OO:len() | |
while M6ilzGJ<=BaX do | |
local SJsW11k,Ki1HJT=W_63_9(E,OO,M6ilzGJ,cR6rJlAl)iW6CD[wZdg]=SJsW11k;wZdg=wZdg+1;M6ilzGJ=eZ0l3ch(OO,Ki1HJT) | |
local wjim8xCV=OO:sub(M6ilzGJ,M6ilzGJ)if wjim8xCV==']'then return iW6CD,M6ilzGJ+1 end;if | |
OO:sub(M6ilzGJ,M6ilzGJ)~=','then | |
E:onDecodeError("expected comma or '['",OO,M6ilzGJ,cR6rJlAl.etc)end | |
M6ilzGJ=eZ0l3ch(OO,M6ilzGJ+1)end | |
E:onDecodeError("unclosed '['",OO,y,cR6rJlAl.etc)end | |
W_63_9=function(E,QLam,qTDt,v)qTDt=eZ0l3ch(QLam,qTDt) | |
if qTDt>QLam:len()then E:onDecodeError("unexpected end of string",QLam, | |
nil,v.etc)end | |
if QLam:find('^"',qTDt)then return XmVolesU(E,QLam,qTDt,v.etc)elseif | |
QLam:find('^[-0123456789 ]',qTDt)then return yA(E,QLam,qTDt,v)elseif QLam:find('^%{',qTDt)then | |
return h9dyA_4T(E,QLam,qTDt,v)elseif QLam:find('^%[',qTDt)then return oh(E,QLam,qTDt,v)elseif QLam:find('^true',qTDt)then return true, | |
qTDt+4 elseif QLam:find('^false',qTDt)then return false,qTDt+5 elseif | |
QLam:find('^null',qTDt)then return nil,qTDt+4 else | |
E:onDecodeError("can't parse JSON",QLam,qTDt,v.etc)end end | |
function lcBL:decode(Ta,u,nArcvQl)if type(nArcvQl)~='table'then nArcvQl={}end;if u~=nil then | |
nArcvQl.etc=u end;if | |
type(self)~='table'or self.__index~=lcBL then | |
lcBL:onDecodeError("JSON:decode must be called in method format",nil,nil,nArcvQl.etc)end | |
if Ta==nil then | |
self:onDecodeOfNilError(string.format("nil passed to JSON:decode()"), | |
nil,nil,nArcvQl.etc)elseif type(Ta)~='string'then | |
self:onDecodeError(string.format("expected string argument to JSON:decode(), got %s",type(Ta)), | |
nil,nil,nArcvQl.etc)end;if Ta:match('^%s*$')then return nil end;if Ta:match('^%s*<')then | |
self:onDecodeOfHTMLError(string.format("html passed to JSON:decode()"),Ta, | |
nil,nArcvQl.etc)end | |
if | |
Ta:sub(1,1):byte()==0 or | |
(Ta:len()>=2 and Ta:sub(2,2):byte()==0)then | |
self:onDecodeError("JSON package groks only UTF-8, sorry",Ta,nil,nArcvQl.etc)end;if nArcvQl.decodeNumbersAsObjects==nil then | |
nArcvQl.decodeNumbersAsObjects=self.decodeNumbersAsObjects end;if | |
nArcvQl.decodeIntegerStringificationLength==nil then | |
nArcvQl.decodeIntegerStringificationLength=self.decodeIntegerStringificationLength end;if | |
nArcvQl.decodeDecimalStringificationLength==nil then | |
nArcvQl.decodeDecimalStringificationLength=self.decodeDecimalStringificationLength end | |
local h6Ub7U,Gm=pcall(W_63_9,self,Ta,1,nArcvQl)if h6Ub7U then return Gm else | |
if self.assert then self.assert(false,Gm)else assert(false,Gm)end;return nil,Gm end end | |
local function DZXGTh(YKA7cU) | |
if YKA7cU=="\n"then return"\\n"elseif YKA7cU=="\r"then return"\\r"elseif YKA7cU=="\t"then return"\\t"elseif YKA7cU=="\b"then | |
return"\\b"elseif YKA7cU=="\f"then return"\\f"elseif YKA7cU=='"'then return'\\"'elseif YKA7cU=='\\'then return'\\\\'else return | |
string.format("\\u%04x",YKA7cU:byte())end end | |
local Su9Koz='['..'"'.. | |
'%\\'..'%z'..'\001'..'-'..'\031'..']'local Uk7e=AI0R2TQ6(0x2028)local KwQCk_G=AI0R2TQ6(0x2029) | |
local function ptZa(mCsewfX,yY) | |
local Xf=mCsewfX:gsub(Su9Koz,DZXGTh)if yY.stringsAreUtf8 then | |
Xf=Xf:gsub(Uk7e,'\\u2028'):gsub(KwQCk_G,'\\u2029')end;return'"'..Xf..'"'end | |
local function PEqsd(UlFdiZ7v,U,wFeA)local JQgI={}local N={}local fs52REi=false;local PUNkgaiM | |
for X in pairs(U)do | |
if type(X)=='string'then | |
table.insert(JQgI,X)elseif type(X)=='number'then table.insert(N,X) | |
if X<=0 or X>=math.huge then | |
fs52REi=true elseif not PUNkgaiM or X>PUNkgaiM then PUNkgaiM=X end else | |
UlFdiZ7v:onEncodeError("can't encode table with a key of type "..type(X),wFeA)end end | |
if#JQgI==0 and not fs52REi then | |
if#N>0 then return nil,PUNkgaiM elseif | |
tostring(U)=="JSON array"then return nil elseif tostring(U)=="JSON object"then return{}else return nil end end;table.sort(JQgI)local s6FbB | |
if#N>0 then if UlFdiZ7v.noKeyConversion then | |
UlFdiZ7v:onEncodeError("a table with both numeric and string keys could be an object or array; aborting",wFeA)end | |
s6FbB={}for dc61,aguhyl in pairs(U)do s6FbB[dc61]=aguhyl end | |
table.sort(N) | |
for p,gOPDv in ipairs(N)do local aSdZU3=tostring(gOPDv) | |
if s6FbB[aSdZU3]==nil then | |
table.insert(JQgI,aSdZU3)s6FbB[aSdZU3]=U[gOPDv]else | |
UlFdiZ7v:onEncodeError( | |
"conflict converting table with mixed-type keys into a JSON object: key "..gOPDv.." exists both as a string and a number.",wFeA)end end end;return JQgI,nil,s6FbB end;local iSj | |
function iSj(YKDL,oFyb6OLp,oGdh_mv,WjvvK,TASVwBgU,KjUncMB,XkT) | |
if oFyb6OLp==nil or | |
(not XkT and TASVwBgU and TASVwBgU.null and oFyb6OLp== | |
TASVwBgU.null)then return'null'elseif | |
type(oFyb6OLp)=='string'then return ptZa(oFyb6OLp,TASVwBgU)elseif type(oFyb6OLp)=='number'then | |
if | |
oFyb6OLp~=oFyb6OLp then return"null"elseif oFyb6OLp>=math.huge then return"1e+9999"elseif oFyb6OLp<=-math.huge then | |
return"-1e+9999"else return tostring(oFyb6OLp)end elseif type(oFyb6OLp)=='boolean'then return tostring(oFyb6OLp)elseif type(oFyb6OLp)~= | |
'table'then | |
YKDL:onEncodeError("can't convert "..type(oFyb6OLp).." to JSON",WjvvK)elseif getmetatable(oFyb6OLp)==scRP0 then return tostring(oFyb6OLp)else | |
local c3dr=oFyb6OLp;if type(TASVwBgU)~='table'then TASVwBgU={}end;if type(KjUncMB)~= | |
'string'then KjUncMB=""end | |
if oGdh_mv[c3dr]then | |
YKDL:onEncodeError("table ".. | |
tostring(c3dr).." is a child of itself",WjvvK)else oGdh_mv[c3dr]=true end;local NGH;local tIc,MD2O,HQ=PEqsd(YKDL,c3dr,WjvvK) | |
if MD2O then local cng={}for lE=1,MD2O do | |
table.insert(cng,iSj(YKDL,c3dr[lE],oGdh_mv,WjvvK,TASVwBgU,KjUncMB))end | |
if TASVwBgU.pretty then NGH="[ ".. | |
table.concat(cng,", ").." ]"else NGH="[".. | |
table.concat(cng,",").."]"end elseif tIc then local nI2F0id=HQ or c3dr | |
if TASVwBgU.pretty then local N4aMD_P={}local pCi=0 | |
for lNOqUk8,YAnZNei in ipairs(tIc)do | |
local h8YWR44E=iSj(YKDL,tostring(YAnZNei),oGdh_mv,WjvvK,TASVwBgU,KjUncMB,true) | |
if TASVwBgU.align_keys then pCi=math.max(pCi,#h8YWR44E)end;table.insert(N4aMD_P,h8YWR44E)end | |
local NzeoQJ=KjUncMB..tostring(TASVwBgU.indent or"") | |
local AwGfFV=NzeoQJ..string.rep(" ",pCi).. | |
(TASVwBgU.align_keys and" "or"") | |
local wCRY="%s%"..string.format("%d",pCi).."s: %s"local d0uKSVw1={} | |
for VF,fTrMe in ipairs(tIc)do | |
local ypDndT8=iSj(YKDL,nI2F0id[fTrMe],oGdh_mv,WjvvK,TASVwBgU,AwGfFV) | |
table.insert(d0uKSVw1,string.format(wCRY,NzeoQJ,N4aMD_P[VF],ypDndT8))end;NGH="{\n".. | |
table.concat(d0uKSVw1,",\n").."\n"..KjUncMB.."}"else local MV65={} | |
for Y3D66Ym9,q in | |
ipairs(tIc)do | |
local PhJ=iSj(YKDL,nI2F0id[q],oGdh_mv,WjvvK,TASVwBgU,KjUncMB) | |
local h=iSj(YKDL,tostring(q),oGdh_mv,WjvvK,TASVwBgU,KjUncMB,true) | |
table.insert(MV65,string.format("%s:%s",h,PhJ))end;NGH="{"..table.concat(MV65,",").."}"end else NGH="[]"end;oGdh_mv[c3dr]=false;return NGH end end | |
function lcBL:encode(j2K,r8hgwQ,_6U)if type(self)~='table'or self.__index~=lcBL then | |
lcBL:onEncodeError("JSON:encode must be called in method format",r8hgwQ)end;if | |
type(_6U)~='table'then _6U={}end;return iSj(self,j2K,{},r8hgwQ,_6U)end | |
function lcBL:encode_pretty(GLSzBQs,c,xg)if type(self)~='table'or self.__index~=lcBL then | |
lcBL:onEncodeError("JSON:encode_pretty must be called in method format",c)end;if | |
type(xg)~='table'then xg=dx end;return iSj(self,GLSzBQs,{},c,xg)end;function lcBL.__tostring()return"JSON encode/decode package"end | |
lcBL.__index=lcBL | |
function lcBL:new(Id2KoP_G)local Y2or={}if Id2KoP_G then | |
for zN8ASHV5,iju in pairs(Id2KoP_G)do Y2or[zN8ASHV5]=iju end end | |
return setmetatable(Y2or,lcBL)end;return lcBL:new() | |
]===])() | |
local s=(function() | |
local YKA7cU=[[ Copyright (c) The python-semanticversion project | |
All rights reserved. | |
Redistribution and use in source and binary forms, with or without | |
modification, are permitted provided that the following conditions are met: | |
1. Redistributions of source code must retain the above copyright notice, this | |
list of conditions and the following disclaimer. | |
2. Redistributions in binary form must reproduce the above copyright notice, | |
this list of conditions and the following disclaimer in the documentation | |
and/or other materials provided with the distribution. | |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | |
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
]] | |
YKA7cU=[[ The use of the library is similar to the original one, | |
check the documentation here: https://python-semanticversion.readthedocs.io/en/latest/ | |
]]local mCsewfX,yY,Xf | |
do local p=table;mCsewfX,yY,Xf=p.concat,p.insert,p.unpack end;local UlFdiZ7v | |
UlFdiZ7v=function(gOPDv)do local aSdZU3=tonumber(gOPDv) | |
if aSdZU3 then return aSdZU3,true else return gOPDv,false end end end;local U | |
U=function(YKDL)return | |
YKDL and YKDL[1]=='0'and tonumber(YKDL and YKDL~='0')end;local wFeA | |
wFeA=function(oFyb6OLp,oGdh_mv)if oFyb6OLp==oGdh_mv then return 0 end | |
if oFyb6OLp>oGdh_mv then return 1 end;if oFyb6OLp<oGdh_mv then return-1 end end;local JQgI | |
JQgI=function(WjvvK,TASVwBgU)local KjUncMB,XkT=UlFdiZ7v(WjvvK)local c3dr,NGH=UlFdiZ7v(TASVwBgU) | |
if | |
XkT and NGH then return wFeA(KjUncMB,c3dr)elseif XkT then return-1 elseif NGH then return 1 else return wFeA(KjUncMB,c3dr)end end;local N | |
N=function(tIc,MD2O)local HQ | |
do local cng={}for lE=1,#tIc do | |
if MD2O[lE]then cng[tIc[lE]]=MD2O[lE]end end;HQ=cng end | |
for nI2F0id,N4aMD_P in pairs(HQ)do local pCi=JQgI(nI2F0id,N4aMD_P)if pCi~=0 then return pCi end end;return wFeA(#tIc,#MD2O)end;local fs52REi | |
do local NzeoQJ | |
local AwGfFV={_coerce=function(d0uKSVw1,lNOqUk8,YAnZNei)if YAnZNei==nil then YAnZNei=false end;if | |
lNOqUk8 ==nil and YAnZNei then return lNOqUk8 end;return tonumber(lNOqUk8)end,next_major=function(h8YWR44E) | |
if | |
h8YWR44E.prerelease and h8YWR44E.minor==0 and h8YWR44E.patch==0 then | |
return | |
fs52REi(mCsewfX((function()local VF={}local fTrMe=1 | |
local ypDndT8={h8YWR44E.major,h8YWR44E.minor,h8YWR44E.patch}for MV65=1,#ypDndT8 do local Y3D66Ym9=ypDndT8[MV65]VF[fTrMe]=tostring(Y3D66Ym9)fTrMe= | |
fTrMe+1 end;return VF end)(),'.'))else | |
return | |
fs52REi(mCsewfX((function()local q={}local PhJ=1;local h={h8YWR44E.major+1,0,0} | |
for j2K=1,#h do | |
local r8hgwQ=h[j2K]q[PhJ]=tostring(r8hgwQ)PhJ=PhJ+1 end;return q end)(),'.'))end end,next_minor=function(_6U)if | |
not(_6U.minor)then | |
error("Partial version doesn't contain the minor component!")end | |
if | |
_6U.prerelease and _6U.patch==0 then | |
return | |
fs52REi(mCsewfX((function()local GLSzBQs={}local c=1;local xg={_6U.major,_6U.minor,_6U.patch} | |
for Id2KoP_G=1,# | |
xg do local Y2or=xg[Id2KoP_G]GLSzBQs[c]=tostring(Y2or)c=c+1 end;return GLSzBQs end)(),'.'))else | |
return | |
fs52REi(mCsewfX((function()local zN8ASHV5={}local iju=1;local XsWgh={_6U.major,_6U.minor+1,0}for l4Hdz=1,#XsWgh | |
do local NSXCgSH=XsWgh[l4Hdz]zN8ASHV5[iju]=tostring(NSXCgSH) | |
iju=iju+1 end;return zN8ASHV5 end)(),'.'))end end,next_patch=function(Wq)if | |
not(Wq.patch)then | |
error("Partial version doesn't contain the patch component!")end | |
if Wq.prerelease then | |
return | |
fs52REi(mCsewfX((function()local SbOQ={}local IiuHGo=1 | |
local cGqxtYr={Wq.major,Wq.minor,Wq.patch}for bgJFKeeZ=1,#cGqxtYr do local yu9fg0nN=cGqxtYr[bgJFKeeZ] | |
SbOQ[IiuHGo]=tostring(yu9fg0nN)IiuHGo=IiuHGo+1 end | |
return SbOQ end)(),'.'))else | |
return | |
fs52REi(mCsewfX((function()local wgx={}local zlU7X=1 | |
local t={Wq.major,Wq.minor,Wq.patch+1} | |
for f6qbO=1,#t do local kk=t[f6qbO]wgx[zlU7X]=tostring(kk)zlU7X=zlU7X+1 end;return wgx end)(),'.'))end end,coerce=function(QrubIAv,bLHDW,YjFd7b)if | |
YjFd7b==nil then YjFd7b=false end;local jZgPYb | |
jZgPYb=function(I0JvPpn) | |
local Ce4ZE,OVx_mN=I0JvPpn:match('^(%d+)(.*)$')if not(Ce4ZE)then return nil end;local lB=Ce4ZE | |
local byE,bITCI=OVx_mN:match('^%.(%d+)(.*)$')if byE then OVx_mN=bITCI;lB=lB.. ('.'..byE)end;local K | |
K,bITCI=OVx_mN:match('^%.(%d+)(.*)$')if K then OVx_mN=bITCI;lB=lB.. ('.'..K)end;return I0JvPpn,lB end;local zN2,IN69pa5=jZgPYb(bLHDW)if not(zN2)then | |
error("Version string lacks a numerical component: "..tostring(bLHDW))end | |
local UOWJ=bLHDW:sub(1,#IN69pa5) | |
if not YjFd7b then while({UOWJ:gsub('.','')})[2]<2 do UOWJ= | |
UOWJ..'.0'end end | |
if#IN69pa5 ==#bLHDW then return fs52REi(UOWJ,YjFd7b)end;local WtalJw=bLHDW:sub(#IN69pa5+1) | |
WtalJw=WtalJw:gsub('[^a-zA-Z0-9+.-]','-')local JYrf2,KHDOUlRY=nil,nil | |
if WtalJw:sub(1,1)=='+'then JYrf2='' | |
KHDOUlRY=WtalJw:sub(2)elseif WtalJw:sub(1,1)=='.'then JYrf2=''KHDOUlRY=WtalJw:sub(2)elseif | |
WtalJw:sub(1,1)=='-'then WtalJw=WtalJw:sub(2) | |
do local F5dtVpnN=WtalJw:find('+') | |
if | |
F5dtVpnN then | |
JYrf2,KHDOUlRY=WtalJw:sub(1,F5dtVpnN-1),WtalJw:sub(F5dtVpnN+1,-1)else JYrf2,KHDOUlRY=WtalJw,''end end else do local kxeBp=WtalJw:find('+') | |
if kxeBp then JYrf2,KHDOUlRY=WtalJw:sub(1,kxeBp-1),WtalJw:sub( | |
kxeBp+1,-1)else JYrf2,KHDOUlRY=WtalJw,''end end end;KHDOUlRY=KHDOUlRY:gsub('+','.')if JYrf2 and JYrf2 ~=''then UOWJ=UOWJ.. | |
('-'..JYrf2)end | |
if | |
KHDOUlRY and KHDOUlRY~=''then UOWJ=UOWJ.. ('+'..KHDOUlRY)end;return QrubIAv.__class(UOWJ,YjFd7b)end,parse=function(a,kQ,EE9LAE,iVx)if | |
EE9LAE==nil then EE9LAE=false end;if iVx==nil then iVx=false end;if not kQ or | |
type(kQ)~='string'or kQ==''then | |
error("Invalid empty version string: ".. | |
tostring(tostring(kQ)))end;local eg;if EE9LAE then | |
eg=a.__class.partialVersionRe else eg=a.__class.versionRe end | |
local AQviNt,T6,NviN0i,BlMQce,o=eg(a.__class,kQ)if not AQviNt then | |
error("Invalid version string: "..tostring(kQ))end;if U(AQviNt)then | |
error("Invalid leading zero in major: "..tostring(kQ))end;if U(T6)then | |
error("Invalid leading zero in minor: "..tostring(kQ))end;if U(NviN0i)then | |
error("Invalid leading zero in patch: "..tostring(kQ))end;AQviNt=tonumber(AQviNt) | |
T6=a:_coerce(T6,EE9LAE)NviN0i=a:_coerce(NviN0i,EE9LAE) | |
if BlMQce==nil then | |
if EE9LAE and o==nil then return{AQviNt,T6,NviN0i,nil, | |
nil}else BlMQce={}end elseif BlMQce==''then BlMQce={}else | |
do local dpRE={}local fEiXwWq=1;for r3JzMga6 in BlMQce:gmatch('[^.]+')do | |
dpRE[fEiXwWq]=r3JzMga6;fEiXwWq=fEiXwWq+1 end;BlMQce=dpRE end;a:_validateIdentifiers(BlMQce,false)end | |
if o==nil then if EE9LAE then o=nil else o={}end elseif o==''then o={}else | |
do local Tuyw={}local FYLcr2nu=1;for ioS69 in o:gmatch('[^.]+')do | |
Tuyw[FYLcr2nu]=ioS69;FYLcr2nu=FYLcr2nu+1 end;o=Tuyw end;a:_validateIdentifiers(o,true)end;return{AQviNt,T6,NviN0i,BlMQce,o}end,_validateIdentifiers=function(AiP,S2jwpoi,_WX9u)if | |
_WX9u==nil then _WX9u=false end | |
for u0riyU=1,#S2jwpoi do local UH=S2jwpoi[u0riyU]if not UH then | |
error( | |
"Invalid empty identifier ".. | |
tostring(UH).." in "..tostring(mCsewfX(S2jwpoi,'.')))end;if | |
UH:sub(1,1)=='0'and | |
tonumber(UH)and UH~='0'and not _WX9u then | |
error("Invalid leading zero in identifier "..tostring(UH))end end end,__pairs=function(WNph)return | |
pairs({WNph.major,WNph.minor,WNph.patch,WNph.prerelease,WNph.build})end,__ipairs=function(ytF)return | |
ipairs({ytF.major,ytF.minor,ytF.patch,ytF.prerelease,ytF.build})end,__tostring=function(d) | |
local gRm=tostring(d.major) | |
if d.minor~=nil then gRm=gRm.. ('.'..d.minor)end | |
if d.patch~=nil then gRm=gRm.. ('.'..d.patch)end | |
if d.prerelease and#d.prerelease>0 or | |
d.partial and d.prerelease and | |
#d.prerelease==0 and d.build==nil then gRm=gRm.. ('-'.. | |
mCsewfX(d.prerelease,'.'))end | |
if d.build and#d.build>0 or | |
d.partial and d.build and#d.build==0 then gRm=gRm.. | |
('+'..mCsewfX(d.build,'.'))end;return gRm end,_comparsionFunctions=function(LPX0,g)if | |
g==nil then g=false end;local _l | |
_l=function(N8,Gzk) | |
if N8 and Gzk then return N(N8,Gzk)elseif N8 then return-1 elseif Gzk then return 1 else return 0 end end;local qao | |
qao=function(J7nsK,dXbd)if J7nsK==dXbd then return 0 else return'not implemented'end end;local ipUPIzc | |
ipUPIzc=function(vQj)local sVBxyy | |
sVBxyy=function(N9d,S7) | |
if N9d==nil or S7 ==nil then return 0 else return vQj(N9d,S7)end end;return sVBxyy end | |
if g then return | |
{wFeA,ipUPIzc(wFeA),ipUPIzc(wFeA),ipUPIzc(_l),ipUPIzc(qao)}else return{wFeA,wFeA,wFeA,_l,qao}end end,__compare=function(bJtvRSR,aBhZK5) | |
local Jz8JUscj=bJtvRSR:_comparsionFunctions( | |
bJtvRSR.partial or aBhZK5.partial) | |
local OtGmbAgE={{Jz8JUscj[1],bJtvRSR.major,aBhZK5.major},{Jz8JUscj[2],bJtvRSR.minor,aBhZK5.minor},{Jz8JUscj[3],bJtvRSR.patch,aBhZK5.patch},{Jz8JUscj[4],bJtvRSR.prerelease,aBhZK5.prerelease},{Jz8JUscj[5],bJtvRSR.build,aBhZK5.build}} | |
for oU_r=1,#OtGmbAgE do local n_lv=OtGmbAgE[oU_r]local UYQF,WXx,W4EuxJXi=Xf(n_lv) | |
local BlYNd61h=UYQF(WXx,W4EuxJXi)if BlYNd61h~=0 then return BlYNd61h end end;return 0 end,__compareHelper=function(XDPndG,sJYFQIP4,Ogq0S2,n8Cw3SR) | |
local GJqd7gt=XDPndG:__compare(sJYFQIP4)if GJqd7gt=='not implemented'then return n8Cw3SR end;return | |
Ogq0S2(GJqd7gt)end,__eq=function(slE5aDm2,aL_g) | |
local IMUI10L;IMUI10L=function(vPA)return vPA==0 end;return | |
slE5aDm2:__compareHelper(aL_g,IMUI10L,false)end,__lt=function(pUXZ6G4,mk) | |
local OeQex1U4;OeQex1U4=function(i0cV9)return i0cV9 <0 end;return | |
pUXZ6G4:__compareHelper(mk,OeQex1U4,false)end,__le=function(EGD,VWiGCreH) | |
local B_kkL;B_kkL=function(uEO6Y)return uEO6Y<=0 end;return | |
EGD:__compareHelper(VWiGCreH,B_kkL,false)end}AwGfFV.__index=AwGfFV | |
NzeoQJ=setmetatable({__init=function(i_053JPY,l,UK)if UK==nil then UK=false end | |
local NzaICo,k1X83nYm,xxzxfj,_ad1m4I,H1QsS=Xf(i_053JPY:parse(l,UK)) | |
i_053JPY.major,i_053JPY.minor,i_053JPY.patch,i_053JPY.prerelease,i_053JPY.build,i_053JPY.partial=NzaICo,k1X83nYm,xxzxfj,_ad1m4I,H1QsS,UK end,__base=AwGfFV,__name="Version"},{__index=AwGfFV,__call=function(rIMx,...) | |
local TiA=setmetatable({},AwGfFV)rIMx.__init(TiA,...)return TiA end})AwGfFV.__class=NzeoQJ;local wCRY=NzeoQJ | |
wCRY.versionRe=function(wCRY,Y51P) | |
local ichL,NOK,Alv,YeLO2=Y51P:match('^(%d+)%.(%d+)%.(%d+)(.*)$')if not(ichL)then return nil end | |
local CkrmO,ooovsSJe=YeLO2:match('^%-([0-9a-zA-z.-]+)(.*)$')if CkrmO then YeLO2=ooovsSJe end;local s5IsD | |
s5IsD,ooovsSJe=YeLO2:match('^%+([0-9a-zA-Z.-]+)(.*)$')if s5IsD then YeLO2=ooovsSJe end;if#YeLO2 >0 then return nil end | |
return ichL,NOK,Alv,CkrmO,s5IsD end | |
wCRY.partialVersionRe=function(wCRY,KvYEVoXt)local VWWD_P,zsMuNkv=KvYEVoXt:match('^(%d+)(.*)$')if not | |
(VWWD_P)then return nil end | |
local aXxi,Q18a7QTy=zsMuNkv:match('^%.(%d+)(.*)$')if aXxi then zsMuNkv=Q18a7QTy end;local K5Rp6 | |
K5Rp6,Q18a7QTy=zsMuNkv:match('^%.(%d+)(.*)$')if K5Rp6 then zsMuNkv=Q18a7QTy end;local GTIA | |
GTIA,Q18a7QTy=zsMuNkv:match('^%-([0-9a-zA-Z.-]*)(.*)$')if GTIA then zsMuNkv=Q18a7QTy end;local gdPUe | |
gdPUe,Q18a7QTy=zsMuNkv:match('^%+([0-9a-zA-Z.-]*)(.*)$')if gdPUe then zsMuNkv=Q18a7QTy end;if#zsMuNkv>0 then return nil end;return VWWD_P, | |
aXxi,K5Rp6,GTIA,gdPUe end;fs52REi=NzeoQJ end;local PUNkgaiM | |
do local _bxEn | |
local pcN_ceXY={parse=function(rq,mo)if not mo or type(mo)~='string'or mo==''then | |
error( | |
"Invalid empty requirement specification: "..tostring(tostring(mo)))end;if mo=='*'then return | |
{rq.__class.KIND_ANY,''}end | |
local I,RAAJAsR=rq.__class:reSpec(mo)if not I then | |
error("Invalid requirement specification: "..tostring(mo))end | |
I=rq.__class.KIND_ALIASES[I]or I;local c1pjj7=fs52REi(RAAJAsR,true) | |
if | |
c1pjj7.build~=nil and | |
I~=rq.__class.KIND_EQUAL and I~=rq.__class.KIND_NEQ then | |
error("Invalid requirement specification "..tostring(mo)..": build numbers have no ordering")end;return{I,c1pjj7}end,match=function(BMv,NQh8) | |
local P=BMv.kind | |
if BMv.__class.KIND_ANY==P then return true elseif BMv.__class.KIND_LT==P then return | |
NQh8 <BMv.spec elseif BMv.__class.KIND_LTE==P then return NQh8 <=BMv.spec elseif | |
BMv.__class.KIND_EQUAL==P then return NQh8 ==BMv.spec elseif BMv.__class.KIND_GTE==P then return NQh8 >= | |
BMv.spec elseif BMv.__class.KIND_GT==P then return NQh8 >BMv.spec elseif | |
BMv.__class.KIND_NEQ==P then return NQh8 ~=BMv.spec elseif BMv.__class.KIND_CARET==P then | |
return BMv.spec<= | |
NQh8 and NQh8 <BMv.spec:next_major()elseif BMv.__class.KIND_TILDE==P then return BMv.spec<=NQh8 and | |
NQh8 <BMv.spec:next_minor()else | |
return error("Unexpected match kind: ".. | |
tostring(BMv.kind))end end,__tostring=function(bkTe)return | |
tostring(bkTe.kind)..tostring(bkTe.spec)end,__eq=function(ohmPbyDd,D) | |
return | |
ohmPbyDd.kind==D.kind and ohmPbyDd.spec==D.spec end}pcN_ceXY.__index=pcN_ceXY | |
_bxEn=setmetatable({__init=function(DfDLWkT,MTU8HP4d) | |
DfDLWkT.kind,DfDLWkT.spec=Xf(DfDLWkT:parse(MTU8HP4d))end,__base=pcN_ceXY,__name="SpecItem"},{__index=pcN_ceXY,__call=function(hIM_cG0i,...) | |
local jD=setmetatable({},pcN_ceXY)hIM_cG0i.__init(jD,...)return jD end})pcN_ceXY.__class=_bxEn;local _P=_bxEn;_P.KIND_ANY='*'_P.KIND_LT='<' | |
_P.KIND_LTE='<='_P.KIND_EQUAL='=='_P.KIND_SHORTEQ='='_P.KIND_EMPTY=''_P.KIND_GTE='>=' | |
_P.KIND_GT='>'_P.KIND_NEQ='!='_P.KIND_CARET='^'_P.KIND_TILDE='~' | |
_P.KIND_ALIASES={[_P.__class.KIND_SHORTEQ]=_P.__class.KIND_EQUAL,[_P.__class.KIND_EMPTY]=_P.__class.KIND_EQUAL} | |
_P.reSpec=function(_P,me)local sgU5HAMG,FDydY=me:match('^(.-)(%d.*)$') | |
if | |
not | |
( | |
sgU5HAMG=='<'or | |
sgU5HAMG=='<='or sgU5HAMG==''or sgU5HAMG=='='or sgU5HAMG=='=='or sgU5HAMG=='>='or sgU5HAMG=='>'or | |
sgU5HAMG=='!='or | |
sgU5HAMG=='^'or | |
sgU5HAMG=='~')then return nil else return sgU5HAMG,FDydY end end;PUNkgaiM=_bxEn end;local s6FbB | |
do local PEZ_ | |
local c={parse=function(ElbTbcZG,r3)local p={}local UiVYRok=1;for jvPsY9 in r3:gmatch('[^,]+')do | |
p[UiVYRok]=PUNkgaiM(jvPsY9)UiVYRok=UiVYRok+1 end;return p end,match=function(tEBmuypm,hW) | |
local iOcgdUx=tEBmuypm.specs;for kCwLIk=1,#iOcgdUx do local _l=iOcgdUx[kCwLIk] | |
if not _l:match(hW)then return false end end;return true end,filter=function(rjQ,Euo0) | |
local LIV=0 | |
return function() | |
while true do LIV=LIV+1;local vydlAbZ3=Euo0[LIV]if not(vydlAbZ3)then return nil end;if | |
rjQ:match(vydlAbZ3)then return vydlAbZ3 end end end end,select=function(BXxv5z,mKLU) | |
local Him;do local cPDhu={}local UQnOS=1 | |
for tRWU in BXxv5z:filter(mKLU)do cPDhu[UQnOS]=tRWU;UQnOS=UQnOS+1 end;Him=cPDhu end | |
if#Him>0 then | |
local X2Zy_nb=Him[1] | |
for ITtw3N7E=1,#Him do local yozOp=Him[ITtw3N7E]if X2Zy_nb<yozOp then X2Zy_nb=yozOp end end;return X2Zy_nb else return nil end end,__index=function(wxU,kOmS5sy)if | |
wxU:match(kOmS5sy)then return true else return nil end end,__pairs=function(CLSdD)return | |
pairs(CLSdD.specs)end,__ipairs=function(Fh)return ipairs(Fh.specs)end,__tostring=function(IlAPA) | |
return | |
mCsewfX((function() | |
local jLKMpQuK={}local sUQpby=1;local mbA=IlAPA.specs;for _qPhpaFx=1,#mbA do local zex=mbA[_qPhpaFx] | |
jLKMpQuK[sUQpby]=tostring(zex)sUQpby=sUQpby+1 end | |
return jLKMpQuK end)(),',')end,__eq=function(pPGcdu,rjp) | |
local cT2z=pPGcdu.specs | |
for zke1tWps=1,#cT2z do local gRFA=cT2z[zke1tWps]local jX9a0tJX=false;local YFy4TGc=rjp.specs | |
for YjpbYkCb=1,#YFy4TGc do | |
local L1p7luJ=YFy4TGc[YjpbYkCb]if gRFA==L1p7luJ then jX9a0tJX=true;break end end;if not jX9a0tJX then return false end end;return true end}c.__index=c | |
PEZ_=setmetatable({__init=function(eH,WpOZ) | |
if type(WpOZ)=='string'then WpOZ={WpOZ}end;local fD2289 | |
do local folfO={}local vtsK=1;for E1p4Mv=1,#WpOZ do local IHap=WpOZ[E1p4Mv] | |
folfO[vtsK]=eH:parse(IHap)vtsK=vtsK+1 end;fD2289=folfO end;eH.specs={} | |
for rDvV=1,#fD2289 do local RX1L2q=fD2289[rDvV]for bCBtWguf=1,#RX1L2q do | |
local q=RX1L2q[bCBtWguf]yY(eH.specs,q)end end end,__base=c,__name="Spec"},{__index=c,__call=function(e1sXUN4f,...) | |
local x=setmetatable({},c)e1sXUN4f.__init(x,...)return x end})c.__class=PEZ_;s6FbB=PEZ_ end;local X | |
X=function(VP,IQwqq)return wFeA(fs52REi(VP,fs52REi(IQwqq)))end;local dc61 | |
dc61=function(Xcc4,fqw5)return s6FbB(Xcc4):match(fs52REi(fqw5))end;local aguhyl | |
aguhyl=function(qnVfOeRE)return | |
({fs52REi:parse(qnVfOeRE)})[1]end | |
return{Spec=s6FbB,SpecItem=PUNkgaiM,Version=fs52REi,compare=X,match=dc61,validate=aguhyl}end)()local YAtG_LV3;YAtG_LV3=require("component").isAvailable;local LfEJbh_,JD | |
do | |
local YIiSKsxK=require("shell")LfEJbh_,JD=YIiSKsxK.parse,YIiSKsxK.getWorkingDirectory end;local u=require("shell")local pzDMZwG,XPoQB,XxJ,o5sms,JQi1jg;do | |
local Ua=require("filesystem") | |
pzDMZwG,XPoQB,XxJ,o5sms,JQi1jg=Ua.isDirectory,Ua.exists,Ua.makeDirectory,Ua.concat,Ua.copy end | |
local wVzn=require("filesystem")local pE,RSjapQ;do local qeJtG=require("serialization") | |
pE,RSjapQ=qeJtG.serialize,qeJtG.unserialize end;local QJf | |
QJf=require("event").pull;local zC,pfZ3SPy_,pDNa2ox6;do local pdpNgBcZ=require("term") | |
zC,pfZ3SPy_,pDNa2ox6=pdpNgBcZ.clearLine,pdpNgBcZ.getCursor,pdpNgBcZ.clear end;local Do6yo7nm | |
Do6yo7nm=os.exit;local y06X3k,ivnJjrA | |
do local wV=io;y06X3k,ivnJjrA=wV.write,wV.stderr end;local d3fMjkg,el | |
do local rLd=table;d3fMjkg,el=rLd.insert,rLd.unpack end;local Wu_uIt=wVzn.list;local w,sgeP={},{}local CM=nil;local Qlmlet={}local _={}local RkGFh6="/etc/hpm/module/" | |
local hw18="/var/lib/hpm/dist/"local nvCiFt7r=0;local xSebv5Jc="/etc/hpm/hpm.cfg" | |
local mMp=[[Usage: hpm OPTIONS COMMAND | |
See `man hpm` for more info.]] | |
local rDtVf=[[-- << Global settings >> ------------------------------------------------------- | |
-- A directory where package manifests will be placed. | |
-- It will be created if it doesn't exist. | |
dist = "/var/lib/hpm/dist" | |
-- A place where to search for custom hpm modules. | |
-- It will be created if it doesn't exist. | |
modules = "/etc/hpm/module" | |
-- << Settings related to the hel module >> ------------------------------------ | |
hel = {} | |
-- If set to `false`, hpm will *only* remove a package that hpm is told to | |
-- remove. Otherwise, all of its dependants will be also removed. | |
hel.remove_dependants = true | |
-- << Settings related to the oppm module >> ----------------------------------- | |
oppm = {} | |
-- A directory where package manifests will be stored for faster access. | |
oppm.cache_directory = "/var/cache/hpm/oppm" | |
-- See hel.remove_dependants above. | |
oppm.remove_dependants = true]] | |
local vj={info=function(...) | |
if w.v then | |
return | |
print(table.concat((function(...)local z8oF={}local DB6A7N=1;local VhYX={...}for Ha7ErH=1,#VhYX do local rjU95v=VhYX[Ha7ErH] | |
z8oF[DB6A7N]=tostring(rjU95v)DB6A7N=DB6A7N+1 end;return z8oF end)(...),"\t"))end end,print=function(...) | |
if | |
not(w.q)then | |
return | |
print(table.concat((function(...)local sxBl={}local m=1;local nD4LhX6z={...}for iN=1,#nD4LhX6z do | |
local Lq=nD4LhX6z[iN]sxBl[m]=tostring(Lq)m=m+1 end | |
return sxBl end)(...),"\t"))end end,error=function(...) | |
if | |
not(w.q)then | |
return | |
ivnJjrA:write( | |
table.concat((function(...)local s9tW={}local R61K=1;local Jf4os={...} | |
for a4xc=1,#Jf4os do | |
local e=Jf4os[a4xc]s9tW[R61K]=tostring(e)R61K=R61K+1 end;return s9tW end)(...),"\t")..'\n')end end,fatal=function(...) | |
if | |
not(w.q)then | |
ivnJjrA:write( | |
table.concat((function(...)local la5={}local i=1;local R={...}for xWVu=1,#R do local Yw8Yxix=R[xWVu] | |
la5[i]=tostring(Yw8Yxix)i=i+1 end;return la5 end)(...),"\t")..'\n')end;return Do6yo7nm(1)end}local z | |
z=function(i,VoXG)if not(i)then return vj.fatal(VoXG)end end;local Zg | |
Zg=function(JL0I04c)return | |
vj.fatal((tostring(JL0I04c))..": Not implemented yet!")end;local ykRppH | |
ykRppH=function()y06X3k(mMp)return Do6yo7nm(0)end;local WQ6 | |
WQ6=function(En6r_K97,T4AA)if not(En6r_K97)then vj.fatal(T4AA)end;return En6r_K97 end;local y36Aetn | |
y36Aetn=function(VnuCKTdu,XnNgn,H1JD) | |
if not(type(VnuCKTdu==XnNgn))then | |
vj.fatal("Value '".. | |
tostring(VnuCKTdu).. | |
"' is "..tostring(type(H1JD)).. | |
", however, a "..tostring(XnNgn).." is expected.")end;return H1JD end;local iPL3B4cr;iPL3B4cr=function(gEEa9I) | |
return y36Aetn(gEEa9I,"number",tonumber(gEEa9I))end | |
local GI2hz6SK | |
GI2hz6SK=function(ULLLDUm) | |
return y36Aetn(ULLLDUm,"string",tostring(ULLLDUm))end;local Oh | |
Oh=function(e4F3,GsfNt7) | |
for fF0,YWPfQKb2 in pairs(GsfNt7)do if YWPfQKb2 ==e4F3 then return true,fF0 end end;return false end;local PG | |
PG=function(r)local OS0Zp3i=0;for BK,Idjbe70 in pairs(r)do OS0Zp3i=OS0Zp3i+1 end | |
return OS0Zp3i end;local n | |
n=function(B) | |
if type(B)=="nil"then return true elseif type(B)=="string"then return not B or#B<1 elseif type(B)== | |
"table"then return not B or PG(B)<1 else return true end end;local O | |
O=function(nDjt) | |
for NVWt=1,#nDjt do local efuUGMh=nDjt[NVWt]if not efuUGMh then return false end end;return true end;local N5UjTN | |
N5UjTN=function(p4nNp)return XPoQB(p4nNp)and pzDMZwG(p4nNp)end;local qLH5 | |
qLH5=function(VW)return XPoQB(VW)and not pzDMZwG(VW)end;local tE | |
tE=function(Zt)return Zt==1 and""or"s"end;local VcV0EuD | |
VcV0EuD=function(V)return V~=1 and""or"s"end;local pX4gCR | |
pX4gCR=function(mzeTI)return mzeTI==1 and"is"or"are"end;local gad4ZcL;gad4ZcL=function(sy4J) | |
return sy4J:match("^([^:]-):?([^:@]+)@?([^:@]*)$")end | |
local dk | |
dk=function(ztJhP_u8) | |
if | |
wVzn.get(u.resolve(ztJhP_u8)).isReadOnly()then return false,"the path is readonly!"elseif not XPoQB(ztJhP_u8)then return false, | |
"the filesystem node doesn't exist."else | |
if not | |
(pzDMZwG(ztJhP_u8)or wVzn.isLink(ztJhP_u8))then return wVzn.remove(ztJhP_u8)else for D in | |
WQ6(Wu_uIt(ztJhP_u8))do dk(o5sms(ztJhP_u8,D))end;return | |
wVzn.remove(ztJhP_u8)end end end;local E | |
E=function()local XIcl=w.c or w.config or xSebv5Jc | |
if not qLH5(XIcl)then | |
local U2=wVzn.path(XIcl) | |
if not N5UjTN(U2)then local Z,ZDICnKE=XxJ(U2)if not Z then | |
return false,"Failed to create '".. | |
tostring(U2).. | |
"' directory for the config file: "..tostring(ZDICnKE)end end;local X,zLtWO09=io.open(XIcl,"w")if X then X:write(rDtVf)X:close()else | |
return false, | |
"Failed to open config file for writing: "..tostring(zLtWO09)end end;local ys,rMQ1um8=io.open(XIcl,"r") | |
if ys then local L=ys:read("*all") | |
ys:close()local B58={};(load(L,"config","t",B58))() | |
local PYVzrNl | |
PYVzrNl=function(KTVmRC)if KTVmRC==nil then KTVmRC={}end | |
return | |
setmetatable(KTVmRC,{__index={get=function(Pa,bmK,OJPc3R)if | |
type(KTVmRC[Pa])~="nil"then | |
if type(KTVmRC[Pa])=="table"then return PYVzrNl(KTVmRC[Pa])end;return KTVmRC[Pa]end | |
vj.error( | |
"Attempt to access undeclared config field '"..tostring(Pa).."'!")if not OJPc3R then return bmK else return PYVzrNl(bmK)end end}})end;_=PYVzrNl(B58)RkGFh6=_.get("modules",RkGFh6) | |
hw18=_.get("dist",hw18)return _ else | |
return false,"Failed to open config file for reading: "..tostring(rMQ1um8)end end;local OO | |
OO=function()if not(YAtG_LV3("internet"))then | |
vj.fatal("This command requires an internet card to run!")end;CM=CM or | |
require("internet").request end;local y;y=function(j)OO()return pcall(CM,j)end;local cR6rJlAl | |
cR6rJlAl=function() | |
if | |
not N5UjTN(RkGFh6)then local M9K,Zeu=XxJ(RkGFh6)if not M9K then | |
return false,"Failed to create '".. | |
tostring(RkGFh6).."' directory for custom modules: "..tostring(Zeu)end end;local vMgKnGj=WQ6(Wu_uIt(RkGFh6)) | |
for Q2_d in vMgKnGj do | |
local W0iTcMIt=Q2_d:match("^(.+)%..+$") | |
local N=(loadfile(o5sms(RkGFh6,Q2_d),"t",_ENV))()if N then Qlmlet[W0iTcMIt]=N end end;return true end;local M6ilzGJ | |
M6ilzGJ=function(Hald6SO)local Dq=Hald6SO;local y3Ur | |
do local GL70F7uL=Hald6SO:find(':')if GL70F7uL then Dq=Hald6SO:sub( | |
GL70F7uL+1) | |
y3Ur=Hald6SO:sub(1,GL70F7uL-1)end end | |
if not y3Ur then local lqANrrJA={} | |
for WUFTXBy6,y3Ur in pairs(Qlmlet)do | |
if y3Ur[Dq]then if type(y3Ur[Dq])=="table"and | |
y3Ur[Dq].__public==true then | |
d3fMjkg(lqANrrJA,{class=y3Ur,module=WUFTXBy6,method=y3Ur[Dq]})end end end | |
if#lqANrrJA>1 then local aEZf=nil;for QjQ_o,y3Ur in pairs(lqANrrJA)do | |
if y3Ur.module=="hel"then aEZf=QjQ_o;break end end;if aEZf then | |
lqANrrJA={lqANrrJA[aEZf]}end end | |
if#lqANrrJA>1 then | |
vj.print("Ambiguous choice: method ".. | |
tostring(Dq).." is implemented in the following modules:")for wDiq_=1,#lqANrrJA do local y3Ur=lqANrrJA[wDiq_] | |
vj.print(" * "..tostring(y3Ur.module))end | |
vj.print( | |
"Choose a specific module by prepending its name with a colon, e.g., ".. | |
tostring(lqANrrJA[1].module)..":"..tostring(Dq)..".")return false elseif#lqANrrJA==0 then | |
vj.error("Unknown command: "..tostring(Dq))return false else y3Ur=lqANrrJA[1].module | |
vj.info("Note, using "..tostring(y3Ur)..":".. | |
tostring(Dq)..".")return function(...) | |
return lqANrrJA[1].method(lqANrrJA[1].class,...)end end else | |
if Qlmlet[y3Ur]and n(Dq)then local QYA5WJOY={} | |
for yliV8,rjpKFl in pairs(Qlmlet[y3Ur])do if | |
type(rjpKFl)=="table"and rjpKFl.__public==true then | |
d3fMjkg(QYA5WJOY,tostring(yliV8))end end | |
vj.print("Available module-specific commands: "..tostring(table.concat(QYA5WJOY,", ")))return false end | |
if | |
not Qlmlet[y3Ur]or not Qlmlet[y3Ur][Dq]or | |
Qlmlet[y3Ur][Dq]and | |
(type(Qlmlet[y3Ur][Dq])~="table"or | |
Qlmlet[y3Ur][Dq].__public~=true)then | |
vj.error("Unknown command: "..tostring(y3Ur)..":"..tostring(Dq))return false else return function(...) | |
return Qlmlet[y3Ur][Dq](Qlmlet[y3Ur],...)end end end end;local iW6CD | |
iW6CD=function(YUGQovw) | |
if not YUGQovw or YUGQovw==""then YUGQovw="hel"else YUGQovw=YUGQovw end;return Qlmlet[YUGQovw]or Qlmlet.default end;local wZdg | |
wZdg=function(XZt7GyF,Zn3SC,...)if XZt7GyF==nil then XZt7GyF=Qlmlet.default end | |
if | |
XZt7GyF[Zn3SC]then return XZt7GyF[Zn3SC](XZt7GyF,...)else return | |
Qlmlet.default[Zn3SC](Qlmlet.default,...)end end;local BaX | |
BaX=function(D4,crA9EKx,IcsJ,A)if crA9EKx==nil then crA9EKx="hel"end;if IcsJ==nil then | |
IcsJ=o5sms(hw18,crA9EKx)end;if A==nil then A=D4.name end;if not D4 then | |
return false,"'nil' given"end | |
if not N5UjTN(IcsJ)then local o0_XG8FI,jLsxpw=XxJ(IcsJ) | |
if not o0_XG8FI then return | |
false, | |
"Failed to create '"..tostring(o5sms(IcsJ,crA9EKx)).."' directory for manifest files: ".. | |
tostring(jLsxpw)end end;local Wp9xT,P=io.open(o5sms(IcsJ,A),"w") | |
if Wp9xT then | |
Wp9xT:write(pE(D4))Wp9xT:close()return true else return false, | |
"Failed to open file for writing: "..tostring(P)end end;local SJsW11k | |
SJsW11k=function(x,AXNfV,cX)if cX==nil then cX="hel"end | |
AXNfV=AXNfV or o5sms(hw18,cX,x) | |
if qLH5(AXNfV)then local iyx,bxvn=io.open(AXNfV,"rb") | |
if iyx then | |
local mWYrzB=WQ6(RSjapQ(iyx:read("*all")))iyx:close()return mWYrzB else | |
return false,"Failed to open manifest for '"..tostring(x).. | |
"' package: "..tostring(bxvn)end else | |
return false,"No manifest found for '"..tostring(x).."' package"end end;local Ki1HJT | |
Ki1HJT=function(O7kX,Q4XSpdY)if Q4XSpdY==nil then Q4XSpdY="hel"end | |
local fzTyrQ9F=o5sms(hw18,Q4XSpdY,O7kX) | |
if qLH5(fzTyrQ9F)then return dk(fzTyrQ9F)else return false,"No manifest found for '".. | |
tostring(O7kX).."' package"end end;local wjim8xCV | |
wjim8xCV=function(fAumJ0i)return | |
setmetatable({__public=true},{__call=function(i0,...)return fAumJ0i(...)end})end;local EQLam | |
EQLam=function(tZliF4,jlmopoj) | |
return | |
function()local R,uS_N6=pcall(tZliF4)if not(R)then | |
return false,"Could not download '"..tostring(jlmopoj).."': ".. | |
tostring(uS_N6)else return uS_N6 end end end;local qTDt | |
qTDt=function(o5SLRA,ztwXaCR,M2WtMgiq) | |
if ztwXaCR==nil then ztwXaCR="Could not download '%s': %s"end | |
if M2WtMgiq==nil then M2WtMgiq="Could not download '%s': %s"end;local FgfME,ylH9o,CC4Kfjh=y(o5SLRA)if not(FgfME and ylH9o)then return false, | |
ztwXaCR:format(o5SLRA,CC4Kfjh)end;local k=""for eUQ0x,CC4Kfjh in | |
EQLam(ylH9o)do | |
if eUQ0x then k=k..eUQ0x else return false,M2WtMgiq:format(o5SLRA,CC4Kfjh)end end;return k end;local v | |
v=function() | |
if not(w.y)then io.write("Press [ENTER] to continue...") | |
local r0OR=select(3,QJf("key_down")) | |
if r0OR==13 then zC()return true else io.write("\n")return false end else return true end end;local Ta | |
Ta=function(pYHkv)local hxZHlgP=0;local zct={} | |
if not(n(pYHkv.install))then | |
local WQk6Wkd={"Packages to INSTALL:",table.concat(pYHkv.install," ")}d3fMjkg(zct,WQk6Wkd) | |
hxZHlgP=hxZHlgP+#pYHkv.install else pYHkv.install={}end | |
if not(n(pYHkv.reinstall))then | |
local t={"Packages to REINSTALL:",table.concat(pYHkv.reinstall," ")}d3fMjkg(zct,t)hxZHlgP=hxZHlgP+#pYHkv.reinstall else | |
pYHkv.reinstall={}end | |
if not(n(pYHkv.upgrade))then | |
local pRCHPl={"Packages to UPGRADE:",table.concat(pYHkv.upgrade," ")}d3fMjkg(zct,pRCHPl) | |
hxZHlgP=hxZHlgP+#pYHkv.upgrade else pYHkv.upgrade={}end | |
if not(n(pYHkv.remove))then | |
local sCffg4HK={"Packages to REMOVE:",table.concat(pYHkv.remove," ")}d3fMjkg(zct,sCffg4HK) | |
hxZHlgP=hxZHlgP+#pYHkv.remove else pYHkv.remove={}end | |
do | |
local EyljhkFp={tostring(#pYHkv.install).." to INSTALL, ".. | |
tostring(#pYHkv.reinstall).. | |
" to REINSTALL, ".. | |
tostring(#pYHkv.upgrade).." to UPGRADE, "..tostring(#pYHkv.remove).. | |
" to REMOVE."}d3fMjkg(zct,EyljhkFp)end | |
for uGDn542,DQ in pairs(zct)do for uGDn542,s6Ahlni_ in pairs(DQ)do | |
if uGDn542 ==1 then vj.print(s6Ahlni_)else vj.print(" ".. | |
tostring(s6Ahlni_))end end;if uGDn542 ~=#zct then | |
vj.print("")end end | |
if hxZHlgP>0 then if not(v())then return Do6yo7nm(7)end end end | |
do local T6dNu;local H={}H.__index=H | |
T6dNu=setmetatable({__init=function()end,__base=H,__name="default"},{__index=H,__call=function(vj9879b5,...) | |
local cotcYZ1f=setmetatable({},H)vj9879b5.__init(cotcYZ1f,...)return cotcYZ1f end})H.__class=T6dNu;local YlzZm=T6dNu | |
YlzZm.install=function()return | |
vj.fatal("Incorrect source is provided! No default 'install' implementation.")end | |
YlzZm.remove=function(YlzZm,FRcmT,zfl)if zfl==nil then zfl="hel"end | |
if FRcmT then | |
if FRcmT.files then | |
for itxD,JPHs7A in pairs(FRcmT.files)do | |
local yzYgnMtr=o5sms(JPHs7A.dir,JPHs7A.name)local o,wmkJ=dk(yzYgnMtr)if not(o)then | |
return false,"Failed to remove '"..tostring(yzYgnMtr).. | |
"': "..tostring(wmkJ)end end end;return Ki1HJT(FRcmT.name,zfl)else | |
return false,"Package can't be removed: the manifest is empty."end end | |
YlzZm.save=function()return | |
vj.fatal("Incorrect source is provided! No default 'save' implementation.")end;Qlmlet.default=T6dNu end | |
do local I1;local gXu5hG=Qlmlet.default;local R60Ru4bj={}R60Ru4bj.__index=R60Ru4bj | |
setmetatable(R60Ru4bj,gXu5hG.__base) | |
I1=setmetatable({__init=function(WT2AX,...)return I1.__parent.__init(WT2AX,...)end,__base=R60Ru4bj,__name="hel",__parent=gXu5hG},{__index=function(_AvO,qEO) | |
local q=rawget(R60Ru4bj,qEO)if q==nil then local WUY7=rawget(_AvO,"__parent") | |
if WUY7 then return WUY7[qEO]end else return q end end,__call=function(_puepou,...) | |
local DYLeJ=setmetatable({},R60Ru4bj)_puepou.__init(DYLeJ,...)return DYLeJ end})R60Ru4bj.__class=I1;local eQWRf=I1 | |
eQWRf.URL="https://hel-roottree.rhcloud.com/" | |
eQWRf.parsePackageJSON=function(eQWRf,udbF,dt1)if dt1 ==nil then dt1=s.Spec("*")end;local V7eMEiVW=nil | |
local Co1tUVas={} | |
for rQYWEt,nCwsa in pairs(udbF.versions)do local IPPy=s.Version(rQYWEt)if not(IPPy)then | |
vj.fatal( | |
"Could not parse the version in package: "..tostring(IPPy))end;Co1tUVas[IPPy]=nCwsa end | |
local B,UjlBMb=pcall(function()return | |
dt1:select((function()local zYGA2q2={}local I9Mw=1 | |
for e,BUtIET in pairs(Co1tUVas)do zYGA2q2[I9Mw]=e;I9Mw=I9Mw+1 end;return zYGA2q2 end)())end)if not(B)then | |
vj.fatal("Could not select the best version: "..tostring(UjlBMb))end;V7eMEiVW=tostring(UjlBMb)if not | |
(UjlBMb)then | |
vj.fatal("No candidate for version specification '"..tostring(dt1).."' found!")end | |
local PKWIJ9={name=udbF.name,version=V7eMEiVW,files={},dependencies={}}for NvAj,Icg in pairs(Co1tUVas[UjlBMb].files)do local PzMsk=Icg.dir;local axLuO=Icg.name | |
d3fMjkg(PKWIJ9.files,{url=NvAj,dir=PzMsk,name=axLuO})end | |
for j,As in | |
pairs(Co1tUVas[UjlBMb].depends)do local JmCzKm=As.version;local Mwhc=As.type | |
d3fMjkg(PKWIJ9.dependencies,{name=j,version=JmCzKm,type=Mwhc})end;return PKWIJ9 end | |
eQWRf.getPackageSpec=function(eQWRf,A6z) | |
vj.info("Downloading package data for "..tostring(A6z).." ...") | |
local _Mk,PXrrrSid=y(eQWRf.URL.."packages/"..A6z)if not(_Mk)then | |
vj.fatal("HTTP request error: "..PXrrrSid)end;local L9="" | |
for dbTwy in PXrrrSid do L9=L9 ..dbTwy end;local _KZPScl=JtAjijkG:decode(L9) | |
if not(_KZPScl)then vj.fatal("Incorrect JSON format!\n".. | |
tostring(L9))end;return _KZPScl.data end | |
eQWRf.rawInstall=function(eQWRf,R4f819q,Kj1I,nTUMgqomA)if Kj1I==nil then Kj1I=false end | |
if nTUMgqomA==nil then nTUMgqomA=false end;local Id5sIM | |
if nTUMgqomA then Id5sIM=o5sms(JD(),R4f819q.name)else Id5sIM="/"end | |
if nTUMgqomA and not N5UjTN(Id5sIM)then local gZM2ANLt,aC72qEnu=XxJ(Id5sIM) | |
if not | |
(gZM2ANLt)then | |
vj.fatal("Failed creating '"..tostring(Id5sIM).. | |
"' directory for package '"..tostring(R4f819q.name).. | |
"'! \n"..tostring(aC72qEnu))end elseif not nTUMgqomA then local B60J=SJsW11k(R4f819q.name,nil,"hel") | |
if B60J then | |
if B60J.version== | |
tostring(R4f819q.version)then | |
vj.print("'"..tostring(R4f819q.name).. | |
"@".. | |
tostring(B60J.version).."' is already installed, skipping...")return B60J else | |
vj.fatal("'".. | |
tostring(R4f819q.name).. | |
"@".. | |
tostring(R4f819q.version).. | |
"' was attempted to install, however, another version of the same package is already installed: '"..tostring(R4f819q.name).. | |
"@"..tostring(B60J.version).."'")end end end | |
for Y4,f in pairs(R4f819q.files)do | |
vj.info("Fetching '"..tostring(f.name).."' ...")local yeCnvcd6=WQ6(qTDt(f.url))local Iq93c6cA=o5sms(Id5sIM,f.dir) | |
if not | |
N5UjTN(Iq93c6cA)then local nsM0h,Czi=XxJ(Iq93c6cA)if not(nsM0h)then | |
vj.fatal("Failed to create '".. | |
tostring(Iq93c6cA).. | |
"' directory for '"..tostring(f.name).."'! \n"..tostring(Czi))end end | |
do local IlxN;f,IlxN=io.open(o5sms(Iq93c6cA,f.name),"w")if | |
not(f)then | |
vj.fatal("Could not open '"..tostring(o5sms(Iq93c6cA,f.name)).."' for writing: ".. | |
tostring(IlxN))end | |
f:write(yeCnvcd6)f:close()end end;return | |
{name=R4f819q.name,version=tostring(R4f819q.version),files=R4f819q.files,dependencies=R4f819q.dependencies,manual=Kj1I}end | |
eQWRf.resolveDependencies=function(eQWRf,EA_3x01A,m54tY2,WJWMdKI,AhbP)if m54tY2 ==nil then m54tY2={}end | |
if WJWMdKI==nil then WJWMdKI={}end;if AhbP==nil then AhbP={}end | |
for QHFgYUN=1,#EA_3x01A do local RoEsr7So=EA_3x01A[QHFgYUN]local dX,Rz | |
dX,Rz=RoEsr7So.name,RoEsr7So.version;local j177r=false;for j=1,#m54tY2 do local qCaFw=m54tY2[j] | |
if qCaFw.pkg.name==dX then j177r=true;break end end | |
if not(j177r)then | |
d3fMjkg(WJWMdKI,{name=dX,version=""})local syvPi=SJsW11k(dX,nil,"hel") | |
if not syvPi or not | |
Rz:match(s.Version(syvPi.version))then | |
local NrgSK2=eQWRf:getPackageSpec(dX)local wIH=eQWRf:parsePackageJSON(NrgSK2,Rz) | |
WJWMdKI[#WJWMdKI].version=wIH.version;local TYWkpc=wIH.dependencies | |
for k=1,#TYWkpc do local J=TYWkpc[k]j177r=false | |
for gtlO9=1,#m54tY2 do | |
local Lun=m54tY2[gtlO9]if Lun.pkg.name==J.name then j177r=true;break end end | |
if not j177r then local beUJXhjw=nil;for zY7adu,Nlvw in pairs(WJWMdKI)do | |
if Nlvw.name==J.name then beUJXhjw=zY7adu;break end end | |
if beUJXhjw then | |
if | |
WJWMdKI[beUJXhjw].version==J.version then | |
vj.fatal("Circular dependencies detected: '".. | |
tostring(dX).. | |
"@".. | |
tostring(wIH.version).. | |
"' depends on '".. | |
tostring(J.name).. | |
"@".. | |
tostring(J.version).. | |
"', and '".. | |
tostring(WJWMdKI[beUJXhjw].name).. | |
"@"..tostring(WJWMdKI[beUJXhjw].version).. | |
"' depends on '"..tostring(dX).."@".. | |
tostring(wIH.version).."'.")else | |
vj.fatal("Attempted to install two versions of the same package: '".. | |
tostring(J.name).. | |
"@".. | |
tostring(J.version).. | |
"' and '".. | |
tostring(WJWMdKI[beUJXhjw].name).."@".. | |
tostring(WJWMdKI[beUJXhjw].version).."' when resolving dependencies for '".. | |
tostring(dX).."@"..tostring(wIH.version).."'.")end end | |
eQWRf:resolveDependencies({{name=J.name,version=s.Spec(J.version)}},m54tY2,WJWMdKI,AhbP)end end;d3fMjkg(m54tY2,{pkg=wIH})d3fMjkg(AhbP,{pkg=wIH})else | |
d3fMjkg(m54tY2,{pkg=syvPi})end;WJWMdKI[#WJWMdKI]=nil end end;return AhbP end | |
eQWRf.getPackageDependants=function(eQWRf,K55,BJcMTdMi,f1MKKJ)if BJcMTdMi==nil then BJcMTdMi={}end | |
if f1MKKJ==nil then f1MKKJ={}end | |
for nFf=1,#K55 do local EIqL41=K55[nFf]local iv=false | |
for rfmMR4=1,#BJcMTdMi do local Tq2I=BJcMTdMi[rfmMR4]if Tq2I.name== | |
EIqL41 then iv=true;break end end | |
if not(iv)then d3fMjkg(f1MKKJ,{name=EIqL41}) | |
local GNo=SJsW11k(EIqL41,nil,"hel") | |
if GNo then d3fMjkg(BJcMTdMi,{name=EIqL41,manifest=GNo}) | |
local e5x=WQ6(Wu_uIt(o5sms(hw18,"hel"))) | |
for QrONvWGq in e5x do GNo=WQ6(SJsW11k(QrONvWGq,nil,"hel")) | |
local D94fnZaa=GNo.dependencies | |
for XI=1,#D94fnZaa do local FNi=D94fnZaa[XI] | |
if FNi.name==EIqL41 then iv=false | |
for pRW2nEmK=1,#BJcMTdMi do | |
local OR=BJcMTdMi[pRW2nEmK]if OR.name==QrONvWGq then iv=true;break end end | |
if not iv then | |
for Arww=1,#f1MKKJ do local BYH=f1MKKJ[Arww]if BYH.name==QrONvWGq then | |
vj.fatal("Circular dependencies detected: ".. | |
tostring(QrONvWGq))end end | |
eQWRf:getPackageDependants({QrONvWGq},BJcMTdMi,f1MKKJ)end end end end else | |
vj.fatal("Package ".. | |
tostring(EIqL41).." is referenced as a dependant of another package, however, this package isn't installed.")end;f1MKKJ[#f1MKKJ]=nil end end;return BJcMTdMi end | |
eQWRf.install=wjim8xCV(function(eQWRf,...) | |
if w.l or w["local"]then local Ef=u.resolve(...) | |
local P=WQ6(SJsW11k(Ef,o5sms(Ef,"manifest")))local F4AWvI=eQWRf:resolveDependencies(P.depends,nil)local GYVN=w.d or | |
w.onlyDeps;local DNlB1V={}for erb6G_E=1,#F4AWvI do local QFUU10K=F4AWvI[erb6G_E] | |
d3fMjkg(DNlB1V, | |
tostring(QFUU10K.pkg.name).."@"..tostring(QFUU10K.pkg.version))end;if | |
not(GYVN)then | |
d3fMjkg(DNlB1V,tostring(P.name).."@"..tostring(P.version))end;Ta({install=DNlB1V}) | |
for xNPDtul=1,#F4AWvI,1 | |
do local k8=F4AWvI[xNPDtul] | |
vj.print("Installing '"..tostring(k8.pkg.name).."@".. | |
tostring(k8.pkg.version).."'...")P=eQWRf:rawInstall(k8.pkg,false,false) | |
local HmgRk,UuCdpVi=BaX(P,"hel") | |
if HmgRk then | |
vj.info("Saved the manifest of '"..tostring(P.name).."'.")else | |
vj.fatal("Couldn't save the manifest of '"..tostring(P.name).. | |
"': "..tostring(UuCdpVi)..".")end end | |
if not GYVN then | |
vj.print("Installing '"..tostring(P.name).. | |
"@"..tostring(P.version).."'...") | |
for CA0uX7n,ze5Vpc3 in pairs(P.files)do if | |
not N5UjTN(o5sms(ze5Vpc3.dir,ze5Vpc3.name))then XxJ(ze5Vpc3.dir)end | |
local vwK8,Sk_SiC=JQi1jg(o5sms(Ef,ze5Vpc3.url),o5sms(ze5Vpc3.dir,ze5Vpc3.name))if not(vwK8)then | |
vj.fatal("Cannot copy file '"..tostring(ze5Vpc3.name).. | |
"': "..tostring(Sk_SiC))end end;local fghe,vFXf=BaX(P,"hel") | |
if fghe then | |
vj.info("Saved the manifest of '"..tostring(P.name).."'.")else | |
vj.fatal("Couldn't save the manifest of '"..tostring(P.name).. | |
"': "..tostring(vFXf)..".")end end end;local o7E8TLH={}local N5N27Jd={...} | |
for X0bgPvA=1,#N5N27Jd do local M9CyqH=N5N27Jd[X0bgPvA]local z0x4qSAN,X0GTupeV=M9CyqH:match( | |
"^(.+)@(.+)$"or M9CyqH)if n(X0GTupeV)then | |
X0GTupeV="*"end | |
vj.info("Creating version specification for "..tostring(X0GTupeV).." ...") | |
local rQ,k=pcall(function()return s.Spec(X0GTupeV)end)if not(rQ)then | |
vj.fatal("Could not parse the version specification: "..tostring(k).."!")end | |
d3fMjkg(o7E8TLH,{name=z0x4qSAN,version=k})end;local m=w.r or w.reinstall;local nK=w.s or w.save | |
local _zr=eQWRf:resolveDependencies(o7E8TLH)local f5={}local UAc={} | |
for Oc=1,#_zr do local IHovU=false | |
repeat local e_wDQjk=_zr[Oc] | |
if m then local ClglY=false;for S=1,#o7E8TLH do | |
local NKetZhs=o7E8TLH[S] | |
if NKetZhs.name==e_wDQjk.pkg.name then ClglY=true;break end end;if ClglY then | |
d3fMjkg(f5, | |
tostring(e_wDQjk.pkg.name).."@"..tostring(e_wDQjk.pkg.version))IHovU=true;break end end | |
d3fMjkg(UAc,tostring(e_wDQjk.pkg.name).."@".. | |
tostring(e_wDQjk.pkg.version))IHovU=true until true;if not IHovU then break end end;Ta({install=UAc,reinstall=f5}) | |
if m then local EFLZ0N1 | |
do local gL={}local m4=1 | |
for rNOL8G=1,#o7E8TLH do | |
local q=o7E8TLH[rNOL8G]gL[m4]=WQ6(SJsW11k(q.name,nil,"hel"))m4=m4+1 end;EFLZ0N1=gL end;eQWRf:_remove(EFLZ0N1,true,false)end | |
for lKO=1,#_zr do local hcwgu=_zr[lKO] | |
vj.print("Installing '"..tostring(hcwgu.pkg.name).."@".. | |
tostring(hcwgu.pkg.version).."'...")local omgCdqp8=false | |
for xxNCdF=1,#o7E8TLH do local _cl1b=o7E8TLH[xxNCdF]if | |
_cl1b.name==hcwgu.pkg.name then omgCdqp8=true;break end end;local X17eHTx=eQWRf:rawInstall(hcwgu.pkg,omgCdqp8,nK) | |
local SGF,myIHU=BaX(X17eHTx,"hel") | |
if SGF then | |
vj.info("Saved the manifest of '"..tostring(X17eHTx.name).."'.")else | |
vj.fatal("Couldn't save the manifest of '"..tostring(X17eHTx.name).. | |
"': "..tostring(myIHU)..".")end end end) | |
eQWRf.remove=wjim8xCV(function(eQWRf,...)local Xz18nk={...}local P={} | |
for sTX4=1,#Xz18nk do local A0TJx=Xz18nk[sTX4] | |
local Nqdkw=WQ6(SJsW11k(A0TJx,nil,"hel"))d3fMjkg(P,Nqdkw)end;return eQWRf:_remove(P,false)end) | |
eQWRf._remove=function(eQWRf,t,QbMO,wYZ)if QbMO==nil then QbMO=false end;if wYZ==nil then wYZ=true end | |
local aMd | |
if | |
not _.get("hel",{},true).get("remove_dependants",true)or not wYZ then | |
do local o0pf={}local tx1LD=1;for N3ROeR=1,#t do local I1oQVnUd=t[N3ROeR] | |
o0pf[tx1LD]={name=I1oQVnUd.name,manifest=I1oQVnUd}tx1LD=tx1LD+1 end | |
aMd=o0pf end else | |
aMd=eQWRf:getPackageDependants((function()local oTX={}local WZlF4=1;for IxqPDOWH=1,#t do local GZqV=t[IxqPDOWH] | |
oTX[WZlF4]=GZqV.name;WZlF4=WZlF4+1 end;return oTX end)())end | |
if not(QbMO)then | |
Ta({remove=(function()local OVubrDw_={}local G2_TeR8=1 | |
for yk=1,#aMd do local OPSPMfr_=aMd[yk] | |
OVubrDw_[G2_TeR8]="hel:".. | |
tostring(OPSPMfr_.manifest.name).."@"..tostring(OPSPMfr_.manifest.version)G2_TeR8=G2_TeR8+1 end;return OVubrDw_ end)()})end | |
for QnNOl=1,#aMd do local aQs=aMd[QnNOl] | |
vj.print("Removing '".. | |
tostring(aQs.manifest.name).."@".. | |
tostring(aQs.manifest.version).."' ...") | |
WQ6(I1.__parent.remove(eQWRf,aQs.manifest,"hel"))end;return true end | |
eQWRf.upgrade=wjim8xCV(function(eQWRf)local uow_0tb={} | |
for m8 in WQ6(Wu_uIt(o5sms(hw18,"hel")))do if not | |
(pzDMZwG(o5sms(hw18,"hel",m8)))then | |
d3fMjkg(uow_0tb,WQ6(SJsW11k(m8,nil,"hel")))end end;local tykg={} | |
for mcoAHO=1,#uow_0tb do local d3gFWO=uow_0tb[mcoAHO] | |
local D=eQWRf:getPackageSpec(d3gFWO.name)local obodPKnu=eQWRf:parsePackageJSON(D) | |
d3gFWO.latest={spec=D,data=obodPKnu} | |
if s.Version(d3gFWO.latest.data.version)> | |
s.Version(d3gFWO.version)then d3fMjkg(tykg,d3gFWO)end end | |
local C_pPyW=eQWRf:resolveDependencies((function()local kgdzk={}local oVSp=1;for uBJ=1,#tykg do local A=tykg[uBJ] | |
kgdzk[oVSp]={name=A.name,version=s.Spec(A.latest.data.version)}oVSp=oVSp+1 end | |
return kgdzk end)())local mgb4b | |
do local MP={}local jb=1 | |
for uKSj=1,#tykg do local YXgXQB=tykg[uKSj] | |
MP[jb]=tostring(YXgXQB.name).. | |
"@{".. | |
tostring(YXgXQB.version).." => ".. | |
tostring(YXgXQB.latest.data.version).."}"jb=jb+1 end;mgb4b=MP end;local LOBqxO={} | |
for bvL1X4=1,#C_pPyW do local PPNahh=C_pPyW[bvL1X4]local z2g=true | |
for m9JTkVv6=1,#tykg do | |
local Q=tykg[m9JTkVv6]if Q.name==PPNahh.pkg.name then z2g=false;break end end;if z2g then | |
d3fMjkg(LOBqxO,tostring(PPNahh.pkg.name).."@".. | |
tostring(PPNahh.pkg.version))end end;Ta({upgrade=mgb4b,install=LOBqxO}) | |
for bWkP=1,#C_pPyW do | |
local JtFj=C_pPyW[bWkP]local PQ3=false;local _xCtN=false | |
for xUGt=1,#tykg do local _U=tykg[xUGt]if _U.name==JtFj.pkg.name then | |
PQ3=_U;_xCtN=_U.manual;break end end;if PQ3 then eQWRf:_remove({PQ3},true,false)end | |
vj.print( | |
"Installing '"..tostring(JtFj.pkg.name).."@".. | |
tostring(JtFj.pkg.version).."'...")local JVpe=eQWRf:rawInstall(JtFj.pkg,_xCtN,false) | |
local nG36XmZC,Vf26=BaX(JVpe,"hel") | |
if nG36XmZC then | |
vj.info("Saved the manifest of '"..tostring(JVpe.name).."'.")else | |
vj.fatal("Couldn't save the manifest of '"..tostring(JVpe.name).. | |
"': "..tostring(Vf26)..".")end end end) | |
eQWRf.info=wjim8xCV(function(eQWRf,hkI39,MwwN)if MwwN==nil then MwwN="*"end;if n(hkI39)then | |
vj.fatal("Usage: hpm hel:info <package name> [<version specification>]")end;if n(MwwN)then MwwN="*"end | |
vj.print( | |
"Creating version specification for "..tostring(MwwN).." ...") | |
local oZ9,OXlT0=pcall(function()return s.Spec(MwwN)end)if not(oZ9)then | |
vj.fatal("Could not parse the version specification: "..tostring(OXlT0).."!")end | |
local V=eQWRf:getPackageSpec(hkI39)local zIYNIXy1=eQWRf:parsePackageJSON(V,OXlT0)local c={}d3fMjkg(c,"- Package name: ".. | |
tostring(V.name)) | |
d3fMjkg(c, | |
"- Description:\n"..tostring(V.description)) | |
d3fMjkg(c,"- Package owners: "..tostring(table.concat(V.owners,", "))) | |
d3fMjkg(c,"- Authors:\n".. | |
tostring(table.concat((function()local mReHt4h={}local I7=1;local Upw=V.authors | |
for nqBfKL=1,#Upw do | |
local gs3a=Upw[nqBfKL]mReHt4h[I7]=" - "..tostring(gs3a)I7=I7+1 end;return mReHt4h end)(),"\n"))) | |
d3fMjkg(c,"- License: "..tostring(V.license)) | |
d3fMjkg(c,"- Versions: "..tostring(PG(V.versions))..", latest: ".. | |
tostring(zIYNIXy1.version)) | |
d3fMjkg(c," - Files: "..tostring(#zIYNIXy1.files)) | |
d3fMjkg(c," - Depends: ".. | |
tostring(table.concat((function()local AkKaBC={}local OmRH8=1;local GY=zIYNIXy1.dependencies | |
for oukM79R=1,#GY do | |
local D_j=GY[oukM79R] | |
AkKaBC[OmRH8]=tostring(D_j.name).."@"..tostring(D_j.version)OmRH8=OmRH8+1 end;return AkKaBC end)()))) | |
d3fMjkg(c," - Changes:\n".. | |
tostring(V.versions[zIYNIXy1.version].changes))d3fMjkg(c,"- Stats:") | |
d3fMjkg(c," - Views: "..tostring(V.stats.views)) | |
d3fMjkg(c,"- Creation date: "..tostring(V.stats.date.created).." UTC") | |
d3fMjkg(c,"- Last updated: ".. | |
tostring(V.stats.date["last-updated"]).." UTC")return vj.print(table.concat(c,"\n"))end) | |
eQWRf.search=wjim8xCV(function(eQWRf,...)local mZPe4w=0 | |
while true do local OvZ={}local cBOpf=eQWRf.URL.."packages" | |
if...then | |
cBOpf=cBOpf.. | |
( | |
"?q=".. | |
table.concat((function(...)local XgRb={}local G3e=1;local GoP6={...} | |
for cZ_=1,#GoP6 do local NYc8=GoP6[cZ_]XgRb[G3e]='"'.. | |
NYc8:gsub("\"","")..'"'G3e=G3e+1 end;return XgRb end)(...)," "):gsub("&",""))end | |
cBOpf=cBOpf.."?offset="..tostring(mZPe4w)local KZYA5y,YoCAN7OU=y(cBOpf)if not(KZYA5y)then | |
vj.fatal("HTTP request error: "..YoCAN7OU)end;local FoP="" | |
for Dff8 in YoCAN7OU do FoP=FoP..Dff8 end;local jqtWXY=JtAjijkG:decode(FoP) | |
if not(jqtWXY)then vj.fatal("Incorrect JSON format!\n".. | |
tostring(FoP))end;OvZ=jqtWXY.data.list;for lEYwsOG9=1,#OvZ do local M=OvZ[lEYwsOG9] | |
vj.print(tostring(M.name).. | |
": "..tostring(M.short_description))end | |
if | |
#OvZ==0 and mZPe4w==0 then vj.print("No packages found.")break end | |
if jqtWXY.data.truncated and jqtWXY.data.sent+jqtWXY.data.offset< | |
jqtWXY.data.total then mZPe4w= | |
jqtWXY.data.offset+jqtWXY.data.sent else break end end end) | |
if gXu5hG.__inherited then gXu5hG.__inherited(gXu5hG,I1)end;Qlmlet.hel=I1 end | |
do local Vt95q2G;local jsPbwU=Qlmlet.default;local Wvs3rd6o={}Wvs3rd6o.__index=Wvs3rd6o | |
setmetatable(Wvs3rd6o,jsPbwU.__base) | |
Vt95q2G=setmetatable({__init=function(N,...)return Vt95q2G.__parent.__init(N,...)end,__base=Wvs3rd6o,__name="oppm",__parent=jsPbwU},{__index=function(v9mB_RUi,hX) | |
local AVU=rawget(Wvs3rd6o,hX)if AVU==nil then local I=rawget(v9mB_RUi,"__parent")if I then return I[hX]end else | |
return AVU end end,__call=function(_x5O1,...) | |
local eFI8dI3=setmetatable({},Wvs3rd6o)_x5O1.__init(eFI8dI3,...)return eFI8dI3 end})Wvs3rd6o.__class=Vt95q2G;local UdVlP=Vt95q2G | |
UdVlP.REPOS="https://raw.githubusercontent.com/OpenPrograms/openprograms.github.io/master/repos.cfg"UdVlP.PACKAGES="https://raw.githubusercontent.com/%s/master/programs.cfg" | |
UdVlP.FILES="https://raw.githubusercontent.com/%s/%s"UdVlP.DIRECTORY="https://api.github.com/repos/%s/contents/%s?ref=%s" | |
UdVlP.DEFAULT_CACHE_DIRECTORY="/var/cache/hpm/oppm" | |
UdVlP.cacheDirectory=function(UdVlP) | |
local i=_.get("oppm",{},true).get("cache_directory",UdVlP.DEFAULT_CACHE_DIRECTORY) | |
if not(N5UjTN(i))then local l6xUetCb,lOb_Sv=XxJ(i)if not(l6xUetCb)then | |
vj.fatal( | |
"Could not create the cache directory at "..tostring(i)..": "..tostring(lOb_Sv))end end;return i end | |
UdVlP.listCache=function(UdVlP)local VspvGB9V={}local LrFLp5=UdVlP:cacheDirectory() | |
local GfB7=WQ6(Wu_uIt(LrFLp5)) | |
for Iz_w1j in GfB7 do | |
if pzDMZwG(o5sms(LrFLp5,Iz_w1j))then | |
local G=WQ6(Wu_uIt(o5sms(LrFLp5,Iz_w1j))) | |
for X7YKzX in G do | |
if pzDMZwG(o5sms(LrFLp5,Iz_w1j,X7YKzX))then | |
local od0VOF=WQ6(Wu_uIt(o5sms(LrFLp5,Iz_w1j,X7YKzX))) | |
for oO6SbZ in od0VOF do local UE_vrsNx=o5sms(LrFLp5,Iz_w1j,X7YKzX,oO6SbZ) | |
if not | |
(pzDMZwG(UE_vrsNx))then local kef2zBS | |
do local ze0,ylW3uC0=io.open(UE_vrsNx,"r") | |
if not ze0 then return false, | |
"Could not open '".. | |
tostring(UE_vrsNx).."' for reading: "..tostring(ylW3uC0)end;O=ze0:read("*all")kef2zBS=RSjapQ(O)ze0:close()end;local Z=o5sms(Iz_w1j,X7YKzX) | |
d3fMjkg(VspvGB9V,{path=UE_vrsNx,repo=Z,pkg=oO6SbZ,data=kef2zBS})end end end end end end;return VspvGB9V end | |
UdVlP.fixCache=function(UdVlP)local N_G1=UdVlP:cacheDirectory() | |
local wkGNE=WQ6(Wu_uIt(N_G1)) | |
for ccK in wkGNE do local BV=true;local HnLY=o5sms(N_G1,ccK) | |
if pzDMZwG(HnLY)then | |
local cm51CH1n=WQ6(Wu_uIt(HnLY)) | |
for iWrSgT in cm51CH1n do local C=true;local YK1=o5sms(HnLY,iWrSgT) | |
if pzDMZwG(YK1)then | |
local t96Qtz=WQ6(Wu_uIt(YK1)) | |
for HjKNi in t96Qtz do local Ub9iqg=true;local r_S8HFRo=o5sms(YK1,HjKNi)if | |
not(pzDMZwG(r_S8HFRo))then Ub9iqg,C,BV=false,false,false end;if Ub9iqg then | |
dk(r_S8HFRo)end end end;if C then dk(YK1)end end end;if BV then dk(HnLY)end end;return true end | |
UdVlP.resolveDirectory=function(UdVlP,qIF4RFBv,wNbC65Ta,xOiPW) | |
local Z9j=WQ6(qTDt(UdVlP.DIRECTORY:format(qIF4RFBv,xOiPW,wNbC65Ta)))Z9j=JtAjijkG:decode(Z9j) | |
if Z9j.message then | |
return false,"Could not fetch ".. | |
tostring(qIF4RFBv)..":".. | |
tostring(wNbC65Ta).. | |
"/"..tostring(xOiPW)..": "..tostring(Z9j.message)end;local r={}local OnJ1=1 | |
for KFU0=1,#Z9j do local Pvuq=Z9j[KFU0]if Pvuq.type=="file"then | |
r[OnJ1]={name=Pvuq.name,url=Pvuq.download_url,path=Pvuq.path}OnJ1=OnJ1+1 end end;return r end | |
UdVlP.updateCache=function(UdVlP)local lOpDJ=UdVlP:cacheDirectory() | |
local YLe=WQ6(UdVlP:listCache())local lTH,JL=qTDt(UdVlP.REPOS)if not(lTH)then | |
return false,"Could not fetch ".. | |
tostring(UdVlP.REPOS)..": "..tostring(JL)end;lTH=RSjapQ(lTH)local FpU_E={} | |
for uEKPPpj_,aYO4NN in | |
pairs(lTH)do local CtG9nSQL=false | |
repeat | |
if aYO4NN.repo then | |
vj.info("Fetching '"..tostring(uEKPPpj_).."' at '".. | |
tostring(aYO4NN.repo).."' ...")local uZtK5yX,kr2CYaS | |
uZtK5yX,kr2CYaS,JL=y(UdVlP.PACKAGES:format(aYO4NN.repo)) | |
if not(uZtK5yX and kr2CYaS)then | |
vj.error("Could not fetch '".. | |
tostring(uEKPPpj_).."' at '".. | |
tostring(aYO4NN.repo).."': "..tostring(JL))CtG9nSQL=true;break end;local hXgSzEI="" | |
for uZtK5yX,B in function()return pcall(kr2CYaS)end do | |
if not uZtK5yX then | |
vj.error("Could not fetch '".. | |
tostring(uEKPPpj_).. | |
"' at '"..tostring(aYO4NN.repo).."': "..tostring(B))hXgSzEI=false;break else if not B then break end;hXgSzEI=hXgSzEI..B end end;if hXgSzEI==false then CtG9nSQL=true;break end | |
if n(hXgSzEI)then | |
vj.error("Could not fetch '".. | |
tostring(uEKPPpj_).."' at '"..tostring(aYO4NN.repo).."'")CtG9nSQL=true;break end;local AUQ;AUQ,JL=RSjapQ(hXgSzEI) | |
if not AUQ then | |
vj.error("Manifest '"..tostring(uEKPPpj_).. | |
"' at '".. | |
tostring(aYO4NN.repo).."' is malformed: "..tostring(JL))CtG9nSQL=true;break end | |
for J,coSiE in pairs(AUQ)do local wm=false | |
repeat | |
if J:match("[^A-Za-z0-9._-]")then | |
vj.error("Package name contains illegal characters: ".. | |
tostring(uEKPPpj_)..":"..tostring(J).."!")wm=true;break end | |
d3fMjkg(FpU_E,{repo=aYO4NN.repo,name=J,data=coSiE})wm=true until true;if not wm then break end end end;CtG9nSQL=true until true;if not CtG9nSQL then break end end;local JWtwnQ2t={} | |
for _O=1,#FpU_E do local smj=FpU_E[_O]local obBu,cbQlG,YZQu1DR4 | |
obBu,cbQlG,YZQu1DR4=smj.name,smj.repo,smj.data;if Oh(o5sms(cbQlG,obBu),JWtwnQ2t)then | |
vj.error("There're multiple packages under the same name: ".. | |
tostring(obBu).."!")end | |
if not | |
(N5UjTN(o5sms(lOpDJ,cbQlG)))then local EGpun;EGpun,JL=XxJ(o5sms(lOpDJ,cbQlG))if not | |
(EGpun)then | |
return false,"Could not create directory '"..tostring(o5sms(lOpDJ,cbQlG)).. | |
"': "..tostring(JL)end end;local kza;kza,JL=io.open(o5sms(lOpDJ,cbQlG,obBu),"w") | |
if not | |
(kza)then return false, | |
"Could not open '"..tostring(o5sms(lOpDJ,cbQlG,obBu)).."' for writing: ".. | |
tostring(JL)end;do | |
kza:write(pE({name=obBu,repo=cbQlG,data=YZQu1DR4}))kza:close()end;local CvGDk_2 | |
do for LNlhK,cnx_1g in pairs(YLe)do | |
if cnx_1g.repo== | |
cbQlG and cnx_1g.pkg==obBu then CvGDk_2=LNlhK;break end end end;if CvGDk_2 then table.remove(YLe,CvGDk_2)else | |
d3fMjkg(JWtwnQ2t,o5sms(cbQlG,obBu))end end;vj.print("Removing old cache files ...") | |
for eV=1,#YLe do | |
local DGQnw=YLe[eV]local yLgHuF;yLgHuF=DGQnw.path;dk(yLgHuF)end;vj.print("Fixing bad cache nodes ...") | |
UdVlP:fixCache() | |
vj.print("- "..tostring(#FpU_E).." program".. | |
tostring(tE(#FpU_E)).." cached.") | |
vj.print("- ".. | |
tostring(#JWtwnQ2t).." package".. | |
tostring(tE(#JWtwnQ2t)).." "..tostring(pX4gCR(# | |
JWtwnQ2t)).." new.") | |
vj.print("- "..tostring(#YLe).. | |
" package"..tostring(tE(#YLe)).." no longer exist".. | |
tostring(VcV0EuD(#YLe))..".")return true end | |
UdVlP.parseLocalPath=function(UdVlP,fpL,k6)if k6:sub(1,2)=="//"then return o5sms(fpL,k6:sub(3))else return | |
o5sms(fpL,"usr",k6)end end | |
UdVlP.rawInstall=function(UdVlP,m,rvNhq6v,gC,QO)if rvNhq6v==nil then rvNhq6v="/"end | |
if gC==nil then gC=false end;if QO==nil then QO=false end;local VvzMQHj=UdVlP:listCache() | |
local fSYJX={filesInstalled=0,packagesInstalled=0} | |
if QO and not N5UjTN(rvNhq6v)then local Gi,wpv1=XxJ(rvNhq6v)if not(Gi)then | |
vj.fatal( | |
"Failed to create '".. | |
tostring(rvNhq6v).."' directory for package '".. | |
tostring(m).."'! \n"..tostring(wpv1))end elseif not QO then local I9IMuWm=SJsW11k(m, | |
nil,"oppm")if I9IMuWm then | |
vj.print("'".. | |
tostring(m).."' is already installed, skipping...")return I9IMuWm,fSYJX end end;local WV | |
for a=1,#VvzMQHj do local rZ=VvzMQHj[a]local VKTNfzUf,Oms4,JfA,CPu1 | |
VKTNfzUf,Oms4,JfA,CPu1=rZ.path,rZ.pkg,rZ.repo,rZ.data;if Oms4 ==m then WV=rZ;break end end;if not(WV)then | |
vj.fatal("No such package: "..tostring(m))end;local yUho4MXRx={}local J2=WV.repo | |
for pfyhF,pglFz82w in | |
pairs(WV.data.data.files)do local RkeCL={} | |
if pfyhF:sub(1,1)==":"then | |
RkeCL=UdVlP:resolveDirectory(J2,pfyhF:sub(2,pfyhF:find("/")- | |
1,nil),pfyhF:sub(pfyhF:find("/")+1))else | |
RkeCL={{name=wVzn.name(pfyhF),path=pfyhF,url=UdVlP.FILES:format(J2,pfyhF)}}end;local m | |
for LoW_7e=1,#RkeCL do local mLgQ=RkeCL[LoW_7e]local ng,Pp_NboV | |
m,ng,Pp_NboV=mLgQ.name,mLgQ.path,mLgQ.url;local owAp3u2G=WQ6(qTDt(Pp_NboV)) | |
local OH0C=UdVlP:parseLocalPath(rvNhq6v,pglFz82w)if not(N5UjTN(OH0C))then XxJ(OH0C)end | |
do | |
local kmQkm9cr,IE97m=io.open(o5sms(OH0C,m),"w")if not kmQkm9cr then | |
vj.fatal("Could not open file for writing: "..tostring(IE97m))end | |
kmQkm9cr:write(owAp3u2G)kmQkm9cr:close()end;fSYJX.filesInstalled=fSYJX.filesInstalled+1 | |
d3fMjkg(yUho4MXRx,{name=m,url=Pp_NboV,dir=OH0C})end end;local hgrBfz0w={} | |
if WV.data.data.dependencies then for wey in pairs(WV.data.data.dependencies)do | |
d3fMjkg(hgrBfz0w,{name=wey})end end;fSYJX.packagesInstalled=fSYJX.packagesInstalled+1;return | |
{name=m,files=yUho4MXRx,dependencies=hgrBfz0w,manual=gC},fSYJX end | |
UdVlP.resolveDependencies=function(UdVlP,hThO6,zXU,HmJym2,Jjb7Am5)if zXU==nil then zXU={}end | |
if HmJym2 ==nil then HmJym2={}end;if Jjb7Am5 ==nil then Jjb7Am5={}end;local UwqY7A=UdVlP:listCache() | |
for k=1,#hThO6 | |
do local d7gPKcw=hThO6[k]local naeNp=false;for gA=1,#zXU do local r=zXU[gA] | |
if r==d7gPKcw then naeNp=true;break end end | |
if not(naeNp)then HmJym2[d7gPKcw]=true;local LWe=SJsW11k(d7gPKcw, | |
nil,"oppm") | |
if not LWe then local _3Tq | |
for Rq1hByv=1,#UwqY7A do | |
local iFk=UwqY7A[Rq1hByv]local sEFtmNgB;sEFtmNgB=iFk.pkg;if sEFtmNgB==d7gPKcw then _3Tq=iFk;break end end;if not(_3Tq)then | |
return false,"Unknown package: "..tostring(d7gPKcw)end | |
if _3Tq.data.data.dependencies then | |
for qxiez0Cn in | |
pairs(_3Tq.data.data.dependencies)do naeNp=false | |
for Ck_H=1,#zXU do local Sc=zXU[Ck_H]if Sc==qxiez0Cn then naeNp=true;break end end | |
if not(naeNp)then | |
if HmJym2[qxiez0Cn]then | |
vj.fatal("Circular dependencies detected: '".. | |
tostring(d7gPKcw).."' depends on '".. | |
tostring(qxiez0Cn).."', and '"..tostring(qxiez0Cn).. | |
"' depends on '"..tostring(d7gPKcw).."'.")end | |
UdVlP:resolveDependencies({qxiez0Cn},zXU,HmJym2,Jjb7Am5)end end end;d3fMjkg(Jjb7Am5,d7gPKcw)end;d3fMjkg(zXU,d7gPKcw)HmJym2[d7gPKcw]=nil end end;return Jjb7Am5 end | |
UdVlP.getPackageDependants=function(UdVlP,_QFw_It,WLqHf,vN)if WLqHf==nil then WLqHf={}end;if vN==nil then vN={}end | |
for BIwW6_=1,#_QFw_It | |
do local Vdfc3=_QFw_It[BIwW6_]local CzM7PG=false | |
for RKf6s5=1,#WLqHf do local tP9E_=WLqHf[RKf6s5]if | |
tP9E_.name==Vdfc3 then CzM7PG=true;break end end | |
if not(CzM7PG)then d3fMjkg(vN,{name=Vdfc3}) | |
local Y1WX=SJsW11k(Vdfc3,nil,"oppm") | |
if Y1WX then d3fMjkg(WLqHf,{name=Vdfc3,manifest=Y1WX}) | |
local G06Z2=WQ6(Wu_uIt(o5sms(hw18,"oppm"))) | |
for K in G06Z2 do Y1WX=WQ6(SJsW11k(K,nil,"oppm")) | |
local tQx9TV=Y1WX.dependencies | |
for FL7g2o=1,#tQx9TV do local dkh7Tt9=tQx9TV[FL7g2o] | |
if dkh7Tt9.name==Vdfc3 then CzM7PG=false | |
for XiNd_H=1,#WLqHf do | |
local Q_c4px86=WLqHf[XiNd_H]if Q_c4px86.name==K then CzM7PG=true;break end end | |
if not CzM7PG then | |
for _F6VYt=1,#vN do local ITv3PH1i=vN[_F6VYt]if ITv3PH1i.name==K then | |
vj.fatal("Circular dependencies detected: ".. | |
tostring(K))end end;UdVlP:getPackageDependants({K},WLqHf,vN)end end end end else | |
vj.fatal("Package ".. | |
tostring(Vdfc3).." is referenced as a dependant of another package, however, this package isn't installed.")end;vN[#vN]=nil end end;return WLqHf end | |
UdVlP.whatDependsOn=function(UdVlP,_5fF)local OUQqQp=WQ6(SJsW11k(_5fF,nil,"oppm")) | |
local OyOfzTWn={}local rx=WQ6(Wu_uIt(o5sms(hw18,"oppm"))) | |
for ijvSrZA1 in rx do OUQqQp=WQ6(SJsW11k(ijvSrZA1, | |
nil,"oppm")) | |
local STNuSN6=OUQqQp.dependencies | |
for PYOeGnAZ=1,#STNuSN6 do local s10ar5XH=STNuSN6[PYOeGnAZ]if s10ar5XH.name==_5fF then | |
d3fMjkg(OyOfzTWn,ijvSrZA1)end end end;return OyOfzTWn end | |
UdVlP.install=wjim8xCV(function(UdVlP,...)local YoKhvIs={...}local I2ipE=w.r or w.reinstall | |
local qS730I=w.s or w.save | |
local PYEbnua=WQ6(UdVlP:resolveDependencies(YoKhvIs)) | |
Ta({install=(function()local AF={}local shIHW=1 | |
for H5=1,#PYEbnua do local HYY=PYEbnua[H5]if | |
not I2ipE or not Oh(HYY,YoKhvIs)then AF[shIHW]=HYY;shIHW=shIHW+1 end end;return AF end)(),reinstall= | |
I2ipE and | |
(function()local C3={}local SkCMMH=1 | |
for kvvs=1,#PYEbnua do local _yTx3S94=PYEbnua[kvvs]if Oh(_yTx3S94,YoKhvIs)then | |
C3[SkCMMH]=_yTx3S94;SkCMMH=SkCMMH+1 end end;return C3 end)()or nil})local Um4ZYiT={filesInstalled=0,packagesInstalled=0} | |
if I2ipE then local Mm | |
do local g524={}local WUdVeYc=1 | |
for lHep6wo=1,#YoKhvIs | |
do local BKZsJ=YoKhvIs[lHep6wo] | |
g524[WUdVeYc]=WQ6(SJsW11k(BKZsJ,nil,"oppm"))WUdVeYc=WUdVeYc+1 end;Mm=g524 end;UdVlP:_remove(Mm,true,false)end | |
for Sw=1,#PYEbnua do local W67mm9p6=PYEbnua[Sw]vj.print("Installing '".. | |
tostring(W67mm9p6).."'...") | |
local oBxdTi6u;if qS730I then oBxdTi6u="./"..tostring(W67mm9p6).."/"else | |
oBxdTi6u="/"end | |
local T7hLe5j,I_=UdVlP:rawInstall(W67mm9p6,oBxdTi6u,Oh(W67mm9p6,YoKhvIs),qS730I) | |
Um4ZYiT.filesInstalled=Um4ZYiT.filesInstalled+I_.filesInstalled | |
Um4ZYiT.packagesInstalled=Um4ZYiT.packagesInstalled+I_.packagesInstalled | |
if Um4ZYiT.packagesInstalled~=0 then local J2Jin,Rvg=BaX(T7hLe5j,"oppm") | |
if J2Jin then | |
vj.info( | |
"Saved the manifest of '"..tostring(T7hLe5j.name).."'.")else | |
vj.fatal("Couldn't save the manifest of '"..tostring(T7hLe5j.name).. | |
"': "..tostring(Rvg)..".")end end end | |
vj.print("- ".. | |
tostring(Um4ZYiT.packagesInstalled).." package".. | |
tostring(tE(Um4ZYiT.packagesInstalled)).." installed.")return | |
vj.print("- ".. | |
tostring(Um4ZYiT.filesInstalled).." file".. | |
tostring(tE(Um4ZYiT.filesInstalled)).." installed.")end) | |
UdVlP.remove=wjim8xCV(function(UdVlP,...)local HpdA={...}local DsAJbW={} | |
for AXfX=1,#HpdA do local btcUUhB=HpdA[AXfX] | |
local iw0S=WQ6(SJsW11k(btcUUhB,nil,"oppm"))d3fMjkg(DsAJbW,iw0S)end;return UdVlP:_remove(DsAJbW,false)end) | |
UdVlP._remove=function(UdVlP,Tjg,n2srE7H,Rf)if n2srE7H==nil then n2srE7H=false end | |
if Rf==nil then Rf=true end;local X9ZjrTz | |
if not | |
_.get("oppm",{},true).get("remove_dependants",true)or not Rf then | |
do local tYFIuD={} | |
local Ht5Ge=1;for l=1,#Tjg do local IO=Tjg[l]tYFIuD[Ht5Ge]={name=IO.name,manifest=IO} | |
Ht5Ge=Ht5Ge+1 end;X9ZjrTz=tYFIuD end else | |
X9ZjrTz=UdVlP:getPackageDependants((function()local YDJY={}local t=1;for Rdi8NIft=1,#Tjg do local J0uTkQ9=Tjg[Rdi8NIft] | |
YDJY[t]=J0uTkQ9.name;t=t+1 end;return YDJY end)())end | |
if not(n2srE7H)then | |
Ta({remove=(function()local sd6k={}local a=1;for lK7=1,#X9ZjrTz do local KWMxs7a=X9ZjrTz[lK7] | |
sd6k[a]=tostring(KWMxs7a.name)a=a+1 end;return sd6k end)()})end | |
for T=1,#X9ZjrTz do local LBIp4=X9ZjrTz[T] | |
vj.print("Removing '".. | |
tostring(LBIp4.manifest.name).."' ...") | |
WQ6(Vt95q2G.__parent.remove(UdVlP,LBIp4.manifest,"oppm"))end;return true end | |
UdVlP.cache=wjim8xCV(function(UdVlP,A5,...)local PV168s0f=A5 | |
if"update"==PV168s0f then | |
vj.print("Updating OpenPrograms program cache ...")WQ6(UdVlP:updateCache())return vj.print("Done.")elseif | |
"fix"==PV168s0f then | |
vj.print("Fixing OpenPrograms program cache ...")WQ6(UdVlP:fixCache())return vj.print("Done.")else | |
vj.error("Unknown command.")return vj.print("Usage: hpm oppm:cache {update|fix}")end end) | |
UdVlP.autoremove=wjim8xCV(function(UdVlP)local bjK={}local Us1Xh={} | |
local rs59=WQ6(Wu_uIt(o5sms(hw18,"oppm"))) | |
for R in rs59 do local rGa2MaGH=WQ6(SJsW11k(R,nil,"oppm")) | |
if not | |
(rGa2MaGH.manual)then local i6=UdVlP:getPackageDependants(R)if#i6 ==1 then | |
d3fMjkg(bjK,R)d3fMjkg(Us1Xh,R)end end end | |
while true do local u33wPQT=false | |
rs59=WQ6(Wu_uIt(o5sms(hw18,"oppm"))) | |
for aNrMnPZ in rs59 do | |
if not(Oh(aNrMnPZ,bjK))then | |
local fC=WQ6(SJsW11k(aNrMnPZ,nil,"oppm")) | |
if not(fC.manual)then | |
local Kl=UdVlP:getPackageDependants(aNrMnPZ)table.remove(Kl,1) | |
if | |
O((function()local EmJGBwA={}local _E3=1;for j3=1,#Kl do local f=Kl[j3] | |
EmJGBwA[_E3]=Oh(f.name,bjK)_E3=_E3+1 end;return EmJGBwA end)())then | |
for jy=1,#Kl do local Ifev2bUE=Kl[jy]local ZY,KCpJbzHT=Oh(Ifev2bUE.name,Us1Xh)if KCpJbzHT then | |
table.remove(Us1Xh,KCpJbzHT)end end;d3fMjkg(bjK,aNrMnPZ)d3fMjkg(Us1Xh,aNrMnPZ)u33wPQT=true end end end end;if not(u33wPQT)then break end end | |
Ta({remove=(function() | |
if#bjK>0 then local g={}local dQl0xvy2=1;for hX=1,#bjK do local wYTrvPn=bjK[hX] | |
g[dQl0xvy2]="oppm:"..tostring(wYTrvPn)dQl0xvy2=dQl0xvy2+1 end | |
return g else return nil end end)()})for pB6K=1,#Us1Xh do local YV=Us1Xh[pB6K] | |
UdVlP:_remove({WQ6(SJsW11k(YV,nil,"oppm"))},false)end;vj.print("Done.") | |
return true end) | |
UdVlP.search=wjim8xCV(function(UdVlP,...)local zPm=UdVlP:listCache()local JmEyZ5={} | |
if...then | |
for FGvy=1,#zPm do | |
local KpnA=zPm[FGvy]local j_F9c;j_F9c=KpnA.data;local q=j_F9c.data;local b7G0ciz={...} | |
for rF2te=#b7G0ciz,1,-1 do | |
local KG_EjN=b7G0ciz[rF2te] | |
if j_F9c.name:find(KG_EjN)then table.remove(b7G0ciz,rF2te)break end;if q.name and q.name:find(KG_EjN)then | |
table.remove(b7G0ciz,rF2te)break end | |
if q.description and | |
q.description:find(KG_EjN)then table.remove(b7G0ciz,rF2te)break end;if q.note and q.note:find(KG_EjN)then | |
table.remove(b7G0ciz,rF2te)break end end;if#b7G0ciz==0 then d3fMjkg(JmEyZ5,j_F9c)end end else | |
do local aIrjXeB={}local sZdri=1;for pT=1,#zPm do local XgkgIR9=zPm[pT]aIrjXeB[sZdri]=XgkgIR9.data;sZdri= | |
sZdri+1 end;JmEyZ5=aIrjXeB end end | |
for sm2=1,#JmEyZ5 do local cz=JmEyZ5[sm2] | |
vj.print(tostring(cz.name).." - ".. | |
tostring(cz.data.name or cz.name)..": "..tostring(cz.data.description))end end) | |
if jsPbwU.__inherited then jsPbwU.__inherited(jsPbwU,Vt95q2G)end;Qlmlet.oppm=Vt95q2G end;local unArcvQl | |
unArcvQl=function()local pSL=WQ6(Wu_uIt(hw18))n=true | |
for ifrP9 in pSL do | |
local Iynmp=wVzn.name(ifrP9) | |
if pzDMZwG(o5sms(hw18,Iynmp))then | |
local PFvHX=WQ6(Wu_uIt(o5sms(hw18,Iynmp))) | |
for sP in PFvHX do | |
if not(pzDMZwG(o5sms(hw18,Iynmp,sP)))then local Y=WQ6(SJsW11k(sP, | |
nil,Iynmp)) | |
vj.print(Iynmp.. | |
":"..sP.. (Y.version and | |
" @ "..Y.version or""))n=false end end end end | |
if n then return vj.print("No packages installed.")end end;local h6Ub7U | |
h6Ub7U=function(...)sgeP,w=LfEJbh_(...)if#sgeP<1 then return ykRppH()end end;local Gm | |
Gm=function()local QHxdp58D=sgeP[1] | |
if"list"==QHxdp58D then return unArcvQl()elseif"help"==QHxdp58D then return | |
ykRppH()else | |
do local efdknL=M6ilzGJ(sgeP[1]) | |
if efdknL then return | |
efdknL(el((function()local YUdva={}local x8FBS=1;for LGBr=2,#sgeP do | |
local M=sgeP[LGBr]YUdva[x8FBS]=M;x8FBS=x8FBS+1 end | |
return YUdva end)()))end end end end;h6Ub7U(...)WQ6(E())cR6rJlAl()Gm()return nvCiFt7r |
local s=load([===[ | |
local rA5U=20160728.17 | |
local Uc06="-[ JSON.lua package by Jeffrey Friedl (http://regex.info/blog/lua/json) version 20160728.17 ]-"local lcBL={VERSION=rA5U,AUTHOR_NOTE=Uc06}local DHPxI=" " | |
local dx={pretty=true,align_keys=false,indent=DHPxI} | |
local RRuSHnxf={__tostring=function()return"JSON array"end}RRuSHnxf.__index=RRuSHnxf | |
local mcYOuT={__tostring=function()return"JSON object"end}mcYOuT.__index=mcYOuT;function lcBL:newArray(iXxD6s) | |
return setmetatable(iXxD6s or{},RRuSHnxf)end;function lcBL:newObject(oiY)return | |
setmetatable(oiY or{},mcYOuT)end;local function Rr(FsYIVlkf) | |
return | |
type(FsYIVlkf)=='number'and FsYIVlkf or FsYIVlkf.N end | |
local scRP0={__index=isNumber,__tostring=function(HLXS0Q_)return HLXS0Q_.S end,__unm=function(Kw)return | |
Rr(Kw)end,__concat=function(nvaIsNv7,vDnoL55) | |
return tostring(nvaIsNv7)..tostring(vDnoL55)end,__add=function(xlAK,zr1y)return Rr(xlAK)+Rr(zr1y)end,__sub=function(Hs,jk)return | |
Rr(Hs)-Rr(jk)end,__mul=function(qzSFyIO,Z65) | |
return Rr(qzSFyIO)*Rr(Z65)end,__div=function(umyCNfj,FT)return Rr(umyCNfj)/Rr(FT)end,__mod=function(YVLXYq,bJfct)return | |
Rr(YVLXYq)%Rr(bJfct)end,__pow=function(OhuFpq_N,Dzg)return | |
Rr(OhuFpq_N)^Rr(Dzg)end,__lt=function(_4O,C)return Rr(_4O)<Rr(C)end,__eq=function(fLI2zRe,_Fr2YU)return | |
Rr(fLI2zRe)==Rr(_Fr2YU)end,__le=function(Xfn,U)return | |
Rr(Xfn)<=Rr(U)end} | |
function lcBL:asNumber(Ebsw) | |
if getmetatable(Ebsw)==scRP0 then return Ebsw elseif | |
type(Ebsw)=='table'and | |
type(Ebsw.S)=='string'and type(Ebsw.N)=='number'then return setmetatable(Ebsw,scRP0)else | |
local UlikV={S=tostring(Ebsw),N=tonumber(Ebsw)}return setmetatable(UlikV,scRP0)end end | |
local function AI0R2TQ6(JtAjijkG) | |
if JtAjijkG<=127 then return string.char(JtAjijkG)elseif JtAjijkG<=2047 then | |
local s=math.floor(JtAjijkG/0x40)local YAtG_LV3=JtAjijkG- (0x40*s)return | |
string.char(0xC0+s,0x80+YAtG_LV3)elseif JtAjijkG<=65535 then | |
local LfEJbh_=math.floor(JtAjijkG/0x1000)local JD=JtAjijkG-0x1000*LfEJbh_ | |
local u=math.floor(JD/0x40)local pzDMZwG=JD-0x40*u;LfEJbh_=0xE0+LfEJbh_;u=0x80+u | |
pzDMZwG=0x80+pzDMZwG | |
if | |
(LfEJbh_==0xE0 and u<0xA0)or | |
(LfEJbh_==0xED and u>0x9F)or(LfEJbh_==0xF0 and u<0x90)or(LfEJbh_==0xF4 and u>0x8F)then return"?"else return string.char(LfEJbh_,u,pzDMZwG)end else local XPoQB=math.floor(JtAjijkG/0x40000) | |
local XxJ=JtAjijkG-0x40000*XPoQB;local o5sms=math.floor(XxJ/0x1000) | |
XxJ=XxJ-0x1000*o5sms;local JQi1jg=math.floor(XxJ/0x40)local wVzn=XxJ-0x40*JQi1jg | |
return string.char( | |
0xF0+XPoQB,0x80+o5sms,0x80+JQi1jg,0x80+wVzn)end end | |
function lcBL:onDecodeError(pE,RSjapQ,QJf,zC)if RSjapQ then | |
if QJf then | |
pE=string.format("%s at char %d of: %s",pE,QJf,RSjapQ)else pE=string.format("%s: %s",pE,RSjapQ)end end | |
if zC~=nil then pE=pE.." (".. | |
lcBL:encode(zC)..")"end | |
if self.assert then self.assert(false,pE)else assert(false,pE)end end;lcBL.onDecodeOfNilError=lcBL.onDecodeError | |
lcBL.onDecodeOfHTMLError=lcBL.onDecodeError | |
function lcBL:onEncodeError(pfZ3SPy_,pDNa2ox6) | |
if pDNa2ox6 ~=nil then pfZ3SPy_=pfZ3SPy_.. | |
" ("..lcBL:encode(pDNa2ox6)..")"end;if self.assert then self.assert(false,pfZ3SPy_)else | |
assert(false,pfZ3SPy_)end end | |
local function yA(Do6yo7nm,y06X3k,ivnJjrA,d3fMjkg) | |
local el=y06X3k:match('^-?[1-9]%d*',ivnJjrA)or y06X3k:match("^-?0",ivnJjrA)if not el then | |
Do6yo7nm:onDecodeError("expected number",y06X3k,ivnJjrA,d3fMjkg.etc)end | |
local Wu_uIt=ivnJjrA+el:len()local w=y06X3k:match('^%.%d+',Wu_uIt)or""Wu_uIt=Wu_uIt+ | |
w:len() | |
local sgeP=y06X3k:match('^[eE][-+]?%d+',Wu_uIt)or""Wu_uIt=Wu_uIt+sgeP:len()local CM=el..w..sgeP;if | |
d3fMjkg.decodeNumbersAsObjects then return lcBL:asNumber(CM),Wu_uIt end | |
if | |
( | |
d3fMjkg.decodeIntegerStringificationLength and(el:len()>=d3fMjkg.decodeIntegerStringificationLength or | |
sgeP:len()>0))or | |
(d3fMjkg.decodeDecimalStringificationLength and | |
( | |
w:len()>=d3fMjkg.decodeDecimalStringificationLength or sgeP:len()>0))then return CM,Wu_uIt end;local Qlmlet=tonumber(CM)if not Qlmlet then | |
Do6yo7nm:onDecodeError("bad number",y06X3k,ivnJjrA,d3fMjkg.etc)end;return Qlmlet,Wu_uIt end | |
local function XmVolesU(_,RkGFh6,hw18,nvCiFt7r)if RkGFh6:sub(hw18,hw18)~='"'then | |
_:onDecodeError("expected string's opening quote",RkGFh6,hw18,nvCiFt7r.etc)end;local xSebv5Jc=hw18+1 | |
local mMp=RkGFh6:len()local rDtVf="" | |
while xSebv5Jc<=mMp do local vj=RkGFh6:sub(xSebv5Jc,xSebv5Jc)if | |
vj=='"'then return rDtVf,xSebv5Jc+1 end | |
if vj~='\\'then rDtVf=rDtVf..vj;xSebv5Jc= | |
xSebv5Jc+1 elseif RkGFh6:match('^\\b',xSebv5Jc)then rDtVf=rDtVf.."\b"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\f',xSebv5Jc)then rDtVf=rDtVf.."\f"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\n',xSebv5Jc)then rDtVf=rDtVf.."\n"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\r',xSebv5Jc)then rDtVf=rDtVf.."\r"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\t',xSebv5Jc)then rDtVf=rDtVf.."\t"xSebv5Jc= | |
xSebv5Jc+2 else | |
local z=RkGFh6:match('^\\u([0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])',xSebv5Jc) | |
if z then xSebv5Jc=xSebv5Jc+6;local Zg=tonumber(z,16) | |
if | |
Zg>=0xD800 and Zg<=0xDBFF then | |
local ykRppH=RkGFh6:match('^\\u([dD][cdefCDEF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])',xSebv5Jc) | |
if ykRppH then xSebv5Jc=xSebv5Jc+6;Zg=0x2400+ (Zg-0xD800)*0x400+ | |
tonumber(ykRppH,16)else end end;rDtVf=rDtVf..AI0R2TQ6(Zg)else rDtVf=rDtVf.. | |
RkGFh6:match('^\\(.)',xSebv5Jc)xSebv5Jc=xSebv5Jc+2 end end end | |
_:onDecodeError("unclosed string",RkGFh6,hw18,nvCiFt7r.etc)end | |
local function eZ0l3ch(WQ6,y36Aetn)local iPL3B4cr,GI2hz6SK=WQ6:find("^[ \n\r\t]+",y36Aetn)if GI2hz6SK then | |
return GI2hz6SK+1 else return y36Aetn end end;local W_63_9 | |
local function h9dyA_4T(Oh,PG,n,O)if PG:sub(n,n)~='{'then | |
Oh:onDecodeError("expected '{'",PG,n,O.etc)end;local N5UjTN=eZ0l3ch(PG,n+1)local qLH5=Oh.strictTypes and | |
Oh:newObject{}or{}if | |
PG:sub(N5UjTN,N5UjTN)=='}'then return qLH5,N5UjTN+1 end | |
local tE=PG:len() | |
while N5UjTN<=tE do local VcV0EuD,pX4gCR=XmVolesU(Oh,PG,N5UjTN,O) | |
N5UjTN=eZ0l3ch(PG,pX4gCR)if PG:sub(N5UjTN,N5UjTN)~=':'then | |
Oh:onDecodeError("expected colon",PG,N5UjTN,O.etc)end | |
N5UjTN=eZ0l3ch(PG,N5UjTN+1)local gad4ZcL,pX4gCR=W_63_9(Oh,PG,N5UjTN,O)qLH5[VcV0EuD]=gad4ZcL | |
N5UjTN=eZ0l3ch(PG,pX4gCR)local dk=PG:sub(N5UjTN,N5UjTN) | |
if dk=='}'then return qLH5,N5UjTN+1 end;if PG:sub(N5UjTN,N5UjTN)~=','then | |
Oh:onDecodeError("expected comma or '}'",PG,N5UjTN,O.etc)end | |
N5UjTN=eZ0l3ch(PG,N5UjTN+1)end;Oh:onDecodeError("unclosed '{'",PG,n,O.etc)end | |
local function oh(E,OO,y,cR6rJlAl)if OO:sub(y,y)~='['then | |
E:onDecodeError("expected '['",OO,y,cR6rJlAl.etc)end;local M6ilzGJ=eZ0l3ch(OO,y+1)local iW6CD=E.strictTypes and | |
E:newArray{}or{}if | |
OO:sub(M6ilzGJ,M6ilzGJ)==']'then return iW6CD,M6ilzGJ+1 end | |
local wZdg=1;local BaX=OO:len() | |
while M6ilzGJ<=BaX do | |
local SJsW11k,Ki1HJT=W_63_9(E,OO,M6ilzGJ,cR6rJlAl)iW6CD[wZdg]=SJsW11k;wZdg=wZdg+1;M6ilzGJ=eZ0l3ch(OO,Ki1HJT) | |
local wjim8xCV=OO:sub(M6ilzGJ,M6ilzGJ)if wjim8xCV==']'then return iW6CD,M6ilzGJ+1 end;if | |
OO:sub(M6ilzGJ,M6ilzGJ)~=','then | |
E:onDecodeError("expected comma or '['",OO,M6ilzGJ,cR6rJlAl.etc)end | |
M6ilzGJ=eZ0l3ch(OO,M6ilzGJ+1)end | |
E:onDecodeError("unclosed '['",OO,y,cR6rJlAl.etc)end | |
W_63_9=function(E,QLam,qTDt,v)qTDt=eZ0l3ch(QLam,qTDt) | |
if qTDt>QLam:len()then E:onDecodeError("unexpected end of string",QLam, | |
nil,v.etc)end | |
if QLam:find('^"',qTDt)then return XmVolesU(E,QLam,qTDt,v.etc)elseif | |
QLam:find('^[-0123456789 ]',qTDt)then return yA(E,QLam,qTDt,v)elseif QLam:find('^%{',qTDt)then | |
return h9dyA_4T(E,QLam,qTDt,v)elseif QLam:find('^%[',qTDt)then return oh(E,QLam,qTDt,v)elseif QLam:find('^true',qTDt)then return true, | |
qTDt+4 elseif QLam:find('^false',qTDt)then return false,qTDt+5 elseif | |
QLam:find('^null',qTDt)then return nil,qTDt+4 else | |
E:onDecodeError("can't parse JSON",QLam,qTDt,v.etc)end end | |
function lcBL:decode(Ta,u,nArcvQl)if type(nArcvQl)~='table'then nArcvQl={}end;if u~=nil then | |
nArcvQl.etc=u end;if | |
type(self)~='table'or self.__index~=lcBL then | |
lcBL:onDecodeError("JSON:decode must be called in method format",nil,nil,nArcvQl.etc)end | |
if Ta==nil then | |
self:onDecodeOfNilError(string.format("nil passed to JSON:decode()"), | |
nil,nil,nArcvQl.etc)elseif type(Ta)~='string'then | |
self:onDecodeError(string.format("expected string argument to JSON:decode(), got %s",type(Ta)), | |
nil,nil,nArcvQl.etc)end;if Ta:match('^%s*$')then return nil end;if Ta:match('^%s*<')then | |
self:onDecodeOfHTMLError(string.format("html passed to JSON:decode()"),Ta, | |
nil,nArcvQl.etc)end | |
if | |
Ta:sub(1,1):byte()==0 or | |
(Ta:len()>=2 and Ta:sub(2,2):byte()==0)then | |
self:onDecodeError("JSON package groks only UTF-8, sorry",Ta,nil,nArcvQl.etc)end;if nArcvQl.decodeNumbersAsObjects==nil then | |
nArcvQl.decodeNumbersAsObjects=self.decodeNumbersAsObjects end;if | |
nArcvQl.decodeIntegerStringificationLength==nil then | |
nArcvQl.decodeIntegerStringificationLength=self.decodeIntegerStringificationLength end;if | |
nArcvQl.decodeDecimalStringificationLength==nil then | |
nArcvQl.decodeDecimalStringificationLength=self.decodeDecimalStringificationLength end | |
local h6Ub7U,Gm=pcall(W_63_9,self,Ta,1,nArcvQl)if h6Ub7U then return Gm else | |
if self.assert then self.assert(false,Gm)else assert(false,Gm)end;return nil,Gm end end | |
local function DZXGTh(YKA7cU) | |
if YKA7cU=="\n"then return"\\n"elseif YKA7cU=="\r"then return"\\r"elseif YKA7cU=="\t"then return"\\t"elseif YKA7cU=="\b"then | |
return"\\b"elseif YKA7cU=="\f"then return"\\f"elseif YKA7cU=='"'then return'\\"'elseif YKA7cU=='\\'then return'\\\\'else return | |
string.format("\\u%04x",YKA7cU:byte())end end | |
local Su9Koz='['..'"'.. | |
'%\\'..'%z'..'\001'..'-'..'\031'..']'local Uk7e=AI0R2TQ6(0x2028)local KwQCk_G=AI0R2TQ6(0x2029) | |
local function ptZa(mCsewfX,yY) | |
local Xf=mCsewfX:gsub(Su9Koz,DZXGTh)if yY.stringsAreUtf8 then | |
Xf=Xf:gsub(Uk7e,'\\u2028'):gsub(KwQCk_G,'\\u2029')end;return'"'..Xf..'"'end | |
local function PEqsd(UlFdiZ7v,U,wFeA)local JQgI={}local N={}local fs52REi=false;local PUNkgaiM | |
for X in pairs(U)do | |
if type(X)=='string'then | |
table.insert(JQgI,X)elseif type(X)=='number'then table.insert(N,X) | |
if X<=0 or X>=math.huge then | |
fs52REi=true elseif not PUNkgaiM or X>PUNkgaiM then PUNkgaiM=X end else | |
UlFdiZ7v:onEncodeError("can't encode table with a key of type "..type(X),wFeA)end end | |
if#JQgI==0 and not fs52REi then | |
if#N>0 then return nil,PUNkgaiM elseif | |
tostring(U)=="JSON array"then return nil elseif tostring(U)=="JSON object"then return{}else return nil end end;table.sort(JQgI)local s6FbB | |
if#N>0 then if UlFdiZ7v.noKeyConversion then | |
UlFdiZ7v:onEncodeError("a table with both numeric and string keys could be an object or array; aborting",wFeA)end | |
s6FbB={}for dc61,aguhyl in pairs(U)do s6FbB[dc61]=aguhyl end | |
table.sort(N) | |
for p,gOPDv in ipairs(N)do local aSdZU3=tostring(gOPDv) | |
if s6FbB[aSdZU3]==nil then | |
table.insert(JQgI,aSdZU3)s6FbB[aSdZU3]=U[gOPDv]else | |
UlFdiZ7v:onEncodeError( | |
"conflict converting table with mixed-type keys into a JSON object: key "..gOPDv.." exists both as a string and a number.",wFeA)end end end;return JQgI,nil,s6FbB end;local iSj | |
function iSj(YKDL,oFyb6OLp,oGdh_mv,WjvvK,TASVwBgU,KjUncMB,XkT) | |
if oFyb6OLp==nil or | |
(not XkT and TASVwBgU and TASVwBgU.null and oFyb6OLp== | |
TASVwBgU.null)then return'null'elseif | |
type(oFyb6OLp)=='string'then return ptZa(oFyb6OLp,TASVwBgU)elseif type(oFyb6OLp)=='number'then | |
if | |
oFyb6OLp~=oFyb6OLp then return"null"elseif oFyb6OLp>=math.huge then return"1e+9999"elseif oFyb6OLp<=-math.huge then | |
return"-1e+9999"else return tostring(oFyb6OLp)end elseif type(oFyb6OLp)=='boolean'then return tostring(oFyb6OLp)elseif type(oFyb6OLp)~= | |
'table'then | |
YKDL:onEncodeError("can't convert "..type(oFyb6OLp).." to JSON",WjvvK)elseif getmetatable(oFyb6OLp)==scRP0 then return tostring(oFyb6OLp)else | |
local c3dr=oFyb6OLp;if type(TASVwBgU)~='table'then TASVwBgU={}end;if type(KjUncMB)~= | |
'string'then KjUncMB=""end | |
if oGdh_mv[c3dr]then | |
YKDL:onEncodeError("table ".. | |
tostring(c3dr).." is a child of itself",WjvvK)else oGdh_mv[c3dr]=true end;local NGH;local tIc,MD2O,HQ=PEqsd(YKDL,c3dr,WjvvK) | |
if MD2O then local cng={}for lE=1,MD2O do | |
table.insert(cng,iSj(YKDL,c3dr[lE],oGdh_mv,WjvvK,TASVwBgU,KjUncMB))end | |
if TASVwBgU.pretty then NGH="[ ".. | |
table.concat(cng,", ").." ]"else NGH="[".. | |
table.concat(cng,",").."]"end elseif tIc then local nI2F0id=HQ or c3dr | |
if TASVwBgU.pretty then local N4aMD_P={}local pCi=0 | |
for lNOqUk8,YAnZNei in ipairs(tIc)do | |
local h8YWR44E=iSj(YKDL,tostring(YAnZNei),oGdh_mv,WjvvK,TASVwBgU,KjUncMB,true) | |
if TASVwBgU.align_keys then pCi=math.max(pCi,#h8YWR44E)end;table.insert(N4aMD_P,h8YWR44E)end | |
local NzeoQJ=KjUncMB..tostring(TASVwBgU.indent or"") | |
local AwGfFV=NzeoQJ..string.rep(" ",pCi).. | |
(TASVwBgU.align_keys and" "or"") | |
local wCRY="%s%"..string.format("%d",pCi).."s: %s"local d0uKSVw1={} | |
for VF,fTrMe in ipairs(tIc)do | |
local ypDndT8=iSj(YKDL,nI2F0id[fTrMe],oGdh_mv,WjvvK,TASVwBgU,AwGfFV) | |
table.insert(d0uKSVw1,string.format(wCRY,NzeoQJ,N4aMD_P[VF],ypDndT8))end;NGH="{\n".. | |
table.concat(d0uKSVw1,",\n").."\n"..KjUncMB.."}"else local MV65={} | |
for Y3D66Ym9,q in | |
ipairs(tIc)do | |
local PhJ=iSj(YKDL,nI2F0id[q],oGdh_mv,WjvvK,TASVwBgU,KjUncMB) | |
local h=iSj(YKDL,tostring(q),oGdh_mv,WjvvK,TASVwBgU,KjUncMB,true) | |
table.insert(MV65,string.format("%s:%s",h,PhJ))end;NGH="{"..table.concat(MV65,",").."}"end else NGH="[]"end;oGdh_mv[c3dr]=false;return NGH end end | |
function lcBL:encode(j2K,r8hgwQ,_6U)if type(self)~='table'or self.__index~=lcBL then | |
lcBL:onEncodeError("JSON:encode must be called in method format",r8hgwQ)end;if | |
type(_6U)~='table'then _6U={}end;return iSj(self,j2K,{},r8hgwQ,_6U)end | |
function lcBL:encode_pretty(GLSzBQs,c,xg)if type(self)~='table'or self.__index~=lcBL then | |
lcBL:onEncodeError("JSON:encode_pretty must be called in method format",c)end;if | |
type(xg)~='table'then xg=dx end;return iSj(self,GLSzBQs,{},c,xg)end;function lcBL.__tostring()return"JSON encode/decode package"end | |
lcBL.__index=lcBL | |
function lcBL:new(Id2KoP_G)local Y2or={}if Id2KoP_G then | |
for zN8ASHV5,iju in pairs(Id2KoP_G)do Y2or[zN8ASHV5]=iju end end | |
return setmetatable(Y2or,lcBL)end;return lcBL:new() | |
]===])() | |
local YAtG_LV3=(function() | |
local yY=[[ Copyright (c) The python-semanticversion project | |
All rights reserved. | |
Redistribution and use in source and binary forms, with or without | |
modification, are permitted provided that the following conditions are met: | |
1. Redistributions of source code must retain the above copyright notice, this | |
list of conditions and the following disclaimer. | |
2. Redistributions in binary form must reproduce the above copyright notice, | |
this list of conditions and the following disclaimer in the documentation | |
and/or other materials provided with the distribution. | |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | |
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
]] | |
yY=[[ The use of the library is similar to the original one, | |
check the documentation here: https://python-semanticversion.readthedocs.io/en/latest/ | |
]]local Xf,UlFdiZ7v,U;do local aSdZU3=table | |
Xf,UlFdiZ7v,U=aSdZU3.concat,aSdZU3.insert,aSdZU3.unpack end;local wFeA | |
wFeA=function(YKDL) | |
do local oFyb6OLp=tonumber(YKDL)if | |
oFyb6OLp then return oFyb6OLp,true else return YKDL,false end end end;local JQgI | |
JQgI=function(oGdh_mv)return oGdh_mv and oGdh_mv[1]=='0'and | |
tonumber(oGdh_mv and oGdh_mv~='0')end;local N | |
N=function(WjvvK,TASVwBgU)if WjvvK==TASVwBgU then return 0 end | |
if WjvvK>TASVwBgU then return 1 end;if WjvvK<TASVwBgU then return-1 end end;local fs52REi | |
fs52REi=function(KjUncMB,XkT)local c3dr,NGH=wFeA(KjUncMB)local tIc,MD2O=wFeA(XkT) | |
if NGH and MD2O then | |
return N(c3dr,tIc)elseif NGH then return-1 elseif MD2O then return 1 else return N(c3dr,tIc)end end;local PUNkgaiM | |
PUNkgaiM=function(HQ,cng)local lE;do local nI2F0id={}for N4aMD_P=1,#HQ do if cng[N4aMD_P]then | |
nI2F0id[HQ[N4aMD_P]]=cng[N4aMD_P]end end | |
lE=nI2F0id end | |
for pCi,NzeoQJ in pairs(lE)do | |
local AwGfFV=fs52REi(pCi,NzeoQJ)if AwGfFV~=0 then return AwGfFV end end;return N(#HQ,#cng)end;local s6FbB | |
do local wCRY | |
local d0uKSVw1={_coerce=function(YAnZNei,h8YWR44E,VF)if VF==nil then VF=false end | |
if h8YWR44E==nil and VF then return h8YWR44E end;return tonumber(h8YWR44E)end,next_major=function(fTrMe) | |
if | |
fTrMe.prerelease and fTrMe.minor==0 and fTrMe.patch==0 then | |
return | |
s6FbB(Xf((function()local ypDndT8={}local MV65=1 | |
local Y3D66Ym9={fTrMe.major,fTrMe.minor,fTrMe.patch}for q=1,#Y3D66Ym9 do local PhJ=Y3D66Ym9[q]ypDndT8[MV65]=tostring(PhJ) | |
MV65=MV65+1 end;return ypDndT8 end)(),'.'))else | |
return | |
s6FbB(Xf((function()local h={}local j2K=1;local r8hgwQ={fTrMe.major+1,0,0} | |
for _6U=1,#r8hgwQ do | |
local GLSzBQs=r8hgwQ[_6U]h[j2K]=tostring(GLSzBQs)j2K=j2K+1 end;return h end)(),'.'))end end,next_minor=function(c)if | |
not(c.minor)then | |
error("Partial version doesn't contain the minor component!")end | |
if c.prerelease and c.patch==0 then | |
return | |
s6FbB(Xf((function() | |
local xg={}local Id2KoP_G=1;local Y2or={c.major,c.minor,c.patch} | |
for zN8ASHV5=1,#Y2or do | |
local iju=Y2or[zN8ASHV5]xg[Id2KoP_G]=tostring(iju)Id2KoP_G=Id2KoP_G+1 end;return xg end)(),'.'))else | |
return | |
s6FbB(Xf((function()local XsWgh={}local l4Hdz=1;local NSXCgSH={c.major,c.minor+1,0} | |
for Wq=1,#NSXCgSH do | |
local SbOQ=NSXCgSH[Wq]XsWgh[l4Hdz]=tostring(SbOQ)l4Hdz=l4Hdz+1 end;return XsWgh end)(),'.'))end end,next_patch=function(IiuHGo)if | |
not(IiuHGo.patch)then | |
error("Partial version doesn't contain the patch component!")end | |
if IiuHGo.prerelease then | |
return | |
s6FbB(Xf((function()local cGqxtYr={} | |
local bgJFKeeZ=1;local yu9fg0nN={IiuHGo.major,IiuHGo.minor,IiuHGo.patch} | |
for wgx=1,# | |
yu9fg0nN do local zlU7X=yu9fg0nN[wgx] | |
cGqxtYr[bgJFKeeZ]=tostring(zlU7X)bgJFKeeZ=bgJFKeeZ+1 end;return cGqxtYr end)(),'.'))else | |
return | |
s6FbB(Xf((function()local t={}local f6qbO=1 | |
local kk={IiuHGo.major,IiuHGo.minor,IiuHGo.patch+1} | |
for QrubIAv=1,#kk do local bLHDW=kk[QrubIAv]t[f6qbO]=tostring(bLHDW)f6qbO=f6qbO+1 end;return t end)(),'.'))end end,coerce=function(YjFd7b,jZgPYb,zN2)if | |
zN2 ==nil then zN2=false end;local IN69pa5 | |
IN69pa5=function(OVx_mN) | |
local lB,byE=OVx_mN:match('^(%d+)(.*)$')if not(lB)then return nil end;local bITCI=lB | |
local K,F5dtVpnN=byE:match('^%.(%d+)(.*)$')if K then byE=F5dtVpnN;bITCI=bITCI.. ('.'..K)end;local kxeBp | |
kxeBp,F5dtVpnN=byE:match('^%.(%d+)(.*)$') | |
if kxeBp then byE=F5dtVpnN;bITCI=bITCI.. ('.'..kxeBp)end;return OVx_mN,bITCI end;local UOWJ,WtalJw=IN69pa5(jZgPYb)if not(UOWJ)then | |
error("Version string lacks a numerical component: ".. | |
tostring(jZgPYb))end | |
local JYrf2=jZgPYb:sub(1,#WtalJw) | |
if not zN2 then while({JYrf2:gsub('.','')})[2]<2 do JYrf2= | |
JYrf2 ..'.0'end end;if#WtalJw==#jZgPYb then return s6FbB(JYrf2,zN2)end;local KHDOUlRY=jZgPYb:sub( | |
#WtalJw+1) | |
KHDOUlRY=KHDOUlRY:gsub('[^a-zA-Z0-9+.-]','-')local I0JvPpn,Ce4ZE=nil,nil | |
if KHDOUlRY:sub(1,1)=='+'then I0JvPpn='' | |
Ce4ZE=KHDOUlRY:sub(2)elseif KHDOUlRY:sub(1,1)=='.'then I0JvPpn=''Ce4ZE=KHDOUlRY:sub(2)elseif | |
KHDOUlRY:sub(1,1)=='-'then KHDOUlRY=KHDOUlRY:sub(2) | |
do | |
local a=KHDOUlRY:find('+')if a then | |
I0JvPpn,Ce4ZE=KHDOUlRY:sub(1,a-1),KHDOUlRY:sub(a+1,-1)else I0JvPpn,Ce4ZE=KHDOUlRY,''end end else do local kQ=KHDOUlRY:find('+') | |
if kQ then I0JvPpn,Ce4ZE=KHDOUlRY:sub(1,kQ-1),KHDOUlRY:sub( | |
kQ+1,-1)else I0JvPpn,Ce4ZE=KHDOUlRY,''end end end;Ce4ZE=Ce4ZE:gsub('+','.')if I0JvPpn and I0JvPpn~=''then JYrf2=JYrf2 .. | |
('-'..I0JvPpn)end;if | |
Ce4ZE and Ce4ZE~=''then JYrf2=JYrf2 .. ('+'..Ce4ZE)end;return | |
YjFd7b.__class(JYrf2,zN2)end,parse=function(EE9LAE,iVx,eg,AQviNt)if | |
eg==nil then eg=false end;if AQviNt==nil then AQviNt=false end;if not iVx or | |
type(iVx)~='string'or iVx==''then | |
error("Invalid empty version string: ".. | |
tostring(tostring(iVx)))end;local T6 | |
if eg then | |
T6=EE9LAE.__class.partialVersionRe else T6=EE9LAE.__class.versionRe end;local NviN0i,BlMQce,o,dpRE,fEiXwWq=T6(EE9LAE.__class,iVx)if not NviN0i then | |
error( | |
"Invalid version string: "..tostring(iVx))end;if JQgI(NviN0i)then | |
error("Invalid leading zero in major: ".. | |
tostring(iVx))end;if JQgI(BlMQce)then | |
error("Invalid leading zero in minor: ".. | |
tostring(iVx))end;if JQgI(o)then | |
error("Invalid leading zero in patch: ".. | |
tostring(iVx))end;NviN0i=tonumber(NviN0i) | |
BlMQce=EE9LAE:_coerce(BlMQce,eg)o=EE9LAE:_coerce(o,eg) | |
if dpRE==nil then if eg and fEiXwWq==nil then return | |
{NviN0i,BlMQce,o,nil,nil}else dpRE={}end elseif dpRE==''then dpRE={}else | |
do | |
local r3JzMga6={}local Tuyw=1 | |
for FYLcr2nu in dpRE:gmatch('[^.]+')do r3JzMga6[Tuyw]=FYLcr2nu;Tuyw=Tuyw+1 end;dpRE=r3JzMga6 end;EE9LAE:_validateIdentifiers(dpRE,false)end | |
if fEiXwWq==nil then if eg then fEiXwWq=nil else fEiXwWq={}end elseif fEiXwWq==''then fEiXwWq={}else do | |
local ioS69={}local AiP=1 | |
for S2jwpoi in fEiXwWq:gmatch('[^.]+')do ioS69[AiP]=S2jwpoi;AiP=AiP+1 end;fEiXwWq=ioS69 end | |
EE9LAE:_validateIdentifiers(fEiXwWq,true)end;return{NviN0i,BlMQce,o,dpRE,fEiXwWq}end,_validateIdentifiers=function(_WX9u,u0riyU,UH)if | |
UH==nil then UH=false end | |
for WNph=1,#u0riyU do local ytF=u0riyU[WNph]if not ytF then | |
error( | |
"Invalid empty identifier ".. | |
tostring(ytF).." in "..tostring(Xf(u0riyU,'.')))end;if | |
ytF:sub(1,1)=='0'and | |
tonumber(ytF)and ytF~='0'and not UH then | |
error("Invalid leading zero in identifier "..tostring(ytF))end end end,__pairs=function(d)return | |
pairs({d.major,d.minor,d.patch,d.prerelease,d.build})end,__ipairs=function(gRm)return | |
ipairs({gRm.major,gRm.minor,gRm.patch,gRm.prerelease,gRm.build})end,__tostring=function(LPX0) | |
local g=tostring(LPX0.major) | |
if LPX0.minor~=nil then g=g.. ('.'..LPX0.minor)end | |
if LPX0.patch~=nil then g=g.. ('.'..LPX0.patch)end | |
if LPX0.prerelease and#LPX0.prerelease>0 or | |
LPX0.partial and LPX0.prerelease and#LPX0.prerelease==0 and LPX0.build==nil then g=g.. ('-'.. | |
Xf(LPX0.prerelease,'.'))end | |
if | |
LPX0.build and#LPX0.build>0 or LPX0.partial and LPX0.build and# | |
LPX0.build==0 then g=g.. ('+'..Xf(LPX0.build,'.'))end;return g end,_comparsionFunctions=function(_l,qao)if | |
qao==nil then qao=false end;local ipUPIzc | |
ipUPIzc=function(J7nsK,dXbd) | |
if J7nsK and dXbd then | |
return PUNkgaiM(J7nsK,dXbd)elseif J7nsK then return-1 elseif dXbd then return 1 else return 0 end end;local N8 | |
N8=function(vQj,sVBxyy)if vQj==sVBxyy then return 0 else return'not implemented'end end;local Gzk | |
Gzk=function(N9d)local S7 | |
S7=function(bJtvRSR,aBhZK5)if bJtvRSR==nil or aBhZK5 ==nil then return 0 else | |
return N9d(bJtvRSR,aBhZK5)end end;return S7 end;if qao then return{N,Gzk(N),Gzk(N),Gzk(ipUPIzc),Gzk(N8)}else return | |
{N,N,N,ipUPIzc,N8}end end,__compare=function(Jz8JUscj,OtGmbAgE) | |
local oU_r=Jz8JUscj:_comparsionFunctions( | |
Jz8JUscj.partial or OtGmbAgE.partial) | |
local n_lv={{oU_r[1],Jz8JUscj.major,OtGmbAgE.major},{oU_r[2],Jz8JUscj.minor,OtGmbAgE.minor},{oU_r[3],Jz8JUscj.patch,OtGmbAgE.patch},{oU_r[4],Jz8JUscj.prerelease,OtGmbAgE.prerelease},{oU_r[5],Jz8JUscj.build,OtGmbAgE.build}} | |
for UYQF=1,#n_lv do local WXx=n_lv[UYQF]local W4EuxJXi,BlYNd61h,XDPndG=U(WXx) | |
local sJYFQIP4=W4EuxJXi(BlYNd61h,XDPndG)if sJYFQIP4 ~=0 then return sJYFQIP4 end end;return 0 end,__compareHelper=function(Ogq0S2,n8Cw3SR,GJqd7gt,slE5aDm2) | |
local aL_g=Ogq0S2:__compare(n8Cw3SR)if aL_g=='not implemented'then return slE5aDm2 end | |
return GJqd7gt(aL_g)end,__eq=function(IMUI10L,vPA) | |
local pUXZ6G4;pUXZ6G4=function(mk)return mk==0 end;return | |
IMUI10L:__compareHelper(vPA,pUXZ6G4,false)end,__lt=function(OeQex1U4,i0cV9) | |
local EGD;EGD=function(VWiGCreH)return VWiGCreH<0 end;return | |
OeQex1U4:__compareHelper(i0cV9,EGD,false)end,__le=function(B_kkL,uEO6Y) | |
local i_053JPY;i_053JPY=function(l)return l<=0 end;return | |
B_kkL:__compareHelper(uEO6Y,i_053JPY,false)end}d0uKSVw1.__index=d0uKSVw1 | |
wCRY=setmetatable({__init=function(UK,NzaICo,k1X83nYm) | |
if k1X83nYm==nil then k1X83nYm=false end;local xxzxfj,_ad1m4I,H1QsS,rIMx,TiA=U(UK:parse(NzaICo,k1X83nYm)) | |
UK.major,UK.minor,UK.patch,UK.prerelease,UK.build,UK.partial=xxzxfj,_ad1m4I,H1QsS,rIMx,TiA,k1X83nYm end,__base=d0uKSVw1,__name="Version"},{__index=d0uKSVw1,__call=function(Y51P,...) | |
local ichL=setmetatable({},d0uKSVw1)Y51P.__init(ichL,...)return ichL end})d0uKSVw1.__class=wCRY;local lNOqUk8=wCRY | |
lNOqUk8.versionRe=function(lNOqUk8,NOK) | |
local Alv,YeLO2,CkrmO,ooovsSJe=NOK:match('^(%d+)%.(%d+)%.(%d+)(.*)$')if not(Alv)then return nil end | |
local s5IsD,KvYEVoXt=ooovsSJe:match('^%-([0-9a-zA-z.-]+)(.*)$')if s5IsD then ooovsSJe=KvYEVoXt end;local VWWD_P | |
VWWD_P,KvYEVoXt=ooovsSJe:match('^%+([0-9a-zA-Z.-]+)(.*)$')if VWWD_P then ooovsSJe=KvYEVoXt end;if#ooovsSJe>0 then return nil end;return | |
Alv,YeLO2,CkrmO,s5IsD,VWWD_P end | |
lNOqUk8.partialVersionRe=function(lNOqUk8,zsMuNkv)local aXxi,Q18a7QTy=zsMuNkv:match('^(%d+)(.*)$')if | |
not(aXxi)then return nil end | |
local K5Rp6,GTIA=Q18a7QTy:match('^%.(%d+)(.*)$')if K5Rp6 then Q18a7QTy=GTIA end;local gdPUe | |
gdPUe,GTIA=Q18a7QTy:match('^%.(%d+)(.*)$')if gdPUe then Q18a7QTy=GTIA end;local _bxEn | |
_bxEn,GTIA=Q18a7QTy:match('^%-([0-9a-zA-Z.-]*)(.*)$')if _bxEn then Q18a7QTy=GTIA end;local pcN_ceXY | |
pcN_ceXY,GTIA=Q18a7QTy:match('^%+([0-9a-zA-Z.-]*)(.*)$')if pcN_ceXY then Q18a7QTy=GTIA end;if#Q18a7QTy>0 then return nil end;return aXxi, | |
K5Rp6,gdPUe,_bxEn,pcN_ceXY end;s6FbB=wCRY end;local X | |
do local _P | |
local rq={parse=function(I,RAAJAsR)if | |
not RAAJAsR or type(RAAJAsR)~='string'or RAAJAsR==''then | |
error("Invalid empty requirement specification: "..tostring(tostring(RAAJAsR)))end;if RAAJAsR== | |
'*'then return{I.__class.KIND_ANY,''}end | |
local c1pjj7,BMv=I.__class:reSpec(RAAJAsR)if not c1pjj7 then | |
error("Invalid requirement specification: "..tostring(RAAJAsR))end;c1pjj7= | |
I.__class.KIND_ALIASES[c1pjj7]or c1pjj7;local NQh8=s6FbB(BMv,true) | |
if | |
NQh8.build~=nil and c1pjj7 ~=I.__class.KIND_EQUAL and c1pjj7 ~= | |
I.__class.KIND_NEQ then | |
error( | |
"Invalid requirement specification "..tostring(RAAJAsR)..": build numbers have no ordering")end;return{c1pjj7,NQh8}end,match=function(P,bkTe) | |
local ohmPbyDd=P.kind | |
if P.__class.KIND_ANY==ohmPbyDd then return true elseif P.__class.KIND_LT==ohmPbyDd then return bkTe< | |
P.spec elseif P.__class.KIND_LTE==ohmPbyDd then return bkTe<=P.spec elseif | |
P.__class.KIND_EQUAL==ohmPbyDd then return bkTe==P.spec elseif P.__class.KIND_GTE==ohmPbyDd then return bkTe>= | |
P.spec elseif P.__class.KIND_GT==ohmPbyDd then return bkTe>P.spec elseif | |
P.__class.KIND_NEQ==ohmPbyDd then return bkTe~=P.spec elseif P.__class.KIND_CARET==ohmPbyDd then | |
return | |
P.spec<=bkTe and bkTe<P.spec:next_major()elseif P.__class.KIND_TILDE==ohmPbyDd then return P.spec<=bkTe and | |
bkTe<P.spec:next_minor()else return | |
error("Unexpected match kind: "..tostring(P.kind))end end,__tostring=function(D)return | |
tostring(D.kind)..tostring(D.spec)end,__eq=function(DfDLWkT,MTU8HP4d)return | |
DfDLWkT.kind==MTU8HP4d.kind and DfDLWkT.spec==MTU8HP4d.spec end}rq.__index=rq | |
_P=setmetatable({__init=function(hIM_cG0i,jD) | |
hIM_cG0i.kind,hIM_cG0i.spec=U(hIM_cG0i:parse(jD))end,__base=rq,__name="SpecItem"},{__index=rq,__call=function(me,...) | |
local sgU5HAMG=setmetatable({},rq)me.__init(sgU5HAMG,...)return sgU5HAMG end})rq.__class=_P;local mo=_P;mo.KIND_ANY='*'mo.KIND_LT='<'mo.KIND_LTE='<=' | |
mo.KIND_EQUAL='=='mo.KIND_SHORTEQ='='mo.KIND_EMPTY=''mo.KIND_GTE='>='mo.KIND_GT='>' | |
mo.KIND_NEQ='!='mo.KIND_CARET='^'mo.KIND_TILDE='~' | |
mo.KIND_ALIASES={[mo.__class.KIND_SHORTEQ]=mo.__class.KIND_EQUAL,[mo.__class.KIND_EMPTY]=mo.__class.KIND_EQUAL} | |
mo.reSpec=function(mo,FDydY)local PEZ_,c=FDydY:match('^(.-)(%d.*)$') | |
if not | |
( | |
PEZ_=='<'or PEZ_=='<='or PEZ_==''or PEZ_=='='or PEZ_=='=='or PEZ_=='>='or PEZ_=='>'or PEZ_=='!='or PEZ_=='^'or PEZ_=='~')then return nil else | |
return PEZ_,c end end;X=_P end;local dc61 | |
do local ElbTbcZG | |
local r3={parse=function(pUiVYRok,jvPsY9)local tEBmuypm={}local hW=1;for iOcgdUx in jvPsY9:gmatch('[^,]+')do | |
tEBmuypm[hW]=X(iOcgdUx)hW=hW+1 end;return tEBmuypm end,match=function(kCwLIk,_l) | |
local rjQ=kCwLIk.specs | |
for Euo0=1,#rjQ do local LIV=rjQ[Euo0]if not LIV:match(_l)then return false end end;return true end,filter=function(vydlAbZ3,BXxv5z) | |
local mKLU=0 | |
return function() | |
while true do mKLU=mKLU+1;local Him=BXxv5z[mKLU]if not(Him)then return nil end;if | |
vydlAbZ3:match(Him)then return Him end end end end,select=function(cPDhu,UQnOS) | |
local tRWU | |
do local X2Zy_nb={}local ITtw3N7E=1;for yozOp in cPDhu:filter(UQnOS)do X2Zy_nb[ITtw3N7E]=yozOp;ITtw3N7E= | |
ITtw3N7E+1 end;tRWU=X2Zy_nb end | |
if#tRWU>0 then local wxU=tRWU[1]for kOmS5sy=1,#tRWU do local CLSdD=tRWU[kOmS5sy] | |
if wxU<CLSdD then wxU=CLSdD end end;return wxU else return nil end end,__index=function(Fh,IlAPA)if | |
Fh:match(IlAPA)then return true else return nil end end,__pairs=function(jLKMpQuK)return | |
pairs(jLKMpQuK.specs)end,__ipairs=function(sUQpby)return ipairs(sUQpby.specs)end,__tostring=function(mbA) | |
return | |
Xf((function() | |
local _qPhpaFx={}local zex=1;local pPGcdu=mbA.specs;for rjp=1,#pPGcdu do local cT2z=pPGcdu[rjp] | |
_qPhpaFx[zex]=tostring(cT2z)zex=zex+1 end;return _qPhpaFx end)(),',')end,__eq=function(zke1tWps,gRFA) | |
local jX9a0tJX=zke1tWps.specs | |
for YFy4TGc=1,#jX9a0tJX do local YjpbYkCb=jX9a0tJX[YFy4TGc]local L1p7luJ=false;local eH=gRFA.specs | |
for WpOZ=1,#eH do | |
local fD2289=eH[WpOZ]if YjpbYkCb==fD2289 then L1p7luJ=true;break end end;if not L1p7luJ then return false end end;return true end}r3.__index=r3 | |
ElbTbcZG=setmetatable({__init=function(folfO,vtsK) | |
if type(vtsK)=='string'then vtsK={vtsK}end;local E1p4Mv | |
do local IHap={}local rDvV=1;for RX1L2q=1,#vtsK do local bCBtWguf=vtsK[RX1L2q] | |
IHap[rDvV]=folfO:parse(bCBtWguf)rDvV=rDvV+1 end;E1p4Mv=IHap end;folfO.specs={} | |
for q=1,#E1p4Mv do local e1sXUN4f=E1p4Mv[q]for x=1,#e1sXUN4f do local VP=e1sXUN4f[x] | |
UlFdiZ7v(folfO.specs,VP)end end end,__base=r3,__name="Spec"},{__index=r3,__call=function(IQwqq,...) | |
local Xcc4=setmetatable({},r3)IQwqq.__init(Xcc4,...)return Xcc4 end})r3.__class=ElbTbcZG;dc61=ElbTbcZG end;local aguhyl | |
aguhyl=function(fqw5,qnVfOeRE)return N(s6FbB(fqw5,s6FbB(qnVfOeRE)))end;local p | |
p=function(YIiSKsxK,Ua)return dc61(YIiSKsxK):match(s6FbB(Ua))end;local gOPDv;gOPDv=function(qeJtG) | |
return({s6FbB:parse(qeJtG)})[1]end;return | |
{Spec=dc61,SpecItem=X,Version=s6FbB,compare=aguhyl,match=p,validate=gOPDv}end)()local LfEJbh_;LfEJbh_=require("component").isAvailable;local JD,u | |
do | |
local pdpNgBcZ=require("shell")JD,u=pdpNgBcZ.parse,pdpNgBcZ.getWorkingDirectory end;local pzDMZwG=require("shell")local XPoQB,XxJ,o5sms,JQi1jg,wVzn;do | |
local wV=require("filesystem") | |
XPoQB,XxJ,o5sms,JQi1jg,wVzn=wV.isDirectory,wV.exists,wV.makeDirectory,wV.concat,wV.copy end | |
local pE=require("filesystem")local RSjapQ,QJf;do local rLd=require("serialization") | |
RSjapQ,QJf=rLd.serialize,rLd.unserialize end;local zC | |
zC=require("event").pull;local pfZ3SPy_,pDNa2ox6,Do6yo7nm;do local z8oF=require("term") | |
pfZ3SPy_,pDNa2ox6,Do6yo7nm=z8oF.clearLine,z8oF.getCursor,z8oF.clear end;local y06X3k;y06X3k=os.exit | |
local ivnJjrA,d3fMjkg | |
do local DB6A7N=io;ivnJjrA,d3fMjkg=DB6A7N.write,DB6A7N.stderr end;local el,Wu_uIt | |
do local VhYX=table;el,Wu_uIt=VhYX.insert,VhYX.unpack end;local w=pE.list;local sgeP,CM={},{}local Qlmlet=nil;local _={}local RkGFh6={}local hw18={} | |
local nvCiFt7r="/etc/hpm/module/"local xSebv5Jc="/var/lib/hpm/dist/"local mMp=0;local rDtVf="/etc/hpm/hpm.cfg" | |
local vj=[[Usage: hpm OPTIONS COMMAND | |
See `man hpm` for more info.]] | |
local z=[[-- << Global settings >> ------------------------------------------------------- | |
-- A directory where package manifests will be placed. | |
-- It will be created if it doesn't exist. | |
dist = "/var/lib/hpm/dist" | |
-- A place where to search for custom hpm modules. | |
-- It will be created if it doesn't exist. | |
modules = "/etc/hpm/module" | |
-- << Settings related to the hel module >> ------------------------------------ | |
hel = {} | |
-- If set to `false`, hpm will *only* remove a package that hpm is told to | |
-- remove. Otherwise, all of its dependants will be also removed. | |
hel.remove_dependants = true | |
-- << Settings related to the oppm module >> ----------------------------------- | |
oppm = {} | |
-- A directory where package manifests will be stored for faster access. | |
oppm.cache_directory = "/var/cache/hpm/oppm" | |
-- See hel.remove_dependants above. | |
oppm.remove_dependants = true]] | |
local Zg={info=function(...) | |
if sgeP.v then | |
return | |
print(table.concat((function(...)local Ha7ErH={}local rjU95v=1;local sxBl={...}for m=1,#sxBl do local nD4LhX6z=sxBl[m] | |
Ha7ErH[rjU95v]=tostring(nD4LhX6z)rjU95v=rjU95v+1 end;return Ha7ErH end)(...),"\t"))end end,print=function(...) | |
if | |
not(sgeP.q)then | |
return | |
print(table.concat((function(...)local iN={}local Lq=1;local s9tW={...}for R61K=1,#s9tW do local Jf4os=s9tW[R61K] | |
iN[Lq]=tostring(Jf4os)Lq=Lq+1 end;return iN end)(...),"\t"))end end,error=function(...) | |
if | |
not(sgeP.q)then | |
return | |
d3fMjkg:write( | |
table.concat((function(...)local a4xc={}local e=1;local la5={...}for i=1,#la5 do local R=la5[i] | |
a4xc[e]=tostring(R)e=e+1 end;return a4xc end)(...),"\t")..'\n')end end,fatal=function(...) | |
if | |
not(sgeP.q)then | |
d3fMjkg:write( | |
table.concat((function(...)local xWVu={}local Yw8Yxix=1;local i={...} | |
for VoXG=1,#i do | |
local JL0I04c=i[VoXG]xWVu[Yw8Yxix]=tostring(JL0I04c)Yw8Yxix=Yw8Yxix+1 end;return xWVu end)(...),"\t")..'\n')end;return y06X3k(1)end}local ykRppH | |
ykRppH=function(En6r_K97,T4AA)if not(En6r_K97)then return Zg.fatal(T4AA)end end;local WQ6 | |
WQ6=function(VnuCKTdu)return | |
Zg.fatal((tostring(VnuCKTdu))..": Not implemented yet!")end;local y36Aetn | |
y36Aetn=function()ivnJjrA(vj)return y06X3k(0)end;local iPL3B4cr | |
iPL3B4cr=function(XnNgn,H1JD)if not(XnNgn)then Zg.fatal(H1JD)end;return XnNgn end;local GI2hz6SK | |
GI2hz6SK=function(gEEa9I,ULLLDUm,e4F3) | |
if not(type(gEEa9I==ULLLDUm))then | |
Zg.fatal("Value '".. | |
tostring(gEEa9I).. | |
"' is "..tostring(type(e4F3)).. | |
", however, a "..tostring(ULLLDUm).." is expected.")end;return e4F3 end;local Oh;Oh=function(GsfNt7) | |
return GI2hz6SK(GsfNt7,"number",tonumber(GsfNt7))end;local PG | |
PG=function(fF0)return | |
GI2hz6SK(fF0,"string",tostring(fF0))end;local n | |
n=function(YWPfQKb2,r) | |
for OS0Zp3i,BK in pairs(r)do if BK==YWPfQKb2 then return true,OS0Zp3i end end;return false end;local O | |
O=function(Idjbe70)local B=0;for nDjt,NVWt in pairs(Idjbe70)do B=B+1 end;return B end;local N5UjTN | |
N5UjTN=function(efuUGMh) | |
if type(efuUGMh)=="nil"then return true elseif type(efuUGMh)=="string"then return | |
not efuUGMh or#efuUGMh<1 elseif type(efuUGMh)=="table"then return | |
not efuUGMh or O(efuUGMh)<1 else return true end end;local qLH5 | |
qLH5=function(p4nNp) | |
for VW=1,#p4nNp do local Zt=p4nNp[VW]if not Zt then return false end end;return true end;local tE | |
tE=function(V)return XxJ(V)and XPoQB(V)end;local VcV0EuD | |
VcV0EuD=function(mzeTI)return XxJ(mzeTI)and not XPoQB(mzeTI)end;local pX4gCR | |
pX4gCR=function(sy4J)return sy4J==1 and""or"s"end;local gad4ZcL | |
gad4ZcL=function(ztJhP_u8)return ztJhP_u8 ~=1 and""or"s"end;local dk | |
dk=function(D)return D==1 and"is"or"are"end;local E | |
E=function(XIcl)return XIcl:match("^([^:]-):?([^:@]+)@?([^:@]*)$")end;local OO | |
OO=function(ys) | |
if | |
pE.get(pzDMZwG.resolve(ys)).isReadOnly()then return false,"the path is readonly!"elseif not XxJ(ys)then | |
return false,"the filesystem node doesn't exist."else | |
if not(XPoQB(ys)or pE.isLink(ys))then | |
return pE.remove(ys)else | |
for rMQ1um8 in iPL3B4cr(w(ys))do OO(JQi1jg(ys,rMQ1um8))end;return pE.remove(ys)end end end;local y | |
y=function()local U2=sgeP.c or sgeP.config or rDtVf | |
if | |
not VcV0EuD(U2)then local Z=pE.path(U2) | |
if not tE(Z)then local B58,PYVzrNl=o5sms(Z)if not B58 then | |
return false,"Failed to create '".. | |
tostring(Z).."' directory for the config file: "..tostring(PYVzrNl)end end;local ZDICnKE,L=io.open(U2,"w")if ZDICnKE then ZDICnKE:write(z) | |
ZDICnKE:close()else | |
return false,"Failed to open config file for writing: "..tostring(L)end end;local X,zLtWO09=io.open(U2,"r") | |
if X then local KTVmRC=X:read("*all")X:close() | |
local Pa={};(load(KTVmRC,"config","t",Pa))() | |
local bmK | |
bmK=function(OJPc3R)if OJPc3R==nil then OJPc3R={}end | |
return | |
setmetatable(OJPc3R,{__index={get=function(j,vMgKnGj,M9K)if | |
type(OJPc3R[j])~="nil"then | |
if type(OJPc3R[j])=="table"then return bmK(OJPc3R[j])end;return OJPc3R[j]end | |
Zg.error( | |
"Attempt to access undeclared config field '"..tostring(j).."'!")if not M9K then return vMgKnGj else return bmK(vMgKnGj)end end}})end;RkGFh6=bmK(Pa)nvCiFt7r=RkGFh6.get("modules",nvCiFt7r) | |
xSebv5Jc=RkGFh6.get("dist",xSebv5Jc)return RkGFh6 else return false, | |
"Failed to open config file for reading: "..tostring(zLtWO09)end end;local cR6rJlAl | |
cR6rJlAl=function()if not(LfEJbh_("internet"))then | |
Zg.fatal("This command requires an internet card to run!")end;Qlmlet=Qlmlet or | |
require("internet").request end;local M6ilzGJ | |
M6ilzGJ=function(Zeu)cR6rJlAl()return pcall(Qlmlet,Zeu)end;local iW6CD | |
iW6CD=function() | |
if not tE(nvCiFt7r)then local W0iTcMIt,N=o5sms(nvCiFt7r)if not W0iTcMIt then | |
return false, | |
"Failed to create '".. | |
tostring(nvCiFt7r).."' directory for custom modules: "..tostring(N)end end;local Q2_d=iPL3B4cr(w(nvCiFt7r))for Hald6SO in Q2_d do | |
local Dq=Hald6SO:match("^(.+)%..+$") | |
local y3Ur=(iPL3B4cr(loadfile(JQi1jg(nvCiFt7r,Hald6SO),"t",hw18)))()end;return true end;local wZdg | |
wZdg=function(GL70F7uL)local lqANrrJA=GL70F7uL;local WUFTXBy6 | |
do local aEZf=GL70F7uL:find(':')if aEZf then lqANrrJA=GL70F7uL:sub( | |
aEZf+1) | |
WUFTXBy6=GL70F7uL:sub(1,aEZf-1)end end | |
if not WUFTXBy6 then local QjQ_o={} | |
for wDiq_,WUFTXBy6 in pairs(_)do | |
if WUFTXBy6[lqANrrJA]then if | |
type(WUFTXBy6[lqANrrJA])== | |
"table"and WUFTXBy6[lqANrrJA].__public==true then | |
el(QjQ_o,{class=WUFTXBy6,module=wDiq_,method=WUFTXBy6[lqANrrJA]})end end end | |
if#QjQ_o>1 then local QYA5WJOY=nil;for yliV8,WUFTXBy6 in pairs(QjQ_o)do | |
if WUFTXBy6.module=="hel"then QYA5WJOY=yliV8;break end end;if QYA5WJOY then | |
QjQ_o={QjQ_o[QYA5WJOY]}end end | |
if#QjQ_o>1 then | |
Zg.print("Ambiguous choice: method ".. | |
tostring(lqANrrJA).." is implemented in the following modules:")for rjpKFl=1,#QjQ_o do local WUFTXBy6=QjQ_o[rjpKFl] | |
Zg.print(" * "..tostring(WUFTXBy6.module))end | |
Zg.print( | |
"Choose a specific module by prepending its name with a colon, e.g., "..tostring(QjQ_o[1].module).. | |
":"..tostring(lqANrrJA)..".")return false elseif#QjQ_o==0 then | |
Zg.error("Unknown command: "..tostring(lqANrrJA))return false else WUFTXBy6=QjQ_o[1].module | |
Zg.info("Note, using "..tostring(WUFTXBy6)..":".. | |
tostring(lqANrrJA)..".")return | |
function(...)return QjQ_o[1].method(QjQ_o[1].class,...)end end else | |
if _[WUFTXBy6]and N5UjTN(lqANrrJA)then local YUGQovw={} | |
for XZt7GyF,Zn3SC in pairs(_[WUFTXBy6])do if | |
type(Zn3SC)=="table"and Zn3SC.__public==true then | |
el(YUGQovw,tostring(XZt7GyF))end end | |
Zg.print("Available module-specific commands: "..tostring(table.concat(YUGQovw,", ")))return false end | |
if | |
not _[WUFTXBy6]or not _[WUFTXBy6][lqANrrJA]or _[WUFTXBy6][lqANrrJA]and | |
( | |
type(_[WUFTXBy6][lqANrrJA])~="table"or _[WUFTXBy6][lqANrrJA].__public~=true)then | |
Zg.error("Unknown command: ".. | |
tostring(WUFTXBy6)..":"..tostring(lqANrrJA))return false else return function(...) | |
return _[WUFTXBy6][lqANrrJA](_[WUFTXBy6],...)end end end end;local BaX | |
BaX=function(D4)if not D4 or D4 ==""then D4="hel"else D4=D4 end;return | |
_[D4]or _.default end;local SJsW11k | |
SJsW11k=function(crA9EKx,IcsJ,...)if crA9EKx==nil then crA9EKx=_.default end | |
if crA9EKx[IcsJ]then return | |
crA9EKx[IcsJ](crA9EKx,...)else return _.default[IcsJ](_.default,...)end end;local Ki1HJT | |
Ki1HJT=function(A,Wp9xT,P,o0_XG8FI)if Wp9xT==nil then Wp9xT="hel"end;if P==nil then | |
P=JQi1jg(xSebv5Jc,Wp9xT)end;if o0_XG8FI==nil then o0_XG8FI=A.name end;if not A then return false, | |
"'nil' given"end | |
if not tE(P)then local AXNfV,cX=o5sms(P) | |
if not AXNfV then return false, | |
"Failed to create '"..tostring(JQi1jg(P,Wp9xT)).. | |
"' directory for manifest files: "..tostring(cX)end end;local jLsxpw,x=io.open(JQi1jg(P,o0_XG8FI),"w") | |
if jLsxpw then | |
jLsxpw:write(RSjapQ(A))jLsxpw:close()return true else return false, | |
"Failed to open file for writing: "..tostring(x)end end;local wjim8xCV | |
wjim8xCV=function(iyx,bxvn,mWYrzB)if mWYrzB==nil then mWYrzB="hel"end;bxvn=bxvn or | |
JQi1jg(xSebv5Jc,mWYrzB,iyx) | |
if VcV0EuD(bxvn)then | |
local O7kX,Q4XSpdY=io.open(bxvn,"rb") | |
if O7kX then | |
local fzTyrQ9F=iPL3B4cr(QJf(O7kX:read("*all")))O7kX:close()return fzTyrQ9F else return false, | |
"Failed to open manifest for '"..tostring(iyx).."' package: ".. | |
tostring(Q4XSpdY)end else | |
return false,"No manifest found for '"..tostring(iyx).."' package"end end;local EQLam | |
EQLam=function(fAumJ0i,i0)if i0 ==nil then i0="hel"end | |
local tZliF4=JQi1jg(xSebv5Jc,i0,fAumJ0i) | |
if VcV0EuD(tZliF4)then return OO(tZliF4)else return false,"No manifest found for '".. | |
tostring(fAumJ0i).."' package"end end;local qTDt | |
qTDt=function(jlmopoj)return | |
setmetatable({__public=true},{__call=function(R,...)return jlmopoj(...)end})end;local v | |
v=function(uS_N6,o5SLRA) | |
return | |
function()local ztwXaCR,M2WtMgiq=pcall(uS_N6) | |
if not(ztwXaCR)then return false, | |
"Could not download '"..tostring(o5SLRA).. | |
"': "..tostring(M2WtMgiq)else return M2WtMgiq end end end;local Ta | |
Ta=function(FgfME,ylH9o,CC4Kfjh) | |
if ylH9o==nil then ylH9o="Could not download '%s': %s"end | |
if CC4Kfjh==nil then CC4Kfjh="Could not download '%s': %s"end;local k,eUQ0x,r0OR=M6ilzGJ(FgfME)if not(k and eUQ0x)then return false, | |
ylH9o:format(FgfME,r0OR)end;local pYHkv=""for hxZHlgP,r0OR in v(eUQ0x)do | |
if hxZHlgP then pYHkv=pYHkv.. | |
hxZHlgP else return false,CC4Kfjh:format(FgfME,r0OR)end end;return pYHkv end;local unArcvQl | |
unArcvQl=function() | |
if not(sgeP.y)then | |
io.write("Press [ENTER] to continue...")local zct=select(3,zC("key_down"))if zct==13 then pfZ3SPy_()return true else | |
io.write("\n")return false end else return true end end;local h6Ub7U | |
h6Ub7U=function(WQk6Wkd)local t=0;local pRCHPl={} | |
if not(N5UjTN(WQk6Wkd.install))then | |
local sCffg4HK={"Packages to INSTALL:",table.concat(WQk6Wkd.install," ")}el(pRCHPl,sCffg4HK)t=t+#WQk6Wkd.install else | |
WQk6Wkd.install={}end | |
if not(N5UjTN(WQk6Wkd.reinstall))then | |
local EyljhkFp={"Packages to REINSTALL:",table.concat(WQk6Wkd.reinstall," ")}el(pRCHPl,EyljhkFp)t=t+#WQk6Wkd.reinstall else | |
WQk6Wkd.reinstall={}end | |
if not(N5UjTN(WQk6Wkd.upgrade))then | |
local uGDn542={"Packages to UPGRADE:",table.concat(WQk6Wkd.upgrade," ")}el(pRCHPl,uGDn542)t=t+#WQk6Wkd.upgrade else | |
WQk6Wkd.upgrade={}end | |
if not(N5UjTN(WQk6Wkd.remove))then | |
local DQ={"Packages to REMOVE:",table.concat(WQk6Wkd.remove," ")}el(pRCHPl,DQ)t=t+#WQk6Wkd.remove else WQk6Wkd.remove={}end | |
do | |
local s6Ahlni_={tostring(#WQk6Wkd.install).. | |
" to INSTALL, ".. | |
tostring(#WQk6Wkd.reinstall).." to REINSTALL, ".. | |
tostring(#WQk6Wkd.upgrade).." to UPGRADE, ".. | |
tostring(#WQk6Wkd.remove).." to REMOVE."}el(pRCHPl,s6Ahlni_)end | |
for T6dNu,H in pairs(pRCHPl)do | |
for T6dNu,YlzZm in pairs(H)do if T6dNu==1 then Zg.print(YlzZm)else | |
Zg.print(" "..tostring(YlzZm))end end;if T6dNu~=#pRCHPl then Zg.print("")end end | |
if t>0 then if not(unArcvQl())then return y06X3k(7)end end end | |
do local vj9879b5;local cotcYZ1f={}cotcYZ1f.__index=cotcYZ1f | |
vj9879b5=setmetatable({__init=function()end,__base=cotcYZ1f,__name="default"},{__index=cotcYZ1f,__call=function(zfl,...) | |
local itxD=setmetatable({},cotcYZ1f)zfl.__init(itxD,...)return itxD end})cotcYZ1f.__class=vj9879b5;local FRcmT=vj9879b5 | |
FRcmT.install=function()return | |
Zg.fatal("Incorrect source is provided! No default 'install' implementation.")end | |
FRcmT.remove=function(FRcmT,JPHs7A,yzYgnMtr)if yzYgnMtr==nil then yzYgnMtr="hel"end | |
if JPHs7A then | |
if JPHs7A.files then | |
for o,wmkJ in | |
pairs(JPHs7A.files)do local I1=JQi1jg(wmkJ.dir,wmkJ.name)local gXu5hG,R60Ru4bj=OO(I1) | |
if | |
not(gXu5hG)then return false, | |
"Failed to remove '"..tostring(I1).."': "..tostring(R60Ru4bj)end end end;return EQLam(JPHs7A.name,yzYgnMtr)else | |
return false,"Package can't be removed: the manifest is empty."end end | |
FRcmT.save=function()return | |
Zg.fatal("Incorrect source is provided! No default 'save' implementation.")end;_.default=vj9879b5 end | |
do local eQWRf;local WT2AX=_.default;local _AvO={}_AvO.__index=_AvO | |
setmetatable(_AvO,WT2AX.__base) | |
eQWRf=setmetatable({__init=function(q,...)return eQWRf.__parent.__init(q,...)end,__base=_AvO,__name="hel",__parent=WT2AX},{__index=function(WUY7,_puepou) | |
local DYLeJ=rawget(_AvO,_puepou)if DYLeJ==nil then local udbF=rawget(WUY7,"__parent") | |
if udbF then return udbF[_puepou]end else return DYLeJ end end,__call=function(dt1,...) | |
local V7eMEiVW=setmetatable({},_AvO)dt1.__init(V7eMEiVW,...)return V7eMEiVW end})_AvO.__class=eQWRf;local qEO=eQWRf;qEO.URL="https://hel-roottree.rhcloud.com/" | |
qEO.parsePackageJSON=function(qEO,Co1tUVas,B)if | |
B==nil then B=YAtG_LV3.Spec("*")end;local UjlBMb=nil;local PKWIJ9={} | |
for zYGA2q2,I9Mw in | |
pairs(Co1tUVas.versions)do local e=YAtG_LV3.Version(zYGA2q2)if not(e)then | |
Zg.fatal( | |
"Could not parse the version in package: "..tostring(e))end;PKWIJ9[e]=I9Mw end | |
local rQYWEt,nCwsa=pcall(function()return | |
B:select((function()local BUtIET={}local NvAj=1 | |
for Icg,PzMsk in pairs(PKWIJ9)do BUtIET[NvAj]=Icg;NvAj=NvAj+1 end;return BUtIET end)())end)if not(rQYWEt)then | |
Zg.fatal("Could not select the best version: "..tostring(nCwsa))end;UjlBMb=tostring(nCwsa)if not | |
(nCwsa)then | |
Zg.fatal("No candidate for version specification '"..tostring(B).."' found!")end | |
local IPPy={name=Co1tUVas.name,version=UjlBMb,files={},dependencies={}}for axLuO,j in pairs(PKWIJ9[nCwsa].files)do local As=j.dir;local JmCzKm=j.name | |
el(IPPy.files,{url=axLuO,dir=As,name=JmCzKm})end | |
for Mwhc,A6z in | |
pairs(PKWIJ9[nCwsa].depends)do local _Mk=A6z.version;local PXrrrSid=A6z.type | |
el(IPPy.dependencies,{name=Mwhc,version=_Mk,type=PXrrrSid})end;return IPPy end | |
qEO.getPackageSpec=function(qEO,L9) | |
Zg.info("Downloading package data for "..tostring(L9).." ...") | |
local _KZPScl,dbTwy=M6ilzGJ(qEO.URL.."packages/"..L9)if not(_KZPScl)then | |
Zg.fatal("HTTP request error: "..dbTwy)end;local R4f819q=""for nTUMgqomA in dbTwy do | |
R4f819q=R4f819q..nTUMgqomA end;local Kj1I=s:decode(R4f819q)if not(Kj1I)then | |
Zg.fatal( | |
"Incorrect JSON format!\n"..tostring(R4f819q))end;return Kj1I.data end | |
qEO.rawInstall=function(qEO,Id5sIM,gZM2ANLt,aC72qEnu)if gZM2ANLt==nil then gZM2ANLt=false end;if aC72qEnu==nil then | |
aC72qEnu=false end;local B60J;if aC72qEnu then B60J=JQi1jg(u(),Id5sIM.name)else | |
B60J="/"end | |
if aC72qEnu and not tE(B60J)then | |
local Y4,f=o5sms(B60J)if not(Y4)then | |
Zg.fatal("Failed creating '".. | |
tostring(B60J).."' directory for package '"..tostring(Id5sIM.name).."'! \n".. | |
tostring(f))end elseif | |
not aC72qEnu then local yeCnvcd6=wjim8xCV(Id5sIM.name,nil,"hel") | |
if yeCnvcd6 then | |
if yeCnvcd6.version== | |
tostring(Id5sIM.version)then | |
Zg.print("'"..tostring(Id5sIM.name).. | |
"@".. | |
tostring(yeCnvcd6.version).."' is already installed, skipping...")return yeCnvcd6 else | |
Zg.fatal("'".. | |
tostring(Id5sIM.name).. | |
"@".. | |
tostring(Id5sIM.version).. | |
"' was attempted to install, however, another version of the same package is already installed: '"..tostring(Id5sIM.name).. | |
"@"..tostring(yeCnvcd6.version).."'")end end end | |
for Iq93c6cA,nsM0h in pairs(Id5sIM.files)do | |
Zg.info("Fetching '"..tostring(nsM0h.name).."' ...")local Czi=iPL3B4cr(Ta(nsM0h.url)) | |
local IlxN=JQi1jg(B60J,nsM0h.dir) | |
if not tE(IlxN)then local EA_3x01A,m54tY2=o5sms(IlxN)if not(EA_3x01A)then | |
Zg.fatal("Failed to create '".. | |
tostring(IlxN).."' directory for '".. | |
tostring(nsM0h.name).."'! \n"..tostring(m54tY2))end end | |
do local WJWMdKI | |
nsM0h,WJWMdKI=io.open(JQi1jg(IlxN,nsM0h.name),"w")if not(nsM0h)then | |
Zg.fatal("Could not open '"..tostring(JQi1jg(IlxN,nsM0h.name)).. | |
"' for writing: "..tostring(WJWMdKI))end | |
nsM0h:write(Czi)nsM0h:close()end end;return | |
{name=Id5sIM.name,version=tostring(Id5sIM.version),files=Id5sIM.files,dependencies=Id5sIM.dependencies,manual=gZM2ANLt}end | |
qEO.resolveDependencies=function(qEO,AhbP,QHFgYUN,RoEsr7So,dX)if QHFgYUN==nil then QHFgYUN={}end | |
if RoEsr7So==nil then RoEsr7So={}end;if dX==nil then dX={}end | |
for Rz=1,#AhbP do local j177r=AhbP[Rz]local j,qCaFw | |
j,qCaFw=j177r.name,j177r.version;local syvPi=false;for NrgSK2=1,#QHFgYUN do local wIH=QHFgYUN[NrgSK2]if wIH.pkg.name==j then syvPi=true | |
break end end | |
if not | |
(syvPi)then el(RoEsr7So,{name=j,version=""}) | |
local TYWkpc=wjim8xCV(j,nil,"hel") | |
if not TYWkpc or not | |
qCaFw:match(YAtG_LV3.Version(TYWkpc.version))then | |
local k=qEO:getPackageSpec(j)local J=qEO:parsePackageJSON(k,qCaFw) | |
RoEsr7So[#RoEsr7So].version=J.version;local gtlO9=J.dependencies | |
for Lun=1,#gtlO9 do local beUJXhjw=gtlO9[Lun]syvPi=false;for zY7adu=1,#QHFgYUN do | |
local Nlvw=QHFgYUN[zY7adu] | |
if Nlvw.pkg.name==beUJXhjw.name then syvPi=true;break end end | |
if not syvPi then local K55=nil | |
for BJcMTdMi,f1MKKJ in | |
pairs(RoEsr7So)do if f1MKKJ.name==beUJXhjw.name then K55=BJcMTdMi;break end end | |
if K55 then | |
if RoEsr7So[K55].version==beUJXhjw.version then | |
Zg.fatal( | |
"Circular dependencies detected: '".. | |
tostring(j).. | |
"@".. | |
tostring(J.version).. | |
"' depends on '".. | |
tostring(beUJXhjw.name).. | |
"@".. | |
tostring(beUJXhjw.version).."', and '".. | |
tostring(RoEsr7So[K55].name).."@".. | |
tostring(RoEsr7So[K55].version).."' depends on '".. | |
tostring(j).."@"..tostring(J.version).."'.")else | |
Zg.fatal("Attempted to install two versions of the same package: '".. | |
tostring(beUJXhjw.name).. | |
"@".. | |
tostring(beUJXhjw.version).. | |
"' and '".. | |
tostring(RoEsr7So[K55].name).."@".. | |
tostring(RoEsr7So[K55].version).."' when resolving dependencies for '"..tostring(j).. | |
"@"..tostring(J.version).."'.")end end | |
qEO:resolveDependencies({{name=beUJXhjw.name,version=YAtG_LV3.Spec(beUJXhjw.version)}},QHFgYUN,RoEsr7So,dX)end end;el(QHFgYUN,{pkg=J})el(dX,{pkg=J})else | |
el(QHFgYUN,{pkg=TYWkpc})end;RoEsr7So[#RoEsr7So]=nil end end;return dX end | |
qEO.getPackageDependants=function(qEO,nFf,EIqL41,iv)if EIqL41 ==nil then EIqL41={}end;if iv==nil then iv={}end | |
for rfmMR4=1,#nFf | |
do local Tq2I=nFf[rfmMR4]local GNo=false | |
for e5x=1,#EIqL41 do local QrONvWGq=EIqL41[e5x]if | |
QrONvWGq.name==Tq2I then GNo=true;break end end | |
if not(GNo)then el(iv,{name=Tq2I}) | |
local D94fnZaa=wjim8xCV(Tq2I,nil,"hel") | |
if D94fnZaa then el(EIqL41,{name=Tq2I,manifest=D94fnZaa}) | |
local XI=iPL3B4cr(w(JQi1jg(xSebv5Jc,"hel"))) | |
for FNi in XI do D94fnZaa=iPL3B4cr(wjim8xCV(FNi,nil,"hel")) | |
local pRW2nEmK=D94fnZaa.dependencies | |
for OR=1,#pRW2nEmK do local Arww=pRW2nEmK[OR] | |
if Arww.name==Tq2I then GNo=false | |
for BYH=1,#EIqL41 do | |
local o7E8TLH=EIqL41[BYH]if o7E8TLH.name==FNi then GNo=true;break end end | |
if not GNo then | |
for N5N27Jd=1,#iv do local m=iv[N5N27Jd]if m.name==FNi then | |
Zg.fatal("Circular dependencies detected: "..tostring(FNi))end end;qEO:getPackageDependants({FNi},EIqL41,iv)end end end end else | |
Zg.fatal("Package ".. | |
tostring(Tq2I).." is referenced as a dependant of another package, however, this package isn't installed.")end;iv[#iv]=nil end end;return EIqL41 end | |
qEO.install=qTDt(function(qEO,...) | |
if sgeP.l or sgeP["local"]then | |
local GYVN=pzDMZwG.resolve(...) | |
local DNlB1V=iPL3B4cr(wjim8xCV(GYVN,JQi1jg(GYVN,"manifest"))) | |
local erb6G_E=qEO:resolveDependencies((function()local k8={}local HmgRk=1;local UuCdpVi=DNlB1V.dependencies | |
for fghe=1,#UuCdpVi do | |
local vFXf=UuCdpVi[fghe]local CA0uX7n,ze5Vpc3;CA0uX7n,ze5Vpc3=vFXf.name,vFXf.version | |
k8[HmgRk]={name=CA0uX7n,version=YAtG_LV3.Spec(ze5Vpc3)}HmgRk=HmgRk+1 end;return k8 end)())local QFUU10K=sgeP.d or sgeP.onlyDeps;local xNPDtul={}for vwK8=1,#erb6G_E do | |
local Sk_SiC=erb6G_E[vwK8] | |
el(xNPDtul,tostring(Sk_SiC.pkg.name).. | |
"@"..tostring(Sk_SiC.pkg.version))end;if | |
not(QFUU10K)then | |
el(xNPDtul,tostring(DNlB1V.name).."@"..tostring(DNlB1V.version))end | |
h6Ub7U({install=xNPDtul}) | |
for X0bgPvA=1,#erb6G_E,1 do local M9CyqH=erb6G_E[X0bgPvA] | |
Zg.print("Installing '".. | |
tostring(M9CyqH.pkg.name).. | |
"@"..tostring(M9CyqH.pkg.version).."'...")local z0x4qSAN=qEO:rawInstall(M9CyqH.pkg,false,false) | |
local X0GTupeV,rQ=Ki1HJT(z0x4qSAN,"hel") | |
if X0GTupeV then | |
Zg.info("Saved the manifest of '"..tostring(z0x4qSAN.name).."'.")else | |
Zg.fatal("Couldn't save the manifest of '"..tostring(z0x4qSAN.name).. | |
"': "..tostring(rQ)..".")end end | |
if not QFUU10K then | |
Zg.print("Installing '"..tostring(DNlB1V.name).."@".. | |
tostring(DNlB1V.version).."'...") | |
for IHovU,e_wDQjk in pairs(DNlB1V.files)do | |
if not | |
tE(JQi1jg(e_wDQjk.dir,e_wDQjk.name))then o5sms(e_wDQjk.dir)end | |
local ClglY,S=wVzn(JQi1jg(GYVN,e_wDQjk.url),JQi1jg(e_wDQjk.dir,e_wDQjk.name))if not(ClglY)then | |
Zg.fatal("Cannot copy file '".. | |
tostring(e_wDQjk.name).."': "..tostring(S))end end;local k,Oc=Ki1HJT(DNlB1V,"hel") | |
if k then | |
Zg.info("Saved the manifest of '"..tostring(DNlB1V.name).. | |
"'.")else | |
Zg.fatal("Couldn't save the manifest of '"..tostring(DNlB1V.name).. | |
"': "..tostring(Oc)..".")end end;return true end;local nK={}local _zr={...} | |
for NKetZhs=1,#_zr do local EFLZ0N1=_zr[NKetZhs]local gL,m4= | |
EFLZ0N1:match("^(.+)@(.+)$")or EFLZ0N1 | |
if N5UjTN(m4)then m4="*"end | |
Zg.info("Creating version specification for "..tostring(m4).." ...") | |
local rNOL8G,q=pcall(function()return YAtG_LV3.Spec(m4)end)if not(rNOL8G)then | |
Zg.fatal("Could not parse the version specification: "..tostring(q).."!")end | |
el(nK,{name=gL,version=q})end;local f5=sgeP.r or sgeP.reinstall | |
local UAc=sgeP.s or sgeP.save;local Ef=qEO:resolveDependencies(nK)local P={}local F4AWvI={} | |
for lKO=1,#Ef do local hcwgu=false | |
repeat | |
local omgCdqp8=Ef[lKO] | |
if f5 then local X17eHTx=false | |
for SGF=1,#nK do local myIHU=nK[SGF]if myIHU.name==omgCdqp8.pkg.name then | |
X17eHTx=true;break end end;if X17eHTx then | |
el(P,tostring(omgCdqp8.pkg.name).."@".. | |
tostring(omgCdqp8.pkg.version))hcwgu=true;break end end | |
el(F4AWvI,tostring(omgCdqp8.pkg.name).."@".. | |
tostring(omgCdqp8.pkg.version))hcwgu=true until true;if not hcwgu then break end end;h6Ub7U({install=F4AWvI,reinstall=P}) | |
if f5 then local xxNCdF | |
do local _cl1b={} | |
local Xz18nk=1;for PsTX4=1,#nK do local A0TJx=nK[PsTX4] | |
_cl1b[Xz18nk]=iPL3B4cr(wjim8xCV(A0TJx.name,nil,"hel"))Xz18nk=Xz18nk+1 end | |
xxNCdF=_cl1b end;qEO:_remove(xxNCdF,true,false)end | |
for Nqdkw=1,#Ef do local t=Ef[Nqdkw] | |
Zg.print("Installing '"..tostring(t.pkg.name).."@".. | |
tostring(t.pkg.version).."'...")local QbMO=false;for tx1LD=1,#nK do local N3ROeR=nK[tx1LD] | |
if N3ROeR.name==t.pkg.name then QbMO=true;break end end | |
local wYZ=qEO:rawInstall(t.pkg,QbMO,UAc)local aMd,o0pf=Ki1HJT(wYZ,"hel") | |
if aMd then | |
Zg.info("Saved the manifest of '".. | |
tostring(wYZ.name).."'.")else | |
Zg.fatal("Couldn't save the manifest of '"..tostring(wYZ.name).. | |
"': "..tostring(o0pf)..".")end end end) | |
qEO.remove=qTDt(function(qEO,...)local I1oQVnUd={...}local oTX={}for WZlF4=1,#I1oQVnUd do local IxqPDOWH=I1oQVnUd[WZlF4]local GZqV=iPL3B4cr(wjim8xCV(IxqPDOWH, | |
nil,"hel")) | |
el(oTX,GZqV)end;return | |
qEO:_remove(oTX,false)end) | |
qEO._remove=function(qEO,OVubrDw_,G2_TeR8,yk)if G2_TeR8 ==nil then G2_TeR8=false end | |
if yk==nil then yk=true end;local OPSPMfr_ | |
if not | |
RkGFh6.get("hel",{},true).get("remove_dependants",true)or not yk then | |
do | |
local QnNOl={}local aQs=1;for uow_0tb=1,#OVubrDw_ do local tykg=OVubrDw_[uow_0tb] | |
QnNOl[aQs]={name=tykg.name,manifest=tykg}aQs=aQs+1 end | |
OPSPMfr_=QnNOl end else | |
OPSPMfr_=qEO:getPackageDependants((function()local C_pPyW={}local mgb4b=1;for LOBqxO=1,#OVubrDw_ do local m8=OVubrDw_[LOBqxO] | |
C_pPyW[mgb4b]=m8.name;mgb4b=mgb4b+1 end;return C_pPyW end)())end | |
if not(G2_TeR8)then | |
h6Ub7U({remove=(function()local mcoAHO={}local d3gFWO=1 | |
for D=1,#OPSPMfr_ do local obodPKnu=OPSPMfr_[D] | |
mcoAHO[d3gFWO]= | |
"hel:"..tostring(obodPKnu.manifest.name).."@".. | |
tostring(obodPKnu.manifest.version)d3gFWO=d3gFWO+1 end;return mcoAHO end)()})end | |
for kgdzk=1,#OPSPMfr_ do local oVSp=OPSPMfr_[kgdzk] | |
Zg.print("Removing '".. | |
tostring(oVSp.manifest.name).. | |
"@"..tostring(oVSp.manifest.version).."' ...") | |
iPL3B4cr(eQWRf.__parent.remove(qEO,oVSp.manifest,"hel"))end;return true end | |
qEO.upgrade=qTDt(function(qEO)local uBJ={} | |
for YXgXQB in iPL3B4cr(w(JQi1jg(xSebv5Jc,"hel")))do if not | |
(XPoQB(JQi1jg(xSebv5Jc,"hel",YXgXQB)))then | |
el(uBJ,iPL3B4cr(wjim8xCV(YXgXQB,nil,"hel")))end end;local A={} | |
for bvL1X4=1,#uBJ do local PPNahh=uBJ[bvL1X4] | |
local z2g,m9JTkVv6=pcall(qEO.getPackageSpec,qEO,PPNahh.name) | |
if z2g then local Q=qEO:parsePackageJSON(m9JTkVv6) | |
PPNahh.latest={spec=m9JTkVv6,data=Q} | |
if YAtG_LV3.Version(PPNahh.latest.data.version)> | |
YAtG_LV3.Version(PPNahh.version)then el(A,PPNahh)end end end | |
local MP=qEO:resolveDependencies((function()local bWkP={}local JtFj=1 | |
for PQ3=1,#A do local _xCtN=A[PQ3] | |
bWkP[JtFj]={name=_xCtN.name,version=YAtG_LV3.Spec(_xCtN.latest.data.version)}JtFj=JtFj+1 end;return bWkP end)())local jb | |
do local JVpe={}local nG36XmZC=1 | |
for Vf26=1,#A do local xUGt=A[Vf26] | |
JVpe[nG36XmZC]=tostring(xUGt.name).. | |
"@{".. | |
tostring(xUGt.version).. | |
" => "..tostring(xUGt.latest.data.version).."}"nG36XmZC=nG36XmZC+1 end;jb=JVpe end;local uKSj={} | |
for _U=1,#MP do local hkI39=MP[_U]local MwwN=true | |
for oZ9=1,#A do local OXlT0=A[oZ9]if | |
OXlT0.name==hkI39.pkg.name then MwwN=false;break end end;if MwwN then | |
el(uKSj,tostring(hkI39.pkg.name).. | |
"@"..tostring(hkI39.pkg.version))end end;h6Ub7U({upgrade=jb,install=uKSj}) | |
for V=1,#MP do local zIYNIXy1=MP[V] | |
local c=false;local mReHt4h=false | |
for gs3a=1,#A do local AkKaBC=A[gs3a]if AkKaBC.name==zIYNIXy1.pkg.name then | |
c=AkKaBC;mReHt4h=AkKaBC.manual;break end end;if c then qEO:_remove({c},true,false)end | |
Zg.print("Installing '".. | |
tostring(zIYNIXy1.pkg.name).. | |
"@"..tostring(zIYNIXy1.pkg.version).."'...")local I7=qEO:rawInstall(zIYNIXy1.pkg,mReHt4h,false) | |
local Upw,nqBfKL=Ki1HJT(I7,"hel") | |
if Upw then | |
Zg.info("Saved the manifest of '"..tostring(I7.name).."'.")else | |
Zg.fatal("Couldn't save the manifest of '"..tostring(I7.name).. | |
"': "..tostring(nqBfKL)..".")end end end) | |
qEO.info=qTDt(function(qEO,OmRH8,GY)if GY==nil then GY="*"end;if N5UjTN(OmRH8)then | |
Zg.fatal("Usage: hpm hel:info <package name> [<version specification>]")end | |
if N5UjTN(GY)then GY="*"end | |
Zg.print("Creating version specification for "..tostring(GY).." ...") | |
local oukM79R,D_j=pcall(function()return YAtG_LV3.Spec(GY)end)if not(oukM79R)then | |
Zg.fatal("Could not parse the version specification: "..tostring(D_j).."!")end | |
local mZPe4w=qEO:getPackageSpec(OmRH8)local OvZ=qEO:parsePackageJSON(mZPe4w,D_j)local cBOpf={} | |
el(cBOpf,"- Package name: ".. | |
tostring(mZPe4w.name)) | |
el(cBOpf,"- Description:\n"..tostring(mZPe4w.description)) | |
el(cBOpf,"- Package owners: "..tostring(table.concat(mZPe4w.owners,", "))) | |
el(cBOpf,"- Authors:\n".. | |
tostring(table.concat((function()local KZYA5y={}local YoCAN7OU=1;local FoP=mZPe4w.authors;for jqtWXY=1,#FoP do | |
local XgRb=FoP[jqtWXY]KZYA5y[YoCAN7OU]=" - "..tostring(XgRb) | |
YoCAN7OU=YoCAN7OU+1 end;return KZYA5y end)(),"\n"))) | |
el(cBOpf,"- License: "..tostring(mZPe4w.license)) | |
el(cBOpf,"- Versions: "..tostring(O(mZPe4w.versions))..", latest: ".. | |
tostring(OvZ.version)) | |
el(cBOpf," - Files: "..tostring(#OvZ.files)) | |
el(cBOpf," - Depends: ".. | |
tostring(table.concat((function()local G3e={}local GoP6=1;local cZ_=OvZ.dependencies;for NYc8=1,#cZ_ do | |
local Dff8=cZ_[NYc8] | |
G3e[GoP6]=tostring(Dff8.name).."@"..tostring(Dff8.version)GoP6=GoP6+1 end | |
return G3e end)()))) | |
el(cBOpf," - Changes:\n".. | |
tostring(mZPe4w.versions[OvZ.version].changes))el(cBOpf,"- Stats:") | |
el(cBOpf," - Views: ".. | |
tostring(mZPe4w.stats.views)) | |
el(cBOpf,"- Creation date: ".. | |
tostring(mZPe4w.stats.date.created).." UTC") | |
el(cBOpf,"- Last updated: ".. | |
tostring(mZPe4w.stats.date["last-updated"]).." UTC")return Zg.print(table.concat(cBOpf,"\n"))end) | |
qEO.search=qTDt(function(qEO,...)local lEYwsOG9=0 | |
while true do local M={}local Vt95q2G=qEO.URL.."packages" | |
if...then | |
Vt95q2G=Vt95q2G.. | |
("?q=".. | |
table.concat((function(...) | |
local v9mB_RUi={}local hX=1;local AVU={...} | |
for I=1,#AVU do local _x5O1=AVU[I]v9mB_RUi[hX]='"'.. | |
_x5O1:gsub("\"","")..'"'hX=hX+1 end;return v9mB_RUi end)(...)," "):gsub("&",""))end | |
Vt95q2G=Vt95q2G.."?offset="..tostring(lEYwsOG9)local jsPbwU,Wvs3rd6o=M6ilzGJ(Vt95q2G)if not(jsPbwU)then | |
Zg.fatal("HTTP request error: "..Wvs3rd6o)end;local UdVlP="" | |
for eFI8dI3 in Wvs3rd6o do UdVlP=UdVlP..eFI8dI3 end;local N=s:decode(UdVlP)if not(N)then | |
Zg.fatal("Incorrect JSON format!\n"..tostring(UdVlP))end;M=N.data.list;for i=1,#M do local l6xUetCb=M[i] | |
Zg.print( | |
tostring(l6xUetCb.name)..": "..tostring(l6xUetCb.short_description))end | |
if | |
#M==0 and lEYwsOG9 ==0 then Zg.print("No packages found.")break end | |
if | |
N.data.truncated and N.data.sent+N.data.offset<N.data.total then lEYwsOG9=N.data.offset+N.data.sent else break end end end) | |
if WT2AX.__inherited then WT2AX.__inherited(WT2AX,eQWRf)end;_.hel=eQWRf end | |
do local lOb_Sv;local VspvGB9V=_.default;local LrFLp5={}LrFLp5.__index=LrFLp5 | |
setmetatable(LrFLp5,VspvGB9V.__base) | |
lOb_Sv=setmetatable({__init=function(Iz_w1j,...)return lOb_Sv.__parent.__init(Iz_w1j,...)end,__base=LrFLp5,__name="oppm",__parent=VspvGB9V},{__index=function(G,X7YKzX) | |
local od0VOF=rawget(LrFLp5,X7YKzX)if od0VOF==nil then local oO6SbZ=rawget(G,"__parent") | |
if oO6SbZ then return oO6SbZ[X7YKzX]end else return od0VOF end end,__call=function(UE_vrsNx,...) | |
local kef2zBS=setmetatable({},LrFLp5)UE_vrsNx.__init(kef2zBS,...)return kef2zBS end})LrFLp5.__class=lOb_Sv;local GfB7=lOb_Sv | |
GfB7.REPOS="https://raw.githubusercontent.com/OpenPrograms/openprograms.github.io/master/repos.cfg"GfB7.PACKAGES="https://raw.githubusercontent.com/%s/master/programs.cfg" | |
GfB7.FILES="https://raw.githubusercontent.com/%s/%s"GfB7.DIRECTORY="https://api.github.com/repos/%s/contents/%s?ref=%s" | |
GfB7.DEFAULT_CACHE_DIRECTORY="/var/cache/hpm/oppm" | |
GfB7.cacheDirectory=function(GfB7) | |
local Z=RkGFh6.get("oppm",{},true).get("cache_directory",GfB7.DEFAULT_CACHE_DIRECTORY) | |
if not(tE(Z))then local ze0,ylW3uC0=o5sms(Z)if not(ze0)then | |
Zg.fatal("Could not create the cache directory at ".. | |
tostring(Z)..": "..tostring(ylW3uC0))end end;return Z end | |
GfB7.listCache=function(GfB7)local N_G1={}local wkGNE=GfB7:cacheDirectory() | |
local ccK=iPL3B4cr(w(wkGNE)) | |
for BV in ccK do | |
if XPoQB(JQi1jg(wkGNE,BV))then | |
local HnLY=iPL3B4cr(w(JQi1jg(wkGNE,BV))) | |
for cm51CH1n in HnLY do | |
if XPoQB(JQi1jg(wkGNE,BV,cm51CH1n))then | |
local iWrSgT=iPL3B4cr(w(JQi1jg(wkGNE,BV,cm51CH1n))) | |
for C in iWrSgT do local YK1=JQi1jg(wkGNE,BV,cm51CH1n,C) | |
if not(XPoQB(YK1))then local t96Qtz | |
do | |
local Ub9iqg,r_S8HFRo=io.open(YK1,"r")if not Ub9iqg then | |
return false,"Could not open '"..tostring(YK1).. | |
"' for reading: "..tostring(r_S8HFRo)end | |
qLH5=Ub9iqg:read("*all")t96Qtz=QJf(qLH5)Ub9iqg:close()end;local HjKNi=JQi1jg(BV,cm51CH1n) | |
el(N_G1,{path=YK1,repo=HjKNi,pkg=C,data=t96Qtz})end end end end end end;return N_G1 end | |
GfB7.fixCache=function(GfB7)local qIF4RFBv=GfB7:cacheDirectory() | |
local wNbC65Ta=iPL3B4cr(w(qIF4RFBv)) | |
for xOiPW in wNbC65Ta do local Z9j=true;local r=JQi1jg(qIF4RFBv,xOiPW) | |
if XPoQB(r)then | |
local OnJ1=iPL3B4cr(w(r)) | |
for KFU0 in OnJ1 do local Pvuq=true;local lOpDJ=JQi1jg(r,KFU0) | |
if XPoQB(lOpDJ)then | |
local YLe=iPL3B4cr(w(lOpDJ)) | |
for lTH in YLe do local JL=true;local FpU_E=JQi1jg(lOpDJ,lTH)if not(XPoQB(FpU_E))then | |
JL,Pvuq,Z9j=false,false,false end;if JL then OO(FpU_E)end end end;if Pvuq then OO(lOpDJ)end end end;if Z9j then OO(r)end end;return true end | |
GfB7.resolveDirectory=function(GfB7,JWtwnQ2t,uEKPPpj_,aYO4NN) | |
local CtG9nSQL=iPL3B4cr(Ta(GfB7.DIRECTORY:format(JWtwnQ2t,aYO4NN,uEKPPpj_)))CtG9nSQL=s:decode(CtG9nSQL) | |
if CtG9nSQL.message then | |
return false,"Could not fetch ".. | |
tostring(JWtwnQ2t)..":".. | |
tostring(uEKPPpj_).."/"..tostring(aYO4NN).. | |
": "..tostring(CtG9nSQL.message)end;local uZtK5yX={}local kr2CYaS=1 | |
for hXgSzEI=1,#CtG9nSQL do local AUQ=CtG9nSQL[hXgSzEI] | |
if AUQ.type=="file"then | |
uZtK5yX[kr2CYaS]={name=AUQ.name,url=AUQ.download_url,path=AUQ.path}kr2CYaS=kr2CYaS+1 end end;return uZtK5yX end | |
GfB7.updateCache=function(GfB7)local B=GfB7:cacheDirectory() | |
local J=iPL3B4cr(GfB7:listCache())local coSiE,wm=Ta(GfB7.REPOS)if not(coSiE)then | |
return false,"Could not fetch "..tostring(GfB7.REPOS)..": ".. | |
tostring(wm)end;coSiE=QJf(coSiE)local _O={} | |
for obBu,cbQlG in | |
pairs(coSiE)do local YZQu1DR4=false | |
repeat | |
if cbQlG.repo then | |
Zg.info("Fetching '"..tostring(obBu).."' at '".. | |
tostring(cbQlG.repo).."' ...")local kza,CvGDk_2 | |
kza,CvGDk_2,wm=M6ilzGJ(GfB7.PACKAGES:format(cbQlG.repo)) | |
if not(kza and CvGDk_2)then | |
Zg.error("Could not fetch '".. | |
tostring(obBu).."' at '".. | |
tostring(cbQlG.repo).."': "..tostring(wm))YZQu1DR4=true;break end;local EGpun="" | |
for kza,cnx_1g in function()return pcall(CvGDk_2)end do | |
if not kza then | |
Zg.error("Could not fetch '".. | |
tostring(obBu).."' at '".. | |
tostring(cbQlG.repo).."': "..tostring(cnx_1g))EGpun=false;break else if not cnx_1g then break end;EGpun=EGpun..cnx_1g end end;if EGpun==false then YZQu1DR4=true;break end | |
if N5UjTN(EGpun)then | |
Zg.error("Could not fetch '".. | |
tostring(obBu).."' at '"..tostring(cbQlG.repo).."'")YZQu1DR4=true;break end;local LNlhK;LNlhK,wm=QJf(EGpun) | |
if not LNlhK then | |
Zg.error("Manifest '"..tostring(obBu).. | |
"' at '".. | |
tostring(cbQlG.repo).."' is malformed: "..tostring(wm))YZQu1DR4=true;break end | |
for eV,DGQnw in pairs(LNlhK)do local yLgHuF=false | |
repeat | |
if eV:match("[^A-Za-z0-9._-]")then | |
Zg.error( | |
"Package name contains illegal characters: "..tostring(obBu)..":"..tostring(eV).."!")yLgHuF=true;break end;el(_O,{repo=cbQlG.repo,name=eV,data=DGQnw}) | |
yLgHuF=true until true;if not yLgHuF then break end end end;YZQu1DR4=true until true;if not YZQu1DR4 then break end end;local smj={} | |
for fpL=1,#_O do local k6=_O[fpL]local m,rvNhq6v,gC;m,rvNhq6v,gC=k6.name,k6.repo,k6.data;if | |
n(JQi1jg(rvNhq6v,m),smj)then | |
Zg.error("There're multiple packages under the same name: "..tostring(m).."!")end | |
if not | |
(tE(JQi1jg(B,rvNhq6v)))then local fSYJX;fSYJX,wm=o5sms(JQi1jg(B,rvNhq6v))if | |
not(fSYJX)then | |
return false,"Could not create directory '".. | |
tostring(JQi1jg(B,rvNhq6v)).."': "..tostring(wm)end end;local QO;QO,wm=io.open(JQi1jg(B,rvNhq6v,m),"w")if not(QO)then | |
return false, | |
"Could not open '".. | |
tostring(JQi1jg(B,rvNhq6v,m)).."' for writing: "..tostring(wm)end;do | |
QO:write(RSjapQ({name=m,repo=rvNhq6v,data=gC}))QO:close()end;local VvzMQHj | |
do for WV,yUho4MXRx in pairs(J)do | |
if | |
yUho4MXRx.repo==rvNhq6v and yUho4MXRx.pkg==m then VvzMQHj=WV;break end end end;if VvzMQHj then table.remove(J,VvzMQHj)else | |
el(smj,JQi1jg(rvNhq6v,m))end end;Zg.print("Removing old cache files ...")for J2=1,#J do | |
local hgrBfz0w=J[J2]local Gi;Gi=hgrBfz0w.path;OO(Gi)end | |
Zg.print("Fixing bad cache nodes ...")GfB7:fixCache() | |
Zg.print("- "..tostring(#_O).." program"..tostring(pX4gCR(#_O)).. | |
" cached.") | |
Zg.print("- "..tostring(#smj).. | |
" package"..tostring(pX4gCR(#smj)).." ".. | |
tostring(dk(#smj)).." new.") | |
Zg.print("- "..tostring(#J).. | |
" package"..tostring(pX4gCR(#J)).." no longer exist".. | |
tostring(gad4ZcL(#J))..".")return true end | |
GfB7.parseLocalPath=function(GfB7,wpv1,I9IMuWm) | |
if I9IMuWm:sub(1,2)=="//"then return | |
JQi1jg(wpv1,I9IMuWm:sub(3))else return JQi1jg(wpv1,"usr",I9IMuWm)end end | |
GfB7.rawInstall=function(GfB7,a,rZ,VKTNfzUf,Oms4)if rZ==nil then rZ="/"end | |
if VKTNfzUf==nil then VKTNfzUf=false end;if Oms4 ==nil then Oms4=false end;local JfA=GfB7:listCache() | |
local CPu1={filesInstalled=0,packagesInstalled=0} | |
if Oms4 and not tE(rZ)then local mLgQ,ng=o5sms(rZ)if not(mLgQ)then | |
Zg.fatal("Failed to create '".. | |
tostring(rZ).. | |
"' directory for package '"..tostring(a).."'! \n"..tostring(ng))end elseif not Oms4 then local Pp_NboV=wjim8xCV(a, | |
nil,"oppm")if Pp_NboV then | |
Zg.print("'".. | |
tostring(a).."' is already installed, skipping...")return Pp_NboV,CPu1 end end;local pfyhF | |
for owAp3u2G=1,#JfA do local OH0C=JfA[owAp3u2G]local kmQkm9cr,IE97m,wey,hThO6 | |
kmQkm9cr,IE97m,wey,hThO6=OH0C.path,OH0C.pkg,OH0C.repo,OH0C.data;if IE97m==a then pfyhF=OH0C;break end end;if not(pfyhF)then | |
Zg.fatal("No such package: "..tostring(a))end;local pglFz82w={}local RkeCL=pfyhF.repo | |
for zXU,HmJym2 in | |
pairs(pfyhF.data.data.files)do local Jjb7Am5={} | |
if zXU:sub(1,1)==":"then | |
Jjb7Am5=GfB7:resolveDirectory(RkeCL,zXU:sub(2,zXU:find("/")-1, | |
nil),zXU:sub(zXU:find("/")+1))else | |
Jjb7Am5={{name=pE.name(zXU),path=zXU,url=GfB7.FILES:format(RkeCL,zXU)}}end;local a | |
for UwqY7A=1,#Jjb7Am5 do local k=Jjb7Am5[UwqY7A]local d7gPKcw,naeNp | |
a,d7gPKcw,naeNp=k.name,k.path,k.url;local gA=iPL3B4cr(Ta(naeNp)) | |
local r=GfB7:parseLocalPath(rZ,HmJym2)if not(tE(r))then o5sms(r)end | |
do | |
local LWe,_3Tq=io.open(JQi1jg(r,a),"w")if not LWe then | |
Zg.fatal("Could not open file for writing: "..tostring(_3Tq))end;LWe:write(gA) | |
LWe:close()end;CPu1.filesInstalled=CPu1.filesInstalled+1 | |
el(pglFz82w,{name=a,url=naeNp,dir=r})end end;local LoW_7e={}if pfyhF.data.data.dependencies then | |
for Rq1hByv in | |
pairs(pfyhF.data.data.dependencies)do el(LoW_7e,{name=Rq1hByv})end end;CPu1.packagesInstalled= | |
CPu1.packagesInstalled+1;return | |
{name=a,files=pglFz82w,dependencies=LoW_7e,manual=VKTNfzUf},CPu1 end | |
GfB7.resolveDependencies=function(GfB7,iFk,sEFtmNgB,qxiez0Cn,Ck_H)if sEFtmNgB==nil then sEFtmNgB={}end;if qxiez0Cn==nil then | |
qxiez0Cn={}end;if Ck_H==nil then Ck_H={}end | |
local Sc=GfB7:listCache() | |
for _QFw_It=1,#iFk do local WLqHf=iFk[_QFw_It]local vN=false | |
for BIwW6_=1,#sEFtmNgB do local Vdfc3=sEFtmNgB[BIwW6_]if | |
Vdfc3 ==WLqHf then vN=true;break end end | |
if not(vN)then qxiez0Cn[WLqHf]=true | |
local CzM7PG=wjim8xCV(WLqHf,nil,"oppm") | |
if not CzM7PG then local RKf6s5 | |
for tP9E_=1,#Sc do local Y1WX=Sc[tP9E_]local G06Z2;G06Z2=Y1WX.pkg;if G06Z2 ==WLqHf then | |
RKf6s5=Y1WX;break end end;if not(RKf6s5)then | |
return false,"Unknown package: "..tostring(WLqHf)end | |
if RKf6s5.data.data.dependencies then | |
for K in | |
pairs(RKf6s5.data.data.dependencies)do vN=false;for tQx9TV=1,#sEFtmNgB do local FL7g2o=sEFtmNgB[tQx9TV] | |
if FL7g2o==K then vN=true;break end end | |
if not(vN)then | |
if qxiez0Cn[K]then | |
Zg.fatal( | |
"Circular dependencies detected: '"..tostring(WLqHf).. | |
"' depends on '"..tostring(K).. | |
"', and '"..tostring(K).."' depends on '".. | |
tostring(WLqHf).."'.")end | |
GfB7:resolveDependencies({K},sEFtmNgB,qxiez0Cn,Ck_H)end end end;el(Ck_H,WLqHf)end;el(sEFtmNgB,WLqHf)qxiez0Cn[WLqHf]=nil end end;return Ck_H end | |
GfB7.getPackageDependants=function(GfB7,dkh7Tt9,XiNd_H,Q_c4px86)if XiNd_H==nil then XiNd_H={}end | |
if Q_c4px86 ==nil then Q_c4px86={}end | |
for _F6VYt=1,#dkh7Tt9 do local ITv3PH1i=dkh7Tt9[_F6VYt]local _5fF=false | |
for OUQqQp=1,#XiNd_H do | |
local OyOfzTWn=XiNd_H[OUQqQp]if OyOfzTWn.name==ITv3PH1i then _5fF=true;break end end | |
if not(_5fF)then el(Q_c4px86,{name=ITv3PH1i}) | |
local rx=wjim8xCV(ITv3PH1i,nil,"oppm") | |
if rx then el(XiNd_H,{name=ITv3PH1i,manifest=rx}) | |
local ijvSrZA1=iPL3B4cr(w(JQi1jg(xSebv5Jc,"oppm"))) | |
for STNuSN6 in ijvSrZA1 do rx=iPL3B4cr(wjim8xCV(STNuSN6,nil,"oppm")) | |
local PYOeGnAZ=rx.dependencies | |
for s10ar5XH=1,#PYOeGnAZ do local YoKhvIs=PYOeGnAZ[s10ar5XH] | |
if YoKhvIs.name==ITv3PH1i then | |
_5fF=false;for I2ipE=1,#XiNd_H do local qS730I=XiNd_H[I2ipE] | |
if qS730I.name==STNuSN6 then _5fF=true;break end end | |
if not _5fF then | |
for PYEbnua=1,#Q_c4px86 do | |
local Um4ZYiT=Q_c4px86[PYEbnua]if Um4ZYiT.name==STNuSN6 then | |
Zg.fatal("Circular dependencies detected: "..tostring(STNuSN6))end end | |
GfB7:getPackageDependants({STNuSN6},XiNd_H,Q_c4px86)end end end end else | |
Zg.fatal("Package ".. | |
tostring(ITv3PH1i).." is referenced as a dependant of another package, however, this package isn't installed.")end;Q_c4px86[#Q_c4px86]=nil end end;return XiNd_H end | |
GfB7.whatDependsOn=function(GfB7,AF)local shIHW=iPL3B4cr(wjim8xCV(AF,nil,"oppm")) | |
local H5={} | |
local HYY=iPL3B4cr(w(JQi1jg(xSebv5Jc,"oppm"))) | |
for C3 in HYY do shIHW=iPL3B4cr(wjim8xCV(C3,nil,"oppm")) | |
local SkCMMH=shIHW.dependencies;for kvvs=1,#SkCMMH do local _yTx3S94=SkCMMH[kvvs] | |
if _yTx3S94.name==AF then el(H5,C3)end end end;return H5 end | |
GfB7.install=qTDt(function(GfB7,...)local Mm={...}local g524=sgeP.r or sgeP.reinstall;local WUdVeYc=sgeP.s or | |
sgeP.save | |
local lHep6wo=iPL3B4cr(GfB7:resolveDependencies(Mm)) | |
h6Ub7U({install=(function()local Sw={}local W67mm9p6=1;for oBxdTi6u=1,#lHep6wo do local T7hLe5j=lHep6wo[oBxdTi6u] | |
if not g524 or | |
not n(T7hLe5j,Mm)then Sw[W67mm9p6]=T7hLe5j;W67mm9p6=W67mm9p6+1 end end | |
return Sw end)(),reinstall= | |
g524 and | |
(function()local I_={}local J2Jin=1;for Rvg=1,#lHep6wo do local HpdA=lHep6wo[Rvg]if n(HpdA,Mm)then I_[J2Jin]=HpdA | |
J2Jin=J2Jin+1 end end;return | |
I_ end)()or nil})local BKZsJ={filesInstalled=0,packagesInstalled=0} | |
if g524 then local DsAJbW | |
do local AXfX={}local btcUUhB=1;for iw0S=1,#Mm do | |
local Tjg=Mm[iw0S] | |
AXfX[btcUUhB]=iPL3B4cr(wjim8xCV(Tjg,nil,"oppm"))btcUUhB=btcUUhB+1 end | |
DsAJbW=AXfX end;GfB7:_remove(DsAJbW,true,false)end | |
for n2srE7H=1,#lHep6wo do local Rf=lHep6wo[n2srE7H] | |
Zg.print("Installing '"..tostring(Rf).."'...")local X9ZjrTz | |
if WUdVeYc then X9ZjrTz="./"..tostring(Rf).."/"else X9ZjrTz="/"end | |
local tYFIuD,Ht5Ge=GfB7:rawInstall(Rf,X9ZjrTz,n(Rf,Mm),WUdVeYc) | |
BKZsJ.filesInstalled=BKZsJ.filesInstalled+Ht5Ge.filesInstalled | |
BKZsJ.packagesInstalled=BKZsJ.packagesInstalled+Ht5Ge.packagesInstalled | |
if BKZsJ.packagesInstalled~=0 then local l,IO=Ki1HJT(tYFIuD,"oppm") | |
if l then | |
Zg.info( | |
"Saved the manifest of '"..tostring(tYFIuD.name).."'.")else | |
Zg.fatal("Couldn't save the manifest of '"..tostring(tYFIuD.name).. | |
"': "..tostring(IO)..".")end end end | |
Zg.print("- ".. | |
tostring(BKZsJ.packagesInstalled).." package".. | |
tostring(pX4gCR(BKZsJ.packagesInstalled)).." installed.")return | |
Zg.print("- ".. | |
tostring(BKZsJ.filesInstalled).." file".. | |
tostring(pX4gCR(BKZsJ.filesInstalled)).." installed.")end) | |
GfB7.remove=qTDt(function(GfB7,...)local YDJY={...}local t={}for Rdi8NIft=1,#YDJY do local J0uTkQ9=YDJY[Rdi8NIft] | |
local sd6k=iPL3B4cr(wjim8xCV(J0uTkQ9,nil,"oppm"))el(t,sd6k)end;return | |
GfB7:_remove(t,false)end) | |
GfB7._remove=function(GfB7,a,lK7,KWMxs7a)if lK7 ==nil then lK7=false end | |
if KWMxs7a==nil then KWMxs7a=true end;local T | |
if | |
not | |
RkGFh6.get("oppm",{},true).get("remove_dependants",true)or not KWMxs7a then | |
do local LBIp4={}local A5=1;for PV168s0f=1,#a do local bjK=a[PV168s0f] | |
LBIp4[A5]={name=bjK.name,manifest=bjK}A5=A5+1 end;T=LBIp4 end else | |
T=GfB7:getPackageDependants((function()local Us1Xh={}local rs59=1;for R=1,#a do local rGa2MaGH=a[R] | |
Us1Xh[rs59]=rGa2MaGH.name;rs59=rs59+1 end;return Us1Xh end)())end | |
if not(lK7)then | |
h6Ub7U({remove=(function()local i6={}local u33wPQT=1;for aNrMnPZ=1,#T do local fC=T[aNrMnPZ] | |
i6[u33wPQT]=tostring(fC.name)u33wPQT=u33wPQT+1 end;return i6 end)()})end | |
for Kl=1,#T do local EmJGBwA=T[Kl] | |
Zg.print("Removing '".. | |
tostring(EmJGBwA.manifest.name).."' ...") | |
iPL3B4cr(lOb_Sv.__parent.remove(GfB7,EmJGBwA.manifest,"oppm"))end;return true end | |
GfB7.cache=qTDt(function(GfB7,_E3,...)local j3=_E3 | |
if"update"==j3 then | |
Zg.print("Updating OpenPrograms program cache ...")iPL3B4cr(GfB7:updateCache()) | |
return Zg.print("Done.")elseif"fix"==j3 then | |
Zg.print("Fixing OpenPrograms program cache ...")iPL3B4cr(GfB7:fixCache())return Zg.print("Done.")else | |
Zg.error("Unknown command.")return Zg.print("Usage: hpm oppm:cache {update|fix}")end end) | |
GfB7.autoremove=qTDt(function(GfB7)local f={}local jy={} | |
local Ifev2bUE=iPL3B4cr(w(JQi1jg(xSebv5Jc,"oppm"))) | |
for ZY in Ifev2bUE do local KCpJbzHT=iPL3B4cr(wjim8xCV(ZY,nil,"oppm"))if not | |
(KCpJbzHT.manual)then local g=GfB7:getPackageDependants(ZY)if#g==1 then el(f,ZY) | |
el(jy,ZY)end end end | |
while true do local dQl0xvy2=false | |
Ifev2bUE=iPL3B4cr(w(JQi1jg(xSebv5Jc,"oppm"))) | |
for hX in Ifev2bUE do | |
if not(n(hX,f))then | |
local wYTrvPn=iPL3B4cr(wjim8xCV(hX,nil,"oppm")) | |
if not(wYTrvPn.manual)then | |
local pB6K=GfB7:getPackageDependants(hX)table.remove(pB6K,1) | |
if | |
qLH5((function()local YV={}local zPm=1;for JmEyZ5=1,#pB6K do local FGvy=pB6K[JmEyZ5] | |
YV[zPm]=n(FGvy.name,f)zPm=zPm+1 end;return YV end)())then | |
for KpnA=1,#pB6K do local j_F9c=pB6K[KpnA]local q,b7G0ciz=n(j_F9c.name,jy)if b7G0ciz then | |
table.remove(jy,b7G0ciz)end end;el(f,hX)el(jy,hX)dQl0xvy2=true end end end end;if not(dQl0xvy2)then break end end | |
h6Ub7U({remove=(function() | |
if#f>0 then local rF2te={}local KG_EjN=1;for aIrjXeB=1,#f do local sZdri=f[aIrjXeB] | |
rF2te[KG_EjN]="oppm:"..tostring(sZdri)KG_EjN=KG_EjN+1 end | |
return rF2te else return nil end end)()})for pT=1,#jy do local XgkgIR9=jy[pT] | |
GfB7:_remove({iPL3B4cr(wjim8xCV(XgkgIR9,nil,"oppm"))},false)end | |
Zg.print("Done.")return true end) | |
GfB7.search=qTDt(function(GfB7,...)local sm2=GfB7:listCache()local cz={} | |
if...then | |
for pSL=1,#sm2 do local ifrP9=sm2[pSL]local Iynmp | |
Iynmp=ifrP9.data;local PFvHX=Iynmp.data;local sP={...} | |
for Y=#sP,1,-1 do local QHxdp58D=sP[Y]if | |
Iynmp.name:find(QHxdp58D)then table.remove(sP,Y)break end | |
if PFvHX.name and | |
PFvHX.name:find(QHxdp58D)then table.remove(sP,Y)break end;if | |
PFvHX.description and PFvHX.description:find(QHxdp58D)then table.remove(sP,Y)break end;if | |
PFvHX.note and PFvHX.note:find(QHxdp58D)then | |
table.remove(sP,Y)break end end;if#sP==0 then el(cz,Iynmp)end end else | |
do local efdknL={}local YUdva=1;for x8FBS=1,#sm2 do local LGBr=sm2[x8FBS]efdknL[YUdva]=LGBr.data | |
YUdva=YUdva+1 end;cz=efdknL end end;for M=1,#cz do local I=cz[M] | |
Zg.print(tostring(I.name).." - ".. | |
tostring(I.data.name or I.name)..": "..tostring(I.data.description))end end) | |
GfB7.info=qTDt(function(GfB7,W)if N5UjTN(W)then | |
Zg.fatal("Usage: hpm oppm:info <package name>")end;local Dx5GC=GfB7:listCache()local kwZhI=nil | |
for T0h=1,# | |
Dx5GC do local H0=Dx5GC[T0h]if H0.pkg==W then kwZhI=H0;break end end | |
if not(kwZhI)then Zg.fatal("No such package.")end | |
Zg.print("- Package name: "..tostring(kwZhI.pkg))if kwZhI.data.data.name then | |
Zg.print(" ".. | |
tostring(kwZhI.data.data.name))end;if kwZhI.data.data.description then | |
Zg.print( | |
"- Description:\n"..tostring(kwZhI.data.data.description))end;if | |
kwZhI.data.data.authors then | |
Zg.print("- Authors:\n"..tostring(kwZhI.data.data.authors))end;if kwZhI.data.data.files then | |
Zg.print( | |
"- Files: "..tostring(O(kwZhI.data.data.files)))end | |
if | |
kwZhI.data.data.dependencies then | |
Zg.print("- Depends: ".. | |
tostring(table.concat((function()local Mrz66={}local A=1;for RR in | |
pairs(kwZhI.data.data.dependencies)do Mrz66[A]=RR;A=A+1 end;return Mrz66 end)())))end;if kwZhI.data.data.note then | |
Zg.print("- Note:\n".. | |
tostring(kwZhI.data.data.note))end | |
return Zg.print("- Repository: https://github.com/".. | |
tostring(kwZhI.repo))end) | |
if VspvGB9V.__inherited then VspvGB9V.__inherited(VspvGB9V,lOb_Sv)end;_.oppm=lOb_Sv end;local Gm | |
Gm=function()local Oj4B=iPL3B4cr(w(xSebv5Jc))N5UjTN=true | |
for aT in Oj4B do | |
local ZN0brC=pE.name(aT) | |
if XPoQB(JQi1jg(xSebv5Jc,ZN0brC))then | |
local g=iPL3B4cr(w(JQi1jg(xSebv5Jc,ZN0brC))) | |
for iYIip_rt in g do | |
if | |
not(XPoQB(JQi1jg(xSebv5Jc,ZN0brC,iYIip_rt)))then | |
local WoJla=iPL3B4cr(wjim8xCV(iYIip_rt,nil,ZN0brC)) | |
Zg.print(ZN0brC..":"..iYIip_rt.. | |
(WoJla.version and" @ "..WoJla.version or""))N5UjTN=false end end end end | |
if N5UjTN then return Zg.print("No packages installed.")end end;local YKA7cU | |
YKA7cU=function(...)CM,sgeP=JD(...)if#CM<1 then return y36Aetn()end end;local mCsewfX | |
mCsewfX=function()local jk=CM[1] | |
if"list"==jk then return Gm()elseif"help"==jk then return y36Aetn()else | |
do | |
local Y=wZdg(CM[1]) | |
if Y then return | |
Y(Wu_uIt((function()local sM={}local MMJEx=1 | |
for EB=2,#CM do local Qy=CM[EB]sM[MMJEx]=Qy;MMJEx=MMJEx+1 end;return sM end)()))end end end end | |
hw18.semver={Version=YAtG_LV3.Version,Spec=YAtG_LV3.Spec,SpecItem=YAtG_LV3.SpecItem,compare=YAtG_LV3.compare,match=YAtG_LV3.match,validate=YAtG_LV3.validate}hw18.json=s;hw18.CONFIG_PATH=rDtVf;hw18.USAGE=vj;hw18.DEFAULT_CONFIG=z | |
hw18.options=sgeP;hw18.args=CM;hw18.request=Qlmlet;hw18.modules=_;hw18.config=RkGFh6 | |
hw18.modulePath=nvCiFt7r;hw18.distPath=xSebv5Jc;hw18.exitCode=mMp;hw18.log=Zg;hw18.assert=ykRppH | |
hw18.unimplemented=WQ6;hw18.printUsage=y36Aetn;hw18.try=iPL3B4cr;hw18.checkType=GI2hz6SK | |
hw18.argNumber=Oh;hw18.argString=PG;hw18.isin=n;hw18.tableLen=O;hw18.empty=N5UjTN | |
hw18.all=qLH5;hw18.existsDir=tE;hw18.existsFile=VcV0EuD;hw18.plural=pX4gCR | |
hw18.singular=gad4ZcL;hw18.linkingVerb=dk;hw18.remove=OO;hw18.loadConfig=y | |
hw18.checkInternet=cR6rJlAl;hw18.download=M6ilzGJ;hw18.findCustomCommand=wZdg;hw18.getModuleBy=BaX | |
hw18.callModuleMethod=SJsW11k;hw18.saveManifest=Ki1HJT;hw18.loadManifest=wjim8xCV | |
hw18.removeManifest=EQLam;hw18.public=qTDt;hw18.wrapResponse=v;hw18.recv=Ta;hw18.confirm=unArcvQl | |
hw18.pkgPlan=h6Ub7U;hw18.printPackageList=Gm;hw18.parseArguments=YKA7cU;hw18.process=mCsewfX;for rCWKBim,i in | |
pairs(_G)do hw18[rCWKBim]=i end;YKA7cU(...) | |
iPL3B4cr(y())iW6CD()mCsewfX()return mMp |
local JtAjijkG=load([===[ | |
local rA5U=20160728.17 | |
local Uc06="-[ JSON.lua package by Jeffrey Friedl (http://regex.info/blog/lua/json) version 20160728.17 ]-"local lcBL={VERSION=rA5U,AUTHOR_NOTE=Uc06}local DHPxI=" " | |
local dx={pretty=true,align_keys=false,indent=DHPxI} | |
local RRuSHnxf={__tostring=function()return"JSON array"end}RRuSHnxf.__index=RRuSHnxf | |
local mcYOuT={__tostring=function()return"JSON object"end}mcYOuT.__index=mcYOuT;function lcBL:newArray(iXxD6s) | |
return setmetatable(iXxD6s or{},RRuSHnxf)end;function lcBL:newObject(oiY)return | |
setmetatable(oiY or{},mcYOuT)end;local function Rr(FsYIVlkf) | |
return | |
type(FsYIVlkf)=='number'and FsYIVlkf or FsYIVlkf.N end | |
local scRP0={__index=isNumber,__tostring=function(HLXS0Q_)return HLXS0Q_.S end,__unm=function(Kw)return | |
Rr(Kw)end,__concat=function(nvaIsNv7,vDnoL55) | |
return tostring(nvaIsNv7)..tostring(vDnoL55)end,__add=function(xlAK,zr1y)return Rr(xlAK)+Rr(zr1y)end,__sub=function(Hs,jk)return | |
Rr(Hs)-Rr(jk)end,__mul=function(qzSFyIO,Z65) | |
return Rr(qzSFyIO)*Rr(Z65)end,__div=function(umyCNfj,FT)return Rr(umyCNfj)/Rr(FT)end,__mod=function(YVLXYq,bJfct)return | |
Rr(YVLXYq)%Rr(bJfct)end,__pow=function(OhuFpq_N,Dzg)return | |
Rr(OhuFpq_N)^Rr(Dzg)end,__lt=function(_4O,C)return Rr(_4O)<Rr(C)end,__eq=function(fLI2zRe,_Fr2YU)return | |
Rr(fLI2zRe)==Rr(_Fr2YU)end,__le=function(Xfn,U)return | |
Rr(Xfn)<=Rr(U)end} | |
function lcBL:asNumber(Ebsw) | |
if getmetatable(Ebsw)==scRP0 then return Ebsw elseif | |
type(Ebsw)=='table'and | |
type(Ebsw.S)=='string'and type(Ebsw.N)=='number'then return setmetatable(Ebsw,scRP0)else | |
local UlikV={S=tostring(Ebsw),N=tonumber(Ebsw)}return setmetatable(UlikV,scRP0)end end | |
local function AI0R2TQ6(JtAjijkG) | |
if JtAjijkG<=127 then return string.char(JtAjijkG)elseif JtAjijkG<=2047 then | |
local s=math.floor(JtAjijkG/0x40)local YAtG_LV3=JtAjijkG- (0x40*s)return | |
string.char(0xC0+s,0x80+YAtG_LV3)elseif JtAjijkG<=65535 then | |
local LfEJbh_=math.floor(JtAjijkG/0x1000)local JD=JtAjijkG-0x1000*LfEJbh_ | |
local u=math.floor(JD/0x40)local pzDMZwG=JD-0x40*u;LfEJbh_=0xE0+LfEJbh_;u=0x80+u | |
pzDMZwG=0x80+pzDMZwG | |
if | |
(LfEJbh_==0xE0 and u<0xA0)or | |
(LfEJbh_==0xED and u>0x9F)or(LfEJbh_==0xF0 and u<0x90)or(LfEJbh_==0xF4 and u>0x8F)then return"?"else return string.char(LfEJbh_,u,pzDMZwG)end else local XPoQB=math.floor(JtAjijkG/0x40000) | |
local XxJ=JtAjijkG-0x40000*XPoQB;local o5sms=math.floor(XxJ/0x1000) | |
XxJ=XxJ-0x1000*o5sms;local JQi1jg=math.floor(XxJ/0x40)local wVzn=XxJ-0x40*JQi1jg | |
return string.char( | |
0xF0+XPoQB,0x80+o5sms,0x80+JQi1jg,0x80+wVzn)end end | |
function lcBL:onDecodeError(pE,RSjapQ,QJf,zC)if RSjapQ then | |
if QJf then | |
pE=string.format("%s at char %d of: %s",pE,QJf,RSjapQ)else pE=string.format("%s: %s",pE,RSjapQ)end end | |
if zC~=nil then pE=pE.." (".. | |
lcBL:encode(zC)..")"end | |
if self.assert then self.assert(false,pE)else assert(false,pE)end end;lcBL.onDecodeOfNilError=lcBL.onDecodeError | |
lcBL.onDecodeOfHTMLError=lcBL.onDecodeError | |
function lcBL:onEncodeError(pfZ3SPy_,pDNa2ox6) | |
if pDNa2ox6 ~=nil then pfZ3SPy_=pfZ3SPy_.. | |
" ("..lcBL:encode(pDNa2ox6)..")"end;if self.assert then self.assert(false,pfZ3SPy_)else | |
assert(false,pfZ3SPy_)end end | |
local function yA(Do6yo7nm,y06X3k,ivnJjrA,d3fMjkg) | |
local el=y06X3k:match('^-?[1-9]%d*',ivnJjrA)or y06X3k:match("^-?0",ivnJjrA)if not el then | |
Do6yo7nm:onDecodeError("expected number",y06X3k,ivnJjrA,d3fMjkg.etc)end | |
local Wu_uIt=ivnJjrA+el:len()local w=y06X3k:match('^%.%d+',Wu_uIt)or""Wu_uIt=Wu_uIt+ | |
w:len() | |
local sgeP=y06X3k:match('^[eE][-+]?%d+',Wu_uIt)or""Wu_uIt=Wu_uIt+sgeP:len()local CM=el..w..sgeP;if | |
d3fMjkg.decodeNumbersAsObjects then return lcBL:asNumber(CM),Wu_uIt end | |
if | |
( | |
d3fMjkg.decodeIntegerStringificationLength and(el:len()>=d3fMjkg.decodeIntegerStringificationLength or | |
sgeP:len()>0))or | |
(d3fMjkg.decodeDecimalStringificationLength and | |
( | |
w:len()>=d3fMjkg.decodeDecimalStringificationLength or sgeP:len()>0))then return CM,Wu_uIt end;local Qlmlet=tonumber(CM)if not Qlmlet then | |
Do6yo7nm:onDecodeError("bad number",y06X3k,ivnJjrA,d3fMjkg.etc)end;return Qlmlet,Wu_uIt end | |
local function XmVolesU(_,RkGFh6,hw18,nvCiFt7r)if RkGFh6:sub(hw18,hw18)~='"'then | |
_:onDecodeError("expected string's opening quote",RkGFh6,hw18,nvCiFt7r.etc)end;local xSebv5Jc=hw18+1 | |
local mMp=RkGFh6:len()local rDtVf="" | |
while xSebv5Jc<=mMp do local vj=RkGFh6:sub(xSebv5Jc,xSebv5Jc)if | |
vj=='"'then return rDtVf,xSebv5Jc+1 end | |
if vj~='\\'then rDtVf=rDtVf..vj;xSebv5Jc= | |
xSebv5Jc+1 elseif RkGFh6:match('^\\b',xSebv5Jc)then rDtVf=rDtVf.."\b"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\f',xSebv5Jc)then rDtVf=rDtVf.."\f"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\n',xSebv5Jc)then rDtVf=rDtVf.."\n"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\r',xSebv5Jc)then rDtVf=rDtVf.."\r"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\t',xSebv5Jc)then rDtVf=rDtVf.."\t"xSebv5Jc= | |
xSebv5Jc+2 else | |
local z=RkGFh6:match('^\\u([0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])',xSebv5Jc) | |
if z then xSebv5Jc=xSebv5Jc+6;local Zg=tonumber(z,16) | |
if | |
Zg>=0xD800 and Zg<=0xDBFF then | |
local ykRppH=RkGFh6:match('^\\u([dD][cdefCDEF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])',xSebv5Jc) | |
if ykRppH then xSebv5Jc=xSebv5Jc+6;Zg=0x2400+ (Zg-0xD800)*0x400+ | |
tonumber(ykRppH,16)else end end;rDtVf=rDtVf..AI0R2TQ6(Zg)else rDtVf=rDtVf.. | |
RkGFh6:match('^\\(.)',xSebv5Jc)xSebv5Jc=xSebv5Jc+2 end end end | |
_:onDecodeError("unclosed string",RkGFh6,hw18,nvCiFt7r.etc)end | |
local function eZ0l3ch(WQ6,y36Aetn)local iPL3B4cr,GI2hz6SK=WQ6:find("^[ \n\r\t]+",y36Aetn)if GI2hz6SK then | |
return GI2hz6SK+1 else return y36Aetn end end;local W_63_9 | |
local function h9dyA_4T(Oh,PG,n,O)if PG:sub(n,n)~='{'then | |
Oh:onDecodeError("expected '{'",PG,n,O.etc)end;local N5UjTN=eZ0l3ch(PG,n+1)local qLH5=Oh.strictTypes and | |
Oh:newObject{}or{}if | |
PG:sub(N5UjTN,N5UjTN)=='}'then return qLH5,N5UjTN+1 end | |
local tE=PG:len() | |
while N5UjTN<=tE do local VcV0EuD,pX4gCR=XmVolesU(Oh,PG,N5UjTN,O) | |
N5UjTN=eZ0l3ch(PG,pX4gCR)if PG:sub(N5UjTN,N5UjTN)~=':'then | |
Oh:onDecodeError("expected colon",PG,N5UjTN,O.etc)end | |
N5UjTN=eZ0l3ch(PG,N5UjTN+1)local gad4ZcL,pX4gCR=W_63_9(Oh,PG,N5UjTN,O)qLH5[VcV0EuD]=gad4ZcL | |
N5UjTN=eZ0l3ch(PG,pX4gCR)local dk=PG:sub(N5UjTN,N5UjTN) | |
if dk=='}'then return qLH5,N5UjTN+1 end;if PG:sub(N5UjTN,N5UjTN)~=','then | |
Oh:onDecodeError("expected comma or '}'",PG,N5UjTN,O.etc)end | |
N5UjTN=eZ0l3ch(PG,N5UjTN+1)end;Oh:onDecodeError("unclosed '{'",PG,n,O.etc)end | |
local function oh(E,OO,y,cR6rJlAl)if OO:sub(y,y)~='['then | |
E:onDecodeError("expected '['",OO,y,cR6rJlAl.etc)end;local M6ilzGJ=eZ0l3ch(OO,y+1)local iW6CD=E.strictTypes and | |
E:newArray{}or{}if | |
OO:sub(M6ilzGJ,M6ilzGJ)==']'then return iW6CD,M6ilzGJ+1 end | |
local wZdg=1;local BaX=OO:len() | |
while M6ilzGJ<=BaX do | |
local SJsW11k,Ki1HJT=W_63_9(E,OO,M6ilzGJ,cR6rJlAl)iW6CD[wZdg]=SJsW11k;wZdg=wZdg+1;M6ilzGJ=eZ0l3ch(OO,Ki1HJT) | |
local wjim8xCV=OO:sub(M6ilzGJ,M6ilzGJ)if wjim8xCV==']'then return iW6CD,M6ilzGJ+1 end;if | |
OO:sub(M6ilzGJ,M6ilzGJ)~=','then | |
E:onDecodeError("expected comma or '['",OO,M6ilzGJ,cR6rJlAl.etc)end | |
M6ilzGJ=eZ0l3ch(OO,M6ilzGJ+1)end | |
E:onDecodeError("unclosed '['",OO,y,cR6rJlAl.etc)end | |
W_63_9=function(E,QLam,qTDt,v)qTDt=eZ0l3ch(QLam,qTDt) | |
if qTDt>QLam:len()then E:onDecodeError("unexpected end of string",QLam, | |
nil,v.etc)end | |
if QLam:find('^"',qTDt)then return XmVolesU(E,QLam,qTDt,v.etc)elseif | |
QLam:find('^[-0123456789 ]',qTDt)then return yA(E,QLam,qTDt,v)elseif QLam:find('^%{',qTDt)then | |
return h9dyA_4T(E,QLam,qTDt,v)elseif QLam:find('^%[',qTDt)then return oh(E,QLam,qTDt,v)elseif QLam:find('^true',qTDt)then return true, | |
qTDt+4 elseif QLam:find('^false',qTDt)then return false,qTDt+5 elseif | |
QLam:find('^null',qTDt)then return nil,qTDt+4 else | |
E:onDecodeError("can't parse JSON",QLam,qTDt,v.etc)end end | |
function lcBL:decode(Ta,u,nArcvQl)if type(nArcvQl)~='table'then nArcvQl={}end;if u~=nil then | |
nArcvQl.etc=u end;if | |
type(self)~='table'or self.__index~=lcBL then | |
lcBL:onDecodeError("JSON:decode must be called in method format",nil,nil,nArcvQl.etc)end | |
if Ta==nil then | |
self:onDecodeOfNilError(string.format("nil passed to JSON:decode()"), | |
nil,nil,nArcvQl.etc)elseif type(Ta)~='string'then | |
self:onDecodeError(string.format("expected string argument to JSON:decode(), got %s",type(Ta)), | |
nil,nil,nArcvQl.etc)end;if Ta:match('^%s*$')then return nil end;if Ta:match('^%s*<')then | |
self:onDecodeOfHTMLError(string.format("html passed to JSON:decode()"),Ta, | |
nil,nArcvQl.etc)end | |
if | |
Ta:sub(1,1):byte()==0 or | |
(Ta:len()>=2 and Ta:sub(2,2):byte()==0)then | |
self:onDecodeError("JSON package groks only UTF-8, sorry",Ta,nil,nArcvQl.etc)end;if nArcvQl.decodeNumbersAsObjects==nil then | |
nArcvQl.decodeNumbersAsObjects=self.decodeNumbersAsObjects end;if | |
nArcvQl.decodeIntegerStringificationLength==nil then | |
nArcvQl.decodeIntegerStringificationLength=self.decodeIntegerStringificationLength end;if | |
nArcvQl.decodeDecimalStringificationLength==nil then | |
nArcvQl.decodeDecimalStringificationLength=self.decodeDecimalStringificationLength end | |
local h6Ub7U,Gm=pcall(W_63_9,self,Ta,1,nArcvQl)if h6Ub7U then return Gm else | |
if self.assert then self.assert(false,Gm)else assert(false,Gm)end;return nil,Gm end end | |
local function DZXGTh(YKA7cU) | |
if YKA7cU=="\n"then return"\\n"elseif YKA7cU=="\r"then return"\\r"elseif YKA7cU=="\t"then return"\\t"elseif YKA7cU=="\b"then | |
return"\\b"elseif YKA7cU=="\f"then return"\\f"elseif YKA7cU=='"'then return'\\"'elseif YKA7cU=='\\'then return'\\\\'else return | |
string.format("\\u%04x",YKA7cU:byte())end end | |
local Su9Koz='['..'"'.. | |
'%\\'..'%z'..'\001'..'-'..'\031'..']'local Uk7e=AI0R2TQ6(0x2028)local KwQCk_G=AI0R2TQ6(0x2029) | |
local function ptZa(mCsewfX,yY) | |
local Xf=mCsewfX:gsub(Su9Koz,DZXGTh)if yY.stringsAreUtf8 then | |
Xf=Xf:gsub(Uk7e,'\\u2028'):gsub(KwQCk_G,'\\u2029')end;return'"'..Xf..'"'end | |
local function PEqsd(UlFdiZ7v,U,wFeA)local JQgI={}local N={}local fs52REi=false;local PUNkgaiM | |
for X in pairs(U)do | |
if type(X)=='string'then | |
table.insert(JQgI,X)elseif type(X)=='number'then table.insert(N,X) | |
if X<=0 or X>=math.huge then | |
fs52REi=true elseif not PUNkgaiM or X>PUNkgaiM then PUNkgaiM=X end else | |
UlFdiZ7v:onEncodeError("can't encode table with a key of type "..type(X),wFeA)end end | |
if#JQgI==0 and not fs52REi then | |
if#N>0 then return nil,PUNkgaiM elseif | |
tostring(U)=="JSON array"then return nil elseif tostring(U)=="JSON object"then return{}else return nil end end;table.sort(JQgI)local s6FbB | |
if#N>0 then if UlFdiZ7v.noKeyConversion then | |
UlFdiZ7v:onEncodeError("a table with both numeric and string keys could be an object or array; aborting",wFeA)end | |
s6FbB={}for dc61,aguhyl in pairs(U)do s6FbB[dc61]=aguhyl end | |
table.sort(N) | |
for p,gOPDv in ipairs(N)do local aSdZU3=tostring(gOPDv) | |
if s6FbB[aSdZU3]==nil then | |
table.insert(JQgI,aSdZU3)s6FbB[aSdZU3]=U[gOPDv]else | |
UlFdiZ7v:onEncodeError( | |
"conflict converting table with mixed-type keys into a JSON object: key "..gOPDv.." exists both as a string and a number.",wFeA)end end end;return JQgI,nil,s6FbB end;local iSj | |
function iSj(YKDL,oFyb6OLp,oGdh_mv,WjvvK,TASVwBgU,KjUncMB,XkT) | |
if oFyb6OLp==nil or | |
(not XkT and TASVwBgU and TASVwBgU.null and oFyb6OLp== | |
TASVwBgU.null)then return'null'elseif | |
type(oFyb6OLp)=='string'then return ptZa(oFyb6OLp,TASVwBgU)elseif type(oFyb6OLp)=='number'then | |
if | |
oFyb6OLp~=oFyb6OLp then return"null"elseif oFyb6OLp>=math.huge then return"1e+9999"elseif oFyb6OLp<=-math.huge then | |
return"-1e+9999"else return tostring(oFyb6OLp)end elseif type(oFyb6OLp)=='boolean'then return tostring(oFyb6OLp)elseif type(oFyb6OLp)~= | |
'table'then | |
YKDL:onEncodeError("can't convert "..type(oFyb6OLp).." to JSON",WjvvK)elseif getmetatable(oFyb6OLp)==scRP0 then return tostring(oFyb6OLp)else | |
local c3dr=oFyb6OLp;if type(TASVwBgU)~='table'then TASVwBgU={}end;if type(KjUncMB)~= | |
'string'then KjUncMB=""end | |
if oGdh_mv[c3dr]then | |
YKDL:onEncodeError("table ".. | |
tostring(c3dr).." is a child of itself",WjvvK)else oGdh_mv[c3dr]=true end;local NGH;local tIc,MD2O,HQ=PEqsd(YKDL,c3dr,WjvvK) | |
if MD2O then local cng={}for lE=1,MD2O do | |
table.insert(cng,iSj(YKDL,c3dr[lE],oGdh_mv,WjvvK,TASVwBgU,KjUncMB))end | |
if TASVwBgU.pretty then NGH="[ ".. | |
table.concat(cng,", ").." ]"else NGH="[".. | |
table.concat(cng,",").."]"end elseif tIc then local nI2F0id=HQ or c3dr | |
if TASVwBgU.pretty then local N4aMD_P={}local pCi=0 | |
for lNOqUk8,YAnZNei in ipairs(tIc)do | |
local h8YWR44E=iSj(YKDL,tostring(YAnZNei),oGdh_mv,WjvvK,TASVwBgU,KjUncMB,true) | |
if TASVwBgU.align_keys then pCi=math.max(pCi,#h8YWR44E)end;table.insert(N4aMD_P,h8YWR44E)end | |
local NzeoQJ=KjUncMB..tostring(TASVwBgU.indent or"") | |
local AwGfFV=NzeoQJ..string.rep(" ",pCi).. | |
(TASVwBgU.align_keys and" "or"") | |
local wCRY="%s%"..string.format("%d",pCi).."s: %s"local d0uKSVw1={} | |
for VF,fTrMe in ipairs(tIc)do | |
local ypDndT8=iSj(YKDL,nI2F0id[fTrMe],oGdh_mv,WjvvK,TASVwBgU,AwGfFV) | |
table.insert(d0uKSVw1,string.format(wCRY,NzeoQJ,N4aMD_P[VF],ypDndT8))end;NGH="{\n".. | |
table.concat(d0uKSVw1,",\n").."\n"..KjUncMB.."}"else local MV65={} | |
for Y3D66Ym9,q in | |
ipairs(tIc)do | |
local PhJ=iSj(YKDL,nI2F0id[q],oGdh_mv,WjvvK,TASVwBgU,KjUncMB) | |
local h=iSj(YKDL,tostring(q),oGdh_mv,WjvvK,TASVwBgU,KjUncMB,true) | |
table.insert(MV65,string.format("%s:%s",h,PhJ))end;NGH="{"..table.concat(MV65,",").."}"end else NGH="[]"end;oGdh_mv[c3dr]=false;return NGH end end | |
function lcBL:encode(j2K,r8hgwQ,_6U)if type(self)~='table'or self.__index~=lcBL then | |
lcBL:onEncodeError("JSON:encode must be called in method format",r8hgwQ)end;if | |
type(_6U)~='table'then _6U={}end;return iSj(self,j2K,{},r8hgwQ,_6U)end | |
function lcBL:encode_pretty(GLSzBQs,c,xg)if type(self)~='table'or self.__index~=lcBL then | |
lcBL:onEncodeError("JSON:encode_pretty must be called in method format",c)end;if | |
type(xg)~='table'then xg=dx end;return iSj(self,GLSzBQs,{},c,xg)end;function lcBL.__tostring()return"JSON encode/decode package"end | |
lcBL.__index=lcBL | |
function lcBL:new(Id2KoP_G)local Y2or={}if Id2KoP_G then | |
for zN8ASHV5,iju in pairs(Id2KoP_G)do Y2or[zN8ASHV5]=iju end end | |
return setmetatable(Y2or,lcBL)end;return lcBL:new() | |
]===])() | |
local s=(function() | |
local YKA7cU=[[ Copyright (c) The python-semanticversion project | |
All rights reserved. | |
Redistribution and use in source and binary forms, with or without | |
modification, are permitted provided that the following conditions are met: | |
1. Redistributions of source code must retain the above copyright notice, this | |
list of conditions and the following disclaimer. | |
2. Redistributions in binary form must reproduce the above copyright notice, | |
this list of conditions and the following disclaimer in the documentation | |
and/or other materials provided with the distribution. | |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | |
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
]] | |
YKA7cU=[[ The use of the library is similar to the original one, | |
check the documentation here: https://python-semanticversion.readthedocs.io/en/latest/ | |
]]local mCsewfX,yY,Xf | |
do local p=table;mCsewfX,yY,Xf=p.concat,p.insert,p.unpack end;local UlFdiZ7v | |
UlFdiZ7v=function(gOPDv)do local aSdZU3=tonumber(gOPDv) | |
if aSdZU3 then return aSdZU3,true else return gOPDv,false end end end;local U | |
U=function(YKDL)return | |
YKDL and YKDL[1]=='0'and tonumber(YKDL and YKDL~='0')end;local wFeA | |
wFeA=function(oFyb6OLp,oGdh_mv)if oFyb6OLp==oGdh_mv then return 0 end | |
if oFyb6OLp>oGdh_mv then return 1 end;if oFyb6OLp<oGdh_mv then return-1 end end;local JQgI | |
JQgI=function(WjvvK,TASVwBgU)local KjUncMB,XkT=UlFdiZ7v(WjvvK)local c3dr,NGH=UlFdiZ7v(TASVwBgU) | |
if | |
XkT and NGH then return wFeA(KjUncMB,c3dr)elseif XkT then return-1 elseif NGH then return 1 else return wFeA(KjUncMB,c3dr)end end;local N | |
N=function(tIc,MD2O)local HQ | |
do local cng={}for lE=1,#tIc do | |
if MD2O[lE]then cng[tIc[lE]]=MD2O[lE]end end;HQ=cng end | |
for nI2F0id,N4aMD_P in pairs(HQ)do local pCi=JQgI(nI2F0id,N4aMD_P)if pCi~=0 then return pCi end end;return wFeA(#tIc,#MD2O)end;local fs52REi | |
do local NzeoQJ | |
local AwGfFV={_coerce=function(d0uKSVw1,lNOqUk8,YAnZNei)if YAnZNei==nil then YAnZNei=false end;if | |
lNOqUk8 ==nil and YAnZNei then return lNOqUk8 end;return tonumber(lNOqUk8)end,next_major=function(h8YWR44E) | |
if | |
h8YWR44E.prerelease and h8YWR44E.minor==0 and h8YWR44E.patch==0 then | |
return | |
fs52REi(mCsewfX((function()local VF={}local fTrMe=1 | |
local ypDndT8={h8YWR44E.major,h8YWR44E.minor,h8YWR44E.patch}for MV65=1,#ypDndT8 do local Y3D66Ym9=ypDndT8[MV65]VF[fTrMe]=tostring(Y3D66Ym9)fTrMe= | |
fTrMe+1 end;return VF end)(),'.'))else | |
return | |
fs52REi(mCsewfX((function()local q={}local PhJ=1;local h={h8YWR44E.major+1,0,0} | |
for j2K=1,#h do | |
local r8hgwQ=h[j2K]q[PhJ]=tostring(r8hgwQ)PhJ=PhJ+1 end;return q end)(),'.'))end end,next_minor=function(_6U)if | |
not(_6U.minor)then | |
error("Partial version doesn't contain the minor component!")end | |
if | |
_6U.prerelease and _6U.patch==0 then | |
return | |
fs52REi(mCsewfX((function()local GLSzBQs={}local c=1;local xg={_6U.major,_6U.minor,_6U.patch} | |
for Id2KoP_G=1,# | |
xg do local Y2or=xg[Id2KoP_G]GLSzBQs[c]=tostring(Y2or)c=c+1 end;return GLSzBQs end)(),'.'))else | |
return | |
fs52REi(mCsewfX((function()local zN8ASHV5={}local iju=1;local XsWgh={_6U.major,_6U.minor+1,0}for l4Hdz=1,#XsWgh | |
do local NSXCgSH=XsWgh[l4Hdz]zN8ASHV5[iju]=tostring(NSXCgSH) | |
iju=iju+1 end;return zN8ASHV5 end)(),'.'))end end,next_patch=function(Wq)if | |
not(Wq.patch)then | |
error("Partial version doesn't contain the patch component!")end | |
if Wq.prerelease then | |
return | |
fs52REi(mCsewfX((function()local SbOQ={}local IiuHGo=1 | |
local cGqxtYr={Wq.major,Wq.minor,Wq.patch}for bgJFKeeZ=1,#cGqxtYr do local yu9fg0nN=cGqxtYr[bgJFKeeZ] | |
SbOQ[IiuHGo]=tostring(yu9fg0nN)IiuHGo=IiuHGo+1 end | |
return SbOQ end)(),'.'))else | |
return | |
fs52REi(mCsewfX((function()local wgx={}local zlU7X=1 | |
local t={Wq.major,Wq.minor,Wq.patch+1} | |
for f6qbO=1,#t do local kk=t[f6qbO]wgx[zlU7X]=tostring(kk)zlU7X=zlU7X+1 end;return wgx end)(),'.'))end end,coerce=function(QrubIAv,bLHDW,YjFd7b)if | |
YjFd7b==nil then YjFd7b=false end;local jZgPYb | |
jZgPYb=function(I0JvPpn) | |
local Ce4ZE,OVx_mN=I0JvPpn:match('^(%d+)(.*)$')if not(Ce4ZE)then return nil end;local lB=Ce4ZE | |
local byE,bITCI=OVx_mN:match('^%.(%d+)(.*)$')if byE then OVx_mN=bITCI;lB=lB.. ('.'..byE)end;local K | |
K,bITCI=OVx_mN:match('^%.(%d+)(.*)$')if K then OVx_mN=bITCI;lB=lB.. ('.'..K)end;return I0JvPpn,lB end;local zN2,IN69pa5=jZgPYb(bLHDW)if not(zN2)then | |
error("Version string lacks a numerical component: "..tostring(bLHDW))end | |
local UOWJ=bLHDW:sub(1,#IN69pa5) | |
if not YjFd7b then while({UOWJ:gsub('.','')})[2]<2 do UOWJ= | |
UOWJ..'.0'end end | |
if#IN69pa5 ==#bLHDW then return fs52REi(UOWJ,YjFd7b)end;local WtalJw=bLHDW:sub(#IN69pa5+1) | |
WtalJw=WtalJw:gsub('[^a-zA-Z0-9+.-]','-')local JYrf2,KHDOUlRY=nil,nil | |
if WtalJw:sub(1,1)=='+'then JYrf2='' | |
KHDOUlRY=WtalJw:sub(2)elseif WtalJw:sub(1,1)=='.'then JYrf2=''KHDOUlRY=WtalJw:sub(2)elseif | |
WtalJw:sub(1,1)=='-'then WtalJw=WtalJw:sub(2) | |
do local F5dtVpnN=WtalJw:find('+') | |
if | |
F5dtVpnN then | |
JYrf2,KHDOUlRY=WtalJw:sub(1,F5dtVpnN-1),WtalJw:sub(F5dtVpnN+1,-1)else JYrf2,KHDOUlRY=WtalJw,''end end else do local kxeBp=WtalJw:find('+') | |
if kxeBp then JYrf2,KHDOUlRY=WtalJw:sub(1,kxeBp-1),WtalJw:sub( | |
kxeBp+1,-1)else JYrf2,KHDOUlRY=WtalJw,''end end end;KHDOUlRY=KHDOUlRY:gsub('+','.')if JYrf2 and JYrf2 ~=''then UOWJ=UOWJ.. | |
('-'..JYrf2)end | |
if | |
KHDOUlRY and KHDOUlRY~=''then UOWJ=UOWJ.. ('+'..KHDOUlRY)end;return QrubIAv.__class(UOWJ,YjFd7b)end,parse=function(a,kQ,EE9LAE,iVx)if | |
EE9LAE==nil then EE9LAE=false end;if iVx==nil then iVx=false end;if not kQ or | |
type(kQ)~='string'or kQ==''then | |
error("Invalid empty version string: ".. | |
tostring(tostring(kQ)))end;local eg;if EE9LAE then | |
eg=a.__class.partialVersionRe else eg=a.__class.versionRe end | |
local AQviNt,T6,NviN0i,BlMQce,o=eg(a.__class,kQ)if not AQviNt then | |
error("Invalid version string: "..tostring(kQ))end;if U(AQviNt)then | |
error("Invalid leading zero in major: "..tostring(kQ))end;if U(T6)then | |
error("Invalid leading zero in minor: "..tostring(kQ))end;if U(NviN0i)then | |
error("Invalid leading zero in patch: "..tostring(kQ))end;AQviNt=tonumber(AQviNt) | |
T6=a:_coerce(T6,EE9LAE)NviN0i=a:_coerce(NviN0i,EE9LAE) | |
if BlMQce==nil then | |
if EE9LAE and o==nil then return{AQviNt,T6,NviN0i,nil, | |
nil}else BlMQce={}end elseif BlMQce==''then BlMQce={}else | |
do local dpRE={}local fEiXwWq=1;for r3JzMga6 in BlMQce:gmatch('[^.]+')do | |
dpRE[fEiXwWq]=r3JzMga6;fEiXwWq=fEiXwWq+1 end;BlMQce=dpRE end;a:_validateIdentifiers(BlMQce,false)end | |
if o==nil then if EE9LAE then o=nil else o={}end elseif o==''then o={}else | |
do local Tuyw={}local FYLcr2nu=1;for ioS69 in o:gmatch('[^.]+')do | |
Tuyw[FYLcr2nu]=ioS69;FYLcr2nu=FYLcr2nu+1 end;o=Tuyw end;a:_validateIdentifiers(o,true)end;return{AQviNt,T6,NviN0i,BlMQce,o}end,_validateIdentifiers=function(AiP,S2jwpoi,_WX9u)if | |
_WX9u==nil then _WX9u=false end | |
for u0riyU=1,#S2jwpoi do local UH=S2jwpoi[u0riyU]if not UH then | |
error( | |
"Invalid empty identifier ".. | |
tostring(UH).." in "..tostring(mCsewfX(S2jwpoi,'.')))end;if | |
UH:sub(1,1)=='0'and | |
tonumber(UH)and UH~='0'and not _WX9u then | |
error("Invalid leading zero in identifier "..tostring(UH))end end end,__pairs=function(WNph)return | |
pairs({WNph.major,WNph.minor,WNph.patch,WNph.prerelease,WNph.build})end,__ipairs=function(ytF)return | |
ipairs({ytF.major,ytF.minor,ytF.patch,ytF.prerelease,ytF.build})end,__tostring=function(d) | |
local gRm=tostring(d.major) | |
if d.minor~=nil then gRm=gRm.. ('.'..d.minor)end | |
if d.patch~=nil then gRm=gRm.. ('.'..d.patch)end | |
if d.prerelease and#d.prerelease>0 or | |
d.partial and d.prerelease and | |
#d.prerelease==0 and d.build==nil then gRm=gRm.. ('-'.. | |
mCsewfX(d.prerelease,'.'))end | |
if d.build and#d.build>0 or | |
d.partial and d.build and#d.build==0 then gRm=gRm.. | |
('+'..mCsewfX(d.build,'.'))end;return gRm end,_comparsionFunctions=function(LPX0,g)if | |
g==nil then g=false end;local _l | |
_l=function(N8,Gzk) | |
if N8 and Gzk then return N(N8,Gzk)elseif N8 then return-1 elseif Gzk then return 1 else return 0 end end;local qao | |
qao=function(J7nsK,dXbd)if J7nsK==dXbd then return 0 else return'not implemented'end end;local ipUPIzc | |
ipUPIzc=function(vQj)local sVBxyy | |
sVBxyy=function(N9d,S7) | |
if N9d==nil or S7 ==nil then return 0 else return vQj(N9d,S7)end end;return sVBxyy end | |
if g then return | |
{wFeA,ipUPIzc(wFeA),ipUPIzc(wFeA),ipUPIzc(_l),ipUPIzc(qao)}else return{wFeA,wFeA,wFeA,_l,qao}end end,__compare=function(bJtvRSR,aBhZK5) | |
local Jz8JUscj=bJtvRSR:_comparsionFunctions( | |
bJtvRSR.partial or aBhZK5.partial) | |
local OtGmbAgE={{Jz8JUscj[1],bJtvRSR.major,aBhZK5.major},{Jz8JUscj[2],bJtvRSR.minor,aBhZK5.minor},{Jz8JUscj[3],bJtvRSR.patch,aBhZK5.patch},{Jz8JUscj[4],bJtvRSR.prerelease,aBhZK5.prerelease},{Jz8JUscj[5],bJtvRSR.build,aBhZK5.build}} | |
for oU_r=1,#OtGmbAgE do local n_lv=OtGmbAgE[oU_r]local UYQF,WXx,W4EuxJXi=Xf(n_lv) | |
local BlYNd61h=UYQF(WXx,W4EuxJXi)if BlYNd61h~=0 then return BlYNd61h end end;return 0 end,__compareHelper=function(XDPndG,sJYFQIP4,Ogq0S2,n8Cw3SR) | |
local GJqd7gt=XDPndG:__compare(sJYFQIP4)if GJqd7gt=='not implemented'then return n8Cw3SR end;return | |
Ogq0S2(GJqd7gt)end,__eq=function(slE5aDm2,aL_g) | |
local IMUI10L;IMUI10L=function(vPA)return vPA==0 end;return | |
slE5aDm2:__compareHelper(aL_g,IMUI10L,false)end,__lt=function(pUXZ6G4,mk) | |
local OeQex1U4;OeQex1U4=function(i0cV9)return i0cV9 <0 end;return | |
pUXZ6G4:__compareHelper(mk,OeQex1U4,false)end,__le=function(EGD,VWiGCreH) | |
local B_kkL;B_kkL=function(uEO6Y)return uEO6Y<=0 end;return | |
EGD:__compareHelper(VWiGCreH,B_kkL,false)end}AwGfFV.__index=AwGfFV | |
NzeoQJ=setmetatable({__init=function(i_053JPY,l,UK)if UK==nil then UK=false end | |
local NzaICo,k1X83nYm,xxzxfj,_ad1m4I,H1QsS=Xf(i_053JPY:parse(l,UK)) | |
i_053JPY.major,i_053JPY.minor,i_053JPY.patch,i_053JPY.prerelease,i_053JPY.build,i_053JPY.partial=NzaICo,k1X83nYm,xxzxfj,_ad1m4I,H1QsS,UK end,__base=AwGfFV,__name="Version"},{__index=AwGfFV,__call=function(rIMx,...) | |
local TiA=setmetatable({},AwGfFV)rIMx.__init(TiA,...)return TiA end})AwGfFV.__class=NzeoQJ;local wCRY=NzeoQJ | |
wCRY.versionRe=function(wCRY,Y51P) | |
local ichL,NOK,Alv,YeLO2=Y51P:match('^(%d+)%.(%d+)%.(%d+)(.*)$')if not(ichL)then return nil end | |
local CkrmO,ooovsSJe=YeLO2:match('^%-([0-9a-zA-z.-]+)(.*)$')if CkrmO then YeLO2=ooovsSJe end;local s5IsD | |
s5IsD,ooovsSJe=YeLO2:match('^%+([0-9a-zA-Z.-]+)(.*)$')if s5IsD then YeLO2=ooovsSJe end;if#YeLO2 >0 then return nil end | |
return ichL,NOK,Alv,CkrmO,s5IsD end | |
wCRY.partialVersionRe=function(wCRY,KvYEVoXt)local VWWD_P,zsMuNkv=KvYEVoXt:match('^(%d+)(.*)$')if not | |
(VWWD_P)then return nil end | |
local aXxi,Q18a7QTy=zsMuNkv:match('^%.(%d+)(.*)$')if aXxi then zsMuNkv=Q18a7QTy end;local K5Rp6 | |
K5Rp6,Q18a7QTy=zsMuNkv:match('^%.(%d+)(.*)$')if K5Rp6 then zsMuNkv=Q18a7QTy end;local GTIA | |
GTIA,Q18a7QTy=zsMuNkv:match('^%-([0-9a-zA-Z.-]*)(.*)$')if GTIA then zsMuNkv=Q18a7QTy end;local gdPUe | |
gdPUe,Q18a7QTy=zsMuNkv:match('^%+([0-9a-zA-Z.-]*)(.*)$')if gdPUe then zsMuNkv=Q18a7QTy end;if#zsMuNkv>0 then return nil end;return VWWD_P, | |
aXxi,K5Rp6,GTIA,gdPUe end;fs52REi=NzeoQJ end;local PUNkgaiM | |
do local _bxEn | |
local pcN_ceXY={parse=function(rq,mo)if not mo or type(mo)~='string'or mo==''then | |
error( | |
"Invalid empty requirement specification: "..tostring(tostring(mo)))end;if mo=='*'then return | |
{rq.__class.KIND_ANY,''}end | |
local I,RAAJAsR=rq.__class:reSpec(mo)if not I then | |
error("Invalid requirement specification: "..tostring(mo))end | |
I=rq.__class.KIND_ALIASES[I]or I;local c1pjj7=fs52REi(RAAJAsR,true) | |
if | |
c1pjj7.build~=nil and | |
I~=rq.__class.KIND_EQUAL and I~=rq.__class.KIND_NEQ then | |
error("Invalid requirement specification "..tostring(mo)..": build numbers have no ordering")end;return{I,c1pjj7}end,match=function(BMv,NQh8) | |
local P=BMv.kind | |
if BMv.__class.KIND_ANY==P then return true elseif BMv.__class.KIND_LT==P then return | |
NQh8 <BMv.spec elseif BMv.__class.KIND_LTE==P then return NQh8 <=BMv.spec elseif | |
BMv.__class.KIND_EQUAL==P then return NQh8 ==BMv.spec elseif BMv.__class.KIND_GTE==P then return NQh8 >= | |
BMv.spec elseif BMv.__class.KIND_GT==P then return NQh8 >BMv.spec elseif | |
BMv.__class.KIND_NEQ==P then return NQh8 ~=BMv.spec elseif BMv.__class.KIND_CARET==P then | |
return BMv.spec<= | |
NQh8 and NQh8 <BMv.spec:next_major()elseif BMv.__class.KIND_TILDE==P then return BMv.spec<=NQh8 and | |
NQh8 <BMv.spec:next_minor()else | |
return error("Unexpected match kind: ".. | |
tostring(BMv.kind))end end,__tostring=function(bkTe)return | |
tostring(bkTe.kind)..tostring(bkTe.spec)end,__eq=function(ohmPbyDd,D) | |
return | |
ohmPbyDd.kind==D.kind and ohmPbyDd.spec==D.spec end}pcN_ceXY.__index=pcN_ceXY | |
_bxEn=setmetatable({__init=function(DfDLWkT,MTU8HP4d) | |
DfDLWkT.kind,DfDLWkT.spec=Xf(DfDLWkT:parse(MTU8HP4d))end,__base=pcN_ceXY,__name="SpecItem"},{__index=pcN_ceXY,__call=function(hIM_cG0i,...) | |
local jD=setmetatable({},pcN_ceXY)hIM_cG0i.__init(jD,...)return jD end})pcN_ceXY.__class=_bxEn;local _P=_bxEn;_P.KIND_ANY='*'_P.KIND_LT='<' | |
_P.KIND_LTE='<='_P.KIND_EQUAL='=='_P.KIND_SHORTEQ='='_P.KIND_EMPTY=''_P.KIND_GTE='>=' | |
_P.KIND_GT='>'_P.KIND_NEQ='!='_P.KIND_CARET='^'_P.KIND_TILDE='~' | |
_P.KIND_ALIASES={[_P.__class.KIND_SHORTEQ]=_P.__class.KIND_EQUAL,[_P.__class.KIND_EMPTY]=_P.__class.KIND_EQUAL} | |
_P.reSpec=function(_P,me)local sgU5HAMG,FDydY=me:match('^(.-)(%d.*)$') | |
if | |
not | |
( | |
sgU5HAMG=='<'or | |
sgU5HAMG=='<='or sgU5HAMG==''or sgU5HAMG=='='or sgU5HAMG=='=='or sgU5HAMG=='>='or sgU5HAMG=='>'or | |
sgU5HAMG=='!='or | |
sgU5HAMG=='^'or | |
sgU5HAMG=='~')then return nil else return sgU5HAMG,FDydY end end;PUNkgaiM=_bxEn end;local s6FbB | |
do local PEZ_ | |
local c={parse=function(ElbTbcZG,r3)local p={}local UiVYRok=1;for jvPsY9 in r3:gmatch('[^,]+')do | |
p[UiVYRok]=PUNkgaiM(jvPsY9)UiVYRok=UiVYRok+1 end;return p end,match=function(tEBmuypm,hW) | |
local iOcgdUx=tEBmuypm.specs;for kCwLIk=1,#iOcgdUx do local _l=iOcgdUx[kCwLIk] | |
if not _l:match(hW)then return false end end;return true end,filter=function(rjQ,Euo0) | |
local LIV=0 | |
return function() | |
while true do LIV=LIV+1;local vydlAbZ3=Euo0[LIV]if not(vydlAbZ3)then return nil end;if | |
rjQ:match(vydlAbZ3)then return vydlAbZ3 end end end end,select=function(BXxv5z,mKLU) | |
local Him;do local cPDhu={}local UQnOS=1 | |
for tRWU in BXxv5z:filter(mKLU)do cPDhu[UQnOS]=tRWU;UQnOS=UQnOS+1 end;Him=cPDhu end | |
if#Him>0 then | |
local X2Zy_nb=Him[1] | |
for ITtw3N7E=1,#Him do local yozOp=Him[ITtw3N7E]if X2Zy_nb<yozOp then X2Zy_nb=yozOp end end;return X2Zy_nb else return nil end end,__index=function(wxU,kOmS5sy)if | |
wxU:match(kOmS5sy)then return true else return nil end end,__pairs=function(CLSdD)return | |
pairs(CLSdD.specs)end,__ipairs=function(Fh)return ipairs(Fh.specs)end,__tostring=function(IlAPA) | |
return | |
mCsewfX((function() | |
local jLKMpQuK={}local sUQpby=1;local mbA=IlAPA.specs;for _qPhpaFx=1,#mbA do local zex=mbA[_qPhpaFx] | |
jLKMpQuK[sUQpby]=tostring(zex)sUQpby=sUQpby+1 end | |
return jLKMpQuK end)(),',')end,__eq=function(pPGcdu,rjp) | |
local cT2z=pPGcdu.specs | |
for zke1tWps=1,#cT2z do local gRFA=cT2z[zke1tWps]local jX9a0tJX=false;local YFy4TGc=rjp.specs | |
for YjpbYkCb=1,#YFy4TGc do | |
local L1p7luJ=YFy4TGc[YjpbYkCb]if gRFA==L1p7luJ then jX9a0tJX=true;break end end;if not jX9a0tJX then return false end end;return true end}c.__index=c | |
PEZ_=setmetatable({__init=function(eH,WpOZ) | |
if type(WpOZ)=='string'then WpOZ={WpOZ}end;local fD2289 | |
do local folfO={}local vtsK=1;for E1p4Mv=1,#WpOZ do local IHap=WpOZ[E1p4Mv] | |
folfO[vtsK]=eH:parse(IHap)vtsK=vtsK+1 end;fD2289=folfO end;eH.specs={} | |
for rDvV=1,#fD2289 do local RX1L2q=fD2289[rDvV]for bCBtWguf=1,#RX1L2q do | |
local q=RX1L2q[bCBtWguf]yY(eH.specs,q)end end end,__base=c,__name="Spec"},{__index=c,__call=function(e1sXUN4f,...) | |
local x=setmetatable({},c)e1sXUN4f.__init(x,...)return x end})c.__class=PEZ_;s6FbB=PEZ_ end;local X | |
X=function(VP,IQwqq)return wFeA(fs52REi(VP,fs52REi(IQwqq)))end;local dc61 | |
dc61=function(Xcc4,fqw5)return s6FbB(Xcc4):match(fs52REi(fqw5))end;local aguhyl | |
aguhyl=function(qnVfOeRE)return | |
({fs52REi:parse(qnVfOeRE)})[1]end | |
return{Spec=s6FbB,SpecItem=PUNkgaiM,Version=fs52REi,compare=X,match=dc61,validate=aguhyl}end)()local YAtG_LV3;YAtG_LV3=require("component").isAvailable;local LfEJbh_,JD | |
do | |
local YIiSKsxK=require("shell")LfEJbh_,JD=YIiSKsxK.parse,YIiSKsxK.getWorkingDirectory end;local u=require("shell")local pzDMZwG,XPoQB,XxJ,o5sms,JQi1jg;do | |
local Ua=require("filesystem") | |
pzDMZwG,XPoQB,XxJ,o5sms,JQi1jg=Ua.isDirectory,Ua.exists,Ua.makeDirectory,Ua.concat,Ua.copy end | |
local wVzn=require("filesystem")local pE,RSjapQ;do local qeJtG=require("serialization") | |
pE,RSjapQ=qeJtG.serialize,qeJtG.unserialize end;local QJf | |
QJf=require("event").pull;local zC,pfZ3SPy_,pDNa2ox6;do local pdpNgBcZ=require("term") | |
zC,pfZ3SPy_,pDNa2ox6=pdpNgBcZ.clearLine,pdpNgBcZ.getCursor,pdpNgBcZ.clear end;local Do6yo7nm | |
Do6yo7nm=os.exit;local y06X3k,ivnJjrA | |
do local wV=io;y06X3k,ivnJjrA=wV.write,wV.stderr end;local d3fMjkg,el | |
do local rLd=table;d3fMjkg,el=rLd.insert,rLd.unpack end;local Wu_uIt=wVzn.list;local w,sgeP={},{}local CM=nil;local Qlmlet={}local _={}local RkGFh6="/etc/hpm/module/" | |
local hw18="/var/lib/hpm/dist/"local nvCiFt7r=0;local xSebv5Jc="/etc/hpm/hpm.cfg" | |
local mMp=[[Usage: hpm OPTIONS COMMAND | |
See `man hpm` for more info.]] | |
local rDtVf=[[-- << Global settings >> ------------------------------------------------------- | |
-- A directory where package manifests will be placed. | |
-- It will be created if it doesn't exist. | |
dist = "/var/lib/hpm/dist" | |
-- A place where to search for custom hpm modules. | |
-- It will be created if it doesn't exist. | |
modules = "/etc/hpm/module" | |
-- << Settings related to the hel module >> ------------------------------------ | |
hel = {} | |
-- If set to `false`, hpm will *only* remove a package that hpm is told to | |
-- remove. Otherwise, all of its dependants will be also removed. | |
hel.remove_dependants = true | |
-- << Settings related to the oppm module >> ----------------------------------- | |
oppm = {} | |
-- A directory where package manifests will be stored for faster access. | |
oppm.cache_directory = "/var/cache/hpm/oppm" | |
-- See hel.remove_dependants above. | |
oppm.remove_dependants = true]] | |
local vj={info=function(...) | |
if w.v then | |
return | |
print(table.concat((function(...)local z8oF={}local DB6A7N=1;local VhYX={...}for Ha7ErH=1,#VhYX do local rjU95v=VhYX[Ha7ErH] | |
z8oF[DB6A7N]=tostring(rjU95v)DB6A7N=DB6A7N+1 end;return z8oF end)(...),"\t"))end end,print=function(...) | |
if | |
not(w.q)then | |
return | |
print(table.concat((function(...)local sxBl={}local m=1;local nD4LhX6z={...}for iN=1,#nD4LhX6z do | |
local Lq=nD4LhX6z[iN]sxBl[m]=tostring(Lq)m=m+1 end | |
return sxBl end)(...),"\t"))end end,error=function(...) | |
if | |
not(w.q)then | |
return | |
ivnJjrA:write( | |
table.concat((function(...)local s9tW={}local R61K=1;local Jf4os={...} | |
for a4xc=1,#Jf4os do | |
local e=Jf4os[a4xc]s9tW[R61K]=tostring(e)R61K=R61K+1 end;return s9tW end)(...),"\t")..'\n')end end,fatal=function(...) | |
if | |
not(w.q)then | |
ivnJjrA:write( | |
table.concat((function(...)local la5={}local i=1;local R={...}for xWVu=1,#R do local Yw8Yxix=R[xWVu] | |
la5[i]=tostring(Yw8Yxix)i=i+1 end;return la5 end)(...),"\t")..'\n')end;return Do6yo7nm(1)end}local z | |
z=function(i,VoXG)if not(i)then return vj.fatal(VoXG)end end;local Zg | |
Zg=function(JL0I04c)return | |
vj.fatal((tostring(JL0I04c))..": Not implemented yet!")end;local ykRppH | |
ykRppH=function()y06X3k(mMp)return Do6yo7nm(0)end;local WQ6 | |
WQ6=function(En6r_K97,T4AA)if not(En6r_K97)then vj.fatal(T4AA)end;return En6r_K97 end;local y36Aetn | |
y36Aetn=function(VnuCKTdu,XnNgn,H1JD) | |
if not(type(VnuCKTdu==XnNgn))then | |
vj.fatal("Value '".. | |
tostring(VnuCKTdu).. | |
"' is "..tostring(type(H1JD)).. | |
", however, a "..tostring(XnNgn).." is expected.")end;return H1JD end;local iPL3B4cr;iPL3B4cr=function(gEEa9I) | |
return y36Aetn(gEEa9I,"number",tonumber(gEEa9I))end | |
local GI2hz6SK | |
GI2hz6SK=function(ULLLDUm) | |
return y36Aetn(ULLLDUm,"string",tostring(ULLLDUm))end;local Oh | |
Oh=function(e4F3,GsfNt7) | |
for fF0,YWPfQKb2 in pairs(GsfNt7)do if YWPfQKb2 ==e4F3 then return true,fF0 end end;return false end;local PG | |
PG=function(r)local OS0Zp3i=0;for BK,Idjbe70 in pairs(r)do OS0Zp3i=OS0Zp3i+1 end | |
return OS0Zp3i end;local n | |
n=function(B) | |
if type(B)=="nil"then return true elseif type(B)=="string"then return not B or#B<1 elseif type(B)== | |
"table"then return not B or PG(B)<1 else return true end end;local O | |
O=function(nDjt) | |
for NVWt=1,#nDjt do local efuUGMh=nDjt[NVWt]if not efuUGMh then return false end end;return true end;local N5UjTN | |
N5UjTN=function(p4nNp)return XPoQB(p4nNp)and pzDMZwG(p4nNp)end;local qLH5 | |
qLH5=function(VW)return XPoQB(VW)and not pzDMZwG(VW)end;local tE | |
tE=function(Zt)return Zt==1 and""or"s"end;local VcV0EuD | |
VcV0EuD=function(V)return V~=1 and""or"s"end;local pX4gCR | |
pX4gCR=function(mzeTI)return mzeTI==1 and"is"or"are"end;local gad4ZcL;gad4ZcL=function(sy4J) | |
return sy4J:match("^([^:]-):?([^:@]+)@?([^:@]*)$")end | |
local dk | |
dk=function(ztJhP_u8) | |
if | |
wVzn.get(u.resolve(ztJhP_u8)).isReadOnly()then return false,"the path is readonly!"elseif not XPoQB(ztJhP_u8)then return false, | |
"the filesystem node doesn't exist."else | |
if not | |
(pzDMZwG(ztJhP_u8)or wVzn.isLink(ztJhP_u8))then return wVzn.remove(ztJhP_u8)else for D in | |
WQ6(Wu_uIt(ztJhP_u8))do dk(o5sms(ztJhP_u8,D))end;return | |
wVzn.remove(ztJhP_u8)end end end;local E | |
E=function()local XIcl=w.c or w.config or xSebv5Jc | |
if not qLH5(XIcl)then | |
local U2=wVzn.path(XIcl) | |
if not N5UjTN(U2)then local Z,ZDICnKE=XxJ(U2)if not Z then | |
return false,"Failed to create '".. | |
tostring(U2).. | |
"' directory for the config file: "..tostring(ZDICnKE)end end;local X,zLtWO09=io.open(XIcl,"w")if X then X:write(rDtVf)X:close()else | |
return false, | |
"Failed to open config file for writing: "..tostring(zLtWO09)end end;local ys,rMQ1um8=io.open(XIcl,"r") | |
if ys then local L=ys:read("*all") | |
ys:close()local B58={};(load(L,"config","t",B58))() | |
local PYVzrNl | |
PYVzrNl=function(KTVmRC)if KTVmRC==nil then KTVmRC={}end | |
return | |
setmetatable(KTVmRC,{__index={get=function(Pa,bmK,OJPc3R)if | |
type(KTVmRC[Pa])~="nil"then | |
if type(KTVmRC[Pa])=="table"then return PYVzrNl(KTVmRC[Pa])end;return KTVmRC[Pa]end | |
vj.error( | |
"Attempt to access undeclared config field '"..tostring(Pa).."'!")if not OJPc3R then return bmK else return PYVzrNl(bmK)end end}})end;_=PYVzrNl(B58)RkGFh6=_.get("modules",RkGFh6) | |
hw18=_.get("dist",hw18)return _ else | |
return false,"Failed to open config file for reading: "..tostring(rMQ1um8)end end;local OO | |
OO=function()if not(YAtG_LV3("internet"))then | |
vj.fatal("This command requires an internet card to run!")end;CM=CM or | |
require("internet").request end;local y;y=function(j)OO()return pcall(CM,j)end;local cR6rJlAl | |
cR6rJlAl=function() | |
if | |
not N5UjTN(RkGFh6)then local M9K,Zeu=XxJ(RkGFh6)if not M9K then | |
return false,"Failed to create '".. | |
tostring(RkGFh6).."' directory for custom modules: "..tostring(Zeu)end end;local vMgKnGj=WQ6(Wu_uIt(RkGFh6)) | |
for Q2_d in vMgKnGj do | |
local W0iTcMIt=Q2_d:match("^(.+)%..+$") | |
local N=(loadfile(o5sms(RkGFh6,Q2_d),"t",_ENV))()if N then Qlmlet[W0iTcMIt]=N end end;return true end;local M6ilzGJ | |
M6ilzGJ=function(Hald6SO)local Dq=Hald6SO;local y3Ur | |
do local GL70F7uL=Hald6SO:find(':')if GL70F7uL then Dq=Hald6SO:sub( | |
GL70F7uL+1) | |
y3Ur=Hald6SO:sub(1,GL70F7uL-1)end end | |
if not y3Ur then local lqANrrJA={} | |
for WUFTXBy6,y3Ur in pairs(Qlmlet)do | |
if y3Ur[Dq]then if type(y3Ur[Dq])=="table"and | |
y3Ur[Dq].__public==true then | |
d3fMjkg(lqANrrJA,{class=y3Ur,module=WUFTXBy6,method=y3Ur[Dq]})end end end | |
if#lqANrrJA>1 then local aEZf=nil;for QjQ_o,y3Ur in pairs(lqANrrJA)do | |
if y3Ur.module=="hel"then aEZf=QjQ_o;break end end;if aEZf then | |
lqANrrJA={lqANrrJA[aEZf]}end end | |
if#lqANrrJA>1 then | |
vj.print("Ambiguous choice: method ".. | |
tostring(Dq).." is implemented in the following modules:")for wDiq_=1,#lqANrrJA do local y3Ur=lqANrrJA[wDiq_] | |
vj.print(" * "..tostring(y3Ur.module))end | |
vj.print( | |
"Choose a specific module by prepending its name with a colon, e.g., ".. | |
tostring(lqANrrJA[1].module)..":"..tostring(Dq)..".")return false elseif#lqANrrJA==0 then | |
vj.error("Unknown command: "..tostring(Dq))return false else y3Ur=lqANrrJA[1].module | |
vj.info("Note, using "..tostring(y3Ur)..":".. | |
tostring(Dq)..".")return function(...) | |
return lqANrrJA[1].method(lqANrrJA[1].class,...)end end else | |
if Qlmlet[y3Ur]and n(Dq)then local QYA5WJOY={} | |
for yliV8,rjpKFl in pairs(Qlmlet[y3Ur])do if | |
type(rjpKFl)=="table"and rjpKFl.__public==true then | |
d3fMjkg(QYA5WJOY,tostring(yliV8))end end | |
vj.print("Available module-specific commands: "..tostring(table.concat(QYA5WJOY,", ")))return false end | |
if | |
not Qlmlet[y3Ur]or not Qlmlet[y3Ur][Dq]or | |
Qlmlet[y3Ur][Dq]and | |
(type(Qlmlet[y3Ur][Dq])~="table"or | |
Qlmlet[y3Ur][Dq].__public~=true)then | |
vj.error("Unknown command: "..tostring(y3Ur)..":"..tostring(Dq))return false else return function(...) | |
return Qlmlet[y3Ur][Dq](Qlmlet[y3Ur],...)end end end end;local iW6CD | |
iW6CD=function(YUGQovw) | |
if not YUGQovw or YUGQovw==""then YUGQovw="hel"else YUGQovw=YUGQovw end;return Qlmlet[YUGQovw]or Qlmlet.default end;local wZdg | |
wZdg=function(XZt7GyF,Zn3SC,...)if XZt7GyF==nil then XZt7GyF=Qlmlet.default end | |
if | |
XZt7GyF[Zn3SC]then return XZt7GyF[Zn3SC](XZt7GyF,...)else return | |
Qlmlet.default[Zn3SC](Qlmlet.default,...)end end;local BaX | |
BaX=function(D4,crA9EKx,IcsJ,A)if crA9EKx==nil then crA9EKx="hel"end;if IcsJ==nil then | |
IcsJ=o5sms(hw18,crA9EKx)end;if A==nil then A=D4.name end;if not D4 then | |
return false,"'nil' given"end | |
if not N5UjTN(IcsJ)then local o0_XG8FI,jLsxpw=XxJ(IcsJ) | |
if not o0_XG8FI then return | |
false, | |
"Failed to create '"..tostring(o5sms(IcsJ,crA9EKx)).."' directory for manifest files: ".. | |
tostring(jLsxpw)end end;local Wp9xT,P=io.open(o5sms(IcsJ,A),"w") | |
if Wp9xT then | |
Wp9xT:write(pE(D4))Wp9xT:close()return true else return false, | |
"Failed to open file for writing: "..tostring(P)end end;local SJsW11k | |
SJsW11k=function(x,AXNfV,cX)if cX==nil then cX="hel"end | |
AXNfV=AXNfV or o5sms(hw18,cX,x) | |
if qLH5(AXNfV)then local iyx,bxvn=io.open(AXNfV,"rb") | |
if iyx then | |
local mWYrzB=WQ6(RSjapQ(iyx:read("*all")))iyx:close()return mWYrzB else | |
return false,"Failed to open manifest for '"..tostring(x).. | |
"' package: "..tostring(bxvn)end else | |
return false,"No manifest found for '"..tostring(x).."' package"end end;local Ki1HJT | |
Ki1HJT=function(O7kX,Q4XSpdY)if Q4XSpdY==nil then Q4XSpdY="hel"end | |
local fzTyrQ9F=o5sms(hw18,Q4XSpdY,O7kX) | |
if qLH5(fzTyrQ9F)then return dk(fzTyrQ9F)else return false,"No manifest found for '".. | |
tostring(O7kX).."' package"end end;local wjim8xCV | |
wjim8xCV=function(fAumJ0i)return | |
setmetatable({__public=true},{__call=function(i0,...)return fAumJ0i(...)end})end;local EQLam | |
EQLam=function(tZliF4,jlmopoj) | |
return | |
function()local R,uS_N6=pcall(tZliF4)if not(R)then | |
return false,"Could not download '"..tostring(jlmopoj).."': ".. | |
tostring(uS_N6)else return uS_N6 end end end;local qTDt | |
qTDt=function(o5SLRA,ztwXaCR,M2WtMgiq) | |
if ztwXaCR==nil then ztwXaCR="Could not download '%s': %s"end | |
if M2WtMgiq==nil then M2WtMgiq="Could not download '%s': %s"end;local FgfME,ylH9o,CC4Kfjh=y(o5SLRA)if not(FgfME and ylH9o)then return false, | |
ztwXaCR:format(o5SLRA,CC4Kfjh)end;local k=""for eUQ0x,CC4Kfjh in | |
EQLam(ylH9o)do | |
if eUQ0x then k=k..eUQ0x else return false,M2WtMgiq:format(o5SLRA,CC4Kfjh)end end;return k end;local v | |
v=function() | |
if not(w.y)then io.write("Press [ENTER] to continue...") | |
local r0OR=select(3,QJf("key_down")) | |
if r0OR==13 then zC()return true else io.write("\n")return false end else return true end end;local Ta | |
Ta=function(pYHkv)local hxZHlgP=0;local zct={} | |
if not(n(pYHkv.install))then | |
local WQk6Wkd={"Packages to INSTALL:",table.concat(pYHkv.install," ")}d3fMjkg(zct,WQk6Wkd) | |
hxZHlgP=hxZHlgP+#pYHkv.install else pYHkv.install={}end | |
if not(n(pYHkv.reinstall))then | |
local t={"Packages to REINSTALL:",table.concat(pYHkv.reinstall," ")}d3fMjkg(zct,t)hxZHlgP=hxZHlgP+#pYHkv.reinstall else | |
pYHkv.reinstall={}end | |
if not(n(pYHkv.upgrade))then | |
local pRCHPl={"Packages to UPGRADE:",table.concat(pYHkv.upgrade," ")}d3fMjkg(zct,pRCHPl) | |
hxZHlgP=hxZHlgP+#pYHkv.upgrade else pYHkv.upgrade={}end | |
if not(n(pYHkv.remove))then | |
local sCffg4HK={"Packages to REMOVE:",table.concat(pYHkv.remove," ")}d3fMjkg(zct,sCffg4HK) | |
hxZHlgP=hxZHlgP+#pYHkv.remove else pYHkv.remove={}end | |
do | |
local EyljhkFp={tostring(#pYHkv.install).." to INSTALL, ".. | |
tostring(#pYHkv.reinstall).. | |
" to REINSTALL, ".. | |
tostring(#pYHkv.upgrade).." to UPGRADE, "..tostring(#pYHkv.remove).. | |
" to REMOVE."}d3fMjkg(zct,EyljhkFp)end | |
for uGDn542,DQ in pairs(zct)do for uGDn542,s6Ahlni_ in pairs(DQ)do | |
if uGDn542 ==1 then vj.print(s6Ahlni_)else vj.print(" ".. | |
tostring(s6Ahlni_))end end;if uGDn542 ~=#zct then | |
vj.print("")end end | |
if hxZHlgP>0 then if not(v())then return Do6yo7nm(7)end end end | |
do local T6dNu;local H={}H.__index=H | |
T6dNu=setmetatable({__init=function()end,__base=H,__name="default"},{__index=H,__call=function(vj9879b5,...) | |
local cotcYZ1f=setmetatable({},H)vj9879b5.__init(cotcYZ1f,...)return cotcYZ1f end})H.__class=T6dNu;local YlzZm=T6dNu | |
YlzZm.install=function()return | |
vj.fatal("Incorrect source is provided! No default 'install' implementation.")end | |
YlzZm.remove=function(YlzZm,FRcmT,zfl)if zfl==nil then zfl="hel"end | |
if FRcmT then | |
if FRcmT.files then | |
for itxD,JPHs7A in pairs(FRcmT.files)do | |
local yzYgnMtr=o5sms(JPHs7A.dir,JPHs7A.name)local o,wmkJ=dk(yzYgnMtr)if not(o)then | |
return false,"Failed to remove '"..tostring(yzYgnMtr).. | |
"': "..tostring(wmkJ)end end end;return Ki1HJT(FRcmT.name,zfl)else | |
return false,"Package can't be removed: the manifest is empty."end end | |
YlzZm.save=function()return | |
vj.fatal("Incorrect source is provided! No default 'save' implementation.")end;Qlmlet.default=T6dNu end | |
do local I1;local gXu5hG=Qlmlet.default;local R60Ru4bj={}R60Ru4bj.__index=R60Ru4bj | |
setmetatable(R60Ru4bj,gXu5hG.__base) | |
I1=setmetatable({__init=function(WT2AX,...)return I1.__parent.__init(WT2AX,...)end,__base=R60Ru4bj,__name="hel",__parent=gXu5hG},{__index=function(_AvO,qEO) | |
local q=rawget(R60Ru4bj,qEO)if q==nil then local WUY7=rawget(_AvO,"__parent") | |
if WUY7 then return WUY7[qEO]end else return q end end,__call=function(_puepou,...) | |
local DYLeJ=setmetatable({},R60Ru4bj)_puepou.__init(DYLeJ,...)return DYLeJ end})R60Ru4bj.__class=I1;local eQWRf=I1 | |
eQWRf.URL="https://hel-roottree.rhcloud.com/" | |
eQWRf.parsePackageJSON=function(eQWRf,udbF,dt1)if dt1 ==nil then dt1=s.Spec("*")end;local V7eMEiVW=nil | |
local Co1tUVas={} | |
for rQYWEt,nCwsa in pairs(udbF.versions)do local IPPy=s.Version(rQYWEt)if not(IPPy)then | |
vj.fatal( | |
"Could not parse the version in package: "..tostring(IPPy))end;Co1tUVas[IPPy]=nCwsa end | |
local B,UjlBMb=pcall(function()return | |
dt1:select((function()local zYGA2q2={}local I9Mw=1 | |
for e,BUtIET in pairs(Co1tUVas)do zYGA2q2[I9Mw]=e;I9Mw=I9Mw+1 end;return zYGA2q2 end)())end)if not(B)then | |
vj.fatal("Could not select the best version: "..tostring(UjlBMb))end;V7eMEiVW=tostring(UjlBMb)if not | |
(UjlBMb)then | |
vj.fatal("No candidate for version specification '"..tostring(dt1).."' found!")end | |
local PKWIJ9={name=udbF.name,version=V7eMEiVW,files={},dependencies={}}for NvAj,Icg in pairs(Co1tUVas[UjlBMb].files)do local PzMsk=Icg.dir;local axLuO=Icg.name | |
d3fMjkg(PKWIJ9.files,{url=NvAj,dir=PzMsk,name=axLuO})end | |
for j,As in | |
pairs(Co1tUVas[UjlBMb].depends)do local JmCzKm=As.version;local Mwhc=As.type | |
d3fMjkg(PKWIJ9.dependencies,{name=j,version=JmCzKm,type=Mwhc})end;return PKWIJ9 end | |
eQWRf.getPackageSpec=function(eQWRf,A6z) | |
vj.info("Downloading package data for "..tostring(A6z).." ...") | |
local _Mk,PXrrrSid=y(eQWRf.URL.."packages/"..A6z)if not(_Mk)then | |
vj.fatal("HTTP request error: "..PXrrrSid)end;local L9="" | |
for dbTwy in PXrrrSid do L9=L9 ..dbTwy end;local _KZPScl=JtAjijkG:decode(L9) | |
if not(_KZPScl)then vj.fatal("Incorrect JSON format!\n".. | |
tostring(L9))end;return _KZPScl.data end | |
eQWRf.rawInstall=function(eQWRf,R4f819q,Kj1I,nTUMgqomA)if Kj1I==nil then Kj1I=false end | |
if nTUMgqomA==nil then nTUMgqomA=false end;local Id5sIM | |
if nTUMgqomA then Id5sIM=o5sms(JD(),R4f819q.name)else Id5sIM="/"end | |
if nTUMgqomA and not N5UjTN(Id5sIM)then local gZM2ANLt,aC72qEnu=XxJ(Id5sIM) | |
if not | |
(gZM2ANLt)then | |
vj.fatal("Failed creating '"..tostring(Id5sIM).. | |
"' directory for package '"..tostring(R4f819q.name).. | |
"'! \n"..tostring(aC72qEnu))end elseif not nTUMgqomA then local B60J=SJsW11k(R4f819q.name,nil,"hel") | |
if B60J then | |
if B60J.version== | |
tostring(R4f819q.version)then | |
vj.print("'"..tostring(R4f819q.name).. | |
"@".. | |
tostring(B60J.version).."' is already installed, skipping...")return B60J else | |
vj.fatal("'".. | |
tostring(R4f819q.name).. | |
"@".. | |
tostring(R4f819q.version).. | |
"' was attempted to install, however, another version of the same package is already installed: '"..tostring(R4f819q.name).. | |
"@"..tostring(B60J.version).."'")end end end | |
for Y4,f in pairs(R4f819q.files)do | |
vj.info("Fetching '"..tostring(f.name).."' ...")local yeCnvcd6=WQ6(qTDt(f.url))local Iq93c6cA=o5sms(Id5sIM,f.dir) | |
if not | |
N5UjTN(Iq93c6cA)then local nsM0h,Czi=XxJ(Iq93c6cA)if not(nsM0h)then | |
vj.fatal("Failed to create '".. | |
tostring(Iq93c6cA).. | |
"' directory for '"..tostring(f.name).."'! \n"..tostring(Czi))end end | |
do local IlxN;f,IlxN=io.open(o5sms(Iq93c6cA,f.name),"w")if | |
not(f)then | |
vj.fatal("Could not open '"..tostring(o5sms(Iq93c6cA,f.name)).."' for writing: ".. | |
tostring(IlxN))end | |
f:write(yeCnvcd6)f:close()end end;return | |
{name=R4f819q.name,version=tostring(R4f819q.version),files=R4f819q.files,dependencies=R4f819q.dependencies,manual=Kj1I}end | |
eQWRf.resolveDependencies=function(eQWRf,EA_3x01A,m54tY2,WJWMdKI,AhbP)if m54tY2 ==nil then m54tY2={}end | |
if WJWMdKI==nil then WJWMdKI={}end;if AhbP==nil then AhbP={}end | |
for QHFgYUN=1,#EA_3x01A do local RoEsr7So=EA_3x01A[QHFgYUN]local dX,Rz | |
dX,Rz=RoEsr7So.name,RoEsr7So.version;local j177r=false;for j=1,#m54tY2 do local qCaFw=m54tY2[j] | |
if qCaFw.pkg.name==dX then j177r=true;break end end | |
if not(j177r)then | |
d3fMjkg(WJWMdKI,{name=dX,version=""})local syvPi=SJsW11k(dX,nil,"hel") | |
if not syvPi or not | |
Rz:match(s.Version(syvPi.version))then | |
local NrgSK2=eQWRf:getPackageSpec(dX)local wIH=eQWRf:parsePackageJSON(NrgSK2,Rz) | |
WJWMdKI[#WJWMdKI].version=wIH.version;local TYWkpc=wIH.dependencies | |
for k=1,#TYWkpc do local J=TYWkpc[k]j177r=false | |
for gtlO9=1,#m54tY2 do | |
local Lun=m54tY2[gtlO9]if Lun.pkg.name==J.name then j177r=true;break end end | |
if not j177r then local beUJXhjw=nil;for zY7adu,Nlvw in pairs(WJWMdKI)do | |
if Nlvw.name==J.name then beUJXhjw=zY7adu;break end end | |
if beUJXhjw then | |
if | |
WJWMdKI[beUJXhjw].version==J.version then | |
vj.fatal("Circular dependencies detected: '".. | |
tostring(dX).. | |
"@".. | |
tostring(wIH.version).. | |
"' depends on '".. | |
tostring(J.name).. | |
"@".. | |
tostring(J.version).. | |
"', and '".. | |
tostring(WJWMdKI[beUJXhjw].name).. | |
"@"..tostring(WJWMdKI[beUJXhjw].version).. | |
"' depends on '"..tostring(dX).."@".. | |
tostring(wIH.version).."'.")else | |
vj.fatal("Attempted to install two versions of the same package: '".. | |
tostring(J.name).. | |
"@".. | |
tostring(J.version).. | |
"' and '".. | |
tostring(WJWMdKI[beUJXhjw].name).."@".. | |
tostring(WJWMdKI[beUJXhjw].version).."' when resolving dependencies for '".. | |
tostring(dX).."@"..tostring(wIH.version).."'.")end end | |
eQWRf:resolveDependencies({{name=J.name,version=s.Spec(J.version)}},m54tY2,WJWMdKI,AhbP)end end;d3fMjkg(m54tY2,{pkg=wIH})d3fMjkg(AhbP,{pkg=wIH})else | |
d3fMjkg(m54tY2,{pkg=syvPi})end;WJWMdKI[#WJWMdKI]=nil end end;return AhbP end | |
eQWRf.getPackageDependants=function(eQWRf,K55,BJcMTdMi,f1MKKJ)if BJcMTdMi==nil then BJcMTdMi={}end | |
if f1MKKJ==nil then f1MKKJ={}end | |
for nFf=1,#K55 do local EIqL41=K55[nFf]local iv=false | |
for rfmMR4=1,#BJcMTdMi do local Tq2I=BJcMTdMi[rfmMR4]if Tq2I.name== | |
EIqL41 then iv=true;break end end | |
if not(iv)then d3fMjkg(f1MKKJ,{name=EIqL41}) | |
local GNo=SJsW11k(EIqL41,nil,"hel") | |
if GNo then d3fMjkg(BJcMTdMi,{name=EIqL41,manifest=GNo}) | |
local e5x=WQ6(Wu_uIt(o5sms(hw18,"hel"))) | |
for QrONvWGq in e5x do GNo=WQ6(SJsW11k(QrONvWGq,nil,"hel")) | |
local D94fnZaa=GNo.dependencies | |
for XI=1,#D94fnZaa do local FNi=D94fnZaa[XI] | |
if FNi.name==EIqL41 then iv=false | |
for pRW2nEmK=1,#BJcMTdMi do | |
local OR=BJcMTdMi[pRW2nEmK]if OR.name==QrONvWGq then iv=true;break end end | |
if not iv then | |
for Arww=1,#f1MKKJ do local BYH=f1MKKJ[Arww]if BYH.name==QrONvWGq then | |
vj.fatal("Circular dependencies detected: ".. | |
tostring(QrONvWGq))end end | |
eQWRf:getPackageDependants({QrONvWGq},BJcMTdMi,f1MKKJ)end end end end else | |
vj.fatal("Package ".. | |
tostring(EIqL41).." is referenced as a dependant of another package, however, this package isn't installed.")end;f1MKKJ[#f1MKKJ]=nil end end;return BJcMTdMi end | |
eQWRf.install=wjim8xCV(function(eQWRf,...) | |
if w.l or w["local"]then local Ef=u.resolve(...) | |
local P=WQ6(SJsW11k(Ef,o5sms(Ef,"manifest")))local F4AWvI=eQWRf:resolveDependencies(P.depends,nil)local GYVN=w.d or | |
w.onlyDeps;local DNlB1V={}for erb6G_E=1,#F4AWvI do local QFUU10K=F4AWvI[erb6G_E] | |
d3fMjkg(DNlB1V, | |
tostring(QFUU10K.pkg.name).."@"..tostring(QFUU10K.pkg.version))end;if | |
not(GYVN)then | |
d3fMjkg(DNlB1V,tostring(P.name).."@"..tostring(P.version))end;Ta({install=DNlB1V}) | |
for xNPDtul=1,#F4AWvI,1 | |
do local k8=F4AWvI[xNPDtul] | |
vj.print("Installing '"..tostring(k8.pkg.name).."@".. | |
tostring(k8.pkg.version).."'...")P=eQWRf:rawInstall(k8.pkg,false,false) | |
local HmgRk,UuCdpVi=BaX(P,"hel") | |
if HmgRk then | |
vj.info("Saved the manifest of '"..tostring(P.name).."'.")else | |
vj.fatal("Couldn't save the manifest of '"..tostring(P.name).. | |
"': "..tostring(UuCdpVi)..".")end end | |
if not GYVN then | |
vj.print("Installing '"..tostring(P.name).. | |
"@"..tostring(P.version).."'...") | |
for CA0uX7n,ze5Vpc3 in pairs(P.files)do if | |
not N5UjTN(o5sms(ze5Vpc3.dir,ze5Vpc3.name))then XxJ(ze5Vpc3.dir)end | |
local vwK8,Sk_SiC=JQi1jg(o5sms(Ef,ze5Vpc3.url),o5sms(ze5Vpc3.dir,ze5Vpc3.name))if not(vwK8)then | |
vj.fatal("Cannot copy file '"..tostring(ze5Vpc3.name).. | |
"': "..tostring(Sk_SiC))end end;local fghe,vFXf=BaX(P,"hel") | |
if fghe then | |
vj.info("Saved the manifest of '"..tostring(P.name).."'.")else | |
vj.fatal("Couldn't save the manifest of '"..tostring(P.name).. | |
"': "..tostring(vFXf)..".")end end end;local o7E8TLH={}local N5N27Jd={...} | |
for X0bgPvA=1,#N5N27Jd do local M9CyqH=N5N27Jd[X0bgPvA]local z0x4qSAN,X0GTupeV=M9CyqH:match( | |
"^(.+)@(.+)$"or M9CyqH)if n(X0GTupeV)then | |
X0GTupeV="*"end | |
vj.info("Creating version specification for "..tostring(X0GTupeV).." ...") | |
local rQ,k=pcall(function()return s.Spec(X0GTupeV)end)if not(rQ)then | |
vj.fatal("Could not parse the version specification: "..tostring(k).."!")end | |
d3fMjkg(o7E8TLH,{name=z0x4qSAN,version=k})end;local m=w.r or w.reinstall;local nK=w.s or w.save | |
local _zr=eQWRf:resolveDependencies(o7E8TLH)local f5={}local UAc={} | |
for Oc=1,#_zr do local IHovU=false | |
repeat local e_wDQjk=_zr[Oc] | |
if m then local ClglY=false;for S=1,#o7E8TLH do | |
local NKetZhs=o7E8TLH[S] | |
if NKetZhs.name==e_wDQjk.pkg.name then ClglY=true;break end end;if ClglY then | |
d3fMjkg(f5, | |
tostring(e_wDQjk.pkg.name).."@"..tostring(e_wDQjk.pkg.version))IHovU=true;break end end | |
d3fMjkg(UAc,tostring(e_wDQjk.pkg.name).."@".. | |
tostring(e_wDQjk.pkg.version))IHovU=true until true;if not IHovU then break end end;Ta({install=UAc,reinstall=f5}) | |
if m then local EFLZ0N1 | |
do local gL={}local m4=1 | |
for rNOL8G=1,#o7E8TLH do | |
local q=o7E8TLH[rNOL8G]gL[m4]=WQ6(SJsW11k(q.name,nil,"hel"))m4=m4+1 end;EFLZ0N1=gL end;eQWRf:_remove(EFLZ0N1,true,false)end | |
for lKO=1,#_zr do local hcwgu=_zr[lKO] | |
vj.print("Installing '"..tostring(hcwgu.pkg.name).."@".. | |
tostring(hcwgu.pkg.version).."'...")local omgCdqp8=false | |
for xxNCdF=1,#o7E8TLH do local _cl1b=o7E8TLH[xxNCdF]if | |
_cl1b.name==hcwgu.pkg.name then omgCdqp8=true;break end end;local X17eHTx=eQWRf:rawInstall(hcwgu.pkg,omgCdqp8,nK) | |
local SGF,myIHU=BaX(X17eHTx,"hel") | |
if SGF then | |
vj.info("Saved the manifest of '"..tostring(X17eHTx.name).."'.")else | |
vj.fatal("Couldn't save the manifest of '"..tostring(X17eHTx.name).. | |
"': "..tostring(myIHU)..".")end end end) | |
eQWRf.remove=wjim8xCV(function(eQWRf,...)local Xz18nk={...}local P={} | |
for sTX4=1,#Xz18nk do local A0TJx=Xz18nk[sTX4] | |
local Nqdkw=WQ6(SJsW11k(A0TJx,nil,"hel"))d3fMjkg(P,Nqdkw)end;return eQWRf:_remove(P,false)end) | |
eQWRf._remove=function(eQWRf,t,QbMO,wYZ)if QbMO==nil then QbMO=false end;if wYZ==nil then wYZ=true end | |
local aMd | |
if | |
not _.get("hel",{},true).get("remove_dependants",true)or not wYZ then | |
do local o0pf={}local tx1LD=1;for N3ROeR=1,#t do local I1oQVnUd=t[N3ROeR] | |
o0pf[tx1LD]={name=I1oQVnUd.name,manifest=I1oQVnUd}tx1LD=tx1LD+1 end | |
aMd=o0pf end else | |
aMd=eQWRf:getPackageDependants((function()local oTX={}local WZlF4=1;for IxqPDOWH=1,#t do local GZqV=t[IxqPDOWH] | |
oTX[WZlF4]=GZqV.name;WZlF4=WZlF4+1 end;return oTX end)())end | |
if not(QbMO)then | |
Ta({remove=(function()local OVubrDw_={}local G2_TeR8=1 | |
for yk=1,#aMd do local OPSPMfr_=aMd[yk] | |
OVubrDw_[G2_TeR8]="hel:".. | |
tostring(OPSPMfr_.manifest.name).."@"..tostring(OPSPMfr_.manifest.version)G2_TeR8=G2_TeR8+1 end;return OVubrDw_ end)()})end | |
for QnNOl=1,#aMd do local aQs=aMd[QnNOl] | |
vj.print("Removing '".. | |
tostring(aQs.manifest.name).."@".. | |
tostring(aQs.manifest.version).."' ...") | |
WQ6(I1.__parent.remove(eQWRf,aQs.manifest,"hel"))end;return true end | |
eQWRf.upgrade=wjim8xCV(function(eQWRf)local uow_0tb={} | |
for m8 in WQ6(Wu_uIt(o5sms(hw18,"hel")))do if not | |
(pzDMZwG(o5sms(hw18,"hel",m8)))then | |
d3fMjkg(uow_0tb,WQ6(SJsW11k(m8,nil,"hel")))end end;local tykg={} | |
for mcoAHO=1,#uow_0tb do local d3gFWO=uow_0tb[mcoAHO] | |
local D=eQWRf:getPackageSpec(d3gFWO.name)local obodPKnu=eQWRf:parsePackageJSON(D) | |
d3gFWO.latest={spec=D,data=obodPKnu} | |
if s.Version(d3gFWO.latest.data.version)> | |
s.Version(d3gFWO.version)then d3fMjkg(tykg,d3gFWO)end end | |
local C_pPyW=eQWRf:resolveDependencies((function()local kgdzk={}local oVSp=1;for uBJ=1,#tykg do local A=tykg[uBJ] | |
kgdzk[oVSp]={name=A.name,version=s.Spec(A.latest.data.version)}oVSp=oVSp+1 end | |
return kgdzk end)())local mgb4b | |
do local MP={}local jb=1 | |
for uKSj=1,#tykg do local YXgXQB=tykg[uKSj] | |
MP[jb]=tostring(YXgXQB.name).. | |
"@{".. | |
tostring(YXgXQB.version).." => ".. | |
tostring(YXgXQB.latest.data.version).."}"jb=jb+1 end;mgb4b=MP end;local LOBqxO={} | |
for bvL1X4=1,#C_pPyW do local PPNahh=C_pPyW[bvL1X4]local z2g=true | |
for m9JTkVv6=1,#tykg do | |
local Q=tykg[m9JTkVv6]if Q.name==PPNahh.pkg.name then z2g=false;break end end;if z2g then | |
d3fMjkg(LOBqxO,tostring(PPNahh.pkg.name).."@".. | |
tostring(PPNahh.pkg.version))end end;Ta({upgrade=mgb4b,install=LOBqxO}) | |
for bWkP=1,#C_pPyW do | |
local JtFj=C_pPyW[bWkP]local PQ3=false;local _xCtN=false | |
for xUGt=1,#tykg do local _U=tykg[xUGt]if _U.name==JtFj.pkg.name then | |
PQ3=_U;_xCtN=_U.manual;break end end;if PQ3 then eQWRf:_remove({PQ3},true,false)end | |
vj.print( | |
"Installing '"..tostring(JtFj.pkg.name).."@".. | |
tostring(JtFj.pkg.version).."'...")local JVpe=eQWRf:rawInstall(JtFj.pkg,_xCtN,false) | |
local nG36XmZC,Vf26=BaX(JVpe,"hel") | |
if nG36XmZC then | |
vj.info("Saved the manifest of '"..tostring(JVpe.name).."'.")else | |
vj.fatal("Couldn't save the manifest of '"..tostring(JVpe.name).. | |
"': "..tostring(Vf26)..".")end end end) | |
eQWRf.info=wjim8xCV(function(eQWRf,hkI39,MwwN)if MwwN==nil then MwwN="*"end;if n(hkI39)then | |
vj.fatal("Usage: hpm hel:info <package name> [<version specification>]")end;if n(MwwN)then MwwN="*"end | |
vj.print( | |
"Creating version specification for "..tostring(MwwN).." ...") | |
local oZ9,OXlT0=pcall(function()return s.Spec(MwwN)end)if not(oZ9)then | |
vj.fatal("Could not parse the version specification: "..tostring(OXlT0).."!")end | |
local V=eQWRf:getPackageSpec(hkI39)local zIYNIXy1=eQWRf:parsePackageJSON(V,OXlT0)local c={}d3fMjkg(c,"- Package name: ".. | |
tostring(V.name)) | |
d3fMjkg(c, | |
"- Description:\n"..tostring(V.description)) | |
d3fMjkg(c,"- Package owners: "..tostring(table.concat(V.owners,", "))) | |
d3fMjkg(c,"- Authors:\n".. | |
tostring(table.concat((function()local mReHt4h={}local I7=1;local Upw=V.authors | |
for nqBfKL=1,#Upw do | |
local gs3a=Upw[nqBfKL]mReHt4h[I7]=" - "..tostring(gs3a)I7=I7+1 end;return mReHt4h end)(),"\n"))) | |
d3fMjkg(c,"- License: "..tostring(V.license)) | |
d3fMjkg(c,"- Versions: "..tostring(PG(V.versions))..", latest: ".. | |
tostring(zIYNIXy1.version)) | |
d3fMjkg(c," - Files: "..tostring(#zIYNIXy1.files)) | |
d3fMjkg(c," - Depends: ".. | |
tostring(table.concat((function()local AkKaBC={}local OmRH8=1;local GY=zIYNIXy1.dependencies | |
for oukM79R=1,#GY do | |
local D_j=GY[oukM79R] | |
AkKaBC[OmRH8]=tostring(D_j.name).."@"..tostring(D_j.version)OmRH8=OmRH8+1 end;return AkKaBC end)()))) | |
d3fMjkg(c," - Changes:\n".. | |
tostring(V.versions[zIYNIXy1.version].changes))d3fMjkg(c,"- Stats:") | |
d3fMjkg(c," - Views: "..tostring(V.stats.views)) | |
d3fMjkg(c,"- Creation date: "..tostring(V.stats.date.created).." UTC") | |
d3fMjkg(c,"- Last updated: ".. | |
tostring(V.stats.date["last-updated"]).." UTC")return vj.print(table.concat(c,"\n"))end) | |
eQWRf.search=wjim8xCV(function(eQWRf,...)local mZPe4w=0 | |
while true do local OvZ={}local cBOpf=eQWRf.URL.."packages" | |
if...then | |
cBOpf=cBOpf.. | |
( | |
"?q=".. | |
table.concat((function(...)local XgRb={}local G3e=1;local GoP6={...} | |
for cZ_=1,#GoP6 do local NYc8=GoP6[cZ_]XgRb[G3e]='"'.. | |
NYc8:gsub("\"","")..'"'G3e=G3e+1 end;return XgRb end)(...)," "):gsub("&",""))end | |
cBOpf=cBOpf.."?offset="..tostring(mZPe4w)local KZYA5y,YoCAN7OU=y(cBOpf)if not(KZYA5y)then | |
vj.fatal("HTTP request error: "..YoCAN7OU)end;local FoP="" | |
for Dff8 in YoCAN7OU do FoP=FoP..Dff8 end;local jqtWXY=JtAjijkG:decode(FoP) | |
if not(jqtWXY)then vj.fatal("Incorrect JSON format!\n".. | |
tostring(FoP))end;OvZ=jqtWXY.data.list;for lEYwsOG9=1,#OvZ do local M=OvZ[lEYwsOG9] | |
vj.print(tostring(M.name).. | |
": "..tostring(M.short_description))end | |
if | |
#OvZ==0 and mZPe4w==0 then vj.print("No packages found.")break end | |
if jqtWXY.data.truncated and jqtWXY.data.sent+jqtWXY.data.offset< | |
jqtWXY.data.total then mZPe4w= | |
jqtWXY.data.offset+jqtWXY.data.sent else break end end end) | |
if gXu5hG.__inherited then gXu5hG.__inherited(gXu5hG,I1)end;Qlmlet.hel=I1 end | |
do local Vt95q2G;local jsPbwU=Qlmlet.default;local Wvs3rd6o={}Wvs3rd6o.__index=Wvs3rd6o | |
setmetatable(Wvs3rd6o,jsPbwU.__base) | |
Vt95q2G=setmetatable({__init=function(N,...)return Vt95q2G.__parent.__init(N,...)end,__base=Wvs3rd6o,__name="oppm",__parent=jsPbwU},{__index=function(v9mB_RUi,hX) | |
local AVU=rawget(Wvs3rd6o,hX)if AVU==nil then local I=rawget(v9mB_RUi,"__parent")if I then return I[hX]end else | |
return AVU end end,__call=function(_x5O1,...) | |
local eFI8dI3=setmetatable({},Wvs3rd6o)_x5O1.__init(eFI8dI3,...)return eFI8dI3 end})Wvs3rd6o.__class=Vt95q2G;local UdVlP=Vt95q2G | |
UdVlP.REPOS="https://raw.githubusercontent.com/OpenPrograms/openprograms.github.io/master/repos.cfg"UdVlP.PACKAGES="https://raw.githubusercontent.com/%s/master/programs.cfg" | |
UdVlP.FILES="https://raw.githubusercontent.com/%s/%s"UdVlP.DIRECTORY="https://api.github.com/repos/%s/contents/%s?ref=%s" | |
UdVlP.DEFAULT_CACHE_DIRECTORY="/var/cache/hpm/oppm" | |
UdVlP.cacheDirectory=function(UdVlP) | |
local i=_.get("oppm",{},true).get("cache_directory",UdVlP.DEFAULT_CACHE_DIRECTORY) | |
if not(N5UjTN(i))then local l6xUetCb,lOb_Sv=XxJ(i)if not(l6xUetCb)then | |
vj.fatal( | |
"Could not create the cache directory at "..tostring(i)..": "..tostring(lOb_Sv))end end;return i end | |
UdVlP.listCache=function(UdVlP)local VspvGB9V={}local LrFLp5=UdVlP:cacheDirectory() | |
local GfB7=WQ6(Wu_uIt(LrFLp5)) | |
for Iz_w1j in GfB7 do | |
if pzDMZwG(o5sms(LrFLp5,Iz_w1j))then | |
local G=WQ6(Wu_uIt(o5sms(LrFLp5,Iz_w1j))) | |
for X7YKzX in G do | |
if pzDMZwG(o5sms(LrFLp5,Iz_w1j,X7YKzX))then | |
local od0VOF=WQ6(Wu_uIt(o5sms(LrFLp5,Iz_w1j,X7YKzX))) | |
for oO6SbZ in od0VOF do local UE_vrsNx=o5sms(LrFLp5,Iz_w1j,X7YKzX,oO6SbZ) | |
if not | |
(pzDMZwG(UE_vrsNx))then local kef2zBS | |
do local ze0,ylW3uC0=io.open(UE_vrsNx,"r") | |
if not ze0 then return false, | |
"Could not open '".. | |
tostring(UE_vrsNx).."' for reading: "..tostring(ylW3uC0)end;O=ze0:read("*all")kef2zBS=RSjapQ(O)ze0:close()end;local Z=o5sms(Iz_w1j,X7YKzX) | |
d3fMjkg(VspvGB9V,{path=UE_vrsNx,repo=Z,pkg=oO6SbZ,data=kef2zBS})end end end end end end;return VspvGB9V end | |
UdVlP.fixCache=function(UdVlP)local N_G1=UdVlP:cacheDirectory() | |
local wkGNE=WQ6(Wu_uIt(N_G1)) | |
for ccK in wkGNE do local BV=true;local HnLY=o5sms(N_G1,ccK) | |
if pzDMZwG(HnLY)then | |
local cm51CH1n=WQ6(Wu_uIt(HnLY)) | |
for iWrSgT in cm51CH1n do local C=true;local YK1=o5sms(HnLY,iWrSgT) | |
if pzDMZwG(YK1)then | |
local t96Qtz=WQ6(Wu_uIt(YK1)) | |
for HjKNi in t96Qtz do local Ub9iqg=true;local r_S8HFRo=o5sms(YK1,HjKNi)if | |
not(pzDMZwG(r_S8HFRo))then Ub9iqg,C,BV=false,false,false end;if Ub9iqg then | |
dk(r_S8HFRo)end end end;if C then dk(YK1)end end end;if BV then dk(HnLY)end end;return true end | |
UdVlP.resolveDirectory=function(UdVlP,qIF4RFBv,wNbC65Ta,xOiPW) | |
local Z9j=WQ6(qTDt(UdVlP.DIRECTORY:format(qIF4RFBv,xOiPW,wNbC65Ta)))Z9j=JtAjijkG:decode(Z9j) | |
if Z9j.message then | |
return false,"Could not fetch ".. | |
tostring(qIF4RFBv)..":".. | |
tostring(wNbC65Ta).. | |
"/"..tostring(xOiPW)..": "..tostring(Z9j.message)end;local r={}local OnJ1=1 | |
for KFU0=1,#Z9j do local Pvuq=Z9j[KFU0]if Pvuq.type=="file"then | |
r[OnJ1]={name=Pvuq.name,url=Pvuq.download_url,path=Pvuq.path}OnJ1=OnJ1+1 end end;return r end | |
UdVlP.updateCache=function(UdVlP)local lOpDJ=UdVlP:cacheDirectory() | |
local YLe=WQ6(UdVlP:listCache())local lTH,JL=qTDt(UdVlP.REPOS)if not(lTH)then | |
return false,"Could not fetch ".. | |
tostring(UdVlP.REPOS)..": "..tostring(JL)end;lTH=RSjapQ(lTH)local FpU_E={} | |
for uEKPPpj_,aYO4NN in | |
pairs(lTH)do local CtG9nSQL=false | |
repeat | |
if aYO4NN.repo then | |
vj.info("Fetching '"..tostring(uEKPPpj_).."' at '".. | |
tostring(aYO4NN.repo).."' ...")local uZtK5yX,kr2CYaS | |
uZtK5yX,kr2CYaS,JL=y(UdVlP.PACKAGES:format(aYO4NN.repo)) | |
if not(uZtK5yX and kr2CYaS)then | |
vj.error("Could not fetch '".. | |
tostring(uEKPPpj_).."' at '".. | |
tostring(aYO4NN.repo).."': "..tostring(JL))CtG9nSQL=true;break end;local hXgSzEI="" | |
for uZtK5yX,B in function()return pcall(kr2CYaS)end do | |
if not uZtK5yX then | |
vj.error("Could not fetch '".. | |
tostring(uEKPPpj_).. | |
"' at '"..tostring(aYO4NN.repo).."': "..tostring(B))hXgSzEI=false;break else if not B then break end;hXgSzEI=hXgSzEI..B end end;if hXgSzEI==false then CtG9nSQL=true;break end | |
if n(hXgSzEI)then | |
vj.error("Could not fetch '".. | |
tostring(uEKPPpj_).."' at '"..tostring(aYO4NN.repo).."'")CtG9nSQL=true;break end;local AUQ;AUQ,JL=RSjapQ(hXgSzEI) | |
if not AUQ then | |
vj.error("Manifest '"..tostring(uEKPPpj_).. | |
"' at '".. | |
tostring(aYO4NN.repo).."' is malformed: "..tostring(JL))CtG9nSQL=true;break end | |
for J,coSiE in pairs(AUQ)do local wm=false | |
repeat | |
if J:match("[^A-Za-z0-9._-]")then | |
vj.error("Package name contains illegal characters: ".. | |
tostring(uEKPPpj_)..":"..tostring(J).."!")wm=true;break end | |
d3fMjkg(FpU_E,{repo=aYO4NN.repo,name=J,data=coSiE})wm=true until true;if not wm then break end end end;CtG9nSQL=true until true;if not CtG9nSQL then break end end;local JWtwnQ2t={} | |
for _O=1,#FpU_E do local smj=FpU_E[_O]local obBu,cbQlG,YZQu1DR4 | |
obBu,cbQlG,YZQu1DR4=smj.name,smj.repo,smj.data;if Oh(o5sms(cbQlG,obBu),JWtwnQ2t)then | |
vj.error("There're multiple packages under the same name: ".. | |
tostring(obBu).."!")end | |
if not | |
(N5UjTN(o5sms(lOpDJ,cbQlG)))then local EGpun;EGpun,JL=XxJ(o5sms(lOpDJ,cbQlG))if not | |
(EGpun)then | |
return false,"Could not create directory '"..tostring(o5sms(lOpDJ,cbQlG)).. | |
"': "..tostring(JL)end end;local kza;kza,JL=io.open(o5sms(lOpDJ,cbQlG,obBu),"w") | |
if not | |
(kza)then return false, | |
"Could not open '"..tostring(o5sms(lOpDJ,cbQlG,obBu)).."' for writing: ".. | |
tostring(JL)end;do | |
kza:write(pE({name=obBu,repo=cbQlG,data=YZQu1DR4}))kza:close()end;local CvGDk_2 | |
do for LNlhK,cnx_1g in pairs(YLe)do | |
if cnx_1g.repo== | |
cbQlG and cnx_1g.pkg==obBu then CvGDk_2=LNlhK;break end end end;if CvGDk_2 then table.remove(YLe,CvGDk_2)else | |
d3fMjkg(JWtwnQ2t,o5sms(cbQlG,obBu))end end;vj.print("Removing old cache files ...") | |
for eV=1,#YLe do | |
local DGQnw=YLe[eV]local yLgHuF;yLgHuF=DGQnw.path;dk(yLgHuF)end;vj.print("Fixing bad cache nodes ...") | |
UdVlP:fixCache() | |
vj.print("- "..tostring(#FpU_E).." program".. | |
tostring(tE(#FpU_E)).." cached.") | |
vj.print("- ".. | |
tostring(#JWtwnQ2t).." package".. | |
tostring(tE(#JWtwnQ2t)).." "..tostring(pX4gCR(# | |
JWtwnQ2t)).." new.") | |
vj.print("- "..tostring(#YLe).. | |
" package"..tostring(tE(#YLe)).." no longer exist".. | |
tostring(VcV0EuD(#YLe))..".")return true end | |
UdVlP.parseLocalPath=function(UdVlP,fpL,k6)if k6:sub(1,2)=="//"then return o5sms(fpL,k6:sub(3))else return | |
o5sms(fpL,"usr",k6)end end | |
UdVlP.rawInstall=function(UdVlP,m,rvNhq6v,gC,QO)if rvNhq6v==nil then rvNhq6v="/"end | |
if gC==nil then gC=false end;if QO==nil then QO=false end;local VvzMQHj=UdVlP:listCache() | |
local fSYJX={filesInstalled=0,packagesInstalled=0} | |
if QO and not N5UjTN(rvNhq6v)then local Gi,wpv1=XxJ(rvNhq6v)if not(Gi)then | |
vj.fatal( | |
"Failed to create '".. | |
tostring(rvNhq6v).."' directory for package '".. | |
tostring(m).."'! \n"..tostring(wpv1))end elseif not QO then local I9IMuWm=SJsW11k(m, | |
nil,"oppm")if I9IMuWm then | |
vj.print("'".. | |
tostring(m).."' is already installed, skipping...")return I9IMuWm,fSYJX end end;local WV | |
for a=1,#VvzMQHj do local rZ=VvzMQHj[a]local VKTNfzUf,Oms4,JfA,CPu1 | |
VKTNfzUf,Oms4,JfA,CPu1=rZ.path,rZ.pkg,rZ.repo,rZ.data;if Oms4 ==m then WV=rZ;break end end;if not(WV)then | |
vj.fatal("No such package: "..tostring(m))end;local yUho4MXRx={}local J2=WV.repo | |
for pfyhF,pglFz82w in | |
pairs(WV.data.data.files)do local RkeCL={} | |
if pfyhF:sub(1,1)==":"then | |
RkeCL=UdVlP:resolveDirectory(J2,pfyhF:sub(2,pfyhF:find("/")- | |
1,nil),pfyhF:sub(pfyhF:find("/")+1))else | |
RkeCL={{name=wVzn.name(pfyhF),path=pfyhF,url=UdVlP.FILES:format(J2,pfyhF)}}end;local m | |
for LoW_7e=1,#RkeCL do local mLgQ=RkeCL[LoW_7e]local ng,Pp_NboV | |
m,ng,Pp_NboV=mLgQ.name,mLgQ.path,mLgQ.url;local owAp3u2G=WQ6(qTDt(Pp_NboV)) | |
local OH0C=UdVlP:parseLocalPath(rvNhq6v,pglFz82w)if not(N5UjTN(OH0C))then XxJ(OH0C)end | |
do | |
local kmQkm9cr,IE97m=io.open(o5sms(OH0C,m),"w")if not kmQkm9cr then | |
vj.fatal("Could not open file for writing: "..tostring(IE97m))end | |
kmQkm9cr:write(owAp3u2G)kmQkm9cr:close()end;fSYJX.filesInstalled=fSYJX.filesInstalled+1 | |
d3fMjkg(yUho4MXRx,{name=m,url=Pp_NboV,dir=OH0C})end end;local hgrBfz0w={} | |
if WV.data.data.dependencies then for wey in pairs(WV.data.data.dependencies)do | |
d3fMjkg(hgrBfz0w,{name=wey})end end;fSYJX.packagesInstalled=fSYJX.packagesInstalled+1;return | |
{name=m,files=yUho4MXRx,dependencies=hgrBfz0w,manual=gC},fSYJX end | |
UdVlP.resolveDependencies=function(UdVlP,hThO6,zXU,HmJym2,Jjb7Am5)if zXU==nil then zXU={}end | |
if HmJym2 ==nil then HmJym2={}end;if Jjb7Am5 ==nil then Jjb7Am5={}end;local UwqY7A=UdVlP:listCache() | |
for k=1,#hThO6 | |
do local d7gPKcw=hThO6[k]local naeNp=false;for gA=1,#zXU do local r=zXU[gA] | |
if r==d7gPKcw then naeNp=true;break end end | |
if not(naeNp)then HmJym2[d7gPKcw]=true;local LWe=SJsW11k(d7gPKcw, | |
nil,"oppm") | |
if not LWe then local _3Tq | |
for Rq1hByv=1,#UwqY7A do | |
local iFk=UwqY7A[Rq1hByv]local sEFtmNgB;sEFtmNgB=iFk.pkg;if sEFtmNgB==d7gPKcw then _3Tq=iFk;break end end;if not(_3Tq)then | |
return false,"Unknown package: "..tostring(d7gPKcw)end | |
if _3Tq.data.data.dependencies then | |
for qxiez0Cn in | |
pairs(_3Tq.data.data.dependencies)do naeNp=false | |
for Ck_H=1,#zXU do local Sc=zXU[Ck_H]if Sc==qxiez0Cn then naeNp=true;break end end | |
if not(naeNp)then | |
if HmJym2[qxiez0Cn]then | |
vj.fatal("Circular dependencies detected: '".. | |
tostring(d7gPKcw).."' depends on '".. | |
tostring(qxiez0Cn).."', and '"..tostring(qxiez0Cn).. | |
"' depends on '"..tostring(d7gPKcw).."'.")end | |
UdVlP:resolveDependencies({qxiez0Cn},zXU,HmJym2,Jjb7Am5)end end end;d3fMjkg(Jjb7Am5,d7gPKcw)end;d3fMjkg(zXU,d7gPKcw)HmJym2[d7gPKcw]=nil end end;return Jjb7Am5 end | |
UdVlP.getPackageDependants=function(UdVlP,_QFw_It,WLqHf,vN)if WLqHf==nil then WLqHf={}end;if vN==nil then vN={}end | |
for BIwW6_=1,#_QFw_It | |
do local Vdfc3=_QFw_It[BIwW6_]local CzM7PG=false | |
for RKf6s5=1,#WLqHf do local tP9E_=WLqHf[RKf6s5]if | |
tP9E_.name==Vdfc3 then CzM7PG=true;break end end | |
if not(CzM7PG)then d3fMjkg(vN,{name=Vdfc3}) | |
local Y1WX=SJsW11k(Vdfc3,nil,"oppm") | |
if Y1WX then d3fMjkg(WLqHf,{name=Vdfc3,manifest=Y1WX}) | |
local G06Z2=WQ6(Wu_uIt(o5sms(hw18,"oppm"))) | |
for K in G06Z2 do Y1WX=WQ6(SJsW11k(K,nil,"oppm")) | |
local tQx9TV=Y1WX.dependencies | |
for FL7g2o=1,#tQx9TV do local dkh7Tt9=tQx9TV[FL7g2o] | |
if dkh7Tt9.name==Vdfc3 then CzM7PG=false | |
for XiNd_H=1,#WLqHf do | |
local Q_c4px86=WLqHf[XiNd_H]if Q_c4px86.name==K then CzM7PG=true;break end end | |
if not CzM7PG then | |
for _F6VYt=1,#vN do local ITv3PH1i=vN[_F6VYt]if ITv3PH1i.name==K then | |
vj.fatal("Circular dependencies detected: ".. | |
tostring(K))end end;UdVlP:getPackageDependants({K},WLqHf,vN)end end end end else | |
vj.fatal("Package ".. | |
tostring(Vdfc3).." is referenced as a dependant of another package, however, this package isn't installed.")end;vN[#vN]=nil end end;return WLqHf end | |
UdVlP.whatDependsOn=function(UdVlP,_5fF)local OUQqQp=WQ6(SJsW11k(_5fF,nil,"oppm")) | |
local OyOfzTWn={}local rx=WQ6(Wu_uIt(o5sms(hw18,"oppm"))) | |
for ijvSrZA1 in rx do OUQqQp=WQ6(SJsW11k(ijvSrZA1, | |
nil,"oppm")) | |
local STNuSN6=OUQqQp.dependencies | |
for PYOeGnAZ=1,#STNuSN6 do local s10ar5XH=STNuSN6[PYOeGnAZ]if s10ar5XH.name==_5fF then | |
d3fMjkg(OyOfzTWn,ijvSrZA1)end end end;return OyOfzTWn end | |
UdVlP.install=wjim8xCV(function(UdVlP,...)local YoKhvIs={...}local I2ipE=w.r or w.reinstall | |
local qS730I=w.s or w.save | |
local PYEbnua=WQ6(UdVlP:resolveDependencies(YoKhvIs)) | |
Ta({install=(function()local AF={}local shIHW=1 | |
for H5=1,#PYEbnua do local HYY=PYEbnua[H5]if | |
not I2ipE or not Oh(HYY,YoKhvIs)then AF[shIHW]=HYY;shIHW=shIHW+1 end end;return AF end)(),reinstall= | |
I2ipE and | |
(function()local C3={}local SkCMMH=1 | |
for kvvs=1,#PYEbnua do local _yTx3S94=PYEbnua[kvvs]if Oh(_yTx3S94,YoKhvIs)then | |
C3[SkCMMH]=_yTx3S94;SkCMMH=SkCMMH+1 end end;return C3 end)()or nil})local Um4ZYiT={filesInstalled=0,packagesInstalled=0} | |
if I2ipE then local Mm | |
do local g524={}local WUdVeYc=1 | |
for lHep6wo=1,#YoKhvIs | |
do local BKZsJ=YoKhvIs[lHep6wo] | |
g524[WUdVeYc]=WQ6(SJsW11k(BKZsJ,nil,"oppm"))WUdVeYc=WUdVeYc+1 end;Mm=g524 end;UdVlP:_remove(Mm,true,false)end | |
for Sw=1,#PYEbnua do local W67mm9p6=PYEbnua[Sw]vj.print("Installing '".. | |
tostring(W67mm9p6).."'...") | |
local oBxdTi6u;if qS730I then oBxdTi6u="./"..tostring(W67mm9p6).."/"else | |
oBxdTi6u="/"end | |
local T7hLe5j,I_=UdVlP:rawInstall(W67mm9p6,oBxdTi6u,Oh(W67mm9p6,YoKhvIs),qS730I) | |
Um4ZYiT.filesInstalled=Um4ZYiT.filesInstalled+I_.filesInstalled | |
Um4ZYiT.packagesInstalled=Um4ZYiT.packagesInstalled+I_.packagesInstalled | |
if Um4ZYiT.packagesInstalled~=0 then local J2Jin,Rvg=BaX(T7hLe5j,"oppm") | |
if J2Jin then | |
vj.info( | |
"Saved the manifest of '"..tostring(T7hLe5j.name).."'.")else | |
vj.fatal("Couldn't save the manifest of '"..tostring(T7hLe5j.name).. | |
"': "..tostring(Rvg)..".")end end end | |
vj.print("- ".. | |
tostring(Um4ZYiT.packagesInstalled).." package".. | |
tostring(tE(Um4ZYiT.packagesInstalled)).." installed.")return | |
vj.print("- ".. | |
tostring(Um4ZYiT.filesInstalled).." file".. | |
tostring(tE(Um4ZYiT.filesInstalled)).." installed.")end) | |
UdVlP.remove=wjim8xCV(function(UdVlP,...)local HpdA={...}local DsAJbW={} | |
for AXfX=1,#HpdA do local btcUUhB=HpdA[AXfX] | |
local iw0S=WQ6(SJsW11k(btcUUhB,nil,"oppm"))d3fMjkg(DsAJbW,iw0S)end;return UdVlP:_remove(DsAJbW,false)end) | |
UdVlP._remove=function(UdVlP,Tjg,n2srE7H,Rf)if n2srE7H==nil then n2srE7H=false end | |
if Rf==nil then Rf=true end;local X9ZjrTz | |
if not | |
_.get("oppm",{},true).get("remove_dependants",true)or not Rf then | |
do local tYFIuD={} | |
local Ht5Ge=1;for l=1,#Tjg do local IO=Tjg[l]tYFIuD[Ht5Ge]={name=IO.name,manifest=IO} | |
Ht5Ge=Ht5Ge+1 end;X9ZjrTz=tYFIuD end else | |
X9ZjrTz=UdVlP:getPackageDependants((function()local YDJY={}local t=1;for Rdi8NIft=1,#Tjg do local J0uTkQ9=Tjg[Rdi8NIft] | |
YDJY[t]=J0uTkQ9.name;t=t+1 end;return YDJY end)())end | |
if not(n2srE7H)then | |
Ta({remove=(function()local sd6k={}local a=1;for lK7=1,#X9ZjrTz do local KWMxs7a=X9ZjrTz[lK7] | |
sd6k[a]=tostring(KWMxs7a.name)a=a+1 end;return sd6k end)()})end | |
for T=1,#X9ZjrTz do local LBIp4=X9ZjrTz[T] | |
vj.print("Removing '".. | |
tostring(LBIp4.manifest.name).."' ...") | |
WQ6(Vt95q2G.__parent.remove(UdVlP,LBIp4.manifest,"oppm"))end;return true end | |
UdVlP.cache=wjim8xCV(function(UdVlP,A5,...)local PV168s0f=A5 | |
if"update"==PV168s0f then | |
vj.print("Updating OpenPrograms program cache ...")WQ6(UdVlP:updateCache())return vj.print("Done.")elseif | |
"fix"==PV168s0f then | |
vj.print("Fixing OpenPrograms program cache ...")WQ6(UdVlP:fixCache())return vj.print("Done.")else | |
vj.error("Unknown command.")return vj.print("Usage: hpm oppm:cache {update|fix}")end end) | |
UdVlP.autoremove=wjim8xCV(function(UdVlP)local bjK={}local Us1Xh={} | |
local rs59=WQ6(Wu_uIt(o5sms(hw18,"oppm"))) | |
for R in rs59 do local rGa2MaGH=WQ6(SJsW11k(R,nil,"oppm")) | |
if not | |
(rGa2MaGH.manual)then local i6=UdVlP:getPackageDependants(R)if#i6 ==1 then | |
d3fMjkg(bjK,R)d3fMjkg(Us1Xh,R)end end end | |
while true do local u33wPQT=false | |
rs59=WQ6(Wu_uIt(o5sms(hw18,"oppm"))) | |
for aNrMnPZ in rs59 do | |
if not(Oh(aNrMnPZ,bjK))then | |
local fC=WQ6(SJsW11k(aNrMnPZ,nil,"oppm")) | |
if not(fC.manual)then | |
local Kl=UdVlP:getPackageDependants(aNrMnPZ)table.remove(Kl,1) | |
if | |
O((function()local EmJGBwA={}local _E3=1;for j3=1,#Kl do local f=Kl[j3] | |
EmJGBwA[_E3]=Oh(f.name,bjK)_E3=_E3+1 end;return EmJGBwA end)())then | |
for jy=1,#Kl do local Ifev2bUE=Kl[jy]local ZY,KCpJbzHT=Oh(Ifev2bUE.name,Us1Xh)if KCpJbzHT then | |
table.remove(Us1Xh,KCpJbzHT)end end;d3fMjkg(bjK,aNrMnPZ)d3fMjkg(Us1Xh,aNrMnPZ)u33wPQT=true end end end end;if not(u33wPQT)then break end end | |
Ta({remove=(function() | |
if#bjK>0 then local g={}local dQl0xvy2=1;for hX=1,#bjK do local wYTrvPn=bjK[hX] | |
g[dQl0xvy2]="oppm:"..tostring(wYTrvPn)dQl0xvy2=dQl0xvy2+1 end | |
return g else return nil end end)()})for pB6K=1,#Us1Xh do local YV=Us1Xh[pB6K] | |
UdVlP:_remove({WQ6(SJsW11k(YV,nil,"oppm"))},false)end;vj.print("Done.") | |
return true end) | |
UdVlP.search=wjim8xCV(function(UdVlP,...)local zPm=UdVlP:listCache()local JmEyZ5={} | |
if...then | |
for FGvy=1,#zPm do | |
local KpnA=zPm[FGvy]local j_F9c;j_F9c=KpnA.data;local q=j_F9c.data;local b7G0ciz={...} | |
for rF2te=#b7G0ciz,1,-1 do | |
local KG_EjN=b7G0ciz[rF2te] | |
if j_F9c.name:find(KG_EjN)then table.remove(b7G0ciz,rF2te)break end;if q.name and q.name:find(KG_EjN)then | |
table.remove(b7G0ciz,rF2te)break end | |
if q.description and | |
q.description:find(KG_EjN)then table.remove(b7G0ciz,rF2te)break end;if q.note and q.note:find(KG_EjN)then | |
table.remove(b7G0ciz,rF2te)break end end;if#b7G0ciz==0 then d3fMjkg(JmEyZ5,j_F9c)end end else | |
do local aIrjXeB={}local sZdri=1;for pT=1,#zPm do local XgkgIR9=zPm[pT]aIrjXeB[sZdri]=XgkgIR9.data;sZdri= | |
sZdri+1 end;JmEyZ5=aIrjXeB end end | |
for sm2=1,#JmEyZ5 do local cz=JmEyZ5[sm2] | |
vj.print(tostring(cz.name).." - ".. | |
tostring(cz.data.name or cz.name)..": "..tostring(cz.data.description))end end) | |
if jsPbwU.__inherited then jsPbwU.__inherited(jsPbwU,Vt95q2G)end;Qlmlet.oppm=Vt95q2G end;local unArcvQl | |
unArcvQl=function()local pSL=WQ6(Wu_uIt(hw18))n=true | |
for ifrP9 in pSL do | |
local Iynmp=wVzn.name(ifrP9) | |
if pzDMZwG(o5sms(hw18,Iynmp))then | |
local PFvHX=WQ6(Wu_uIt(o5sms(hw18,Iynmp))) | |
for sP in PFvHX do | |
if not(pzDMZwG(o5sms(hw18,Iynmp,sP)))then local Y=WQ6(SJsW11k(sP, | |
nil,Iynmp)) | |
vj.print(Iynmp.. | |
":"..sP.. (Y.version and | |
" @ "..Y.version or""))n=false end end end end | |
if n then return vj.print("No packages installed.")end end;local h6Ub7U | |
h6Ub7U=function(...)sgeP,w=LfEJbh_(...)if#sgeP<1 then return ykRppH()end end;local Gm | |
Gm=function()local QHxdp58D=sgeP[1] | |
if"list"==QHxdp58D then return unArcvQl()elseif"help"==QHxdp58D then return | |
ykRppH()else | |
do local efdknL=M6ilzGJ(sgeP[1]) | |
if efdknL then return | |
efdknL(el((function()local YUdva={}local x8FBS=1;for LGBr=2,#sgeP do | |
local M=sgeP[LGBr]YUdva[x8FBS]=M;x8FBS=x8FBS+1 end | |
return YUdva end)()))end end end end;h6Ub7U(...)WQ6(E())cR6rJlAl()Gm()return nvCiFt7r |
local json = load([===[ | |
-- -*- coding: utf-8 -*- | |
-- | |
-- Simple JSON encoding and decoding in pure Lua. | |
-- | |
-- Copyright 2010-2016 Jeffrey Friedl | |
-- http://regex.info/blog/ | |
-- Latest version: http://regex.info/blog/lua/json | |
-- | |
-- This code is released under a Creative Commons CC-BY "Attribution" License: | |
-- http://creativecommons.org/licenses/by/3.0/deed.en_US | |
-- | |
-- It can be used for any purpose so long as the copyright notice above, | |
-- the web-page links above, and the 'AUTHOR_NOTE' string below are | |
-- maintained. Enjoy. | |
-- | |
local VERSION = 20160728.17 -- version history at end of file | |
local AUTHOR_NOTE = "-[ JSON.lua package by Jeffrey Friedl (http://regex.info/blog/lua/json) version 20160728.17 ]-" | |
-- | |
-- The 'AUTHOR_NOTE' variable exists so that information about the source | |
-- of the package is maintained even in compiled versions. It's also | |
-- included in OBJDEF below mostly to quiet warnings about unused variables. | |
-- | |
local OBJDEF = { | |
VERSION = VERSION, | |
AUTHOR_NOTE = AUTHOR_NOTE, | |
} | |
-- | |
-- Simple JSON encoding and decoding in pure Lua. | |
-- JSON definition: http://www.json.org/ | |
-- | |
-- | |
-- JSON = assert(loadfile "JSON.lua")() -- one-time load of the routines | |
-- | |
-- local lua_value = JSON:decode(raw_json_text) | |
-- | |
-- local raw_json_text = JSON:encode(lua_table_or_value) | |
-- local pretty_json_text = JSON:encode_pretty(lua_table_or_value) -- "pretty printed" version for human readability | |
-- | |
-- | |
-- | |
-- DECODING (from a JSON string to a Lua table) | |
-- | |
-- | |
-- JSON = assert(loadfile "JSON.lua")() -- one-time load of the routines | |
-- | |
-- local lua_value = JSON:decode(raw_json_text) | |
-- | |
-- If the JSON text is for an object or an array, e.g. | |
-- { "what": "books", "count": 3 } | |
-- or | |
-- [ "Larry", "Curly", "Moe" ] | |
-- | |
-- the result is a Lua table, e.g. | |
-- { what = "books", count = 3 } | |
-- or | |
-- { "Larry", "Curly", "Moe" } | |
-- | |
-- | |
-- The encode and decode routines accept an optional second argument, | |
-- "etc", which is not used during encoding or decoding, but upon error | |
-- is passed along to error handlers. It can be of any type (including nil). | |
-- | |
-- | |
-- | |
-- ERROR HANDLING | |
-- | |
-- With most errors during decoding, this code calls | |
-- | |
-- JSON:onDecodeError(message, text, location, etc) | |
-- | |
-- with a message about the error, and if known, the JSON text being | |
-- parsed and the byte count where the problem was discovered. You can | |
-- replace the default JSON:onDecodeError() with your own function. | |
-- | |
-- The default onDecodeError() merely augments the message with data | |
-- about the text and the location if known (and if a second 'etc' | |
-- argument had been provided to decode(), its value is tacked onto the | |
-- message as well), and then calls JSON.assert(), which itself defaults | |
-- to Lua's built-in assert(), and can also be overridden. | |
-- | |
-- For example, in an Adobe Lightroom plugin, you might use something like | |
-- | |
-- function JSON:onDecodeError(message, text, location, etc) | |
-- LrErrors.throwUserError("Internal Error: invalid JSON data") | |
-- end | |
-- | |
-- or even just | |
-- | |
-- function JSON.assert(message) | |
-- LrErrors.throwUserError("Internal Error: " .. message) | |
-- end | |
-- | |
-- If JSON:decode() is passed a nil, this is called instead: | |
-- | |
-- JSON:onDecodeOfNilError(message, nil, nil, etc) | |
-- | |
-- and if JSON:decode() is passed HTML instead of JSON, this is called: | |
-- | |
-- JSON:onDecodeOfHTMLError(message, text, nil, etc) | |
-- | |
-- The use of the fourth 'etc' argument allows stronger coordination | |
-- between decoding and error reporting, especially when you provide your | |
-- own error-handling routines. Continuing with the the Adobe Lightroom | |
-- plugin example: | |
-- | |
-- function JSON:onDecodeError(message, text, location, etc) | |
-- local note = "Internal Error: invalid JSON data" | |
-- if type(etc) = 'table' and etc.photo then | |
-- note = note .. " while processing for " .. etc.photo:getFormattedMetadata('fileName') | |
-- end | |
-- LrErrors.throwUserError(note) | |
-- end | |
-- | |
-- : | |
-- : | |
-- | |
-- for i, photo in ipairs(photosToProcess) do | |
-- : | |
-- : | |
-- local data = JSON:decode(someJsonText, { photo = photo }) | |
-- : | |
-- : | |
-- end | |
-- | |
-- | |
-- | |
-- | |
-- | |
-- DECODING AND STRICT TYPES | |
-- | |
-- Because both JSON objects and JSON arrays are converted to Lua tables, | |
-- it's not normally possible to tell which original JSON type a | |
-- particular Lua table was derived from, or guarantee decode-encode | |
-- round-trip equivalency. | |
-- | |
-- However, if you enable strictTypes, e.g. | |
-- | |
-- JSON = assert(loadfile "JSON.lua")() --load the routines | |
-- JSON.strictTypes = true | |
-- | |
-- then the Lua table resulting from the decoding of a JSON object or | |
-- JSON array is marked via Lua metatable, so that when re-encoded with | |
-- JSON:encode() it ends up as the appropriate JSON type. | |
-- | |
-- (This is not the default because other routines may not work well with | |
-- tables that have a metatable set, for example, Lightroom API calls.) | |
-- | |
-- | |
-- ENCODING (from a lua table to a JSON string) | |
-- | |
-- JSON = assert(loadfile "JSON.lua")() -- one-time load of the routines | |
-- | |
-- local raw_json_text = JSON:encode(lua_table_or_value) | |
-- local pretty_json_text = JSON:encode_pretty(lua_table_or_value) -- "pretty printed" version for human readability | |
-- local custom_pretty = JSON:encode(lua_table_or_value, etc, { pretty = true, indent = "| ", align_keys = false }) | |
-- | |
-- On error during encoding, this code calls: | |
-- | |
-- JSON:onEncodeError(message, etc) | |
-- | |
-- which you can override in your local JSON object. | |
-- | |
-- The 'etc' in the error call is the second argument to encode() | |
-- and encode_pretty(), or nil if it wasn't provided. | |
-- | |
-- | |
-- ENCODING OPTIONS | |
-- | |
-- An optional third argument, a table of options, can be provided to encode(). | |
-- | |
-- encode_options = { | |
-- -- options for making "pretty" human-readable JSON (see "PRETTY-PRINTING" below) | |
-- pretty = true, | |
-- indent = " ", | |
-- align_keys = false, | |
-- | |
-- -- other output-related options | |
-- null = "\0", -- see "ENCODING JSON NULL VALUES" below | |
-- stringsAreUtf8 = false, -- see "HANDLING UNICODE LINE AND PARAGRAPH SEPARATORS FOR JAVA" below | |
-- } | |
-- | |
-- json_string = JSON:encode(mytable, etc, encode_options) | |
-- | |
-- | |
-- | |
-- For reference, the defaults are: | |
-- | |
-- pretty = false | |
-- null = nil, | |
-- stringsAreUtf8 = false, | |
-- | |
-- | |
-- | |
-- PRETTY-PRINTING | |
-- | |
-- Enabling the 'pretty' encode option helps generate human-readable JSON. | |
-- | |
-- pretty = JSON:encode(val, etc, { | |
-- pretty = true, | |
-- indent = " ", | |
-- align_keys = false, | |
-- }) | |
-- | |
-- encode_pretty() is also provided: it's identical to encode() except | |
-- that encode_pretty() provides a default options table if none given in the call: | |
-- | |
-- { pretty = true, align_keys = false, indent = " " } | |
-- | |
-- For example, if | |
-- | |
-- JSON:encode(data) | |
-- | |
-- produces: | |
-- | |
-- {"city":"Kyoto","climate":{"avg_temp":16,"humidity":"high","snowfall":"minimal"},"country":"Japan","wards":11} | |
-- | |
-- then | |
-- | |
-- JSON:encode_pretty(data) | |
-- | |
-- produces: | |
-- | |
-- { | |
-- "city": "Kyoto", | |
-- "climate": { | |
-- "avg_temp": 16, | |
-- "humidity": "high", | |
-- "snowfall": "minimal" | |
-- }, | |
-- "country": "Japan", | |
-- "wards": 11 | |
-- } | |
-- | |
-- The following three lines return identical results: | |
-- JSON:encode_pretty(data) | |
-- JSON:encode_pretty(data, nil, { pretty = true, align_keys = false, indent = " " }) | |
-- JSON:encode (data, nil, { pretty = true, align_keys = false, indent = " " }) | |
-- | |
-- An example of setting your own indent string: | |
-- | |
-- JSON:encode_pretty(data, nil, { pretty = true, indent = "| " }) | |
-- | |
-- produces: | |
-- | |
-- { | |
-- | "city": "Kyoto", | |
-- | "climate": { | |
-- | | "avg_temp": 16, | |
-- | | "humidity": "high", | |
-- | | "snowfall": "minimal" | |
-- | }, | |
-- | "country": "Japan", | |
-- | "wards": 11 | |
-- } | |
-- | |
-- An example of setting align_keys to true: | |
-- | |
-- JSON:encode_pretty(data, nil, { pretty = true, indent = " ", align_keys = true }) | |
-- | |
-- produces: | |
-- | |
-- { | |
-- "city": "Kyoto", | |
-- "climate": { | |
-- "avg_temp": 16, | |
-- "humidity": "high", | |
-- "snowfall": "minimal" | |
-- }, | |
-- "country": "Japan", | |
-- "wards": 11 | |
-- } | |
-- | |
-- which I must admit is kinda ugly, sorry. This was the default for | |
-- encode_pretty() prior to version 20141223.14. | |
-- | |
-- | |
-- HANDLING UNICODE LINE AND PARAGRAPH SEPARATORS FOR JAVA | |
-- | |
-- If the 'stringsAreUtf8' encode option is set to true, consider Lua strings not as a sequence of bytes, | |
-- but as a sequence of UTF-8 characters. | |
-- | |
-- Currently, the only practical effect of setting this option is that Unicode LINE and PARAGRAPH | |
-- separators, if found in a string, are encoded with a JSON escape instead of being dumped as is. | |
-- The JSON is valid either way, but encoding this way, apparently, allows the resulting JSON | |
-- to also be valid Java. | |
-- | |
-- AMBIGUOUS SITUATIONS DURING THE ENCODING | |
-- | |
-- During the encode, if a Lua table being encoded contains both string | |
-- and numeric keys, it fits neither JSON's idea of an object, nor its | |
-- idea of an array. To get around this, when any string key exists (or | |
-- when non-positive numeric keys exist), numeric keys are converted to | |
-- strings. | |
-- | |
-- For example, | |
-- JSON:encode({ "one", "two", "three", SOMESTRING = "some string" })) | |
-- produces the JSON object | |
-- {"1":"one","2":"two","3":"three","SOMESTRING":"some string"} | |
-- | |
-- To prohibit this conversion and instead make it an error condition, set | |
-- JSON.noKeyConversion = true | |
-- | |
-- | |
-- ENCODING JSON NULL VALUES | |
-- | |
-- Lua tables completely omit keys whose value is nil, so without special handling there's | |
-- no way to get a field in a JSON object with a null value. For example | |
-- JSON:encode({ username = "admin", password = nil }) | |
-- produces | |
-- {"username":"admin"} | |
-- | |
-- In order to actually produce | |
-- {"username":"admin", "password":null} | |
-- one can include a string value for a "null" field in the options table passed to encode().... | |
-- any Lua table entry with that value becomes null in the JSON output: | |
-- JSON:encode({ username = "admin", password = "xyzzy" }, nil, { null = "xyzzy" }) | |
-- produces | |
-- {"username":"admin", "password":null} | |
-- | |
-- Just be sure to use a string that is otherwise unlikely to appear in your data. | |
-- The string "\0" (a string with one null byte) may well be appropriate for many applications. | |
-- | |
-- The "null" options also applies to Lua tables that become JSON arrays. | |
-- JSON:encode({ "one", "two", nil, nil }) | |
-- produces | |
-- ["one","two"] | |
-- while | |
-- NULL = "\0" | |
-- JSON:encode({ "one", "two", NULL, NULL}, nil, { null = NULL }) | |
-- produces | |
-- ["one","two",null,null] | |
-- | |
-- | |
-- HANDLING LARGE AND/OR PRECISE NUMBERS | |
-- | |
-- Without special handling, numbers in JSON can lose precision in Lua. | |
-- For example: | |
-- | |
-- T = JSON:decode('{ "small":12345, "big":12345678901234567890123456789, "precise":9876.67890123456789012345 }') | |
-- | |
-- print("small: ", type(T.small), T.small) | |
-- print("big: ", type(T.big), T.big) | |
-- print("precise: ", type(T.precise), T.precise) | |
-- | |
-- produces | |
-- | |
-- small: number 12345 | |
-- big: number 1.2345678901235e+28 | |
-- precise: number 9876.6789012346 | |
-- | |
-- Precision is lost with both 'big' and 'precise'. | |
-- | |
-- This package offers ways to try to handle this better (for some definitions of "better")... | |
-- | |
-- The most precise method is by setting the global: | |
-- | |
-- JSON.decodeNumbersAsObjects = true | |
-- | |
-- When this is set, numeric JSON data is encoded into Lua in a form that preserves the exact | |
-- JSON numeric presentation when re-encoded back out to JSON, or accessed in Lua as a string. | |
-- | |
-- (This is done by encoding the numeric data with a Lua table/metatable that returns | |
-- the possibly-imprecise numeric form when accessed numerically, but the original precise | |
-- representation when accessed as a string.) | |
-- | |
-- Consider the example above, with this option turned on: | |
-- | |
-- JSON.decodeNumbersAsObjects = true | |
-- | |
-- T = JSON:decode('{ "small":12345, "big":12345678901234567890123456789, "precise":9876.67890123456789012345 }') | |
-- | |
-- print("small: ", type(T.small), T.small) | |
-- print("big: ", type(T.big), T.big) | |
-- print("precise: ", type(T.precise), T.precise) | |
-- | |
-- This now produces: | |
-- | |
-- small: table 12345 | |
-- big: table 12345678901234567890123456789 | |
-- precise: table 9876.67890123456789012345 | |
-- | |
-- However, within Lua you can still use the values (e.g. T.precise in the example above) in numeric | |
-- contexts. In such cases you'll get the possibly-imprecise numeric version, but in string contexts | |
-- and when the data finds its way to this package's encode() function, the original full-precision | |
-- representation is used. | |
-- | |
-- Even without using the JSON.decodeNumbersAsObjects option, you can encode numbers | |
-- in your Lua table that retain high precision upon encoding to JSON, by using the JSON:asNumber() | |
-- function: | |
-- | |
-- T = { | |
-- imprecise = 123456789123456789.123456789123456789, | |
-- precise = JSON:asNumber("123456789123456789.123456789123456789") | |
-- } | |
-- | |
-- print(JSON:encode_pretty(T)) | |
-- | |
-- This produces: | |
-- | |
-- { | |
-- "precise": 123456789123456789.123456789123456789, | |
-- "imprecise": 1.2345678912346e+17 | |
-- } | |
-- | |
-- | |
-- | |
-- A different way to handle big/precise JSON numbers is to have decode() merely return | |
-- the exact string representation of the number instead of the number itself. | |
-- This approach might be useful when the numbers are merely some kind of opaque | |
-- object identifier and you want to work with them in Lua as strings anyway. | |
-- | |
-- This approach is enabled by setting | |
-- | |
-- JSON.decodeIntegerStringificationLength = 10 | |
-- | |
-- The value is the number of digits (of the integer part of the number) at which to stringify numbers. | |
-- | |
-- Consider our previous example with this option set to 10: | |
-- | |
-- JSON.decodeIntegerStringificationLength = 10 | |
-- | |
-- T = JSON:decode('{ "small":12345, "big":12345678901234567890123456789, "precise":9876.67890123456789012345 }') | |
-- | |
-- print("small: ", type(T.small), T.small) | |
-- print("big: ", type(T.big), T.big) | |
-- print("precise: ", type(T.precise), T.precise) | |
-- | |
-- This produces: | |
-- | |
-- small: number 12345 | |
-- big: string 12345678901234567890123456789 | |
-- precise: number 9876.6789012346 | |
-- | |
-- The long integer of the 'big' field is at least JSON.decodeIntegerStringificationLength digits | |
-- in length, so it's converted not to a Lua integer but to a Lua string. Using a value of 0 or 1 ensures | |
-- that all JSON numeric data becomes strings in Lua. | |
-- | |
-- Note that unlike | |
-- JSON.decodeNumbersAsObjects = true | |
-- this stringification is simple and unintelligent: the JSON number simply becomes a Lua string, and that's the end of it. | |
-- If the string is then converted back to JSON, it's still a string. After running the code above, adding | |
-- print(JSON:encode(T)) | |
-- produces | |
-- {"big":"12345678901234567890123456789","precise":9876.6789012346,"small":12345} | |
-- which is unlikely to be desired. | |
-- | |
-- There's a comparable option for the length of the decimal part of a number: | |
-- | |
-- JSON.decodeDecimalStringificationLength | |
-- | |
-- This can be used alone or in conjunction with | |
-- | |
-- JSON.decodeIntegerStringificationLength | |
-- | |
-- to trip stringification on precise numbers with at least JSON.decodeIntegerStringificationLength digits after | |
-- the decimal point. | |
-- | |
-- This example: | |
-- | |
-- JSON.decodeIntegerStringificationLength = 10 | |
-- JSON.decodeDecimalStringificationLength = 5 | |
-- | |
-- T = JSON:decode('{ "small":12345, "big":12345678901234567890123456789, "precise":9876.67890123456789012345 }') | |
-- | |
-- print("small: ", type(T.small), T.small) | |
-- print("big: ", type(T.big), T.big) | |
-- print("precise: ", type(T.precise), T.precise) | |
-- | |
-- produces: | |
-- | |
-- small: number 12345 | |
-- big: string 12345678901234567890123456789 | |
-- precise: string 9876.67890123456789012345 | |
-- | |
-- | |
-- | |
-- | |
-- | |
-- SUMMARY OF METHODS YOU CAN OVERRIDE IN YOUR LOCAL LUA JSON OBJECT | |
-- | |
-- assert | |
-- onDecodeError | |
-- onDecodeOfNilError | |
-- onDecodeOfHTMLError | |
-- onEncodeError | |
-- | |
-- If you want to create a separate Lua JSON object with its own error handlers, | |
-- you can reload JSON.lua or use the :new() method. | |
-- | |
--------------------------------------------------------------------------- | |
local default_pretty_indent = " " | |
local default_pretty_options = { pretty = true, align_keys = false, indent = default_pretty_indent } | |
local isArray = { __tostring = function() return "JSON array" end } isArray.__index = isArray | |
local isObject = { __tostring = function() return "JSON object" end } isObject.__index = isObject | |
function OBJDEF:newArray(tbl) | |
return setmetatable(tbl or {}, isArray) | |
end | |
function OBJDEF:newObject(tbl) | |
return setmetatable(tbl or {}, isObject) | |
end | |
local function getnum(op) | |
return type(op) == 'number' and op or op.N | |
end | |
local isNumber = { | |
__index = isNumber, | |
__tostring = function(T) return T.S end, | |
__unm = function(op) return getnum(op) end, | |
__concat = function(op1, op2) return tostring(op1) .. tostring(op2) end, | |
__add = function(op1, op2) return getnum(op1) + getnum(op2) end, | |
__sub = function(op1, op2) return getnum(op1) - getnum(op2) end, | |
__mul = function(op1, op2) return getnum(op1) * getnum(op2) end, | |
__div = function(op1, op2) return getnum(op1) / getnum(op2) end, | |
__mod = function(op1, op2) return getnum(op1) % getnum(op2) end, | |
__pow = function(op1, op2) return getnum(op1) ^ getnum(op2) end, | |
__lt = function(op1, op2) return getnum(op1) < getnum(op2) end, | |
__eq = function(op1, op2) return getnum(op1) == getnum(op2) end, | |
__le = function(op1, op2) return getnum(op1) <= getnum(op2) end, | |
} | |
function OBJDEF:asNumber(item) | |
if getmetatable(item) == isNumber then | |
-- it's already a JSON number object. | |
return item | |
elseif type(item) == 'table' and type(item.S) == 'string' and type(item.N) == 'number' then | |
-- it's a number-object table that lost its metatable, so give it one | |
return setmetatable(item, isNumber) | |
else | |
-- the normal situation... given a number or a string representation of a number.... | |
local holder = { | |
S = tostring(item), -- S is the representation of the number as a string, which remains precise | |
N = tonumber(item), -- N is the number as a Lua number. | |
} | |
return setmetatable(holder, isNumber) | |
end | |
end | |
local function unicode_codepoint_as_utf8(codepoint) | |
-- | |
-- codepoint is a number | |
-- | |
if codepoint <= 127 then | |
return string.char(codepoint) | |
elseif codepoint <= 2047 then | |
-- | |
-- 110yyyxx 10xxxxxx <-- useful notation from http://en.wikipedia.org/wiki/Utf8 | |
-- | |
local highpart = math.floor(codepoint / 0x40) | |
local lowpart = codepoint - (0x40 * highpart) | |
return string.char(0xC0 + highpart, | |
0x80 + lowpart) | |
elseif codepoint <= 65535 then | |
-- | |
-- 1110yyyy 10yyyyxx 10xxxxxx | |
-- | |
local highpart = math.floor(codepoint / 0x1000) | |
local remainder = codepoint - 0x1000 * highpart | |
local midpart = math.floor(remainder / 0x40) | |
local lowpart = remainder - 0x40 * midpart | |
highpart = 0xE0 + highpart | |
midpart = 0x80 + midpart | |
lowpart = 0x80 + lowpart | |
-- | |
-- Check for an invalid character (thanks Andy R. at Adobe). | |
-- See table 3.7, page 93, in http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf#G28070 | |
-- | |
if ( highpart == 0xE0 and midpart < 0xA0 ) or | |
( highpart == 0xED and midpart > 0x9F ) or | |
( highpart == 0xF0 and midpart < 0x90 ) or | |
( highpart == 0xF4 and midpart > 0x8F ) | |
then | |
return "?" | |
else | |
return string.char(highpart, | |
midpart, | |
lowpart) | |
end | |
else | |
-- | |
-- 11110zzz 10zzyyyy 10yyyyxx 10xxxxxx | |
-- | |
local highpart = math.floor(codepoint / 0x40000) | |
local remainder = codepoint - 0x40000 * highpart | |
local midA = math.floor(remainder / 0x1000) | |
remainder = remainder - 0x1000 * midA | |
local midB = math.floor(remainder / 0x40) | |
local lowpart = remainder - 0x40 * midB | |
return string.char(0xF0 + highpart, | |
0x80 + midA, | |
0x80 + midB, | |
0x80 + lowpart) | |
end | |
end | |
function OBJDEF:onDecodeError(message, text, location, etc) | |
if text then | |
if location then | |
message = string.format("%s at char %d of: %s", message, location, text) | |
else | |
message = string.format("%s: %s", message, text) | |
end | |
end | |
if etc ~= nil then | |
message = message .. " (" .. OBJDEF:encode(etc) .. ")" | |
end | |
if self.assert then | |
self.assert(false, message) | |
else | |
assert(false, message) | |
end | |
end | |
OBJDEF.onDecodeOfNilError = OBJDEF.onDecodeError | |
OBJDEF.onDecodeOfHTMLError = OBJDEF.onDecodeError | |
function OBJDEF:onEncodeError(message, etc) | |
if etc ~= nil then | |
message = message .. " (" .. OBJDEF:encode(etc) .. ")" | |
end | |
if self.assert then | |
self.assert(false, message) | |
else | |
assert(false, message) | |
end | |
end | |
local function grok_number(self, text, start, options) | |
-- | |
-- Grab the integer part | |
-- | |
local integer_part = text:match('^-?[1-9]%d*', start) | |
or text:match("^-?0", start) | |
if not integer_part then | |
self:onDecodeError("expected number", text, start, options.etc) | |
end | |
local i = start + integer_part:len() | |
-- | |
-- Grab an optional decimal part | |
-- | |
local decimal_part = text:match('^%.%d+', i) or "" | |
i = i + decimal_part:len() | |
-- | |
-- Grab an optional exponential part | |
-- | |
local exponent_part = text:match('^[eE][-+]?%d+', i) or "" | |
i = i + exponent_part:len() | |
local full_number_text = integer_part .. decimal_part .. exponent_part | |
if options.decodeNumbersAsObjects then | |
return OBJDEF:asNumber(full_number_text), i | |
end | |
-- | |
-- If we're told to stringify under certain conditions, so do. | |
-- We punt a bit when there's an exponent by just stringifying no matter what. | |
-- I suppose we should really look to see whether the exponent is actually big enough one | |
-- way or the other to trip stringification, but I'll be lazy about it until someone asks. | |
-- | |
if (options.decodeIntegerStringificationLength | |
and | |
(integer_part:len() >= options.decodeIntegerStringificationLength or exponent_part:len() > 0)) | |
or | |
(options.decodeDecimalStringificationLength | |
and | |
(decimal_part:len() >= options.decodeDecimalStringificationLength or exponent_part:len() > 0)) | |
then | |
return full_number_text, i -- this returns the exact string representation seen in the original JSON | |
end | |
local as_number = tonumber(full_number_text) | |
if not as_number then | |
self:onDecodeError("bad number", text, start, options.etc) | |
end | |
return as_number, i | |
end | |
local function grok_string(self, text, start, options) | |
if text:sub(start,start) ~= '"' then | |
self:onDecodeError("expected string's opening quote", text, start, options.etc) | |
end | |
local i = start + 1 -- +1 to bypass the initial quote | |
local text_len = text:len() | |
local VALUE = "" | |
while i <= text_len do | |
local c = text:sub(i,i) | |
if c == '"' then | |
return VALUE, i + 1 | |
end | |
if c ~= '\\' then | |
VALUE = VALUE .. c | |
i = i + 1 | |
elseif text:match('^\\b', i) then | |
VALUE = VALUE .. "\b" | |
i = i + 2 | |
elseif text:match('^\\f', i) then | |
VALUE = VALUE .. "\f" | |
i = i + 2 | |
elseif text:match('^\\n', i) then | |
VALUE = VALUE .. "\n" | |
i = i + 2 | |
elseif text:match('^\\r', i) then | |
VALUE = VALUE .. "\r" | |
i = i + 2 | |
elseif text:match('^\\t', i) then | |
VALUE = VALUE .. "\t" | |
i = i + 2 | |
else | |
local hex = text:match('^\\u([0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])', i) | |
if hex then | |
i = i + 6 -- bypass what we just read | |
-- We have a Unicode codepoint. It could be standalone, or if in the proper range and | |
-- followed by another in a specific range, it'll be a two-code surrogate pair. | |
local codepoint = tonumber(hex, 16) | |
if codepoint >= 0xD800 and codepoint <= 0xDBFF then | |
-- it's a hi surrogate... see whether we have a following low | |
local lo_surrogate = text:match('^\\u([dD][cdefCDEF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])', i) | |
if lo_surrogate then | |
i = i + 6 -- bypass the low surrogate we just read | |
codepoint = 0x2400 + (codepoint - 0xD800) * 0x400 + tonumber(lo_surrogate, 16) | |
else | |
-- not a proper low, so we'll just leave the first codepoint as is and spit it out. | |
end | |
end | |
VALUE = VALUE .. unicode_codepoint_as_utf8(codepoint) | |
else | |
-- just pass through what's escaped | |
VALUE = VALUE .. text:match('^\\(.)', i) | |
i = i + 2 | |
end | |
end | |
end | |
self:onDecodeError("unclosed string", text, start, options.etc) | |
end | |
local function skip_whitespace(text, start) | |
local _, match_end = text:find("^[ \n\r\t]+", start) -- [http://www.ietf.org/rfc/rfc4627.txt] Section 2 | |
if match_end then | |
return match_end + 1 | |
else | |
return start | |
end | |
end | |
local grok_one -- assigned later | |
local function grok_object(self, text, start, options) | |
if text:sub(start,start) ~= '{' then | |
self:onDecodeError("expected '{'", text, start, options.etc) | |
end | |
local i = skip_whitespace(text, start + 1) -- +1 to skip the '{' | |
local VALUE = self.strictTypes and self:newObject { } or { } | |
if text:sub(i,i) == '}' then | |
return VALUE, i + 1 | |
end | |
local text_len = text:len() | |
while i <= text_len do | |
local key, new_i = grok_string(self, text, i, options) | |
i = skip_whitespace(text, new_i) | |
if text:sub(i, i) ~= ':' then | |
self:onDecodeError("expected colon", text, i, options.etc) | |
end | |
i = skip_whitespace(text, i + 1) | |
local new_val, new_i = grok_one(self, text, i, options) | |
VALUE[key] = new_val | |
-- | |
-- Expect now either '}' to end things, or a ',' to allow us to continue. | |
-- | |
i = skip_whitespace(text, new_i) | |
local c = text:sub(i,i) | |
if c == '}' then | |
return VALUE, i + 1 | |
end | |
if text:sub(i, i) ~= ',' then | |
self:onDecodeError("expected comma or '}'", text, i, options.etc) | |
end | |
i = skip_whitespace(text, i + 1) | |
end | |
self:onDecodeError("unclosed '{'", text, start, options.etc) | |
end | |
local function grok_array(self, text, start, options) | |
if text:sub(start,start) ~= '[' then | |
self:onDecodeError("expected '['", text, start, options.etc) | |
end | |
local i = skip_whitespace(text, start + 1) -- +1 to skip the '[' | |
local VALUE = self.strictTypes and self:newArray { } or { } | |
if text:sub(i,i) == ']' then | |
return VALUE, i + 1 | |
end | |
local VALUE_INDEX = 1 | |
local text_len = text:len() | |
while i <= text_len do | |
local val, new_i = grok_one(self, text, i, options) | |
-- can't table.insert(VALUE, val) here because it's a no-op if val is nil | |
VALUE[VALUE_INDEX] = val | |
VALUE_INDEX = VALUE_INDEX + 1 | |
i = skip_whitespace(text, new_i) | |
-- | |
-- Expect now either ']' to end things, or a ',' to allow us to continue. | |
-- | |
local c = text:sub(i,i) | |
if c == ']' then | |
return VALUE, i + 1 | |
end | |
if text:sub(i, i) ~= ',' then | |
self:onDecodeError("expected comma or '['", text, i, options.etc) | |
end | |
i = skip_whitespace(text, i + 1) | |
end | |
self:onDecodeError("unclosed '['", text, start, options.etc) | |
end | |
grok_one = function(self, text, start, options) | |
-- Skip any whitespace | |
start = skip_whitespace(text, start) | |
if start > text:len() then | |
self:onDecodeError("unexpected end of string", text, nil, options.etc) | |
end | |
if text:find('^"', start) then | |
return grok_string(self, text, start, options.etc) | |
elseif text:find('^[-0123456789 ]', start) then | |
return grok_number(self, text, start, options) | |
elseif text:find('^%{', start) then | |
return grok_object(self, text, start, options) | |
elseif text:find('^%[', start) then | |
return grok_array(self, text, start, options) | |
elseif text:find('^true', start) then | |
return true, start + 4 | |
elseif text:find('^false', start) then | |
return false, start + 5 | |
elseif text:find('^null', start) then | |
return nil, start + 4 | |
else | |
self:onDecodeError("can't parse JSON", text, start, options.etc) | |
end | |
end | |
function OBJDEF:decode(text, etc, options) | |
-- | |
-- If the user didn't pass in a table of decode options, make an empty one. | |
-- | |
if type(options) ~= 'table' then | |
options = {} | |
end | |
-- | |
-- If they passed in an 'etc' argument, stuff it into the options. | |
-- (If not, any 'etc' field in the options they passed in remains to be used) | |
-- | |
if etc ~= nil then | |
options.etc = etc | |
end | |
if type(self) ~= 'table' or self.__index ~= OBJDEF then | |
OBJDEF:onDecodeError("JSON:decode must be called in method format", nil, nil, options.etc) | |
end | |
if text == nil then | |
self:onDecodeOfNilError(string.format("nil passed to JSON:decode()"), nil, nil, options.etc) | |
elseif type(text) ~= 'string' then | |
self:onDecodeError(string.format("expected string argument to JSON:decode(), got %s", type(text)), nil, nil, options.etc) | |
end | |
if text:match('^%s*$') then | |
return nil | |
end | |
if text:match('^%s*<') then | |
-- Can't be JSON... we'll assume it's HTML | |
self:onDecodeOfHTMLError(string.format("html passed to JSON:decode()"), text, nil, options.etc) | |
end | |
-- | |
-- Ensure that it's not UTF-32 or UTF-16. | |
-- Those are perfectly valid encodings for JSON (as per RFC 4627 section 3), | |
-- but this package can't handle them. | |
-- | |
if text:sub(1,1):byte() == 0 or (text:len() >= 2 and text:sub(2,2):byte() == 0) then | |
self:onDecodeError("JSON package groks only UTF-8, sorry", text, nil, options.etc) | |
end | |
-- | |
-- apply global options | |
-- | |
if options.decodeNumbersAsObjects == nil then | |
options.decodeNumbersAsObjects = self.decodeNumbersAsObjects | |
end | |
if options.decodeIntegerStringificationLength == nil then | |
options.decodeIntegerStringificationLength = self.decodeIntegerStringificationLength | |
end | |
if options.decodeDecimalStringificationLength == nil then | |
options.decodeDecimalStringificationLength = self.decodeDecimalStringificationLength | |
end | |
local success, value = pcall(grok_one, self, text, 1, options) | |
if success then | |
return value | |
else | |
-- if JSON:onDecodeError() didn't abort out of the pcall, we'll have received the error message here as "value", so pass it along as an assert. | |
if self.assert then | |
self.assert(false, value) | |
else | |
assert(false, value) | |
end | |
-- and if we're still here, return a nil and throw the error message on as a second arg | |
return nil, value | |
end | |
end | |
local function backslash_replacement_function(c) | |
if c == "\n" then | |
return "\\n" | |
elseif c == "\r" then | |
return "\\r" | |
elseif c == "\t" then | |
return "\\t" | |
elseif c == "\b" then | |
return "\\b" | |
elseif c == "\f" then | |
return "\\f" | |
elseif c == '"' then | |
return '\\"' | |
elseif c == '\\' then | |
return '\\\\' | |
else | |
return string.format("\\u%04x", c:byte()) | |
end | |
end | |
local chars_to_be_escaped_in_JSON_string | |
= '[' | |
.. '"' -- class sub-pattern to match a double quote | |
.. '%\\' -- class sub-pattern to match a backslash | |
.. '%z' -- class sub-pattern to match a null | |
.. '\001' .. '-' .. '\031' -- class sub-pattern to match control characters | |
.. ']' | |
local LINE_SEPARATOR_as_utf8 = unicode_codepoint_as_utf8(0x2028) | |
local PARAGRAPH_SEPARATOR_as_utf8 = unicode_codepoint_as_utf8(0x2029) | |
local function json_string_literal(value, options) | |
local newval = value:gsub(chars_to_be_escaped_in_JSON_string, backslash_replacement_function) | |
if options.stringsAreUtf8 then | |
-- | |
-- This feels really ugly to just look into a string for the sequence of bytes that we know to be a particular utf8 character, | |
-- but utf8 was designed purposefully to make this kind of thing possible. Still, feels dirty. | |
-- I'd rather decode the byte stream into a character stream, but it's not technically needed so | |
-- not technically worth it. | |
-- | |
newval = newval:gsub(LINE_SEPARATOR_as_utf8, '\\u2028'):gsub(PARAGRAPH_SEPARATOR_as_utf8,'\\u2029') | |
end | |
return '"' .. newval .. '"' | |
end | |
local function object_or_array(self, T, etc) | |
-- | |
-- We need to inspect all the keys... if there are any strings, we'll convert to a JSON | |
-- object. If there are only numbers, it's a JSON array. | |
-- | |
-- If we'll be converting to a JSON object, we'll want to sort the keys so that the | |
-- end result is deterministic. | |
-- | |
local string_keys = { } | |
local number_keys = { } | |
local number_keys_must_be_strings = false | |
local maximum_number_key | |
for key in pairs(T) do | |
if type(key) == 'string' then | |
table.insert(string_keys, key) | |
elseif type(key) == 'number' then | |
table.insert(number_keys, key) | |
if key <= 0 or key >= math.huge then | |
number_keys_must_be_strings = true | |
elseif not maximum_number_key or key > maximum_number_key then | |
maximum_number_key = key | |
end | |
else | |
self:onEncodeError("can't encode table with a key of type " .. type(key), etc) | |
end | |
end | |
if #string_keys == 0 and not number_keys_must_be_strings then | |
-- | |
-- An empty table, or a numeric-only array | |
-- | |
if #number_keys > 0 then | |
return nil, maximum_number_key -- an array | |
elseif tostring(T) == "JSON array" then | |
return nil | |
elseif tostring(T) == "JSON object" then | |
return { } | |
else | |
-- have to guess, so we'll pick array, since empty arrays are likely more common than empty objects | |
return nil | |
end | |
end | |
table.sort(string_keys) | |
local map | |
if #number_keys > 0 then | |
-- | |
-- If we're here then we have either mixed string/number keys, or numbers inappropriate for a JSON array | |
-- It's not ideal, but we'll turn the numbers into strings so that we can at least create a JSON object. | |
-- | |
if self.noKeyConversion then | |
self:onEncodeError("a table with both numeric and string keys could be an object or array; aborting", etc) | |
end | |
-- | |
-- Have to make a shallow copy of the source table so we can remap the numeric keys to be strings | |
-- | |
map = { } | |
for key, val in pairs(T) do | |
map[key] = val | |
end | |
table.sort(number_keys) | |
-- | |
-- Throw numeric keys in there as strings | |
-- | |
for _, number_key in ipairs(number_keys) do | |
local string_key = tostring(number_key) | |
if map[string_key] == nil then | |
table.insert(string_keys , string_key) | |
map[string_key] = T[number_key] | |
else | |
self:onEncodeError("conflict converting table with mixed-type keys into a JSON object: key " .. number_key .. " exists both as a string and a number.", etc) | |
end | |
end | |
end | |
return string_keys, nil, map | |
end | |
-- | |
-- Encode | |
-- | |
-- 'options' is nil, or a table with possible keys: | |
-- | |
-- pretty -- If true, return a pretty-printed version. | |
-- | |
-- indent -- A string (usually of spaces) used to indent each nested level. | |
-- | |
-- align_keys -- If true, align all the keys when formatting a table. | |
-- | |
-- null -- If this exists with a string value, table elements with this value are output as JSON null. | |
-- | |
-- stringsAreUtf8 -- If true, consider Lua strings not as a sequence of bytes, but as a sequence of UTF-8 characters. | |
-- (Currently, the only practical effect of setting this option is that Unicode LINE and PARAGRAPH | |
-- separators, if found in a string, are encoded with a JSON escape instead of as raw UTF-8. | |
-- The JSON is valid either way, but encoding this way, apparently, allows the resulting JSON | |
-- to also be valid Java.) | |
-- | |
-- | |
local encode_value -- must predeclare because it calls itself | |
function encode_value(self, value, parents, etc, options, indent, for_key) | |
-- | |
-- keys in a JSON object can never be null, so we don't even consider options.null when converting a key value | |
-- | |
if value == nil or (not for_key and options and options.null and value == options.null) then | |
return 'null' | |
elseif type(value) == 'string' then | |
return json_string_literal(value, options) | |
elseif type(value) == 'number' then | |
if value ~= value then | |
-- | |
-- NaN (Not a Number). | |
-- JSON has no NaN, so we have to fudge the best we can. This should really be a package option. | |
-- | |
return "null" | |
elseif value >= math.huge then | |
-- | |
-- Positive infinity. JSON has no INF, so we have to fudge the best we can. This should | |
-- really be a package option. Note: at least with some implementations, positive infinity | |
-- is both ">= math.huge" and "<= -math.huge", which makes no sense but that's how it is. | |
-- Negative infinity is properly "<= -math.huge". So, we must be sure to check the ">=" | |
-- case first. | |
-- | |
return "1e+9999" | |
elseif value <= -math.huge then | |
-- | |
-- Negative infinity. | |
-- JSON has no INF, so we have to fudge the best we can. This should really be a package option. | |
-- | |
return "-1e+9999" | |
else | |
return tostring(value) | |
end | |
elseif type(value) == 'boolean' then | |
return tostring(value) | |
elseif type(value) ~= 'table' then | |
self:onEncodeError("can't convert " .. type(value) .. " to JSON", etc) | |
elseif getmetatable(value) == isNumber then | |
return tostring(value) | |
else | |
-- | |
-- A table to be converted to either a JSON object or array. | |
-- | |
local T = value | |
if type(options) ~= 'table' then | |
options = {} | |
end | |
if type(indent) ~= 'string' then | |
indent = "" | |
end | |
if parents[T] then | |
self:onEncodeError("table " .. tostring(T) .. " is a child of itself", etc) | |
else | |
parents[T] = true | |
end | |
local result_value | |
local object_keys, maximum_number_key, map = object_or_array(self, T, etc) | |
if maximum_number_key then | |
-- | |
-- An array... | |
-- | |
local ITEMS = { } | |
for i = 1, maximum_number_key do | |
table.insert(ITEMS, encode_value(self, T[i], parents, etc, options, indent)) | |
end | |
if options.pretty then | |
result_value = "[ " .. table.concat(ITEMS, ", ") .. " ]" | |
else | |
result_value = "[" .. table.concat(ITEMS, ",") .. "]" | |
end | |
elseif object_keys then | |
-- | |
-- An object | |
-- | |
local TT = map or T | |
if options.pretty then | |
local KEYS = { } | |
local max_key_length = 0 | |
for _, key in ipairs(object_keys) do | |
local encoded = encode_value(self, tostring(key), parents, etc, options, indent, true) | |
if options.align_keys then | |
max_key_length = math.max(max_key_length, #encoded) | |
end | |
table.insert(KEYS, encoded) | |
end | |
local key_indent = indent .. tostring(options.indent or "") | |
local subtable_indent = key_indent .. string.rep(" ", max_key_length) .. (options.align_keys and " " or "") | |
local FORMAT = "%s%" .. string.format("%d", max_key_length) .. "s: %s" | |
local COMBINED_PARTS = { } | |
for i, key in ipairs(object_keys) do | |
local encoded_val = encode_value(self, TT[key], parents, etc, options, subtable_indent) | |
table.insert(COMBINED_PARTS, string.format(FORMAT, key_indent, KEYS[i], encoded_val)) | |
end | |
result_value = "{\n" .. table.concat(COMBINED_PARTS, ",\n") .. "\n" .. indent .. "}" | |
else | |
local PARTS = { } | |
for _, key in ipairs(object_keys) do | |
local encoded_val = encode_value(self, TT[key], parents, etc, options, indent) | |
local encoded_key = encode_value(self, tostring(key), parents, etc, options, indent, true) | |
table.insert(PARTS, string.format("%s:%s", encoded_key, encoded_val)) | |
end | |
result_value = "{" .. table.concat(PARTS, ",") .. "}" | |
end | |
else | |
-- | |
-- An empty array/object... we'll treat it as an array, though it should really be an option | |
-- | |
result_value = "[]" | |
end | |
parents[T] = false | |
return result_value | |
end | |
end | |
function OBJDEF:encode(value, etc, options) | |
if type(self) ~= 'table' or self.__index ~= OBJDEF then | |
OBJDEF:onEncodeError("JSON:encode must be called in method format", etc) | |
end | |
-- | |
-- If the user didn't pass in a table of decode options, make an empty one. | |
-- | |
if type(options) ~= 'table' then | |
options = {} | |
end | |
return encode_value(self, value, {}, etc, options) | |
end | |
function OBJDEF:encode_pretty(value, etc, options) | |
if type(self) ~= 'table' or self.__index ~= OBJDEF then | |
OBJDEF:onEncodeError("JSON:encode_pretty must be called in method format", etc) | |
end | |
-- | |
-- If the user didn't pass in a table of decode options, use the default pretty ones | |
-- | |
if type(options) ~= 'table' then | |
options = default_pretty_options | |
end | |
return encode_value(self, value, {}, etc, options) | |
end | |
function OBJDEF.__tostring() | |
return "JSON encode/decode package" | |
end | |
OBJDEF.__index = OBJDEF | |
function OBJDEF:new(args) | |
local new = { } | |
if args then | |
for key, val in pairs(args) do | |
new[key] = val | |
end | |
end | |
return setmetatable(new, OBJDEF) | |
end | |
return OBJDEF:new() | |
-- | |
-- Version history: | |
-- | |
-- 20160728.17 Added concatenation to the metatable for JSON:asNumber(). | |
-- | |
-- 20160709.16 Could crash if not passed an options table (thanks jarno heikkinen <jarnoh@capturemonkey.com>). | |
-- | |
-- Made JSON:asNumber() a bit more resilient to being passed the results of itself. | |
-- | |
-- 20160526.15 Added the ability to easily encode null values in JSON, via the new "null" encoding option. | |
-- (Thanks to Adam B for bringing up the issue.) | |
-- | |
-- Added some support for very large numbers and precise floats via | |
-- JSON.decodeNumbersAsObjects | |
-- JSON.decodeIntegerStringificationLength | |
-- JSON.decodeDecimalStringificationLength | |
-- | |
-- Added the "stringsAreUtf8" encoding option. (Hat tip to http://lua-users.org/wiki/JsonModules ) | |
-- | |
-- 20141223.14 The encode_pretty() routine produced fine results for small datasets, but isn't really | |
-- appropriate for anything large, so with help from Alex Aulbach I've made the encode routines | |
-- more flexible, and changed the default encode_pretty() to be more generally useful. | |
-- | |
-- Added a third 'options' argument to the encode() and encode_pretty() routines, to control | |
-- how the encoding takes place. | |
-- | |
-- Updated docs to add assert() call to the loadfile() line, just as good practice so that | |
-- if there is a problem loading JSON.lua, the appropriate error message will percolate up. | |
-- | |
-- 20140920.13 Put back (in a way that doesn't cause warnings about unused variables) the author string, | |
-- so that the source of the package, and its version number, are visible in compiled copies. | |
-- | |
-- 20140911.12 Minor lua cleanup. | |
-- Fixed internal reference to 'JSON.noKeyConversion' to reference 'self' instead of 'JSON'. | |
-- (Thanks to SmugMug's David Parry for these.) | |
-- | |
-- 20140418.11 JSON nulls embedded within an array were being ignored, such that | |
-- ["1",null,null,null,null,null,"seven"], | |
-- would return | |
-- {1,"seven"} | |
-- It's now fixed to properly return | |
-- {1, nil, nil, nil, nil, nil, "seven"} | |
-- Thanks to "haddock" for catching the error. | |
-- | |
-- 20140116.10 The user's JSON.assert() wasn't always being used. Thanks to "blue" for the heads up. | |
-- | |
-- 20131118.9 Update for Lua 5.3... it seems that tostring(2/1) produces "2.0" instead of "2", | |
-- and this caused some problems. | |
-- | |
-- 20131031.8 Unified the code for encode() and encode_pretty(); they had been stupidly separate, | |
-- and had of course diverged (encode_pretty didn't get the fixes that encode got, so | |
-- sometimes produced incorrect results; thanks to Mattie for the heads up). | |
-- | |
-- Handle encoding tables with non-positive numeric keys (unlikely, but possible). | |
-- | |
-- If a table has both numeric and string keys, or its numeric keys are inappropriate | |
-- (such as being non-positive or infinite), the numeric keys are turned into | |
-- string keys appropriate for a JSON object. So, as before, | |
-- JSON:encode({ "one", "two", "three" }) | |
-- produces the array | |
-- ["one","two","three"] | |
-- but now something with mixed key types like | |
-- JSON:encode({ "one", "two", "three", SOMESTRING = "some string" })) | |
-- instead of throwing an error produces an object: | |
-- {"1":"one","2":"two","3":"three","SOMESTRING":"some string"} | |
-- | |
-- To maintain the prior throw-an-error semantics, set | |
-- JSON.noKeyConversion = true | |
-- | |
-- 20131004.7 Release under a Creative Commons CC-BY license, which I should have done from day one, sorry. | |
-- | |
-- 20130120.6 Comment update: added a link to the specific page on my blog where this code can | |
-- be found, so that folks who come across the code outside of my blog can find updates | |
-- more easily. | |
-- | |
-- 20111207.5 Added support for the 'etc' arguments, for better error reporting. | |
-- | |
-- 20110731.4 More feedback from David Kolf on how to make the tests for Nan/Infinity system independent. | |
-- | |
-- 20110730.3 Incorporated feedback from David Kolf at http://lua-users.org/wiki/JsonModules: | |
-- | |
-- * When encoding lua for JSON, Sparse numeric arrays are now handled by | |
-- spitting out full arrays, such that | |
-- JSON:encode({"one", "two", [10] = "ten"}) | |
-- returns | |
-- ["one","two",null,null,null,null,null,null,null,"ten"] | |
-- | |
-- In 20100810.2 and earlier, only up to the first non-null value would have been retained. | |
-- | |
-- * When encoding lua for JSON, numeric value NaN gets spit out as null, and infinity as "1+e9999". | |
-- Version 20100810.2 and earlier created invalid JSON in both cases. | |
-- | |
-- * Unicode surrogate pairs are now detected when decoding JSON. | |
-- | |
-- 20100810.2 added some checking to ensure that an invalid Unicode character couldn't leak in to the UTF-8 encoding | |
-- | |
-- 20100731.1 initial public release | |
-- | |
]===])() | |
local semver = (function() | |
local _ = [[ Copyright (c) The python-semanticversion project | |
All rights reserved. | |
Redistribution and use in source and binary forms, with or without | |
modification, are permitted provided that the following conditions are met: | |
1. Redistributions of source code must retain the above copyright notice, this | |
list of conditions and the following disclaimer. | |
2. Redistributions in binary form must reproduce the above copyright notice, | |
this list of conditions and the following disclaimer in the documentation | |
and/or other materials provided with the distribution. | |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | |
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
]] | |
_ = [[ The use of the library is similar to the original one, | |
check the documentation here: https://python-semanticversion.readthedocs.io/en/latest/ | |
]] | |
local concat, insert, unpack | |
do | |
local _obj_0 = table | |
concat, insert, unpack = _obj_0.concat, _obj_0.insert, _obj_0.unpack | |
end | |
local toInt | |
toInt = function(value) | |
do | |
local tn = tonumber(value) | |
if tn then | |
return tn, true | |
else | |
return value, false | |
end | |
end | |
end | |
local hasLeadingZero | |
hasLeadingZero = function(value) | |
return value and value[1] == '0' and tonumber(value and value ~= '0') | |
end | |
local baseCmp | |
baseCmp = function(x, y) | |
if x == y then | |
return 0 | |
end | |
if x > y then | |
return 1 | |
end | |
if x < y then | |
return -1 | |
end | |
end | |
local identifierCmp | |
identifierCmp = function(a, b) | |
local aCmp, aInt = toInt(a) | |
local bCmp, bInt = toInt(b) | |
if aInt and bInt then | |
return baseCmp(aCmp, bCmp) | |
elseif aInt then | |
return -1 | |
elseif bInt then | |
return 1 | |
else | |
return baseCmp(aCmp, bCmp) | |
end | |
end | |
local identifierListCmp | |
identifierListCmp = function(a, b) | |
local identifierPairs | |
do | |
local _tbl_0 = { } | |
for i = 1, #a do | |
if b[i] then | |
_tbl_0[a[i]] = b[i] | |
end | |
end | |
identifierPairs = _tbl_0 | |
end | |
for idA, idB in pairs(identifierPairs) do | |
local cmpRes = identifierCmp(idA, idB) | |
if cmpRes ~= 0 then | |
return cmpRes | |
end | |
end | |
return baseCmp(#a, #b) | |
end | |
local Version | |
do | |
local _class_0 | |
local _base_0 = { | |
_coerce = function(self, value, allowNil) | |
if allowNil == nil then | |
allowNil = false | |
end | |
if value == nil and allowNil then | |
return value | |
end | |
return tonumber(value) | |
end, | |
next_major = function(self) | |
if self.prerelease and self.minor == 0 and self.patch == 0 then | |
return Version(concat((function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = { | |
self.major, | |
self.minor, | |
self.patch | |
} | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
_accum_0[_len_0] = tostring(x) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)(), '.')) | |
else | |
return Version(concat((function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = { | |
self.major + 1, | |
0, | |
0 | |
} | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
_accum_0[_len_0] = tostring(x) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)(), '.')) | |
end | |
end, | |
next_minor = function(self) | |
if not (self.minor) then | |
error("Partial version doesn't contain the minor component!") | |
end | |
if self.prerelease and self.patch == 0 then | |
return Version(concat((function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = { | |
self.major, | |
self.minor, | |
self.patch | |
} | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
_accum_0[_len_0] = tostring(x) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)(), '.')) | |
else | |
return Version(concat((function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = { | |
self.major, | |
self.minor + 1, | |
0 | |
} | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
_accum_0[_len_0] = tostring(x) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)(), '.')) | |
end | |
end, | |
next_patch = function(self) | |
if not (self.patch) then | |
error("Partial version doesn't contain the patch component!") | |
end | |
if self.prerelease then | |
return Version(concat((function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = { | |
self.major, | |
self.minor, | |
self.patch | |
} | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
_accum_0[_len_0] = tostring(x) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)(), '.')) | |
else | |
return Version(concat((function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = { | |
self.major, | |
self.minor, | |
self.patch + 1 | |
} | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
_accum_0[_len_0] = tostring(x) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)(), '.')) | |
end | |
end, | |
coerce = function(self, versionString, partial) | |
if partial == nil then | |
partial = false | |
end | |
local baseRe | |
baseRe = function(s) | |
local mjr, rmn = s:match('^(%d+)(.*)$') | |
if not (mjr) then | |
return nil | |
end | |
local t = mjr | |
local mnr, r = rmn:match('^%.(%d+)(.*)$') | |
if mnr then | |
rmn = r | |
t = t .. ('.' .. mnr) | |
end | |
local pch | |
pch, r = rmn:match('^%.(%d+)(.*)$') | |
if pch then | |
rmn = r | |
t = t .. ('.' .. pch) | |
end | |
return s, t | |
end | |
local match, matchEnd = baseRe(versionString) | |
if not (match) then | |
error("Version string lacks a numerical component: " .. tostring(versionString)) | |
end | |
local version = versionString:sub(1, #matchEnd) | |
if not partial then | |
while ({ | |
version:gsub('.', '') | |
})[2] < 2 do | |
version = version .. '.0' | |
end | |
end | |
if #matchEnd == #versionString then | |
return Version(version, partial) | |
end | |
local rest = versionString:sub(#matchEnd + 1) | |
rest = rest:gsub('[^a-zA-Z0-9+.-]', '-') | |
local prerelease, build = nil, nil | |
if rest:sub(1, 1) == '+' then | |
prerelease = '' | |
build = rest:sub(2) | |
elseif rest:sub(1, 1) == '.' then | |
prerelease = '' | |
build = rest:sub(2) | |
elseif rest:sub(1, 1) == '-' then | |
rest = rest:sub(2) | |
do | |
local p1 = rest:find('+') | |
if p1 then | |
prerelease, build = rest:sub(1, p1 - 1), rest:sub(p1 + 1, -1) | |
else | |
prerelease, build = rest, '' | |
end | |
end | |
else | |
do | |
local p1 = rest:find('+') | |
if p1 then | |
prerelease, build = rest:sub(1, p1 - 1), rest:sub(p1 + 1, -1) | |
else | |
prerelease, build = rest, '' | |
end | |
end | |
end | |
build = build:gsub('+', '.') | |
if prerelease and prerelease ~= '' then | |
version = version .. ('-' .. prerelease) | |
end | |
if build and build ~= '' then | |
version = version .. ('+' .. build) | |
end | |
return self.__class(version, partial) | |
end, | |
parse = function(self, versionString, partial, coerce) | |
if partial == nil then | |
partial = false | |
end | |
if coerce == nil then | |
coerce = false | |
end | |
if not versionString or type(versionString) ~= 'string' or versionString == '' then | |
error("Invalid empty version string: " .. tostring(tostring(versionString))) | |
end | |
local versionRe | |
if partial then | |
versionRe = self.__class.partialVersionRe | |
else | |
versionRe = self.__class.versionRe | |
end | |
local major, minor, patch, prerelease, build = versionRe(self.__class, versionString) | |
if not major then | |
error("Invalid version string: " .. tostring(versionString)) | |
end | |
if hasLeadingZero(major) then | |
error("Invalid leading zero in major: " .. tostring(versionString)) | |
end | |
if hasLeadingZero(minor) then | |
error("Invalid leading zero in minor: " .. tostring(versionString)) | |
end | |
if hasLeadingZero(patch) then | |
error("Invalid leading zero in patch: " .. tostring(versionString)) | |
end | |
major = tonumber(major) | |
minor = self:_coerce(minor, partial) | |
patch = self:_coerce(patch, partial) | |
if prerelease == nil then | |
if partial and build == nil then | |
return { | |
major, | |
minor, | |
patch, | |
nil, | |
nil | |
} | |
else | |
prerelease = { } | |
end | |
elseif prerelease == '' then | |
prerelease = { } | |
else | |
do | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for x in prerelease:gmatch('[^.]+') do | |
_accum_0[_len_0] = x | |
_len_0 = _len_0 + 1 | |
end | |
prerelease = _accum_0 | |
end | |
self:_validateIdentifiers(prerelease, false) | |
end | |
if build == nil then | |
if partial then | |
build = nil | |
else | |
build = { } | |
end | |
elseif build == '' then | |
build = { } | |
else | |
do | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for x in build:gmatch('[^.]+') do | |
_accum_0[_len_0] = x | |
_len_0 = _len_0 + 1 | |
end | |
build = _accum_0 | |
end | |
self:_validateIdentifiers(build, true) | |
end | |
return { | |
major, | |
minor, | |
patch, | |
prerelease, | |
build | |
} | |
end, | |
_validateIdentifiers = function(self, identifiers, allowLeadingZeroes) | |
if allowLeadingZeroes == nil then | |
allowLeadingZeroes = false | |
end | |
for _index_0 = 1, #identifiers do | |
local item = identifiers[_index_0] | |
if not item then | |
error("Invalid empty identifier " .. tostring(item) .. " in " .. tostring(concat(identifiers, '.'))) | |
end | |
if item:sub(1, 1) == '0' and tonumber(item) and item ~= '0' and not allowLeadingZeroes then | |
error("Invalid leading zero in identifier " .. tostring(item)) | |
end | |
end | |
end, | |
__pairs = function(self) | |
return pairs({ | |
self.major, | |
self.minor, | |
self.patch, | |
self.prerelease, | |
self.build | |
}) | |
end, | |
__ipairs = function(self) | |
return ipairs({ | |
self.major, | |
self.minor, | |
self.patch, | |
self.prerelease, | |
self.build | |
}) | |
end, | |
__tostring = function(self) | |
local version = tostring(self.major) | |
if self.minor ~= nil then | |
version = version .. ('.' .. self.minor) | |
end | |
if self.patch ~= nil then | |
version = version .. ('.' .. self.patch) | |
end | |
if self.prerelease and #self.prerelease > 0 or self.partial and self.prerelease and #self.prerelease == 0 and self.build == nil then | |
version = version .. ('-' .. concat(self.prerelease, '.')) | |
end | |
if self.build and #self.build > 0 or self.partial and self.build and #self.build == 0 then | |
version = version .. ('+' .. concat(self.build, '.')) | |
end | |
return version | |
end, | |
_comparsionFunctions = function(self, partial) | |
if partial == nil then | |
partial = false | |
end | |
local prereleaseCmp | |
prereleaseCmp = function(a, b) | |
if a and b then | |
return identifierListCmp(a, b) | |
elseif a then | |
return -1 | |
elseif b then | |
return 1 | |
else | |
return 0 | |
end | |
end | |
local buildCmp | |
buildCmp = function(a, b) | |
if a == b then | |
return 0 | |
else | |
return 'not implemented' | |
end | |
end | |
local makeOptional | |
makeOptional = function(origCmpFun) | |
local altCmpFun | |
altCmpFun = function(a, b) | |
if a == nil or b == nil then | |
return 0 | |
else | |
return origCmpFun(a, b) | |
end | |
end | |
return altCmpFun | |
end | |
if partial then | |
return { | |
baseCmp, | |
makeOptional(baseCmp), | |
makeOptional(baseCmp), | |
makeOptional(prereleaseCmp), | |
makeOptional(buildCmp) | |
} | |
else | |
return { | |
baseCmp, | |
baseCmp, | |
baseCmp, | |
prereleaseCmp, | |
buildCmp | |
} | |
end | |
end, | |
__compare = function(self, other) | |
local comparsionFunctions = self:_comparsionFunctions(self.partial or other.partial) | |
local comparsions = { | |
{ | |
comparsionFunctions[1], | |
self.major, | |
other.major | |
}, | |
{ | |
comparsionFunctions[2], | |
self.minor, | |
other.minor | |
}, | |
{ | |
comparsionFunctions[3], | |
self.patch, | |
other.patch | |
}, | |
{ | |
comparsionFunctions[4], | |
self.prerelease, | |
other.prerelease | |
}, | |
{ | |
comparsionFunctions[5], | |
self.build, | |
other.build | |
} | |
} | |
for _index_0 = 1, #comparsions do | |
local cmpField = comparsions[_index_0] | |
local cmpFun, selfField, otherField = unpack(cmpField) | |
local cmpRes = cmpFun(selfField, otherField) | |
if cmpRes ~= 0 then | |
return cmpRes | |
end | |
end | |
return 0 | |
end, | |
__compareHelper = function(self, other, condition, notimplTarget) | |
local cmpRes = self:__compare(other) | |
if cmpRes == 'not implemented' then | |
return notimplTarget | |
end | |
return condition(cmpRes) | |
end, | |
__eq = function(self, other) | |
local c | |
c = function(x) | |
return x == 0 | |
end | |
return self:__compareHelper(other, c, false) | |
end, | |
__lt = function(self, other) | |
local c | |
c = function(x) | |
return x < 0 | |
end | |
return self:__compareHelper(other, c, false) | |
end, | |
__le = function(self, other) | |
local c | |
c = function(x) | |
return x <= 0 | |
end | |
return self:__compareHelper(other, c, false) | |
end | |
} | |
_base_0.__index = _base_0 | |
_class_0 = setmetatable({ | |
__init = function(self, versionString, partial) | |
if partial == nil then | |
partial = false | |
end | |
local major, minor, patch, prerelease, build = unpack(self:parse(versionString, partial)) | |
self.major, self.minor, self.patch, self.prerelease, self.build, self.partial = major, minor, patch, prerelease, build, partial | |
end, | |
__base = _base_0, | |
__name = "Version" | |
}, { | |
__index = _base_0, | |
__call = function(cls, ...) | |
local _self_0 = setmetatable({}, _base_0) | |
cls.__init(_self_0, ...) | |
return _self_0 | |
end | |
}) | |
_base_0.__class = _class_0 | |
local self = _class_0 | |
self.versionRe = function(self, s) | |
local mjr, mnr, pch, rmn = s:match('^(%d+)%.(%d+)%.(%d+)(.*)$') | |
if not (mjr) then | |
return nil | |
end | |
local add, r = rmn:match('^%-([0-9a-zA-z.-]+)(.*)$') | |
if add then | |
rmn = r | |
end | |
local meta | |
meta, r = rmn:match('^%+([0-9a-zA-Z.-]+)(.*)$') | |
if meta then | |
rmn = r | |
end | |
if #rmn > 0 then | |
return nil | |
end | |
return mjr, mnr, pch, add, meta | |
end | |
self.partialVersionRe = function(self, s) | |
local mjr, rmn = s:match('^(%d+)(.*)$') | |
if not (mjr) then | |
return nil | |
end | |
local mnr, r = rmn:match('^%.(%d+)(.*)$') | |
if mnr then | |
rmn = r | |
end | |
local pch | |
pch, r = rmn:match('^%.(%d+)(.*)$') | |
if pch then | |
rmn = r | |
end | |
local add | |
add, r = rmn:match('^%-([0-9a-zA-Z.-]*)(.*)$') | |
if add then | |
rmn = r | |
end | |
local meta | |
meta, r = rmn:match('^%+([0-9a-zA-Z.-]*)(.*)$') | |
if meta then | |
rmn = r | |
end | |
if #rmn > 0 then | |
return nil | |
end | |
return mjr, mnr, pch, add, meta | |
end | |
Version = _class_0 | |
end | |
local SpecItem | |
do | |
local _class_0 | |
local _base_0 = { | |
parse = function(self, requirementString) | |
if not requirementString or type(requirementString) ~= 'string' or requirementString == '' then | |
error("Invalid empty requirement specification: " .. tostring(tostring(requirementString))) | |
end | |
if requirementString == '*' then | |
return { | |
self.__class.KIND_ANY, | |
'' | |
} | |
end | |
local kind, version = self.__class:reSpec(requirementString) | |
if not kind then | |
error("Invalid requirement specification: " .. tostring(requirementString)) | |
end | |
kind = self.__class.KIND_ALIASES[kind] or kind | |
local spec = Version(version, true) | |
if spec.build ~= nil and kind ~= self.__class.KIND_EQUAL and kind ~= self.__class.KIND_NEQ then | |
error("Invalid requirement specification " .. tostring(requirementString) .. ": build numbers have no ordering") | |
end | |
return { | |
kind, | |
spec | |
} | |
end, | |
match = function(self, version) | |
local _exp_0 = self.kind | |
if self.__class.KIND_ANY == _exp_0 then | |
return true | |
elseif self.__class.KIND_LT == _exp_0 then | |
return version < self.spec | |
elseif self.__class.KIND_LTE == _exp_0 then | |
return version <= self.spec | |
elseif self.__class.KIND_EQUAL == _exp_0 then | |
return version == self.spec | |
elseif self.__class.KIND_GTE == _exp_0 then | |
return version >= self.spec | |
elseif self.__class.KIND_GT == _exp_0 then | |
return version > self.spec | |
elseif self.__class.KIND_NEQ == _exp_0 then | |
return version ~= self.spec | |
elseif self.__class.KIND_CARET == _exp_0 then | |
return self.spec <= version and version < self.spec:next_major() | |
elseif self.__class.KIND_TILDE == _exp_0 then | |
return self.spec <= version and version < self.spec:next_minor() | |
else | |
return error("Unexpected match kind: " .. tostring(self.kind)) | |
end | |
end, | |
__tostring = function(self) | |
return tostring(self.kind) .. tostring(self.spec) | |
end, | |
__eq = function(self, other) | |
return self.kind == other.kind and self.spec == other.spec | |
end | |
} | |
_base_0.__index = _base_0 | |
_class_0 = setmetatable({ | |
__init = function(self, requirementString) | |
self.kind, self.spec = unpack(self:parse(requirementString)) | |
end, | |
__base = _base_0, | |
__name = "SpecItem" | |
}, { | |
__index = _base_0, | |
__call = function(cls, ...) | |
local _self_0 = setmetatable({}, _base_0) | |
cls.__init(_self_0, ...) | |
return _self_0 | |
end | |
}) | |
_base_0.__class = _class_0 | |
local self = _class_0 | |
self.KIND_ANY = '*' | |
self.KIND_LT = '<' | |
self.KIND_LTE = '<=' | |
self.KIND_EQUAL = '==' | |
self.KIND_SHORTEQ = '=' | |
self.KIND_EMPTY = '' | |
self.KIND_GTE = '>=' | |
self.KIND_GT = '>' | |
self.KIND_NEQ = '!=' | |
self.KIND_CARET = '^' | |
self.KIND_TILDE = '~' | |
self.KIND_ALIASES = { | |
[self.__class.KIND_SHORTEQ] = self.__class.KIND_EQUAL, | |
[self.__class.KIND_EMPTY] = self.__class.KIND_EQUAL | |
} | |
self.reSpec = function(self, s) | |
local chr, v = s:match('^(.-)(%d.*)$') | |
if not (chr == '<' or chr == '<=' or chr == '' or chr == '=' or chr == '==' or chr == '>=' or chr == '>' or chr == '!=' or chr == '^' or chr == '~') then | |
return nil | |
else | |
return chr, v | |
end | |
end | |
SpecItem = _class_0 | |
end | |
local Spec | |
do | |
local _class_0 | |
local _base_0 = { | |
parse = function(self, specsString) | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for x in specsString:gmatch('[^,]+') do | |
_accum_0[_len_0] = SpecItem(x) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end, | |
match = function(self, version) | |
local _list_0 = self.specs | |
for _index_0 = 1, #_list_0 do | |
local spec = _list_0[_index_0] | |
if not spec:match(version) then | |
return false | |
end | |
end | |
return true | |
end, | |
filter = function(self, versions) | |
local i = 0 | |
return function() | |
while true do | |
i = i + 1 | |
local version = versions[i] | |
if not (version) then | |
return nil | |
end | |
if self:match(version) then | |
return version | |
end | |
end | |
end | |
end, | |
select = function(self, versions) | |
local options | |
do | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for x in self:filter(versions) do | |
_accum_0[_len_0] = x | |
_len_0 = _len_0 + 1 | |
end | |
options = _accum_0 | |
end | |
if #options > 0 then | |
local max = options[1] | |
for _index_0 = 1, #options do | |
local ver = options[_index_0] | |
if max < ver then | |
max = ver | |
end | |
end | |
return max | |
else | |
return nil | |
end | |
end, | |
__index = function(self, k) | |
if self:match(k) then | |
return true | |
else | |
return nil | |
end | |
end, | |
__pairs = function(self) | |
return pairs(self.specs) | |
end, | |
__ipairs = function(self) | |
return ipairs(self.specs) | |
end, | |
__tostring = function(self) | |
return concat((function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = self.specs | |
for _index_0 = 1, #_list_0 do | |
local spec = _list_0[_index_0] | |
_accum_0[_len_0] = tostring(spec) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)(), ',') | |
end, | |
__eq = function(self, other) | |
local _list_0 = self.specs | |
for _index_0 = 1, #_list_0 do | |
local selfSpec = _list_0[_index_0] | |
local s = false | |
local _list_1 = other.specs | |
for _index_1 = 1, #_list_1 do | |
local otherSpec = _list_1[_index_1] | |
if selfSpec == otherSpec then | |
s = true | |
break | |
end | |
end | |
if not s then | |
return false | |
end | |
end | |
return true | |
end | |
} | |
_base_0.__index = _base_0 | |
_class_0 = setmetatable({ | |
__init = function(self, specsStrings) | |
if type(specsStrings) == 'string' then | |
specsStrings = { | |
specsStrings | |
} | |
end | |
local subspecs | |
do | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for _index_0 = 1, #specsStrings do | |
local spec = specsStrings[_index_0] | |
_accum_0[_len_0] = self:parse(spec) | |
_len_0 = _len_0 + 1 | |
end | |
subspecs = _accum_0 | |
end | |
self.specs = { } | |
for _index_0 = 1, #subspecs do | |
local subspec = subspecs[_index_0] | |
for _index_1 = 1, #subspec do | |
local spec = subspec[_index_1] | |
insert(self.specs, spec) | |
end | |
end | |
end, | |
__base = _base_0, | |
__name = "Spec" | |
}, { | |
__index = _base_0, | |
__call = function(cls, ...) | |
local _self_0 = setmetatable({}, _base_0) | |
cls.__init(_self_0, ...) | |
return _self_0 | |
end | |
}) | |
_base_0.__class = _class_0 | |
Spec = _class_0 | |
end | |
local compare | |
compare = function(v1, v2) | |
return baseCmp(Version(v1, Version(v2))) | |
end | |
local match | |
match = function(spec, version) | |
return Spec(spec):match(Version(version)) | |
end | |
local validate | |
validate = function(versionString) | |
return ({ | |
Version:parse(versionString) | |
})[1] | |
end | |
return { | |
Spec = Spec, | |
SpecItem = SpecItem, | |
Version = Version, | |
compare = compare, | |
match = match, | |
validate = validate | |
} | |
end)() | |
local isAvailable | |
isAvailable = require("component").isAvailable | |
local parse, getWorkingDirectory | |
do | |
local _obj_0 = require("shell") | |
parse, getWorkingDirectory = _obj_0.parse, _obj_0.getWorkingDirectory | |
end | |
local shell = require("shell") | |
local isDirectory, exists, makeDirectory, concat, copy | |
do | |
local _obj_0 = require("filesystem") | |
isDirectory, exists, makeDirectory, concat, copy = _obj_0.isDirectory, _obj_0.exists, _obj_0.makeDirectory, _obj_0.concat, _obj_0.copy | |
end | |
local fs = require("filesystem") | |
local serialize, unserialize | |
do | |
local _obj_0 = require("serialization") | |
serialize, unserialize = _obj_0.serialize, _obj_0.unserialize | |
end | |
local pull | |
pull = require("event").pull | |
local clearLine, getCursor | |
do | |
local _obj_0 = require("term") | |
clearLine, getCursor = _obj_0.clearLine, _obj_0.getCursor | |
end | |
local exit | |
exit = os.exit | |
local write, stderr | |
do | |
local _obj_0 = io | |
write, stderr = _obj_0.write, _obj_0.stderr | |
end | |
local insert, unpack | |
do | |
local _obj_0 = table | |
insert, unpack = _obj_0.insert, _obj_0.unpack | |
end | |
local listFiles = fs.list | |
local options, args = { }, { } | |
local request = nil | |
local modules = { } | |
local config = { } | |
local modulePath = "/etc/hpm/module/" | |
local distPath = "/var/lib/hpm/dist/" | |
local exitCode = 0 | |
local CONFIG_PATH = "/etc/hpm/hpm.cfg" | |
local USAGE = [[Usage: hpm OPTIONS COMMAND | |
See `man hpm` for more info.]] | |
local DEFAULT_CONFIG = [[-- << Global settings >> ------------------------------------------------------- | |
-- A directory where package manifests will be placed. | |
-- It will be created if it doesn't exist. | |
dist = "/var/lib/hpm/dist" | |
-- A place where to search for custom hpm modules. | |
-- It will be created if it doesn't exist. | |
modules = "/etc/hpm/module" | |
-- << Settings related to the hel module >> ------------------------------------ | |
hel = {} | |
-- If set to `false`, hpm will *only* remove a package that hpm is told to | |
-- remove. Otherwise, all of its dependants will be also removed. | |
hel.remove_dependants = true | |
-- << Settings related to the oppm module >> ----------------------------------- | |
oppm = {} | |
-- A directory where package manifests will be stored for faster access. | |
oppm.cache_directory = "/var/cache/hpm/oppm" | |
-- See hel.remove_dependants above. | |
oppm.remove_dependants = true]] | |
local log = { | |
info = function(...) | |
if options.v then | |
return print(table.concat((function(...) | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = { | |
... | |
} | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
_accum_0[_len_0] = tostring(x) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)(...), "\t")) | |
end | |
end, | |
print = function(...) | |
if not (options.q) then | |
return print(table.concat((function(...) | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = { | |
... | |
} | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
_accum_0[_len_0] = tostring(x) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)(...), "\t")) | |
end | |
end, | |
error = function(...) | |
if not (options.q) then | |
return stderr:write(table.concat((function(...) | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = { | |
... | |
} | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
_accum_0[_len_0] = tostring(x) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)(...), "\t") .. '\n') | |
end | |
end, | |
fatal = function(...) | |
if not (options.q) then | |
stderr:write(table.concat((function(...) | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = { | |
... | |
} | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
_accum_0[_len_0] = tostring(x) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)(...), "\t") .. '\n') | |
end | |
return exit(1) | |
end | |
} | |
local assert | |
assert = function(statement, message) | |
if not (statement) then | |
return log.fatal(message) | |
end | |
end | |
local unimplemented | |
unimplemented = function(what) | |
return log.fatal((tostring(what)) .. ": Not implemented yet!") | |
end | |
local printUsage | |
printUsage = function() | |
write(USAGE) | |
return exit(0) | |
end | |
local try | |
try = function(result, reason) | |
if not (result) then | |
log.fatal(reason) | |
end | |
return result | |
end | |
local checkType | |
checkType = function(v, t, c) | |
if not (type(v == t)) then | |
log.fatal("Value '" .. tostring(v) .. "' is " .. tostring(type(c)) .. ", however, a " .. tostring(t) .. " is expected.") | |
end | |
return c | |
end | |
local argNumber | |
argNumber = function(v) | |
return checkType(v, "number", tonumber(v)) | |
end | |
local argString | |
argString = function(v) | |
return checkType(v, "string", tostring(v)) | |
end | |
local isin | |
isin = function(v, tbl) | |
for k, value in pairs(tbl) do | |
if value == v then | |
return true, k | |
end | |
end | |
return false | |
end | |
local tableLen | |
tableLen = function(tbl) | |
local result = 0 | |
for k, v in pairs(tbl) do | |
result = result + 1 | |
end | |
return result | |
end | |
local empty | |
empty = function(v) | |
if type(v) == "nil" then | |
return true | |
elseif type(v) == "string" then | |
return not v or #v < 1 | |
elseif type(v) == "table" then | |
return not v or tableLen(v) < 1 | |
else | |
return true | |
end | |
end | |
local all | |
all = function(vals) | |
for _index_0 = 1, #vals do | |
local v = vals[_index_0] | |
if not v then | |
return false | |
end | |
end | |
return true | |
end | |
local existsDir | |
existsDir = function(path) | |
return exists(path) and isDirectory(path) | |
end | |
local existsFile | |
existsFile = function(path) | |
return exists(path) and not isDirectory(path) | |
end | |
local plural | |
plural = function(amount) | |
return amount == 1 and "" or "s" | |
end | |
local singular | |
singular = function(amount) | |
return amount ~= 1 and "" or "s" | |
end | |
local linkingVerb | |
linkingVerb = function(amount) | |
return amount == 1 and "is" or "are" | |
end | |
local parsePackageName | |
parsePackageName = function(value) | |
return value:match("^([^:]-):?([^:@]+)@?([^:@]*)$") | |
end | |
local remove | |
remove = function(path) | |
if fs.get(shell.resolve(path)).isReadOnly() then | |
return false, "the path is readonly!" | |
elseif not exists(path) then | |
return false, "the filesystem node doesn't exist." | |
else | |
if not (isDirectory(path) or fs.isLink(path)) then | |
return fs.remove(path) | |
else | |
for file in try(listFiles(path)) do | |
remove(concat(path, file)) | |
end | |
return fs.remove(path) | |
end | |
end | |
end | |
local loadConfig | |
loadConfig = function() | |
local path = options.c or options.config or CONFIG_PATH | |
if not existsFile(path) then | |
local dirPath = fs.path(path) | |
if not existsDir(dirPath) then | |
local result, reason = makeDirectory(dirPath) | |
if not result then | |
return false, "Failed to create '" .. tostring(dirPath) .. "' directory for the config file: " .. tostring(reason) | |
end | |
end | |
local file, reason = io.open(path, "w") | |
if file then | |
file:write(DEFAULT_CONFIG) | |
file:close() | |
else | |
return false, "Failed to open config file for writing: " .. tostring(reason) | |
end | |
end | |
local file, reason = io.open(path, "r") | |
if file then | |
local content = file:read("*all") | |
file:close() | |
local globals = { } | |
(load(content, "config", "t", globals))() | |
local newUndecl | |
newUndecl = function(base) | |
if base == nil then | |
base = { } | |
end | |
return setmetatable(base, { | |
__index = { | |
get = function(k, v, createNewUndecl) | |
if type(base[k]) ~= "nil" then | |
if type(base[k]) == "table" then | |
return newUndecl(base[k]) | |
end | |
return base[k] | |
end | |
log.error("Attempt to access undeclared config field '" .. tostring(k) .. "'!") | |
if not createNewUndecl then | |
return v | |
else | |
return newUndecl(v) | |
end | |
end | |
} | |
}) | |
end | |
config = newUndecl(globals) | |
modulePath = config.get("modules", modulePath) | |
distPath = config.get("dist", distPath) | |
return config | |
else | |
return false, "Failed to open config file for reading: " .. tostring(reason) | |
end | |
end | |
local checkInternet | |
checkInternet = function() | |
if not (isAvailable("internet")) then | |
log.fatal("This command requires an internet card to run!") | |
end | |
request = request or require("internet").request | |
end | |
local download | |
download = function(url) | |
checkInternet() | |
return pcall(request, url) | |
end | |
local loadCustomModules | |
loadCustomModules = function() | |
if not existsDir(modulePath) then | |
local result, reason = makeDirectory(modulePath) | |
if not result then | |
return false, "Failed to create '" .. tostring(modulePath) .. "' directory for custom modules: " .. tostring(reason) | |
end | |
end | |
local list = try(listFiles(modulePath)) | |
for file in list do | |
local name = file:match("^(.+)%..+$") | |
local mod = (loadfile(concat(modulePath, file), "t", _ENV))() | |
if mod then | |
modules[name] = mod | |
end | |
end | |
return true | |
end | |
local findCustomCommand | |
findCustomCommand = function(name) | |
local command = name | |
local mod | |
do | |
local p1 = name:find(':') | |
if p1 then | |
command = name:sub(p1 + 1) | |
mod = name:sub(1, p1 - 1) | |
end | |
end | |
if not mod then | |
local candidates = { } | |
for modName, mod in pairs(modules) do | |
if mod[command] then | |
if type(mod[command]) == "table" and mod[command].__public == true then | |
insert(candidates, { | |
class = mod, | |
module = modName, | |
method = mod[command] | |
}) | |
end | |
end | |
end | |
if #candidates > 1 then | |
local pos = nil | |
for k, mod in pairs(candidates) do | |
if mod.module == "hel" then | |
pos = k | |
break | |
end | |
end | |
if pos then | |
candidates = { | |
candidates[pos] | |
} | |
end | |
end | |
if #candidates > 1 then | |
log.print("Ambiguous choice: method " .. tostring(command) .. " is implemented in the following modules:") | |
for _index_0 = 1, #candidates do | |
local mod = candidates[_index_0] | |
log.print(" * " .. tostring(mod.module)) | |
end | |
log.print("Choose a specific module by prepending its name with a colon, e.g., " .. tostring(candidates[1].module) .. ":" .. tostring(command) .. ".") | |
return false | |
elseif #candidates == 0 then | |
log.error("Unknown command: " .. tostring(command)) | |
return false | |
else | |
mod = candidates[1].module | |
log.info("Note, using " .. tostring(mod) .. ":" .. tostring(command) .. ".") | |
return function(...) | |
return candidates[1].method(candidates[1].class, ...) | |
end | |
end | |
else | |
if modules[mod] and empty(command) then | |
local modSpecMths = { } | |
for k, v in pairs(modules[mod]) do | |
if type(v) == "table" and v.__public == true then | |
insert(modSpecMths, tostring(k)) | |
end | |
end | |
log.print("Available module-specific commands: " .. tostring(table.concat(modSpecMths, ", "))) | |
return false | |
end | |
if not modules[mod] or not modules[mod][command] or modules[mod][command] and (type(modules[mod][command]) ~= "table" or modules[mod][command].__public ~= true) then | |
log.error("Unknown command: " .. tostring(mod) .. ":" .. tostring(command)) | |
return false | |
else | |
return function(...) | |
return modules[mod][command](modules[mod], ...) | |
end | |
end | |
end | |
end | |
local getModuleBy | |
getModuleBy = function(source) | |
if not source or source == "" then | |
source = "hel" | |
else | |
source = source | |
end | |
return modules[source] or modules.default | |
end | |
local callModuleMethod | |
callModuleMethod = function(mod, name, ...) | |
if mod == nil then | |
mod = modules.default | |
end | |
if mod[name] then | |
return mod[name](mod, ...) | |
else | |
return modules.default[name](modules.default, ...) | |
end | |
end | |
local saveManifest | |
saveManifest = function(manifest, mod, path, name) | |
if mod == nil then | |
mod = "hel" | |
end | |
if path == nil then | |
path = concat(distPath, mod) | |
end | |
if name == nil then | |
name = manifest.name | |
end | |
if not manifest then | |
return false, "'nil' given" | |
end | |
if not existsDir(path) then | |
local result, reason = makeDirectory(path) | |
if not result then | |
return false, "Failed to create '" .. tostring(concat(path, mod)) .. "' directory for manifest files: " .. tostring(reason) | |
end | |
end | |
local file, reason = io.open(concat(path, name), "w") | |
if file then | |
file:write(serialize(manifest)) | |
file:close() | |
return true | |
else | |
return false, "Failed to open file for writing: " .. tostring(reason) | |
end | |
end | |
local loadManifest | |
loadManifest = function(name, path, mod) | |
if mod == nil then | |
mod = "hel" | |
end | |
path = path or concat(distPath, mod, name) | |
if existsFile(path) then | |
local file, reason = io.open(path, "rb") | |
if file then | |
local manifest = try(unserialize(file:read("*all"))) | |
file:close() | |
return manifest | |
else | |
return false, "Failed to open manifest for '" .. tostring(name) .. "' package: " .. tostring(reason) | |
end | |
else | |
return false, "No manifest found for '" .. tostring(name) .. "' package" | |
end | |
end | |
local removeManifest | |
removeManifest = function(name, mod) | |
if mod == nil then | |
mod = "hel" | |
end | |
local path = concat(distPath, mod, name) | |
if existsFile(path) then | |
return remove(path) | |
else | |
return false, "No manifest found for '" .. tostring(name) .. "' package" | |
end | |
end | |
local public | |
public = function(func) | |
return setmetatable({ | |
__public = true | |
}, { | |
__call = function(self, ...) | |
return func(...) | |
end | |
}) | |
end | |
local wrapResponse | |
wrapResponse = function(resp, file) | |
return function() | |
local result, chunk = pcall(resp) | |
if not (result) then | |
return false, "Could not download '" .. tostring(file) .. "': " .. tostring(chunk) | |
else | |
return chunk | |
end | |
end | |
end | |
local recv | |
recv = function(url, connectError, downloadError) | |
if connectError == nil then | |
connectError = "Could not download '%s': %s" | |
end | |
if downloadError == nil then | |
downloadError = "Could not download '%s': %s" | |
end | |
local result, response, reason = download(url) | |
if not (result and response) then | |
return false, connectError:format(url, reason) | |
end | |
local data = "" | |
for chunk, reason in wrapResponse(response) do | |
if chunk then | |
data = data .. chunk | |
else | |
return false, downloadError:format(url, reason) | |
end | |
end | |
return data | |
end | |
local confirm | |
confirm = function() | |
if not (options.y) then | |
io.write("Press [ENTER] to continue...") | |
local key = select(3, pull("key_down")) | |
if key == 13 then | |
clearLine() | |
return true | |
else | |
io.write("\n") | |
return false | |
end | |
else | |
return true | |
end | |
end | |
local pkgPlan | |
pkgPlan = function(plan) | |
local complexity = 0 | |
local msg = { } | |
if not (empty(plan.install)) then | |
local m = { | |
"Packages to INSTALL:", | |
table.concat(plan.install, " ") | |
} | |
insert(msg, m) | |
complexity = complexity + #plan.install | |
else | |
plan.install = { } | |
end | |
if not (empty(plan.reinstall)) then | |
local m = { | |
"Packages to REINSTALL:", | |
table.concat(plan.reinstall, " ") | |
} | |
insert(msg, m) | |
complexity = complexity + #plan.reinstall | |
else | |
plan.reinstall = { } | |
end | |
if not (empty(plan.upgrade)) then | |
local m = { | |
"Packages to UPGRADE:", | |
table.concat(plan.upgrade, " ") | |
} | |
insert(msg, m) | |
complexity = complexity + #plan.upgrade | |
else | |
plan.upgrade = { } | |
end | |
if not (empty(plan.remove)) then | |
local m = { | |
"Packages to REMOVE:", | |
table.concat(plan.remove, " ") | |
} | |
insert(msg, m) | |
complexity = complexity + #plan.remove | |
else | |
plan.remove = { } | |
end | |
do | |
local m = { | |
tostring(#plan.install) .. " to INSTALL, " .. tostring(#plan.reinstall) .. " to REINSTALL, " .. tostring(#plan.upgrade) .. " to UPGRADE, " .. tostring(#plan.remove) .. " to REMOVE." | |
} | |
insert(msg, m) | |
end | |
for num, i in pairs(msg) do | |
for num, line in pairs(i) do | |
if num == 1 then | |
log.print(line) | |
else | |
log.print(" " .. tostring(line)) | |
end | |
end | |
if num ~= #msg then | |
log.print("") | |
end | |
end | |
if complexity > 1 then | |
if not (confirm()) then | |
return exit(7) | |
end | |
end | |
end | |
do | |
local _class_0 | |
local _base_0 = { } | |
_base_0.__index = _base_0 | |
_class_0 = setmetatable({ | |
__init = function() end, | |
__base = _base_0, | |
__name = "default" | |
}, { | |
__index = _base_0, | |
__call = function(cls, ...) | |
local _self_0 = setmetatable({}, _base_0) | |
cls.__init(_self_0, ...) | |
return _self_0 | |
end | |
}) | |
_base_0.__class = _class_0 | |
local self = _class_0 | |
self.install = function() | |
return log.fatal("Incorrect source is provided! No default 'install' implementation.") | |
end | |
self.remove = function(self, manifest, mod) | |
if mod == nil then | |
mod = "hel" | |
end | |
if manifest then | |
if manifest.files then | |
for i, file in pairs(manifest.files) do | |
local path = concat(file.dir, file.name) | |
local result, reason = remove(path) | |
if not (result) then | |
return false, "Failed to remove '" .. tostring(path) .. "': " .. tostring(reason) | |
end | |
end | |
end | |
return removeManifest(manifest.name, mod) | |
else | |
return false, "Package can't be removed: the manifest is empty." | |
end | |
end | |
self.save = function() | |
return log.fatal("Incorrect source is provided! No default 'save' implementation.") | |
end | |
modules.default = _class_0 | |
end | |
do | |
local _class_0 | |
local _parent_0 = modules.default | |
local _base_0 = { } | |
_base_0.__index = _base_0 | |
setmetatable(_base_0, _parent_0.__base) | |
_class_0 = setmetatable({ | |
__init = function(self, ...) | |
return _class_0.__parent.__init(self, ...) | |
end, | |
__base = _base_0, | |
__name = "hel", | |
__parent = _parent_0 | |
}, { | |
__index = function(cls, name) | |
local val = rawget(_base_0, name) | |
if val == nil then | |
local parent = rawget(cls, "__parent") | |
if parent then | |
return parent[name] | |
end | |
else | |
return val | |
end | |
end, | |
__call = function(cls, ...) | |
local _self_0 = setmetatable({}, _base_0) | |
cls.__init(_self_0, ...) | |
return _self_0 | |
end | |
}) | |
_base_0.__class = _class_0 | |
local self = _class_0 | |
self.URL = "https://hel-roottree.rhcloud.com/" | |
self.parsePackageJSON = function(self, decoded, spec) | |
if spec == nil then | |
spec = semver.Spec("*") | |
end | |
local selectedVersion = nil | |
local versions = { } | |
for number, data in pairs(decoded.versions) do | |
local v = semver.Version(number) | |
if not (v) then | |
log.fatal("Could not parse the version in package: " .. tostring(v)) | |
end | |
versions[v] = data | |
end | |
local success, bestMatch = pcall(function() | |
return spec:select((function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for version, data in pairs(versions) do | |
_accum_0[_len_0] = version | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)()) | |
end) | |
if not (success) then | |
log.fatal("Could not select the best version: " .. tostring(bestMatch)) | |
end | |
selectedVersion = tostring(bestMatch) | |
if not (bestMatch) then | |
log.fatal("No candidate for version specification '" .. tostring(spec) .. "' found!") | |
end | |
local data = { | |
name = decoded.name, | |
version = selectedVersion, | |
files = { }, | |
dependencies = { } | |
} | |
for url, file in pairs(versions[bestMatch].files) do | |
local dir = file.dir | |
local name = file.name | |
insert(data.files, { | |
url = url, | |
dir = dir, | |
name = name | |
}) | |
end | |
for depName, depData in pairs(versions[bestMatch].depends) do | |
local version = depData.version | |
local depType = depData.type | |
insert(data.dependencies, { | |
name = depName, | |
version = version, | |
type = depType | |
}) | |
end | |
return data | |
end | |
self.getPackageSpec = function(self, name) | |
log.info("Downloading package data for " .. tostring(name) .. " ...") | |
local status, response = download(self.URL .. "packages/" .. name) | |
if not (status) then | |
log.fatal("HTTP request error: " .. response) | |
end | |
local jsonData = "" | |
for chunk in response do | |
jsonData = jsonData .. chunk | |
end | |
local decoded = json:decode(jsonData) | |
if not (decoded) then | |
log.fatal("Incorrect JSON format!\n" .. tostring(jsonData)) | |
end | |
return decoded.data | |
end | |
self.rawInstall = function(self, pkgData, isManuallyInstalled, save) | |
if isManuallyInstalled == nil then | |
isManuallyInstalled = false | |
end | |
if save == nil then | |
save = false | |
end | |
local prefix | |
if save then | |
prefix = concat(getWorkingDirectory(), pkgData.name) | |
else | |
prefix = "/" | |
end | |
if save and not existsDir(prefix) then | |
local result, response = makeDirectory(prefix) | |
if not (result) then | |
log.fatal("Failed creating '" .. tostring(prefix) .. "' directory for package '" .. tostring(pkgData.name) .. "'! \n" .. tostring(response)) | |
end | |
elseif not save then | |
local manifest = loadManifest(pkgData.name, nil, "hel") | |
if manifest then | |
if manifest.version == tostring(pkgData.version) then | |
log.print("'" .. tostring(pkgData.name) .. "@" .. tostring(manifest.version) .. "' is already installed, skipping...") | |
return manifest | |
else | |
log.fatal("'" .. tostring(pkgData.name) .. "@" .. tostring(pkgData.version) .. "' was attempted to install, however, another version of the same package is already installed: '" .. tostring(pkgData.name) .. "@" .. tostring(manifest.version) .. "'") | |
end | |
end | |
end | |
for key, file in pairs(pkgData.files) do | |
log.info("Fetching '" .. tostring(file.name) .. "' ...") | |
local contents = try(recv(file.url)) | |
local path = concat(prefix, file.dir) | |
if not existsDir(path) then | |
local result, response = makeDirectory(path) | |
if not (result) then | |
log.fatal("Failed to create '" .. tostring(path) .. "' directory for '" .. tostring(file.name) .. "'! \n" .. tostring(response)) | |
end | |
end | |
do | |
local reason | |
file, reason = io.open(concat(path, file.name), "w") | |
if not (file) then | |
log.fatal("Could not open '" .. tostring(concat(path, file.name)) .. "' for writing: " .. tostring(reason)) | |
end | |
file:write(contents) | |
file:close() | |
end | |
end | |
return { | |
name = pkgData.name, | |
version = tostring(pkgData.version), | |
files = pkgData.files, | |
dependencies = pkgData.dependencies, | |
manual = isManuallyInstalled | |
} | |
end | |
self.save = function(self, name, version) | |
return self:install(name, version, false, true) | |
end | |
self.resolveDependencies = function(self, packages, resolved, unresolved) | |
if resolved == nil then | |
resolved = { } | |
end | |
if unresolved == nil then | |
unresolved = { } | |
end | |
for _index_0 = 1, #packages do | |
local _des_0 = packages[_index_0] | |
local name, version | |
name, version = _des_0.name, _des_0.version | |
insert(unresolved, { | |
name = name, | |
version = "" | |
}) | |
local manifest = loadManifest(name, nil, "hel") | |
if not manifest or not version:match(semver.Version(manifest.version)) then | |
local spec = self:getPackageSpec(name) | |
local data = self:parsePackageJSON(spec, version) | |
unresolved[#unresolved].version = data.version | |
local _list_0 = data.dependencies | |
for _index_1 = 1, #_list_0 do | |
local dep = _list_0[_index_1] | |
local isResolved = false | |
for _index_2 = 1, #resolved do | |
local pkg = resolved[_index_2] | |
if pkg.pkg.name == dep.name then | |
isResolved = true | |
break | |
end | |
end | |
if not isResolved then | |
local key = nil | |
for k, pkg in pairs(unresolved) do | |
if pkg.name == dep.name then | |
key = k | |
break | |
end | |
end | |
if key then | |
if unresolved[key].version == dep.version then | |
log.fatal("Circular dependencies detected: '" .. tostring(name) .. "@" .. tostring(data.version) .. "' depends on '" .. tostring(dep.name) .. "@" .. tostring(dep.version) .. "', and '" .. tostring(unresolved[key].name) .. "@" .. tostring(unresolved[key].version) .. "' depends on '" .. tostring(name) .. "@" .. tostring(data.version) .. "'.") | |
else | |
log.fatal("Attempted to install two versions of the same package: '" .. tostring(dep.name) .. "@" .. tostring(dep.version) .. "' and '" .. tostring(unresolved[key].name) .. "@" .. tostring(unresolved[key].version) .. "' when resolving dependencies for '" .. tostring(name) .. "@" .. tostring(data.version) .. "'.") | |
end | |
end | |
self:resolveDependencies({ | |
{ | |
name = dep.name, | |
version = semver.Spec(dep.version) | |
} | |
}, resolved, unresolved) | |
end | |
end | |
insert(resolved, { | |
pkg = data | |
}) | |
else | |
insert(resolved, { | |
pkg = manifest | |
}) | |
end | |
unresolved[#unresolved] = nil | |
end | |
return resolved | |
end | |
self.getPackageDependants = function(self, name, resolved, unresolved) | |
if resolved == nil then | |
resolved = { } | |
end | |
if unresolved == nil then | |
unresolved = { } | |
end | |
insert(unresolved, { | |
name = name | |
}) | |
local manifest = loadManifest(name, nil, "hel") | |
if manifest then | |
insert(resolved, { | |
name = name, | |
manifest = manifest | |
}) | |
local list = try(listFiles(concat(distPath, "hel"))) | |
for file in list do | |
manifest = try(loadManifest(file, nil, "hel")) | |
local _list_0 = manifest.dependencies | |
for _index_0 = 1, #_list_0 do | |
local dep = _list_0[_index_0] | |
if dep.name == name then | |
local isResolved = false | |
for _index_1 = 1, #resolved do | |
local pkg = resolved[_index_1] | |
if pkg.name == file then | |
isResolved = true | |
break | |
end | |
end | |
if not isResolved then | |
for _index_1 = 1, #unresolved do | |
local pkg = unresolved[_index_1] | |
if pkg.name == file then | |
log.fatal("Circular dependencies detected: " .. tostring(file)) | |
end | |
end | |
self:getPackageDependants(file, resolved, unresolved) | |
end | |
end | |
end | |
end | |
else | |
log.fatal("Package " .. tostring(name) .. " is referenced as a dependant of another package, however, this package isn't installed.") | |
end | |
unresolved[#unresolved] = nil | |
return resolved | |
end | |
self.install = public(function(self, ...) | |
if options.l or options["local"] then | |
local path = shell.resolve(...) | |
local manifest = try(loadManifest(path, concat(path, "manifest"))) | |
local dependencyGraph = self:resolveDependencies(manifest.depends, nil) | |
local onlyDeps = options.d or options.onlyDeps | |
local toInstall = { } | |
for _index_0 = 1, #dependencyGraph do | |
local node = dependencyGraph[_index_0] | |
insert(toInstall, tostring(node.pkg.name) .. "@" .. tostring(node.pkg.version)) | |
end | |
if not (onlyDeps) then | |
insert(toInstall, tostring(manifest.name) .. "@" .. tostring(manifest.version)) | |
end | |
pkgPlan({ | |
install = toInstall | |
}) | |
for i = 1, #dependencyGraph, 1 do | |
local node = dependencyGraph[i] | |
log.print("Installing '" .. tostring(node.pkg.name) .. "@" .. tostring(node.pkg.version) .. "'...") | |
manifest = self:rawInstall(node.pkg, false, false) | |
local success, reason = saveManifest(manifest, "hel") | |
if success then | |
log.info("Saved the manifest of '" .. tostring(manifest.name) .. "'.") | |
else | |
log.fatal("Couldn't save the manifest of '" .. tostring(manifest.name) .. "': " .. tostring(reason) .. ".") | |
end | |
end | |
if not onlyDeps then | |
log.print("Installing '" .. tostring(manifest.name) .. "@" .. tostring(manifest.version) .. "'...") | |
for key, file in pairs(manifest.files) do | |
if not existsDir(concat(file.dir, file.name)) then | |
makeDirectory(file.dir) | |
end | |
local result, reason = copy(concat(path, file.url), concat(file.dir, file.name)) | |
if not (result) then | |
log.fatal("Cannot copy file '" .. tostring(file.name) .. "': " .. tostring(reason)) | |
end | |
end | |
local success, reason = saveManifest(manifest, "hel") | |
if success then | |
log.info("Saved the manifest of '" .. tostring(manifest.name) .. "'.") | |
else | |
log.fatal("Couldn't save the manifest of '" .. tostring(manifest.name) .. "': " .. tostring(reason) .. ".") | |
end | |
end | |
end | |
local packages = { } | |
local _list_0 = { | |
... | |
} | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
local name, version = x:match("(.+)@?(.-)") | |
if empty(version) then | |
version = "*" | |
end | |
log.info("Creating version specification for " .. tostring(version) .. " ...") | |
local success, spec = pcall(function() | |
return semver.Spec(version) | |
end) | |
if not (success) then | |
log.fatal("Could not parse the version specification: " .. tostring(spec) .. "!") | |
end | |
insert(packages, { | |
name = name, | |
version = spec | |
}) | |
end | |
return self:_install(packages, false) | |
end) | |
self._install = function(self, packages, save) | |
if save == nil then | |
save = false | |
end | |
local reinstall = options.r or options.reinstall | |
local dependencyGraph = self:resolveDependencies(packages) | |
local toReinstall = { } | |
local toInstall = { } | |
for _index_0 = 1, #dependencyGraph do | |
local _continue_0 = false | |
repeat | |
local node = dependencyGraph[_index_0] | |
if reinstall then | |
local found = false | |
for _index_1 = 1, #packages do | |
local pkg = packages[_index_1] | |
if pkg.name == node.pkg.name then | |
found = true | |
break | |
end | |
end | |
if found then | |
insert(toReinstall, tostring(node.pkg.name) .. "@" .. tostring(node.pkg.version)) | |
_continue_0 = true | |
break | |
end | |
end | |
insert(toInstall, tostring(node.pkg.name) .. "@" .. tostring(node.pkg.version)) | |
_continue_0 = true | |
until true | |
if not _continue_0 then | |
break | |
end | |
end | |
pkgPlan({ | |
install = toInstall, | |
reinstall = toReinstall | |
}) | |
if reinstall then | |
for _index_0 = 1, #dependencyGraph do | |
local node = dependencyGraph[_index_0] | |
local found = false | |
for _index_1 = 1, #packages do | |
local pkg = packages[_index_1] | |
if pkg.name == node.pkg.name then | |
found = true | |
break | |
end | |
end | |
if found then | |
self:remove(node.pkg, false, true) | |
end | |
end | |
end | |
for _index_0 = 1, #dependencyGraph do | |
local node = dependencyGraph[_index_0] | |
log.print("Installing '" .. tostring(node.pkg.name) .. "@" .. tostring(node.pkg.version) .. "'...") | |
local manifest = self:rawInstall(node.pkg, isin(node.pkg.name, packages), save) | |
local success, reason = saveManifest(manifest, "hel") | |
if success then | |
log.info("Saved the manifest of '" .. tostring(manifest.name) .. "'.") | |
else | |
log.fatal("Couldn't save the manifest of '" .. tostring(manifest.name) .. "': " .. tostring(reason) .. ".") | |
end | |
end | |
end | |
self.remove = function(self, manifest, recursiveCall, noPlan) | |
if recursiveCall == nil then | |
recursiveCall = false | |
end | |
if noPlan == nil then | |
noPlan = false | |
end | |
if recursiveCall then | |
return _class_0.__parent.remove(self, manifest, "hel") | |
end | |
local deps | |
if not config.get("hel", { }, true).get("remove_dependants", true) then | |
deps = { | |
{ | |
name = manifest.name, | |
manifest = manifest | |
} | |
} | |
else | |
deps = self:getPackageDependants(manifest.name) | |
end | |
if not (noPlan) then | |
pkgPlan({ | |
remove = (function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for _index_0 = 1, #deps do | |
local node = deps[_index_0] | |
_accum_0[_len_0] = "hel:" .. tostring(node.manifest.name) .. "@" .. tostring(node.manifest.version) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)() | |
}) | |
end | |
for _index_0 = 1, #deps do | |
local dep = deps[_index_0] | |
log.print("Removing '" .. tostring(dep.manifest.name) .. "@" .. tostring(dep.manifest.version) .. "' ...") | |
try(self:remove(dep.manifest, true)) | |
end | |
return true | |
end | |
self.info = public(function(self, pkg, specString) | |
if specString == nil then | |
specString = "*" | |
end | |
if empty(pkg) then | |
log.fatal("Usage: hpm hel:info <package name> [<version specification>]") | |
end | |
if empty(specString) then | |
specString = "*" | |
end | |
log.print("Creating version specification for " .. tostring(specString) .. " ...") | |
local success, versionSpec = pcall(function() | |
return semver.Spec(specString) | |
end) | |
if not (success) then | |
log.fatal("Could not parse the version specification: " .. tostring(versionSpec) .. "!") | |
end | |
local spec = self:getPackageSpec(pkg) | |
local data = self:parsePackageJSON(spec, versionSpec) | |
local message = { } | |
insert(message, "- Package name: " .. tostring(spec.name)) | |
insert(message, "- Description:\n" .. tostring(spec.description)) | |
insert(message, "- Package owners: " .. tostring(table.concat(spec.owners, ", "))) | |
insert(message, "- Authors:\n" .. tostring(table.concat((function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = spec.authors | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
_accum_0[_len_0] = " - " .. tostring(x) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)(), "\n"))) | |
insert(message, "- License: " .. tostring(spec.license)) | |
insert(message, "- Versions: " .. tostring(tableLen(spec.versions)) .. ", latest: " .. tostring(data.version)) | |
insert(message, " - Files: " .. tostring(#data.files)) | |
insert(message, " - Depends: " .. tostring(table.concat((function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = data.dependencies | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
_accum_0[_len_0] = tostring(x.name) .. "@" .. tostring(x.version) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)()))) | |
insert(message, " - Changes:\n" .. tostring(spec.versions[data.version].changes)) | |
insert(message, "- Stats:") | |
insert(message, " - Views: " .. tostring(spec.stats.views)) | |
insert(message, "- Creation date: " .. tostring(spec.stats.date.created) .. " UTC") | |
insert(message, "- Last updated: " .. tostring(spec.stats.date["last-updated"]) .. " UTC") | |
return log.print(table.concat(message, "\n")) | |
end) | |
if _parent_0.__inherited then | |
_parent_0.__inherited(_parent_0, _class_0) | |
end | |
modules.hel = _class_0 | |
end | |
do | |
local _class_0 | |
local _parent_0 = modules.default | |
local _base_0 = { } | |
_base_0.__index = _base_0 | |
setmetatable(_base_0, _parent_0.__base) | |
_class_0 = setmetatable({ | |
__init = function(self, ...) | |
return _class_0.__parent.__init(self, ...) | |
end, | |
__base = _base_0, | |
__name = "oppm", | |
__parent = _parent_0 | |
}, { | |
__index = function(cls, name) | |
local val = rawget(_base_0, name) | |
if val == nil then | |
local parent = rawget(cls, "__parent") | |
if parent then | |
return parent[name] | |
end | |
else | |
return val | |
end | |
end, | |
__call = function(cls, ...) | |
local _self_0 = setmetatable({}, _base_0) | |
cls.__init(_self_0, ...) | |
return _self_0 | |
end | |
}) | |
_base_0.__class = _class_0 | |
local self = _class_0 | |
self.REPOS = "https://raw.githubusercontent.com/OpenPrograms/openprograms.github.io/master/repos.cfg" | |
self.PACKAGES = "https://raw.githubusercontent.com/%s/master/programs.cfg" | |
self.FILES = "https://raw.githubusercontent.com/%s/%s" | |
self.DIRECTORY = "https://api.github.com/repos/%s/contents/%s?ref=%s" | |
self.DEFAULT_CACHE_DIRECTORY = "/var/cache/hpm/oppm" | |
self.cacheDirectory = function(self) | |
local dir = config.get("oppm", { }, true).get("cache_directory", self.DEFAULT_CACHE_DIRECTORY) | |
if not (existsDir(dir)) then | |
local result, reason = makeDirectory(dir) | |
if not (result) then | |
log.fatal("Could not create the cache directory at " .. tostring(dir) .. ": " .. tostring(reason)) | |
end | |
end | |
return dir | |
end | |
self.listCache = function(self) | |
local list = { } | |
local cacheDir = self:cacheDirectory() | |
local dirs = try(listFiles(cacheDir)) | |
for dir in dirs do | |
if isDirectory(concat(cacheDir, dir)) then | |
local subdirs = try(listFiles(concat(cacheDir, dir))) | |
for subdir in subdirs do | |
if isDirectory(concat(cacheDir, dir, subdir)) then | |
local pkgs = try(listFiles(concat(cacheDir, dir, subdir))) | |
for pkg in pkgs do | |
local fullPath = concat(cacheDir, dir, subdir, pkg) | |
if not (isDirectory(fullPath)) then | |
local data | |
do | |
local file, reason = io.open(fullPath, "r") | |
if not file then | |
return false, "Could not open '" .. tostring(fullPath) .. "' for reading: " .. tostring(reason) | |
end | |
all = file:read("*all") | |
data = unserialize(all) | |
file:close() | |
end | |
local repo = concat(dir, subdir) | |
insert(list, { | |
path = fullPath, | |
repo = repo, | |
pkg = pkg, | |
data = data | |
}) | |
end | |
end | |
end | |
end | |
end | |
end | |
return list | |
end | |
self.fixCache = function(self) | |
local cacheDir = self:cacheDirectory() | |
local dirs = try(listFiles(cacheDir)) | |
for dir in dirs do | |
local removeDir = true | |
local pathDir = concat(cacheDir, dir) | |
if isDirectory(pathDir) then | |
local subdirs = try(listFiles(pathDir)) | |
for subdir in subdirs do | |
local removeSubdir = true | |
local pathSubdir = concat(pathDir, subdir) | |
if isDirectory(pathSubdir) then | |
local pkgs = try(listFiles(pathSubdir)) | |
for pkg in pkgs do | |
local removePkg = true | |
local pathPkg = concat(pathSubdir, pkg) | |
if not (isDirectory(pathPkg)) then | |
removePkg, removeSubdir, removeDir = false, false, false | |
end | |
if removePkg then | |
remove(pathPkg) | |
end | |
end | |
end | |
if removeSubdir then | |
remove(pathSubdir) | |
end | |
end | |
end | |
if removeDir then | |
remove(pathDir) | |
end | |
end | |
return true | |
end | |
self.resolveDirectory = function(self, repo, branch, path) | |
local data = try(recv(self.DIRECTORY:format(repo, path, branch))) | |
data = json:decode(data) | |
if data.message then | |
return false, "Could not fetch " .. tostring(repo) .. ":" .. tostring(branch) .. "/" .. tostring(path) .. ": " .. tostring(data.message) | |
end | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for _index_0 = 1, #data do | |
local file = data[_index_0] | |
if file.type == "file" then | |
_accum_0[_len_0] = { | |
name = file.name, | |
url = file.download_url, | |
path = file.path | |
} | |
_len_0 = _len_0 + 1 | |
end | |
end | |
return _accum_0 | |
end | |
self.updateCache = function(self) | |
local cacheDir = self:cacheDirectory() | |
local oldFiles = try(self:listCache()) | |
local repos, reason = recv(self.REPOS) | |
if not (repos) then | |
return false, "Could not fetch " .. tostring(self.REPOS) .. ": " .. tostring(reason) | |
end | |
repos = unserialize(repos) | |
local programs = { } | |
for repo, repoData in pairs(repos) do | |
local _continue_0 = false | |
repeat | |
if repoData.repo then | |
log.info("Fetching '" .. tostring(repo) .. "' at '" .. tostring(repoData.repo) .. "' ...") | |
local result, response | |
result, response, reason = download(self.PACKAGES:format(repoData.repo)) | |
if not (result and response) then | |
log.error("Could not fetch '" .. tostring(repo) .. "' at '" .. tostring(repoData.repo) .. "': " .. tostring(reason)) | |
_continue_0 = true | |
break | |
end | |
local data = "" | |
for result, chunk in function() | |
return pcall(response) | |
end do | |
if not result then | |
log.error("Could not fetch '" .. tostring(repo) .. "' at '" .. tostring(repoData.repo) .. "': " .. tostring(chunk)) | |
data = false | |
break | |
else | |
if not chunk then | |
break | |
end | |
data = data .. chunk | |
end | |
end | |
if data == false then | |
_continue_0 = true | |
break | |
end | |
if empty(data) then | |
log.error("Could not fetch '" .. tostring(repo) .. "' at '" .. tostring(repoData.repo) .. "'") | |
_continue_0 = true | |
break | |
end | |
local repoPrograms | |
repoPrograms, reason = unserialize(data) | |
if not repoPrograms then | |
log.error("Manifest '" .. tostring(repo) .. "' at '" .. tostring(repoData.repo) .. "' is malformed: " .. tostring(reason)) | |
_continue_0 = true | |
break | |
end | |
for prg, prgData in pairs(repoPrograms) do | |
local _continue_1 = false | |
repeat | |
if prg:match("[^A-Za-z0-9._-]") then | |
log.error("Package name contains illegal characters: " .. tostring(repo) .. ":" .. tostring(prg) .. "!") | |
_continue_1 = true | |
break | |
end | |
insert(programs, { | |
repo = repoData.repo, | |
name = prg, | |
data = prgData | |
}) | |
_continue_1 = true | |
until true | |
if not _continue_1 then | |
break | |
end | |
end | |
end | |
_continue_0 = true | |
until true | |
if not _continue_0 then | |
break | |
end | |
end | |
local newFiles = { } | |
for _index_0 = 1, #programs do | |
local _des_0 = programs[_index_0] | |
local name, repo, data | |
name, repo, data = _des_0.name, _des_0.repo, _des_0.data | |
if isin(concat(repo, name), newFiles) then | |
log.error("There're multiple packages under the same name: " .. tostring(name) .. "!") | |
end | |
if not (existsDir(concat(cacheDir, repo))) then | |
local result | |
result, reason = makeDirectory(concat(cacheDir, repo)) | |
if not (result) then | |
return false, "Could not create directory '" .. tostring(concat(cacheDir, repo)) .. "': " .. tostring(reason) | |
end | |
end | |
local file | |
file, reason = io.open(concat(cacheDir, repo, name), "w") | |
if not (file) then | |
return false, "Could not open '" .. tostring(concat(cacheDir, repo, name)) .. "' for writing: " .. tostring(reason) | |
end | |
do | |
file:write(serialize({ | |
name = name, | |
repo = repo, | |
data = data | |
})) | |
file:close() | |
end | |
local k | |
do | |
for key, v in pairs(oldFiles) do | |
if v.repo == repo and v.pkg == name then | |
k = key | |
break | |
end | |
end | |
end | |
if k then | |
table.remove(oldFiles, k) | |
else | |
insert(newFiles, concat(repo, name)) | |
end | |
end | |
log.print("Removing old cache files ...") | |
for _index_0 = 1, #oldFiles do | |
local _des_0 = oldFiles[_index_0] | |
local path | |
path = _des_0.path | |
remove(path) | |
end | |
log.print("Fixing bad cache nodes ...") | |
self:fixCache() | |
log.print("- " .. tostring(#programs) .. " program" .. tostring(plural(#programs)) .. " cached.") | |
log.print("- " .. tostring(#newFiles) .. " package" .. tostring(plural(#newFiles)) .. " " .. tostring(linkingVerb(#newFiles)) .. " new.") | |
log.print("- " .. tostring(#oldFiles) .. " package" .. tostring(plural(#oldFiles)) .. " no longer exist" .. tostring(singular(#oldFiles)) .. ".") | |
return true | |
end | |
self.parseLocalPath = function(self, prefix, lPath) | |
if lPath:sub(1, 2) == "//" then | |
return concat(prefix, lPath:sub(3)) | |
else | |
return concat(prefix, "usr", lPath) | |
end | |
end | |
self.rawInstall = function(self, name, prefix, isManuallyInstalled, save) | |
if prefix == nil then | |
prefix = "/" | |
end | |
if isManuallyInstalled == nil then | |
isManuallyInstalled = false | |
end | |
if save == nil then | |
save = false | |
end | |
local cacheList = self:listCache() | |
local stats = { | |
filesInstalled = 0, | |
packagesInstalled = 0 | |
} | |
if save and not existsDir(prefix) then | |
local result, reason = makeDirectory(prefix) | |
if not (result) then | |
log.fatal("Failed to create '" .. tostring(prefix) .. "' directory for package '" .. tostring(name) .. "'! \n" .. tostring(reason)) | |
end | |
elseif not save then | |
local manifest = loadManifest(name, nil, "oppm") | |
if manifest then | |
log.print("'" .. tostring(name) .. "' is already installed, skipping...") | |
return manifest, stats | |
end | |
end | |
local manifest | |
for _index_0 = 1, #cacheList do | |
local package = cacheList[_index_0] | |
local path, pkg, repo, data | |
path, pkg, repo, data = package.path, package.pkg, package.repo, package.data | |
if pkg == name then | |
manifest = package | |
break | |
end | |
end | |
if not (manifest) then | |
log.fatal("No such package: " .. tostring(name)) | |
end | |
local files = { } | |
local repo = manifest.repo | |
for rPath, lPath in pairs(manifest.data.data.files) do | |
local rFiles = { } | |
if rPath:sub(1, 1) == ":" then | |
rFiles = self:resolveDirectory(repo, rPath:sub(2, rPath:find("/") - 1, nil), rPath:sub(rPath:find("/") + 1)) | |
else | |
rFiles = { | |
{ | |
name = fs.name(rPath), | |
path = rPath, | |
url = self.FILES:format(repo, rPath) | |
} | |
} | |
end | |
local name | |
for _index_0 = 1, #rFiles do | |
local _des_0 = rFiles[_index_0] | |
local path, url | |
name, path, url = _des_0.name, _des_0.path, _des_0.url | |
local contents = try(recv(url)) | |
local localPath = self:parseLocalPath(prefix, lPath) | |
if not (existsDir(localPath)) then | |
makeDirectory(localPath) | |
end | |
do | |
local file, reason = io.open(concat(localPath, name), "w") | |
if not file then | |
log.fatal("Could not open file for writing: " .. tostring(reason)) | |
end | |
file:write(contents) | |
file:close() | |
end | |
stats.filesInstalled = stats.filesInstalled + 1 | |
insert(files, { | |
name = name, | |
url = url, | |
dir = localPath | |
}) | |
end | |
end | |
local dependencies = { } | |
if manifest.data.data.dependencies then | |
for dep in pairs(manifest.data.data.dependencies) do | |
insert(dependencies, { | |
name = dep | |
}) | |
end | |
end | |
stats.packagesInstalled = stats.packagesInstalled + 1 | |
return { | |
name = name, | |
files = files, | |
dependencies = dependencies, | |
manual = isManuallyInstalled | |
}, stats | |
end | |
self.resolveDependencies = function(self, name, resolved, unresolved) | |
if resolved == nil then | |
resolved = { } | |
end | |
if unresolved == nil then | |
unresolved = { } | |
end | |
local cacheList = self:listCache() | |
unresolved[name] = true | |
local manifest = loadManifest(name, nil, "oppm") | |
if not manifest then | |
local data | |
for _index_0 = 1, #cacheList do | |
local package = cacheList[_index_0] | |
local pkg | |
pkg = package.pkg | |
if pkg == name then | |
data = package | |
break | |
end | |
end | |
if not (data) then | |
return false, "Unknown package: " .. tostring(name) | |
end | |
if data.data.data.dependencies then | |
for dep in pairs(data.data.data.dependencies) do | |
local isResolved = false | |
for _index_0 = 1, #resolved do | |
local pkg = resolved[_index_0] | |
if pkg == dep then | |
isResolved = true | |
break | |
end | |
end | |
if not (isResolved) then | |
if unresolved[dep] then | |
log.fatal("Circular dependencies detected: '" .. tostring(name) .. "' depends on '" .. tostring(dep) .. "', and '" .. tostring(dep) .. "' depends on '" .. tostring(name) .. "'.") | |
end | |
self:resolveDependencies(dep, resolved, unresolved) | |
end | |
end | |
end | |
insert(resolved, name) | |
else | |
insert(resolved, name) | |
end | |
unresolved[name] = nil | |
return resolved | |
end | |
self.getPackageDependants = function(self, name, resolved, unresolved) | |
if resolved == nil then | |
resolved = { } | |
end | |
if unresolved == nil then | |
unresolved = { } | |
end | |
insert(unresolved, { | |
name = name | |
}) | |
local manifest = loadManifest(name, nil, "oppm") | |
if manifest then | |
insert(resolved, { | |
name = name, | |
manifest = manifest | |
}) | |
local list = try(listFiles(concat(distPath, "oppm"))) | |
for file in list do | |
manifest = try(loadManifest(file, nil, "oppm")) | |
local _list_0 = manifest.dependencies | |
for _index_0 = 1, #_list_0 do | |
local dep = _list_0[_index_0] | |
if dep.name == name then | |
local isResolved = false | |
for _index_1 = 1, #resolved do | |
local pkg = resolved[_index_1] | |
if pkg.name == file then | |
isResolved = true | |
break | |
end | |
end | |
if not isResolved then | |
for _index_1 = 1, #unresolved do | |
local pkg = unresolved[_index_1] | |
if pkg.name == file then | |
log.fatal("Circular dependencies detected: " .. tostring(file)) | |
end | |
end | |
self:getPackageDependants(file, resolved, unresolved) | |
end | |
end | |
end | |
end | |
else | |
log.fatal("Package " .. tostring(name) .. " is referenced as a dependant of another package, however, this package isn't installed.") | |
end | |
unresolved[#unresolved] = nil | |
return resolved | |
end | |
self.whatDependsOn = function(self, name) | |
local manifest = try(loadManifest(name, nil, "oppm")) | |
local result = { } | |
local list = try(listFiles(concat(distPath, "oppm"))) | |
for file in list do | |
manifest = try(loadManifest(file, nil, "oppm")) | |
local _list_0 = manifest.dependencies | |
for _index_0 = 1, #_list_0 do | |
local dep = _list_0[_index_0] | |
if dep.name == name then | |
insert(result, file) | |
end | |
end | |
end | |
return result | |
end | |
self._install = function(self, name, meta, reinstall, save) | |
if reinstall == nil then | |
reinstall = false | |
end | |
if save == nil then | |
save = false | |
end | |
local dependencyGraph = try(self:resolveDependencies(name)) | |
pkgPlan({ | |
install = (function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for _index_0 = 1, #dependencyGraph do | |
local node = dependencyGraph[_index_0] | |
if not reinstall or node ~= name then | |
_accum_0[_len_0] = "oppm:" .. tostring(node) | |
_len_0 = _len_0 + 1 | |
end | |
end | |
return _accum_0 | |
end)(), | |
reinstall = reinstall and { | |
"oppm:" .. tostring(name) | |
} or nil | |
}) | |
local manifests = { } | |
local stats = { | |
filesInstalled = 0, | |
packagesInstalled = 0 | |
} | |
if reinstall then | |
local manifest = try(loadManifest(name, nil, "oppm")) | |
self:remove(manifest, false, true) | |
end | |
for _index_0 = 1, #dependencyGraph do | |
local node = dependencyGraph[_index_0] | |
log.print("Installing '" .. tostring(node) .. "'...") | |
local prefix | |
if save then | |
prefix = "./" .. tostring(node) .. "/" | |
else | |
prefix = "/" | |
end | |
local manifest, statsPart = self:rawInstall(node, prefix, node == name, save) | |
stats.filesInstalled = stats.filesInstalled + statsPart.filesInstalled | |
stats.packagesInstalled = stats.packagesInstalled + statsPart.packagesInstalled | |
if stats.packagesInstalled ~= 0 then | |
insert(manifests, manifest) | |
end | |
end | |
log.print("- " .. tostring(stats.packagesInstalled) .. " package" .. tostring(plural(stats.packagesInstalled)) .. " installed.") | |
log.print("- " .. tostring(stats.filesInstalled) .. " file" .. tostring(plural(stats.filesInstalled)) .. " installed.") | |
return manifests | |
end | |
self.remove = function(self, manifest, recursiveCall, noPlan) | |
if recursiveCall == nil then | |
recursiveCall = false | |
end | |
if noPlan == nil then | |
noPlan = false | |
end | |
if recursiveCall then | |
return _class_0.__parent.remove(self, manifest, "oppm") | |
end | |
local deps | |
if not config.get("oppm", { }, true).get("remove_dependants", true) then | |
deps = { | |
{ | |
name = manifest.name, | |
manifest = manifest | |
} | |
} | |
else | |
deps = self:getPackageDependants(manifest.name) | |
end | |
if not (noPlan) then | |
pkgPlan({ | |
remove = (function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for _index_0 = 1, #deps do | |
local node = deps[_index_0] | |
_accum_0[_len_0] = "oppm:" .. tostring(node.name) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)() | |
}) | |
end | |
for _index_0 = 1, #deps do | |
local dep = deps[_index_0] | |
log.print("Removing '" .. tostring(dep.manifest.name) .. "' ...") | |
try(self:remove(dep.manifest, true)) | |
end | |
return true | |
end | |
self.save = function(self, name, meta) | |
return self:install(name, meta, false, true) | |
end | |
self.cache = public(function(self, command, ...) | |
local _exp_0 = command | |
if "update" == _exp_0 then | |
log.print("Updating OpenPrograms program cache ...") | |
try(self:updateCache()) | |
return log.print("Done.") | |
elseif "fix" == _exp_0 then | |
log.print("Fixing OpenPrograms program cache ...") | |
try(self:fixCache()) | |
return log.print("Done.") | |
else | |
log.error("Unknown command.") | |
return log.print("Usage: hpm oppm:cache {update|fix}") | |
end | |
end) | |
self.autoremove = public(function(self) | |
local toRemove = { } | |
local sorted = { } | |
local list = try(listFiles(concat(distPath, "oppm"))) | |
for file in list do | |
local manifest = try(loadManifest(file, nil, "oppm")) | |
if not (manifest.manual) then | |
local deps = self:getPackageDependants(file) | |
if #deps == 1 then | |
insert(toRemove, file) | |
insert(sorted, file) | |
end | |
end | |
end | |
while true do | |
local changed = false | |
list = try(listFiles(concat(distPath, "oppm"))) | |
for file in list do | |
if not (isin(file, toRemove)) then | |
local manifest = try(loadManifest(file, nil, "oppm")) | |
if not (manifest.manual) then | |
local deps = self:getPackageDependants(file) | |
table.remove(deps, 1) | |
if all((function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for _index_0 = 1, #deps do | |
local x = deps[_index_0] | |
_accum_0[_len_0] = isin(x.name, toRemove) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)()) then | |
for _index_0 = 1, #deps do | |
local dep = deps[_index_0] | |
local _, k = isin(dep.name, sorted) | |
if k then | |
table.remove(sorted, k) | |
end | |
end | |
insert(toRemove, file) | |
insert(sorted, file) | |
changed = true | |
end | |
end | |
end | |
end | |
if not (changed) then | |
break | |
end | |
end | |
pkgPlan({ | |
remove = (function() | |
if #toRemove > 0 then | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for _index_0 = 1, #toRemove do | |
local name = toRemove[_index_0] | |
_accum_0[_len_0] = "oppm:" .. tostring(name) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
else | |
return nil | |
end | |
end)() | |
}) | |
for _index_0 = 1, #sorted do | |
local name = sorted[_index_0] | |
self:remove(try(loadManifest(name, nil, "oppm")), false, false) | |
end | |
log.print("Done.") | |
return true | |
end) | |
if _parent_0.__inherited then | |
_parent_0.__inherited(_parent_0, _class_0) | |
end | |
modules.oppm = _class_0 | |
end | |
local removePackage | |
removePackage = function(source, name) | |
if not (name) then | |
log.fatal("Incorrect package name!") | |
end | |
if empty(source) then | |
source = "hel" | |
end | |
local manifest = try(loadManifest(name, nil, source)) | |
return try(callModuleMethod(getModuleBy(source), "remove", manifest)) | |
end | |
local installPackage | |
installPackage = function(source, name, meta) | |
if not (name) then | |
log.fatal("Incorrect package name!") | |
end | |
if empty(source) then | |
source = "hel" | |
end | |
local reinstallFlag = false | |
local manifest = loadManifest(name, nil, source) | |
if manifest then | |
if not options.r then | |
log.print("'" .. tostring(name) .. "' is already installed, skipping...") | |
return | |
else | |
reinstallFlag = true | |
end | |
end | |
local result, reason = callModuleMethod(getModuleBy(source), "install", name, meta, reinstallFlag) | |
if result then | |
for _index_0 = 1, #result do | |
local manifest = result[_index_0] | |
local success | |
success, reason = saveManifest(manifest, source) | |
if success then | |
log.info("Saved the manifest for '" .. tostring(manifest.name) .. "' package.") | |
else | |
log.error("Couldn't save the manifest for '" .. tostring(name) .. "' package: " .. tostring(reason) .. ".") | |
end | |
end | |
else | |
return log.error("Couldn't install package: " .. tostring(reason)) | |
end | |
end | |
local savePackage | |
savePackage = function(source, name, meta) | |
if not (name) then | |
log.fatal("Incorrect package name!") | |
end | |
if empty(source) then | |
source = "hel" | |
end | |
if source == "local" then | |
log.fatal("No need to save already saved package...") | |
end | |
local result, reason = callModuleMethod(getModuleBy(source), "save", name, meta) | |
if result then | |
for _index_0 = 1, #result do | |
local manifest = result[_index_0] | |
local success | |
success, reason = saveManifest(manifest, "", "./" .. tostring(manifest.name) .. "/", "manifest") | |
if success then | |
log.info("Saved the manifest for local '" .. tostring(name) .. "' package.") | |
else | |
log.error("Couldn't save manifest for local '" .. tostring(name) .. "' package: " .. tostring(reason) .. ".") | |
end | |
end | |
else | |
return log.error("Couldn't install package: " .. tostring(reason) .. ".") | |
end | |
end | |
local printPackageList | |
printPackageList = function() | |
local modList = try(listFiles(distPath)) | |
empty = true | |
for modDir in modList do | |
local mod = fs.name(modDir) | |
if isDirectory(concat(distPath, mod)) then | |
local list = try(listFiles(concat(distPath, mod))) | |
for file in list do | |
if not (isDirectory(concat(distPath, mod, file))) then | |
local manifest = try(loadManifest(file, nil, mod)) | |
log.print(mod .. ":" .. file .. (manifest.version and " @ " .. manifest.version or "")) | |
empty = false | |
end | |
end | |
end | |
end | |
if empty then | |
return log.print("No packages installed.") | |
end | |
end | |
local parseArguments | |
parseArguments = function(...) | |
args, options = parse(...) | |
if #args < 1 then | |
return printUsage() | |
end | |
end | |
local process | |
process = function() | |
local _exp_0 = args[1] | |
if "save" == _exp_0 then | |
if #args < 2 then | |
log.fatal("No package(s) provided!") | |
end | |
for i = 2, #args do | |
savePackage(parsePackageName(args[i])) | |
end | |
elseif "remove" == _exp_0 then | |
if #args < 2 then | |
log.fatal("No package(s) provided!") | |
end | |
for i = 2, #args do | |
removePackage(parsePackageName(args[i])) | |
end | |
elseif "list" == _exp_0 then | |
return printPackageList() | |
elseif "help" == _exp_0 then | |
return printUsage() | |
else | |
do | |
local cmd = findCustomCommand(args[1]) | |
if cmd then | |
return cmd(unpack((function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for _index_0 = 2, #args do | |
local x = args[_index_0] | |
_accum_0[_len_0] = x | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)())) | |
end | |
end | |
end | |
end | |
parseArguments(...) | |
try(loadConfig()) | |
loadCustomModules() | |
process() | |
return exitCode |
local json = load([===[ | |
-- -*- coding: utf-8 -*- | |
-- | |
-- Simple JSON encoding and decoding in pure Lua. | |
-- | |
-- Copyright 2010-2016 Jeffrey Friedl | |
-- http://regex.info/blog/ | |
-- Latest version: http://regex.info/blog/lua/json | |
-- | |
-- This code is released under a Creative Commons CC-BY "Attribution" License: | |
-- http://creativecommons.org/licenses/by/3.0/deed.en_US | |
-- | |
-- It can be used for any purpose so long as the copyright notice above, | |
-- the web-page links above, and the 'AUTHOR_NOTE' string below are | |
-- maintained. Enjoy. | |
-- | |
local VERSION = 20160728.17 -- version history at end of file | |
local AUTHOR_NOTE = "-[ JSON.lua package by Jeffrey Friedl (http://regex.info/blog/lua/json) version 20160728.17 ]-" | |
-- | |
-- The 'AUTHOR_NOTE' variable exists so that information about the source | |
-- of the package is maintained even in compiled versions. It's also | |
-- included in OBJDEF below mostly to quiet warnings about unused variables. | |
-- | |
local OBJDEF = { | |
VERSION = VERSION, | |
AUTHOR_NOTE = AUTHOR_NOTE, | |
} | |
-- | |
-- Simple JSON encoding and decoding in pure Lua. | |
-- JSON definition: http://www.json.org/ | |
-- | |
-- | |
-- JSON = assert(loadfile "JSON.lua")() -- one-time load of the routines | |
-- | |
-- local lua_value = JSON:decode(raw_json_text) | |
-- | |
-- local raw_json_text = JSON:encode(lua_table_or_value) | |
-- local pretty_json_text = JSON:encode_pretty(lua_table_or_value) -- "pretty printed" version for human readability | |
-- | |
-- | |
-- | |
-- DECODING (from a JSON string to a Lua table) | |
-- | |
-- | |
-- JSON = assert(loadfile "JSON.lua")() -- one-time load of the routines | |
-- | |
-- local lua_value = JSON:decode(raw_json_text) | |
-- | |
-- If the JSON text is for an object or an array, e.g. | |
-- { "what": "books", "count": 3 } | |
-- or | |
-- [ "Larry", "Curly", "Moe" ] | |
-- | |
-- the result is a Lua table, e.g. | |
-- { what = "books", count = 3 } | |
-- or | |
-- { "Larry", "Curly", "Moe" } | |
-- | |
-- | |
-- The encode and decode routines accept an optional second argument, | |
-- "etc", which is not used during encoding or decoding, but upon error | |
-- is passed along to error handlers. It can be of any type (including nil). | |
-- | |
-- | |
-- | |
-- ERROR HANDLING | |
-- | |
-- With most errors during decoding, this code calls | |
-- | |
-- JSON:onDecodeError(message, text, location, etc) | |
-- | |
-- with a message about the error, and if known, the JSON text being | |
-- parsed and the byte count where the problem was discovered. You can | |
-- replace the default JSON:onDecodeError() with your own function. | |
-- | |
-- The default onDecodeError() merely augments the message with data | |
-- about the text and the location if known (and if a second 'etc' | |
-- argument had been provided to decode(), its value is tacked onto the | |
-- message as well), and then calls JSON.assert(), which itself defaults | |
-- to Lua's built-in assert(), and can also be overridden. | |
-- | |
-- For example, in an Adobe Lightroom plugin, you might use something like | |
-- | |
-- function JSON:onDecodeError(message, text, location, etc) | |
-- LrErrors.throwUserError("Internal Error: invalid JSON data") | |
-- end | |
-- | |
-- or even just | |
-- | |
-- function JSON.assert(message) | |
-- LrErrors.throwUserError("Internal Error: " .. message) | |
-- end | |
-- | |
-- If JSON:decode() is passed a nil, this is called instead: | |
-- | |
-- JSON:onDecodeOfNilError(message, nil, nil, etc) | |
-- | |
-- and if JSON:decode() is passed HTML instead of JSON, this is called: | |
-- | |
-- JSON:onDecodeOfHTMLError(message, text, nil, etc) | |
-- | |
-- The use of the fourth 'etc' argument allows stronger coordination | |
-- between decoding and error reporting, especially when you provide your | |
-- own error-handling routines. Continuing with the the Adobe Lightroom | |
-- plugin example: | |
-- | |
-- function JSON:onDecodeError(message, text, location, etc) | |
-- local note = "Internal Error: invalid JSON data" | |
-- if type(etc) = 'table' and etc.photo then | |
-- note = note .. " while processing for " .. etc.photo:getFormattedMetadata('fileName') | |
-- end | |
-- LrErrors.throwUserError(note) | |
-- end | |
-- | |
-- : | |
-- : | |
-- | |
-- for i, photo in ipairs(photosToProcess) do | |
-- : | |
-- : | |
-- local data = JSON:decode(someJsonText, { photo = photo }) | |
-- : | |
-- : | |
-- end | |
-- | |
-- | |
-- | |
-- | |
-- | |
-- DECODING AND STRICT TYPES | |
-- | |
-- Because both JSON objects and JSON arrays are converted to Lua tables, | |
-- it's not normally possible to tell which original JSON type a | |
-- particular Lua table was derived from, or guarantee decode-encode | |
-- round-trip equivalency. | |
-- | |
-- However, if you enable strictTypes, e.g. | |
-- | |
-- JSON = assert(loadfile "JSON.lua")() --load the routines | |
-- JSON.strictTypes = true | |
-- | |
-- then the Lua table resulting from the decoding of a JSON object or | |
-- JSON array is marked via Lua metatable, so that when re-encoded with | |
-- JSON:encode() it ends up as the appropriate JSON type. | |
-- | |
-- (This is not the default because other routines may not work well with | |
-- tables that have a metatable set, for example, Lightroom API calls.) | |
-- | |
-- | |
-- ENCODING (from a lua table to a JSON string) | |
-- | |
-- JSON = assert(loadfile "JSON.lua")() -- one-time load of the routines | |
-- | |
-- local raw_json_text = JSON:encode(lua_table_or_value) | |
-- local pretty_json_text = JSON:encode_pretty(lua_table_or_value) -- "pretty printed" version for human readability | |
-- local custom_pretty = JSON:encode(lua_table_or_value, etc, { pretty = true, indent = "| ", align_keys = false }) | |
-- | |
-- On error during encoding, this code calls: | |
-- | |
-- JSON:onEncodeError(message, etc) | |
-- | |
-- which you can override in your local JSON object. | |
-- | |
-- The 'etc' in the error call is the second argument to encode() | |
-- and encode_pretty(), or nil if it wasn't provided. | |
-- | |
-- | |
-- ENCODING OPTIONS | |
-- | |
-- An optional third argument, a table of options, can be provided to encode(). | |
-- | |
-- encode_options = { | |
-- -- options for making "pretty" human-readable JSON (see "PRETTY-PRINTING" below) | |
-- pretty = true, | |
-- indent = " ", | |
-- align_keys = false, | |
-- | |
-- -- other output-related options | |
-- null = "\0", -- see "ENCODING JSON NULL VALUES" below | |
-- stringsAreUtf8 = false, -- see "HANDLING UNICODE LINE AND PARAGRAPH SEPARATORS FOR JAVA" below | |
-- } | |
-- | |
-- json_string = JSON:encode(mytable, etc, encode_options) | |
-- | |
-- | |
-- | |
-- For reference, the defaults are: | |
-- | |
-- pretty = false | |
-- null = nil, | |
-- stringsAreUtf8 = false, | |
-- | |
-- | |
-- | |
-- PRETTY-PRINTING | |
-- | |
-- Enabling the 'pretty' encode option helps generate human-readable JSON. | |
-- | |
-- pretty = JSON:encode(val, etc, { | |
-- pretty = true, | |
-- indent = " ", | |
-- align_keys = false, | |
-- }) | |
-- | |
-- encode_pretty() is also provided: it's identical to encode() except | |
-- that encode_pretty() provides a default options table if none given in the call: | |
-- | |
-- { pretty = true, align_keys = false, indent = " " } | |
-- | |
-- For example, if | |
-- | |
-- JSON:encode(data) | |
-- | |
-- produces: | |
-- | |
-- {"city":"Kyoto","climate":{"avg_temp":16,"humidity":"high","snowfall":"minimal"},"country":"Japan","wards":11} | |
-- | |
-- then | |
-- | |
-- JSON:encode_pretty(data) | |
-- | |
-- produces: | |
-- | |
-- { | |
-- "city": "Kyoto", | |
-- "climate": { | |
-- "avg_temp": 16, | |
-- "humidity": "high", | |
-- "snowfall": "minimal" | |
-- }, | |
-- "country": "Japan", | |
-- "wards": 11 | |
-- } | |
-- | |
-- The following three lines return identical results: | |
-- JSON:encode_pretty(data) | |
-- JSON:encode_pretty(data, nil, { pretty = true, align_keys = false, indent = " " }) | |
-- JSON:encode (data, nil, { pretty = true, align_keys = false, indent = " " }) | |
-- | |
-- An example of setting your own indent string: | |
-- | |
-- JSON:encode_pretty(data, nil, { pretty = true, indent = "| " }) | |
-- | |
-- produces: | |
-- | |
-- { | |
-- | "city": "Kyoto", | |
-- | "climate": { | |
-- | | "avg_temp": 16, | |
-- | | "humidity": "high", | |
-- | | "snowfall": "minimal" | |
-- | }, | |
-- | "country": "Japan", | |
-- | "wards": 11 | |
-- } | |
-- | |
-- An example of setting align_keys to true: | |
-- | |
-- JSON:encode_pretty(data, nil, { pretty = true, indent = " ", align_keys = true }) | |
-- | |
-- produces: | |
-- | |
-- { | |
-- "city": "Kyoto", | |
-- "climate": { | |
-- "avg_temp": 16, | |
-- "humidity": "high", | |
-- "snowfall": "minimal" | |
-- }, | |
-- "country": "Japan", | |
-- "wards": 11 | |
-- } | |
-- | |
-- which I must admit is kinda ugly, sorry. This was the default for | |
-- encode_pretty() prior to version 20141223.14. | |
-- | |
-- | |
-- HANDLING UNICODE LINE AND PARAGRAPH SEPARATORS FOR JAVA | |
-- | |
-- If the 'stringsAreUtf8' encode option is set to true, consider Lua strings not as a sequence of bytes, | |
-- but as a sequence of UTF-8 characters. | |
-- | |
-- Currently, the only practical effect of setting this option is that Unicode LINE and PARAGRAPH | |
-- separators, if found in a string, are encoded with a JSON escape instead of being dumped as is. | |
-- The JSON is valid either way, but encoding this way, apparently, allows the resulting JSON | |
-- to also be valid Java. | |
-- | |
-- AMBIGUOUS SITUATIONS DURING THE ENCODING | |
-- | |
-- During the encode, if a Lua table being encoded contains both string | |
-- and numeric keys, it fits neither JSON's idea of an object, nor its | |
-- idea of an array. To get around this, when any string key exists (or | |
-- when non-positive numeric keys exist), numeric keys are converted to | |
-- strings. | |
-- | |
-- For example, | |
-- JSON:encode({ "one", "two", "three", SOMESTRING = "some string" })) | |
-- produces the JSON object | |
-- {"1":"one","2":"two","3":"three","SOMESTRING":"some string"} | |
-- | |
-- To prohibit this conversion and instead make it an error condition, set | |
-- JSON.noKeyConversion = true | |
-- | |
-- | |
-- ENCODING JSON NULL VALUES | |
-- | |
-- Lua tables completely omit keys whose value is nil, so without special handling there's | |
-- no way to get a field in a JSON object with a null value. For example | |
-- JSON:encode({ username = "admin", password = nil }) | |
-- produces | |
-- {"username":"admin"} | |
-- | |
-- In order to actually produce | |
-- {"username":"admin", "password":null} | |
-- one can include a string value for a "null" field in the options table passed to encode().... | |
-- any Lua table entry with that value becomes null in the JSON output: | |
-- JSON:encode({ username = "admin", password = "xyzzy" }, nil, { null = "xyzzy" }) | |
-- produces | |
-- {"username":"admin", "password":null} | |
-- | |
-- Just be sure to use a string that is otherwise unlikely to appear in your data. | |
-- The string "\0" (a string with one null byte) may well be appropriate for many applications. | |
-- | |
-- The "null" options also applies to Lua tables that become JSON arrays. | |
-- JSON:encode({ "one", "two", nil, nil }) | |
-- produces | |
-- ["one","two"] | |
-- while | |
-- NULL = "\0" | |
-- JSON:encode({ "one", "two", NULL, NULL}, nil, { null = NULL }) | |
-- produces | |
-- ["one","two",null,null] | |
-- | |
-- | |
-- HANDLING LARGE AND/OR PRECISE NUMBERS | |
-- | |
-- Without special handling, numbers in JSON can lose precision in Lua. | |
-- For example: | |
-- | |
-- T = JSON:decode('{ "small":12345, "big":12345678901234567890123456789, "precise":9876.67890123456789012345 }') | |
-- | |
-- print("small: ", type(T.small), T.small) | |
-- print("big: ", type(T.big), T.big) | |
-- print("precise: ", type(T.precise), T.precise) | |
-- | |
-- produces | |
-- | |
-- small: number 12345 | |
-- big: number 1.2345678901235e+28 | |
-- precise: number 9876.6789012346 | |
-- | |
-- Precision is lost with both 'big' and 'precise'. | |
-- | |
-- This package offers ways to try to handle this better (for some definitions of "better")... | |
-- | |
-- The most precise method is by setting the global: | |
-- | |
-- JSON.decodeNumbersAsObjects = true | |
-- | |
-- When this is set, numeric JSON data is encoded into Lua in a form that preserves the exact | |
-- JSON numeric presentation when re-encoded back out to JSON, or accessed in Lua as a string. | |
-- | |
-- (This is done by encoding the numeric data with a Lua table/metatable that returns | |
-- the possibly-imprecise numeric form when accessed numerically, but the original precise | |
-- representation when accessed as a string.) | |
-- | |
-- Consider the example above, with this option turned on: | |
-- | |
-- JSON.decodeNumbersAsObjects = true | |
-- | |
-- T = JSON:decode('{ "small":12345, "big":12345678901234567890123456789, "precise":9876.67890123456789012345 }') | |
-- | |
-- print("small: ", type(T.small), T.small) | |
-- print("big: ", type(T.big), T.big) | |
-- print("precise: ", type(T.precise), T.precise) | |
-- | |
-- This now produces: | |
-- | |
-- small: table 12345 | |
-- big: table 12345678901234567890123456789 | |
-- precise: table 9876.67890123456789012345 | |
-- | |
-- However, within Lua you can still use the values (e.g. T.precise in the example above) in numeric | |
-- contexts. In such cases you'll get the possibly-imprecise numeric version, but in string contexts | |
-- and when the data finds its way to this package's encode() function, the original full-precision | |
-- representation is used. | |
-- | |
-- Even without using the JSON.decodeNumbersAsObjects option, you can encode numbers | |
-- in your Lua table that retain high precision upon encoding to JSON, by using the JSON:asNumber() | |
-- function: | |
-- | |
-- T = { | |
-- imprecise = 123456789123456789.123456789123456789, | |
-- precise = JSON:asNumber("123456789123456789.123456789123456789") | |
-- } | |
-- | |
-- print(JSON:encode_pretty(T)) | |
-- | |
-- This produces: | |
-- | |
-- { | |
-- "precise": 123456789123456789.123456789123456789, | |
-- "imprecise": 1.2345678912346e+17 | |
-- } | |
-- | |
-- | |
-- | |
-- A different way to handle big/precise JSON numbers is to have decode() merely return | |
-- the exact string representation of the number instead of the number itself. | |
-- This approach might be useful when the numbers are merely some kind of opaque | |
-- object identifier and you want to work with them in Lua as strings anyway. | |
-- | |
-- This approach is enabled by setting | |
-- | |
-- JSON.decodeIntegerStringificationLength = 10 | |
-- | |
-- The value is the number of digits (of the integer part of the number) at which to stringify numbers. | |
-- | |
-- Consider our previous example with this option set to 10: | |
-- | |
-- JSON.decodeIntegerStringificationLength = 10 | |
-- | |
-- T = JSON:decode('{ "small":12345, "big":12345678901234567890123456789, "precise":9876.67890123456789012345 }') | |
-- | |
-- print("small: ", type(T.small), T.small) | |
-- print("big: ", type(T.big), T.big) | |
-- print("precise: ", type(T.precise), T.precise) | |
-- | |
-- This produces: | |
-- | |
-- small: number 12345 | |
-- big: string 12345678901234567890123456789 | |
-- precise: number 9876.6789012346 | |
-- | |
-- The long integer of the 'big' field is at least JSON.decodeIntegerStringificationLength digits | |
-- in length, so it's converted not to a Lua integer but to a Lua string. Using a value of 0 or 1 ensures | |
-- that all JSON numeric data becomes strings in Lua. | |
-- | |
-- Note that unlike | |
-- JSON.decodeNumbersAsObjects = true | |
-- this stringification is simple and unintelligent: the JSON number simply becomes a Lua string, and that's the end of it. | |
-- If the string is then converted back to JSON, it's still a string. After running the code above, adding | |
-- print(JSON:encode(T)) | |
-- produces | |
-- {"big":"12345678901234567890123456789","precise":9876.6789012346,"small":12345} | |
-- which is unlikely to be desired. | |
-- | |
-- There's a comparable option for the length of the decimal part of a number: | |
-- | |
-- JSON.decodeDecimalStringificationLength | |
-- | |
-- This can be used alone or in conjunction with | |
-- | |
-- JSON.decodeIntegerStringificationLength | |
-- | |
-- to trip stringification on precise numbers with at least JSON.decodeIntegerStringificationLength digits after | |
-- the decimal point. | |
-- | |
-- This example: | |
-- | |
-- JSON.decodeIntegerStringificationLength = 10 | |
-- JSON.decodeDecimalStringificationLength = 5 | |
-- | |
-- T = JSON:decode('{ "small":12345, "big":12345678901234567890123456789, "precise":9876.67890123456789012345 }') | |
-- | |
-- print("small: ", type(T.small), T.small) | |
-- print("big: ", type(T.big), T.big) | |
-- print("precise: ", type(T.precise), T.precise) | |
-- | |
-- produces: | |
-- | |
-- small: number 12345 | |
-- big: string 12345678901234567890123456789 | |
-- precise: string 9876.67890123456789012345 | |
-- | |
-- | |
-- | |
-- | |
-- | |
-- SUMMARY OF METHODS YOU CAN OVERRIDE IN YOUR LOCAL LUA JSON OBJECT | |
-- | |
-- assert | |
-- onDecodeError | |
-- onDecodeOfNilError | |
-- onDecodeOfHTMLError | |
-- onEncodeError | |
-- | |
-- If you want to create a separate Lua JSON object with its own error handlers, | |
-- you can reload JSON.lua or use the :new() method. | |
-- | |
--------------------------------------------------------------------------- | |
local default_pretty_indent = " " | |
local default_pretty_options = { pretty = true, align_keys = false, indent = default_pretty_indent } | |
local isArray = { __tostring = function() return "JSON array" end } isArray.__index = isArray | |
local isObject = { __tostring = function() return "JSON object" end } isObject.__index = isObject | |
function OBJDEF:newArray(tbl) | |
return setmetatable(tbl or {}, isArray) | |
end | |
function OBJDEF:newObject(tbl) | |
return setmetatable(tbl or {}, isObject) | |
end | |
local function getnum(op) | |
return type(op) == 'number' and op or op.N | |
end | |
local isNumber = { | |
__index = isNumber, | |
__tostring = function(T) return T.S end, | |
__unm = function(op) return getnum(op) end, | |
__concat = function(op1, op2) return tostring(op1) .. tostring(op2) end, | |
__add = function(op1, op2) return getnum(op1) + getnum(op2) end, | |
__sub = function(op1, op2) return getnum(op1) - getnum(op2) end, | |
__mul = function(op1, op2) return getnum(op1) * getnum(op2) end, | |
__div = function(op1, op2) return getnum(op1) / getnum(op2) end, | |
__mod = function(op1, op2) return getnum(op1) % getnum(op2) end, | |
__pow = function(op1, op2) return getnum(op1) ^ getnum(op2) end, | |
__lt = function(op1, op2) return getnum(op1) < getnum(op2) end, | |
__eq = function(op1, op2) return getnum(op1) == getnum(op2) end, | |
__le = function(op1, op2) return getnum(op1) <= getnum(op2) end, | |
} | |
function OBJDEF:asNumber(item) | |
if getmetatable(item) == isNumber then | |
-- it's already a JSON number object. | |
return item | |
elseif type(item) == 'table' and type(item.S) == 'string' and type(item.N) == 'number' then | |
-- it's a number-object table that lost its metatable, so give it one | |
return setmetatable(item, isNumber) | |
else | |
-- the normal situation... given a number or a string representation of a number.... | |
local holder = { | |
S = tostring(item), -- S is the representation of the number as a string, which remains precise | |
N = tonumber(item), -- N is the number as a Lua number. | |
} | |
return setmetatable(holder, isNumber) | |
end | |
end | |
local function unicode_codepoint_as_utf8(codepoint) | |
-- | |
-- codepoint is a number | |
-- | |
if codepoint <= 127 then | |
return string.char(codepoint) | |
elseif codepoint <= 2047 then | |
-- | |
-- 110yyyxx 10xxxxxx <-- useful notation from http://en.wikipedia.org/wiki/Utf8 | |
-- | |
local highpart = math.floor(codepoint / 0x40) | |
local lowpart = codepoint - (0x40 * highpart) | |
return string.char(0xC0 + highpart, | |
0x80 + lowpart) | |
elseif codepoint <= 65535 then | |
-- | |
-- 1110yyyy 10yyyyxx 10xxxxxx | |
-- | |
local highpart = math.floor(codepoint / 0x1000) | |
local remainder = codepoint - 0x1000 * highpart | |
local midpart = math.floor(remainder / 0x40) | |
local lowpart = remainder - 0x40 * midpart | |
highpart = 0xE0 + highpart | |
midpart = 0x80 + midpart | |
lowpart = 0x80 + lowpart | |
-- | |
-- Check for an invalid character (thanks Andy R. at Adobe). | |
-- See table 3.7, page 93, in http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf#G28070 | |
-- | |
if ( highpart == 0xE0 and midpart < 0xA0 ) or | |
( highpart == 0xED and midpart > 0x9F ) or | |
( highpart == 0xF0 and midpart < 0x90 ) or | |
( highpart == 0xF4 and midpart > 0x8F ) | |
then | |
return "?" | |
else | |
return string.char(highpart, | |
midpart, | |
lowpart) | |
end | |
else | |
-- | |
-- 11110zzz 10zzyyyy 10yyyyxx 10xxxxxx | |
-- | |
local highpart = math.floor(codepoint / 0x40000) | |
local remainder = codepoint - 0x40000 * highpart | |
local midA = math.floor(remainder / 0x1000) | |
remainder = remainder - 0x1000 * midA | |
local midB = math.floor(remainder / 0x40) | |
local lowpart = remainder - 0x40 * midB | |
return string.char(0xF0 + highpart, | |
0x80 + midA, | |
0x80 + midB, | |
0x80 + lowpart) | |
end | |
end | |
function OBJDEF:onDecodeError(message, text, location, etc) | |
if text then | |
if location then | |
message = string.format("%s at char %d of: %s", message, location, text) | |
else | |
message = string.format("%s: %s", message, text) | |
end | |
end | |
if etc ~= nil then | |
message = message .. " (" .. OBJDEF:encode(etc) .. ")" | |
end | |
if self.assert then | |
self.assert(false, message) | |
else | |
assert(false, message) | |
end | |
end | |
OBJDEF.onDecodeOfNilError = OBJDEF.onDecodeError | |
OBJDEF.onDecodeOfHTMLError = OBJDEF.onDecodeError | |
function OBJDEF:onEncodeError(message, etc) | |
if etc ~= nil then | |
message = message .. " (" .. OBJDEF:encode(etc) .. ")" | |
end | |
if self.assert then | |
self.assert(false, message) | |
else | |
assert(false, message) | |
end | |
end | |
local function grok_number(self, text, start, options) | |
-- | |
-- Grab the integer part | |
-- | |
local integer_part = text:match('^-?[1-9]%d*', start) | |
or text:match("^-?0", start) | |
if not integer_part then | |
self:onDecodeError("expected number", text, start, options.etc) | |
end | |
local i = start + integer_part:len() | |
-- | |
-- Grab an optional decimal part | |
-- | |
local decimal_part = text:match('^%.%d+', i) or "" | |
i = i + decimal_part:len() | |
-- | |
-- Grab an optional exponential part | |
-- | |
local exponent_part = text:match('^[eE][-+]?%d+', i) or "" | |
i = i + exponent_part:len() | |
local full_number_text = integer_part .. decimal_part .. exponent_part | |
if options.decodeNumbersAsObjects then | |
return OBJDEF:asNumber(full_number_text), i | |
end | |
-- | |
-- If we're told to stringify under certain conditions, so do. | |
-- We punt a bit when there's an exponent by just stringifying no matter what. | |
-- I suppose we should really look to see whether the exponent is actually big enough one | |
-- way or the other to trip stringification, but I'll be lazy about it until someone asks. | |
-- | |
if (options.decodeIntegerStringificationLength | |
and | |
(integer_part:len() >= options.decodeIntegerStringificationLength or exponent_part:len() > 0)) | |
or | |
(options.decodeDecimalStringificationLength | |
and | |
(decimal_part:len() >= options.decodeDecimalStringificationLength or exponent_part:len() > 0)) | |
then | |
return full_number_text, i -- this returns the exact string representation seen in the original JSON | |
end | |
local as_number = tonumber(full_number_text) | |
if not as_number then | |
self:onDecodeError("bad number", text, start, options.etc) | |
end | |
return as_number, i | |
end | |
local function grok_string(self, text, start, options) | |
if text:sub(start,start) ~= '"' then | |
self:onDecodeError("expected string's opening quote", text, start, options.etc) | |
end | |
local i = start + 1 -- +1 to bypass the initial quote | |
local text_len = text:len() | |
local VALUE = "" | |
while i <= text_len do | |
local c = text:sub(i,i) | |
if c == '"' then | |
return VALUE, i + 1 | |
end | |
if c ~= '\\' then | |
VALUE = VALUE .. c | |
i = i + 1 | |
elseif text:match('^\\b', i) then | |
VALUE = VALUE .. "\b" | |
i = i + 2 | |
elseif text:match('^\\f', i) then | |
VALUE = VALUE .. "\f" | |
i = i + 2 | |
elseif text:match('^\\n', i) then | |
VALUE = VALUE .. "\n" | |
i = i + 2 | |
elseif text:match('^\\r', i) then | |
VALUE = VALUE .. "\r" | |
i = i + 2 | |
elseif text:match('^\\t', i) then | |
VALUE = VALUE .. "\t" | |
i = i + 2 | |
else | |
local hex = text:match('^\\u([0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])', i) | |
if hex then | |
i = i + 6 -- bypass what we just read | |
-- We have a Unicode codepoint. It could be standalone, or if in the proper range and | |
-- followed by another in a specific range, it'll be a two-code surrogate pair. | |
local codepoint = tonumber(hex, 16) | |
if codepoint >= 0xD800 and codepoint <= 0xDBFF then | |
-- it's a hi surrogate... see whether we have a following low | |
local lo_surrogate = text:match('^\\u([dD][cdefCDEF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])', i) | |
if lo_surrogate then | |
i = i + 6 -- bypass the low surrogate we just read | |
codepoint = 0x2400 + (codepoint - 0xD800) * 0x400 + tonumber(lo_surrogate, 16) | |
else | |
-- not a proper low, so we'll just leave the first codepoint as is and spit it out. | |
end | |
end | |
VALUE = VALUE .. unicode_codepoint_as_utf8(codepoint) | |
else | |
-- just pass through what's escaped | |
VALUE = VALUE .. text:match('^\\(.)', i) | |
i = i + 2 | |
end | |
end | |
end | |
self:onDecodeError("unclosed string", text, start, options.etc) | |
end | |
local function skip_whitespace(text, start) | |
local _, match_end = text:find("^[ \n\r\t]+", start) -- [http://www.ietf.org/rfc/rfc4627.txt] Section 2 | |
if match_end then | |
return match_end + 1 | |
else | |
return start | |
end | |
end | |
local grok_one -- assigned later | |
local function grok_object(self, text, start, options) | |
if text:sub(start,start) ~= '{' then | |
self:onDecodeError("expected '{'", text, start, options.etc) | |
end | |
local i = skip_whitespace(text, start + 1) -- +1 to skip the '{' | |
local VALUE = self.strictTypes and self:newObject { } or { } | |
if text:sub(i,i) == '}' then | |
return VALUE, i + 1 | |
end | |
local text_len = text:len() | |
while i <= text_len do | |
local key, new_i = grok_string(self, text, i, options) | |
i = skip_whitespace(text, new_i) | |
if text:sub(i, i) ~= ':' then | |
self:onDecodeError("expected colon", text, i, options.etc) | |
end | |
i = skip_whitespace(text, i + 1) | |
local new_val, new_i = grok_one(self, text, i, options) | |
VALUE[key] = new_val | |
-- | |
-- Expect now either '}' to end things, or a ',' to allow us to continue. | |
-- | |
i = skip_whitespace(text, new_i) | |
local c = text:sub(i,i) | |
if c == '}' then | |
return VALUE, i + 1 | |
end | |
if text:sub(i, i) ~= ',' then | |
self:onDecodeError("expected comma or '}'", text, i, options.etc) | |
end | |
i = skip_whitespace(text, i + 1) | |
end | |
self:onDecodeError("unclosed '{'", text, start, options.etc) | |
end | |
local function grok_array(self, text, start, options) | |
if text:sub(start,start) ~= '[' then | |
self:onDecodeError("expected '['", text, start, options.etc) | |
end | |
local i = skip_whitespace(text, start + 1) -- +1 to skip the '[' | |
local VALUE = self.strictTypes and self:newArray { } or { } | |
if text:sub(i,i) == ']' then | |
return VALUE, i + 1 | |
end | |
local VALUE_INDEX = 1 | |
local text_len = text:len() | |
while i <= text_len do | |
local val, new_i = grok_one(self, text, i, options) | |
-- can't table.insert(VALUE, val) here because it's a no-op if val is nil | |
VALUE[VALUE_INDEX] = val | |
VALUE_INDEX = VALUE_INDEX + 1 | |
i = skip_whitespace(text, new_i) | |
-- | |
-- Expect now either ']' to end things, or a ',' to allow us to continue. | |
-- | |
local c = text:sub(i,i) | |
if c == ']' then | |
return VALUE, i + 1 | |
end | |
if text:sub(i, i) ~= ',' then | |
self:onDecodeError("expected comma or '['", text, i, options.etc) | |
end | |
i = skip_whitespace(text, i + 1) | |
end | |
self:onDecodeError("unclosed '['", text, start, options.etc) | |
end | |
grok_one = function(self, text, start, options) | |
-- Skip any whitespace | |
start = skip_whitespace(text, start) | |
if start > text:len() then | |
self:onDecodeError("unexpected end of string", text, nil, options.etc) | |
end | |
if text:find('^"', start) then | |
return grok_string(self, text, start, options.etc) | |
elseif text:find('^[-0123456789 ]', start) then | |
return grok_number(self, text, start, options) | |
elseif text:find('^%{', start) then | |
return grok_object(self, text, start, options) | |
elseif text:find('^%[', start) then | |
return grok_array(self, text, start, options) | |
elseif text:find('^true', start) then | |
return true, start + 4 | |
elseif text:find('^false', start) then | |
return false, start + 5 | |
elseif text:find('^null', start) then | |
return nil, start + 4 | |
else | |
self:onDecodeError("can't parse JSON", text, start, options.etc) | |
end | |
end | |
function OBJDEF:decode(text, etc, options) | |
-- | |
-- If the user didn't pass in a table of decode options, make an empty one. | |
-- | |
if type(options) ~= 'table' then | |
options = {} | |
end | |
-- | |
-- If they passed in an 'etc' argument, stuff it into the options. | |
-- (If not, any 'etc' field in the options they passed in remains to be used) | |
-- | |
if etc ~= nil then | |
options.etc = etc | |
end | |
if type(self) ~= 'table' or self.__index ~= OBJDEF then | |
OBJDEF:onDecodeError("JSON:decode must be called in method format", nil, nil, options.etc) | |
end | |
if text == nil then | |
self:onDecodeOfNilError(string.format("nil passed to JSON:decode()"), nil, nil, options.etc) | |
elseif type(text) ~= 'string' then | |
self:onDecodeError(string.format("expected string argument to JSON:decode(), got %s", type(text)), nil, nil, options.etc) | |
end | |
if text:match('^%s*$') then | |
return nil | |
end | |
if text:match('^%s*<') then | |
-- Can't be JSON... we'll assume it's HTML | |
self:onDecodeOfHTMLError(string.format("html passed to JSON:decode()"), text, nil, options.etc) | |
end | |
-- | |
-- Ensure that it's not UTF-32 or UTF-16. | |
-- Those are perfectly valid encodings for JSON (as per RFC 4627 section 3), | |
-- but this package can't handle them. | |
-- | |
if text:sub(1,1):byte() == 0 or (text:len() >= 2 and text:sub(2,2):byte() == 0) then | |
self:onDecodeError("JSON package groks only UTF-8, sorry", text, nil, options.etc) | |
end | |
-- | |
-- apply global options | |
-- | |
if options.decodeNumbersAsObjects == nil then | |
options.decodeNumbersAsObjects = self.decodeNumbersAsObjects | |
end | |
if options.decodeIntegerStringificationLength == nil then | |
options.decodeIntegerStringificationLength = self.decodeIntegerStringificationLength | |
end | |
if options.decodeDecimalStringificationLength == nil then | |
options.decodeDecimalStringificationLength = self.decodeDecimalStringificationLength | |
end | |
local success, value = pcall(grok_one, self, text, 1, options) | |
if success then | |
return value | |
else | |
-- if JSON:onDecodeError() didn't abort out of the pcall, we'll have received the error message here as "value", so pass it along as an assert. | |
if self.assert then | |
self.assert(false, value) | |
else | |
assert(false, value) | |
end | |
-- and if we're still here, return a nil and throw the error message on as a second arg | |
return nil, value | |
end | |
end | |
local function backslash_replacement_function(c) | |
if c == "\n" then | |
return "\\n" | |
elseif c == "\r" then | |
return "\\r" | |
elseif c == "\t" then | |
return "\\t" | |
elseif c == "\b" then | |
return "\\b" | |
elseif c == "\f" then | |
return "\\f" | |
elseif c == '"' then | |
return '\\"' | |
elseif c == '\\' then | |
return '\\\\' | |
else | |
return string.format("\\u%04x", c:byte()) | |
end | |
end | |
local chars_to_be_escaped_in_JSON_string | |
= '[' | |
.. '"' -- class sub-pattern to match a double quote | |
.. '%\\' -- class sub-pattern to match a backslash | |
.. '%z' -- class sub-pattern to match a null | |
.. '\001' .. '-' .. '\031' -- class sub-pattern to match control characters | |
.. ']' | |
local LINE_SEPARATOR_as_utf8 = unicode_codepoint_as_utf8(0x2028) | |
local PARAGRAPH_SEPARATOR_as_utf8 = unicode_codepoint_as_utf8(0x2029) | |
local function json_string_literal(value, options) | |
local newval = value:gsub(chars_to_be_escaped_in_JSON_string, backslash_replacement_function) | |
if options.stringsAreUtf8 then | |
-- | |
-- This feels really ugly to just look into a string for the sequence of bytes that we know to be a particular utf8 character, | |
-- but utf8 was designed purposefully to make this kind of thing possible. Still, feels dirty. | |
-- I'd rather decode the byte stream into a character stream, but it's not technically needed so | |
-- not technically worth it. | |
-- | |
newval = newval:gsub(LINE_SEPARATOR_as_utf8, '\\u2028'):gsub(PARAGRAPH_SEPARATOR_as_utf8,'\\u2029') | |
end | |
return '"' .. newval .. '"' | |
end | |
local function object_or_array(self, T, etc) | |
-- | |
-- We need to inspect all the keys... if there are any strings, we'll convert to a JSON | |
-- object. If there are only numbers, it's a JSON array. | |
-- | |
-- If we'll be converting to a JSON object, we'll want to sort the keys so that the | |
-- end result is deterministic. | |
-- | |
local string_keys = { } | |
local number_keys = { } | |
local number_keys_must_be_strings = false | |
local maximum_number_key | |
for key in pairs(T) do | |
if type(key) == 'string' then | |
table.insert(string_keys, key) | |
elseif type(key) == 'number' then | |
table.insert(number_keys, key) | |
if key <= 0 or key >= math.huge then | |
number_keys_must_be_strings = true | |
elseif not maximum_number_key or key > maximum_number_key then | |
maximum_number_key = key | |
end | |
else | |
self:onEncodeError("can't encode table with a key of type " .. type(key), etc) | |
end | |
end | |
if #string_keys == 0 and not number_keys_must_be_strings then | |
-- | |
-- An empty table, or a numeric-only array | |
-- | |
if #number_keys > 0 then | |
return nil, maximum_number_key -- an array | |
elseif tostring(T) == "JSON array" then | |
return nil | |
elseif tostring(T) == "JSON object" then | |
return { } | |
else | |
-- have to guess, so we'll pick array, since empty arrays are likely more common than empty objects | |
return nil | |
end | |
end | |
table.sort(string_keys) | |
local map | |
if #number_keys > 0 then | |
-- | |
-- If we're here then we have either mixed string/number keys, or numbers inappropriate for a JSON array | |
-- It's not ideal, but we'll turn the numbers into strings so that we can at least create a JSON object. | |
-- | |
if self.noKeyConversion then | |
self:onEncodeError("a table with both numeric and string keys could be an object or array; aborting", etc) | |
end | |
-- | |
-- Have to make a shallow copy of the source table so we can remap the numeric keys to be strings | |
-- | |
map = { } | |
for key, val in pairs(T) do | |
map[key] = val | |
end | |
table.sort(number_keys) | |
-- | |
-- Throw numeric keys in there as strings | |
-- | |
for _, number_key in ipairs(number_keys) do | |
local string_key = tostring(number_key) | |
if map[string_key] == nil then | |
table.insert(string_keys , string_key) | |
map[string_key] = T[number_key] | |
else | |
self:onEncodeError("conflict converting table with mixed-type keys into a JSON object: key " .. number_key .. " exists both as a string and a number.", etc) | |
end | |
end | |
end | |
return string_keys, nil, map | |
end | |
-- | |
-- Encode | |
-- | |
-- 'options' is nil, or a table with possible keys: | |
-- | |
-- pretty -- If true, return a pretty-printed version. | |
-- | |
-- indent -- A string (usually of spaces) used to indent each nested level. | |
-- | |
-- align_keys -- If true, align all the keys when formatting a table. | |
-- | |
-- null -- If this exists with a string value, table elements with this value are output as JSON null. | |
-- | |
-- stringsAreUtf8 -- If true, consider Lua strings not as a sequence of bytes, but as a sequence of UTF-8 characters. | |
-- (Currently, the only practical effect of setting this option is that Unicode LINE and PARAGRAPH | |
-- separators, if found in a string, are encoded with a JSON escape instead of as raw UTF-8. | |
-- The JSON is valid either way, but encoding this way, apparently, allows the resulting JSON | |
-- to also be valid Java.) | |
-- | |
-- | |
local encode_value -- must predeclare because it calls itself | |
function encode_value(self, value, parents, etc, options, indent, for_key) | |
-- | |
-- keys in a JSON object can never be null, so we don't even consider options.null when converting a key value | |
-- | |
if value == nil or (not for_key and options and options.null and value == options.null) then | |
return 'null' | |
elseif type(value) == 'string' then | |
return json_string_literal(value, options) | |
elseif type(value) == 'number' then | |
if value ~= value then | |
-- | |
-- NaN (Not a Number). | |
-- JSON has no NaN, so we have to fudge the best we can. This should really be a package option. | |
-- | |
return "null" | |
elseif value >= math.huge then | |
-- | |
-- Positive infinity. JSON has no INF, so we have to fudge the best we can. This should | |
-- really be a package option. Note: at least with some implementations, positive infinity | |
-- is both ">= math.huge" and "<= -math.huge", which makes no sense but that's how it is. | |
-- Negative infinity is properly "<= -math.huge". So, we must be sure to check the ">=" | |
-- case first. | |
-- | |
return "1e+9999" | |
elseif value <= -math.huge then | |
-- | |
-- Negative infinity. | |
-- JSON has no INF, so we have to fudge the best we can. This should really be a package option. | |
-- | |
return "-1e+9999" | |
else | |
return tostring(value) | |
end | |
elseif type(value) == 'boolean' then | |
return tostring(value) | |
elseif type(value) ~= 'table' then | |
self:onEncodeError("can't convert " .. type(value) .. " to JSON", etc) | |
elseif getmetatable(value) == isNumber then | |
return tostring(value) | |
else | |
-- | |
-- A table to be converted to either a JSON object or array. | |
-- | |
local T = value | |
if type(options) ~= 'table' then | |
options = {} | |
end | |
if type(indent) ~= 'string' then | |
indent = "" | |
end | |
if parents[T] then | |
self:onEncodeError("table " .. tostring(T) .. " is a child of itself", etc) | |
else | |
parents[T] = true | |
end | |
local result_value | |
local object_keys, maximum_number_key, map = object_or_array(self, T, etc) | |
if maximum_number_key then | |
-- | |
-- An array... | |
-- | |
local ITEMS = { } | |
for i = 1, maximum_number_key do | |
table.insert(ITEMS, encode_value(self, T[i], parents, etc, options, indent)) | |
end | |
if options.pretty then | |
result_value = "[ " .. table.concat(ITEMS, ", ") .. " ]" | |
else | |
result_value = "[" .. table.concat(ITEMS, ",") .. "]" | |
end | |
elseif object_keys then | |
-- | |
-- An object | |
-- | |
local TT = map or T | |
if options.pretty then | |
local KEYS = { } | |
local max_key_length = 0 | |
for _, key in ipairs(object_keys) do | |
local encoded = encode_value(self, tostring(key), parents, etc, options, indent, true) | |
if options.align_keys then | |
max_key_length = math.max(max_key_length, #encoded) | |
end | |
table.insert(KEYS, encoded) | |
end | |
local key_indent = indent .. tostring(options.indent or "") | |
local subtable_indent = key_indent .. string.rep(" ", max_key_length) .. (options.align_keys and " " or "") | |
local FORMAT = "%s%" .. string.format("%d", max_key_length) .. "s: %s" | |
local COMBINED_PARTS = { } | |
for i, key in ipairs(object_keys) do | |
local encoded_val = encode_value(self, TT[key], parents, etc, options, subtable_indent) | |
table.insert(COMBINED_PARTS, string.format(FORMAT, key_indent, KEYS[i], encoded_val)) | |
end | |
result_value = "{\n" .. table.concat(COMBINED_PARTS, ",\n") .. "\n" .. indent .. "}" | |
else | |
local PARTS = { } | |
for _, key in ipairs(object_keys) do | |
local encoded_val = encode_value(self, TT[key], parents, etc, options, indent) | |
local encoded_key = encode_value(self, tostring(key), parents, etc, options, indent, true) | |
table.insert(PARTS, string.format("%s:%s", encoded_key, encoded_val)) | |
end | |
result_value = "{" .. table.concat(PARTS, ",") .. "}" | |
end | |
else | |
-- | |
-- An empty array/object... we'll treat it as an array, though it should really be an option | |
-- | |
result_value = "[]" | |
end | |
parents[T] = false | |
return result_value | |
end | |
end | |
function OBJDEF:encode(value, etc, options) | |
if type(self) ~= 'table' or self.__index ~= OBJDEF then | |
OBJDEF:onEncodeError("JSON:encode must be called in method format", etc) | |
end | |
-- | |
-- If the user didn't pass in a table of decode options, make an empty one. | |
-- | |
if type(options) ~= 'table' then | |
options = {} | |
end | |
return encode_value(self, value, {}, etc, options) | |
end | |
function OBJDEF:encode_pretty(value, etc, options) | |
if type(self) ~= 'table' or self.__index ~= OBJDEF then | |
OBJDEF:onEncodeError("JSON:encode_pretty must be called in method format", etc) | |
end | |
-- | |
-- If the user didn't pass in a table of decode options, use the default pretty ones | |
-- | |
if type(options) ~= 'table' then | |
options = default_pretty_options | |
end | |
return encode_value(self, value, {}, etc, options) | |
end | |
function OBJDEF.__tostring() | |
return "JSON encode/decode package" | |
end | |
OBJDEF.__index = OBJDEF | |
function OBJDEF:new(args) | |
local new = { } | |
if args then | |
for key, val in pairs(args) do | |
new[key] = val | |
end | |
end | |
return setmetatable(new, OBJDEF) | |
end | |
return OBJDEF:new() | |
-- | |
-- Version history: | |
-- | |
-- 20160728.17 Added concatenation to the metatable for JSON:asNumber(). | |
-- | |
-- 20160709.16 Could crash if not passed an options table (thanks jarno heikkinen <jarnoh@capturemonkey.com>). | |
-- | |
-- Made JSON:asNumber() a bit more resilient to being passed the results of itself. | |
-- | |
-- 20160526.15 Added the ability to easily encode null values in JSON, via the new "null" encoding option. | |
-- (Thanks to Adam B for bringing up the issue.) | |
-- | |
-- Added some support for very large numbers and precise floats via | |
-- JSON.decodeNumbersAsObjects | |
-- JSON.decodeIntegerStringificationLength | |
-- JSON.decodeDecimalStringificationLength | |
-- | |
-- Added the "stringsAreUtf8" encoding option. (Hat tip to http://lua-users.org/wiki/JsonModules ) | |
-- | |
-- 20141223.14 The encode_pretty() routine produced fine results for small datasets, but isn't really | |
-- appropriate for anything large, so with help from Alex Aulbach I've made the encode routines | |
-- more flexible, and changed the default encode_pretty() to be more generally useful. | |
-- | |
-- Added a third 'options' argument to the encode() and encode_pretty() routines, to control | |
-- how the encoding takes place. | |
-- | |
-- Updated docs to add assert() call to the loadfile() line, just as good practice so that | |
-- if there is a problem loading JSON.lua, the appropriate error message will percolate up. | |
-- | |
-- 20140920.13 Put back (in a way that doesn't cause warnings about unused variables) the author string, | |
-- so that the source of the package, and its version number, are visible in compiled copies. | |
-- | |
-- 20140911.12 Minor lua cleanup. | |
-- Fixed internal reference to 'JSON.noKeyConversion' to reference 'self' instead of 'JSON'. | |
-- (Thanks to SmugMug's David Parry for these.) | |
-- | |
-- 20140418.11 JSON nulls embedded within an array were being ignored, such that | |
-- ["1",null,null,null,null,null,"seven"], | |
-- would return | |
-- {1,"seven"} | |
-- It's now fixed to properly return | |
-- {1, nil, nil, nil, nil, nil, "seven"} | |
-- Thanks to "haddock" for catching the error. | |
-- | |
-- 20140116.10 The user's JSON.assert() wasn't always being used. Thanks to "blue" for the heads up. | |
-- | |
-- 20131118.9 Update for Lua 5.3... it seems that tostring(2/1) produces "2.0" instead of "2", | |
-- and this caused some problems. | |
-- | |
-- 20131031.8 Unified the code for encode() and encode_pretty(); they had been stupidly separate, | |
-- and had of course diverged (encode_pretty didn't get the fixes that encode got, so | |
-- sometimes produced incorrect results; thanks to Mattie for the heads up). | |
-- | |
-- Handle encoding tables with non-positive numeric keys (unlikely, but possible). | |
-- | |
-- If a table has both numeric and string keys, or its numeric keys are inappropriate | |
-- (such as being non-positive or infinite), the numeric keys are turned into | |
-- string keys appropriate for a JSON object. So, as before, | |
-- JSON:encode({ "one", "two", "three" }) | |
-- produces the array | |
-- ["one","two","three"] | |
-- but now something with mixed key types like | |
-- JSON:encode({ "one", "two", "three", SOMESTRING = "some string" })) | |
-- instead of throwing an error produces an object: | |
-- {"1":"one","2":"two","3":"three","SOMESTRING":"some string"} | |
-- | |
-- To maintain the prior throw-an-error semantics, set | |
-- JSON.noKeyConversion = true | |
-- | |
-- 20131004.7 Release under a Creative Commons CC-BY license, which I should have done from day one, sorry. | |
-- | |
-- 20130120.6 Comment update: added a link to the specific page on my blog where this code can | |
-- be found, so that folks who come across the code outside of my blog can find updates | |
-- more easily. | |
-- | |
-- 20111207.5 Added support for the 'etc' arguments, for better error reporting. | |
-- | |
-- 20110731.4 More feedback from David Kolf on how to make the tests for Nan/Infinity system independent. | |
-- | |
-- 20110730.3 Incorporated feedback from David Kolf at http://lua-users.org/wiki/JsonModules: | |
-- | |
-- * When encoding lua for JSON, Sparse numeric arrays are now handled by | |
-- spitting out full arrays, such that | |
-- JSON:encode({"one", "two", [10] = "ten"}) | |
-- returns | |
-- ["one","two",null,null,null,null,null,null,null,"ten"] | |
-- | |
-- In 20100810.2 and earlier, only up to the first non-null value would have been retained. | |
-- | |
-- * When encoding lua for JSON, numeric value NaN gets spit out as null, and infinity as "1+e9999". | |
-- Version 20100810.2 and earlier created invalid JSON in both cases. | |
-- | |
-- * Unicode surrogate pairs are now detected when decoding JSON. | |
-- | |
-- 20100810.2 added some checking to ensure that an invalid Unicode character couldn't leak in to the UTF-8 encoding | |
-- | |
-- 20100731.1 initial public release | |
-- | |
]===])() | |
local semver = (function() | |
local _ = [[ Copyright (c) The python-semanticversion project | |
All rights reserved. | |
Redistribution and use in source and binary forms, with or without | |
modification, are permitted provided that the following conditions are met: | |
1. Redistributions of source code must retain the above copyright notice, this | |
list of conditions and the following disclaimer. | |
2. Redistributions in binary form must reproduce the above copyright notice, | |
this list of conditions and the following disclaimer in the documentation | |
and/or other materials provided with the distribution. | |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | |
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
]] | |
_ = [[ The use of the library is similar to the original one, | |
check the documentation here: https://python-semanticversion.readthedocs.io/en/latest/ | |
]] | |
local concat, insert, unpack | |
do | |
local _obj_0 = table | |
concat, insert, unpack = _obj_0.concat, _obj_0.insert, _obj_0.unpack | |
end | |
local toInt | |
toInt = function(value) | |
do | |
local tn = tonumber(value) | |
if tn then | |
return tn, true | |
else | |
return value, false | |
end | |
end | |
end | |
local hasLeadingZero | |
hasLeadingZero = function(value) | |
return value and value[1] == '0' and tonumber(value and value ~= '0') | |
end | |
local baseCmp | |
baseCmp = function(x, y) | |
if x == y then | |
return 0 | |
end | |
if x > y then | |
return 1 | |
end | |
if x < y then | |
return -1 | |
end | |
end | |
local identifierCmp | |
identifierCmp = function(a, b) | |
local aCmp, aInt = toInt(a) | |
local bCmp, bInt = toInt(b) | |
if aInt and bInt then | |
return baseCmp(aCmp, bCmp) | |
elseif aInt then | |
return -1 | |
elseif bInt then | |
return 1 | |
else | |
return baseCmp(aCmp, bCmp) | |
end | |
end | |
local identifierListCmp | |
identifierListCmp = function(a, b) | |
local identifierPairs | |
do | |
local _tbl_0 = { } | |
for i = 1, #a do | |
if b[i] then | |
_tbl_0[a[i]] = b[i] | |
end | |
end | |
identifierPairs = _tbl_0 | |
end | |
for idA, idB in pairs(identifierPairs) do | |
local cmpRes = identifierCmp(idA, idB) | |
if cmpRes ~= 0 then | |
return cmpRes | |
end | |
end | |
return baseCmp(#a, #b) | |
end | |
local Version | |
do | |
local _class_0 | |
local _base_0 = { | |
_coerce = function(self, value, allowNil) | |
if allowNil == nil then | |
allowNil = false | |
end | |
if value == nil and allowNil then | |
return value | |
end | |
return tonumber(value) | |
end, | |
next_major = function(self) | |
if self.prerelease and self.minor == 0 and self.patch == 0 then | |
return Version(concat((function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = { | |
self.major, | |
self.minor, | |
self.patch | |
} | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
_accum_0[_len_0] = tostring(x) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)(), '.')) | |
else | |
return Version(concat((function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = { | |
self.major + 1, | |
0, | |
0 | |
} | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
_accum_0[_len_0] = tostring(x) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)(), '.')) | |
end | |
end, | |
next_minor = function(self) | |
if not (self.minor) then | |
error("Partial version doesn't contain the minor component!") | |
end | |
if self.prerelease and self.patch == 0 then | |
return Version(concat((function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = { | |
self.major, | |
self.minor, | |
self.patch | |
} | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
_accum_0[_len_0] = tostring(x) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)(), '.')) | |
else | |
return Version(concat((function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = { | |
self.major, | |
self.minor + 1, | |
0 | |
} | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
_accum_0[_len_0] = tostring(x) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)(), '.')) | |
end | |
end, | |
next_patch = function(self) | |
if not (self.patch) then | |
error("Partial version doesn't contain the patch component!") | |
end | |
if self.prerelease then | |
return Version(concat((function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = { | |
self.major, | |
self.minor, | |
self.patch | |
} | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
_accum_0[_len_0] = tostring(x) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)(), '.')) | |
else | |
return Version(concat((function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = { | |
self.major, | |
self.minor, | |
self.patch + 1 | |
} | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
_accum_0[_len_0] = tostring(x) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)(), '.')) | |
end | |
end, | |
coerce = function(self, versionString, partial) | |
if partial == nil then | |
partial = false | |
end | |
local baseRe | |
baseRe = function(s) | |
local mjr, rmn = s:match('^(%d+)(.*)$') | |
if not (mjr) then | |
return nil | |
end | |
local t = mjr | |
local mnr, r = rmn:match('^%.(%d+)(.*)$') | |
if mnr then | |
rmn = r | |
t = t .. ('.' .. mnr) | |
end | |
local pch | |
pch, r = rmn:match('^%.(%d+)(.*)$') | |
if pch then | |
rmn = r | |
t = t .. ('.' .. pch) | |
end | |
return s, t | |
end | |
local match, matchEnd = baseRe(versionString) | |
if not (match) then | |
error("Version string lacks a numerical component: " .. tostring(versionString)) | |
end | |
local version = versionString:sub(1, #matchEnd) | |
if not partial then | |
while ({ | |
version:gsub('.', '') | |
})[2] < 2 do | |
version = version .. '.0' | |
end | |
end | |
if #matchEnd == #versionString then | |
return Version(version, partial) | |
end | |
local rest = versionString:sub(#matchEnd + 1) | |
rest = rest:gsub('[^a-zA-Z0-9+.-]', '-') | |
local prerelease, build = nil, nil | |
if rest:sub(1, 1) == '+' then | |
prerelease = '' | |
build = rest:sub(2) | |
elseif rest:sub(1, 1) == '.' then | |
prerelease = '' | |
build = rest:sub(2) | |
elseif rest:sub(1, 1) == '-' then | |
rest = rest:sub(2) | |
do | |
local p1 = rest:find('+') | |
if p1 then | |
prerelease, build = rest:sub(1, p1 - 1), rest:sub(p1 + 1, -1) | |
else | |
prerelease, build = rest, '' | |
end | |
end | |
else | |
do | |
local p1 = rest:find('+') | |
if p1 then | |
prerelease, build = rest:sub(1, p1 - 1), rest:sub(p1 + 1, -1) | |
else | |
prerelease, build = rest, '' | |
end | |
end | |
end | |
build = build:gsub('+', '.') | |
if prerelease and prerelease ~= '' then | |
version = version .. ('-' .. prerelease) | |
end | |
if build and build ~= '' then | |
version = version .. ('+' .. build) | |
end | |
return self.__class(version, partial) | |
end, | |
parse = function(self, versionString, partial, coerce) | |
if partial == nil then | |
partial = false | |
end | |
if coerce == nil then | |
coerce = false | |
end | |
if not versionString or type(versionString) ~= 'string' or versionString == '' then | |
error("Invalid empty version string: " .. tostring(tostring(versionString))) | |
end | |
local versionRe | |
if partial then | |
versionRe = self.__class.partialVersionRe | |
else | |
versionRe = self.__class.versionRe | |
end | |
local major, minor, patch, prerelease, build = versionRe(self.__class, versionString) | |
if not major then | |
error("Invalid version string: " .. tostring(versionString)) | |
end | |
if hasLeadingZero(major) then | |
error("Invalid leading zero in major: " .. tostring(versionString)) | |
end | |
if hasLeadingZero(minor) then | |
error("Invalid leading zero in minor: " .. tostring(versionString)) | |
end | |
if hasLeadingZero(patch) then | |
error("Invalid leading zero in patch: " .. tostring(versionString)) | |
end | |
major = tonumber(major) | |
minor = self:_coerce(minor, partial) | |
patch = self:_coerce(patch, partial) | |
if prerelease == nil then | |
if partial and build == nil then | |
return { | |
major, | |
minor, | |
patch, | |
nil, | |
nil | |
} | |
else | |
prerelease = { } | |
end | |
elseif prerelease == '' then | |
prerelease = { } | |
else | |
do | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for x in prerelease:gmatch('[^.]+') do | |
_accum_0[_len_0] = x | |
_len_0 = _len_0 + 1 | |
end | |
prerelease = _accum_0 | |
end | |
self:_validateIdentifiers(prerelease, false) | |
end | |
if build == nil then | |
if partial then | |
build = nil | |
else | |
build = { } | |
end | |
elseif build == '' then | |
build = { } | |
else | |
do | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for x in build:gmatch('[^.]+') do | |
_accum_0[_len_0] = x | |
_len_0 = _len_0 + 1 | |
end | |
build = _accum_0 | |
end | |
self:_validateIdentifiers(build, true) | |
end | |
return { | |
major, | |
minor, | |
patch, | |
prerelease, | |
build | |
} | |
end, | |
_validateIdentifiers = function(self, identifiers, allowLeadingZeroes) | |
if allowLeadingZeroes == nil then | |
allowLeadingZeroes = false | |
end | |
for _index_0 = 1, #identifiers do | |
local item = identifiers[_index_0] | |
if not item then | |
error("Invalid empty identifier " .. tostring(item) .. " in " .. tostring(concat(identifiers, '.'))) | |
end | |
if item:sub(1, 1) == '0' and tonumber(item) and item ~= '0' and not allowLeadingZeroes then | |
error("Invalid leading zero in identifier " .. tostring(item)) | |
end | |
end | |
end, | |
__pairs = function(self) | |
return pairs({ | |
self.major, | |
self.minor, | |
self.patch, | |
self.prerelease, | |
self.build | |
}) | |
end, | |
__ipairs = function(self) | |
return ipairs({ | |
self.major, | |
self.minor, | |
self.patch, | |
self.prerelease, | |
self.build | |
}) | |
end, | |
__tostring = function(self) | |
local version = tostring(self.major) | |
if self.minor ~= nil then | |
version = version .. ('.' .. self.minor) | |
end | |
if self.patch ~= nil then | |
version = version .. ('.' .. self.patch) | |
end | |
if self.prerelease and #self.prerelease > 0 or self.partial and self.prerelease and #self.prerelease == 0 and self.build == nil then | |
version = version .. ('-' .. concat(self.prerelease, '.')) | |
end | |
if self.build and #self.build > 0 or self.partial and self.build and #self.build == 0 then | |
version = version .. ('+' .. concat(self.build, '.')) | |
end | |
return version | |
end, | |
_comparsionFunctions = function(self, partial) | |
if partial == nil then | |
partial = false | |
end | |
local prereleaseCmp | |
prereleaseCmp = function(a, b) | |
if a and b then | |
return identifierListCmp(a, b) | |
elseif a then | |
return -1 | |
elseif b then | |
return 1 | |
else | |
return 0 | |
end | |
end | |
local buildCmp | |
buildCmp = function(a, b) | |
if a == b then | |
return 0 | |
else | |
return 'not implemented' | |
end | |
end | |
local makeOptional | |
makeOptional = function(origCmpFun) | |
local altCmpFun | |
altCmpFun = function(a, b) | |
if a == nil or b == nil then | |
return 0 | |
else | |
return origCmpFun(a, b) | |
end | |
end | |
return altCmpFun | |
end | |
if partial then | |
return { | |
baseCmp, | |
makeOptional(baseCmp), | |
makeOptional(baseCmp), | |
makeOptional(prereleaseCmp), | |
makeOptional(buildCmp) | |
} | |
else | |
return { | |
baseCmp, | |
baseCmp, | |
baseCmp, | |
prereleaseCmp, | |
buildCmp | |
} | |
end | |
end, | |
__compare = function(self, other) | |
local comparsionFunctions = self:_comparsionFunctions(self.partial or other.partial) | |
local comparsions = { | |
{ | |
comparsionFunctions[1], | |
self.major, | |
other.major | |
}, | |
{ | |
comparsionFunctions[2], | |
self.minor, | |
other.minor | |
}, | |
{ | |
comparsionFunctions[3], | |
self.patch, | |
other.patch | |
}, | |
{ | |
comparsionFunctions[4], | |
self.prerelease, | |
other.prerelease | |
}, | |
{ | |
comparsionFunctions[5], | |
self.build, | |
other.build | |
} | |
} | |
for _index_0 = 1, #comparsions do | |
local cmpField = comparsions[_index_0] | |
local cmpFun, selfField, otherField = unpack(cmpField) | |
local cmpRes = cmpFun(selfField, otherField) | |
if cmpRes ~= 0 then | |
return cmpRes | |
end | |
end | |
return 0 | |
end, | |
__compareHelper = function(self, other, condition, notimplTarget) | |
local cmpRes = self:__compare(other) | |
if cmpRes == 'not implemented' then | |
return notimplTarget | |
end | |
return condition(cmpRes) | |
end, | |
__eq = function(self, other) | |
local c | |
c = function(x) | |
return x == 0 | |
end | |
return self:__compareHelper(other, c, false) | |
end, | |
__lt = function(self, other) | |
local c | |
c = function(x) | |
return x < 0 | |
end | |
return self:__compareHelper(other, c, false) | |
end, | |
__le = function(self, other) | |
local c | |
c = function(x) | |
return x <= 0 | |
end | |
return self:__compareHelper(other, c, false) | |
end | |
} | |
_base_0.__index = _base_0 | |
_class_0 = setmetatable({ | |
__init = function(self, versionString, partial) | |
if partial == nil then | |
partial = false | |
end | |
local major, minor, patch, prerelease, build = unpack(self:parse(versionString, partial)) | |
self.major, self.minor, self.patch, self.prerelease, self.build, self.partial = major, minor, patch, prerelease, build, partial | |
end, | |
__base = _base_0, | |
__name = "Version" | |
}, { | |
__index = _base_0, | |
__call = function(cls, ...) | |
local _self_0 = setmetatable({}, _base_0) | |
cls.__init(_self_0, ...) | |
return _self_0 | |
end | |
}) | |
_base_0.__class = _class_0 | |
local self = _class_0 | |
self.versionRe = function(self, s) | |
local mjr, mnr, pch, rmn = s:match('^(%d+)%.(%d+)%.(%d+)(.*)$') | |
if not (mjr) then | |
return nil | |
end | |
local add, r = rmn:match('^%-([0-9a-zA-z.-]+)(.*)$') | |
if add then | |
rmn = r | |
end | |
local meta | |
meta, r = rmn:match('^%+([0-9a-zA-Z.-]+)(.*)$') | |
if meta then | |
rmn = r | |
end | |
if #rmn > 0 then | |
return nil | |
end | |
return mjr, mnr, pch, add, meta | |
end | |
self.partialVersionRe = function(self, s) | |
local mjr, rmn = s:match('^(%d+)(.*)$') | |
if not (mjr) then | |
return nil | |
end | |
local mnr, r = rmn:match('^%.(%d+)(.*)$') | |
if mnr then | |
rmn = r | |
end | |
local pch | |
pch, r = rmn:match('^%.(%d+)(.*)$') | |
if pch then | |
rmn = r | |
end | |
local add | |
add, r = rmn:match('^%-([0-9a-zA-Z.-]*)(.*)$') | |
if add then | |
rmn = r | |
end | |
local meta | |
meta, r = rmn:match('^%+([0-9a-zA-Z.-]*)(.*)$') | |
if meta then | |
rmn = r | |
end | |
if #rmn > 0 then | |
return nil | |
end | |
return mjr, mnr, pch, add, meta | |
end | |
Version = _class_0 | |
end | |
local SpecItem | |
do | |
local _class_0 | |
local _base_0 = { | |
parse = function(self, requirementString) | |
if not requirementString or type(requirementString) ~= 'string' or requirementString == '' then | |
error("Invalid empty requirement specification: " .. tostring(tostring(requirementString))) | |
end | |
if requirementString == '*' then | |
return { | |
self.__class.KIND_ANY, | |
'' | |
} | |
end | |
local kind, version = self.__class:reSpec(requirementString) | |
if not kind then | |
error("Invalid requirement specification: " .. tostring(requirementString)) | |
end | |
kind = self.__class.KIND_ALIASES[kind] or kind | |
local spec = Version(version, true) | |
if spec.build ~= nil and kind ~= self.__class.KIND_EQUAL and kind ~= self.__class.KIND_NEQ then | |
error("Invalid requirement specification " .. tostring(requirementString) .. ": build numbers have no ordering") | |
end | |
return { | |
kind, | |
spec | |
} | |
end, | |
match = function(self, version) | |
local _exp_0 = self.kind | |
if self.__class.KIND_ANY == _exp_0 then | |
return true | |
elseif self.__class.KIND_LT == _exp_0 then | |
return version < self.spec | |
elseif self.__class.KIND_LTE == _exp_0 then | |
return version <= self.spec | |
elseif self.__class.KIND_EQUAL == _exp_0 then | |
return version == self.spec | |
elseif self.__class.KIND_GTE == _exp_0 then | |
return version >= self.spec | |
elseif self.__class.KIND_GT == _exp_0 then | |
return version > self.spec | |
elseif self.__class.KIND_NEQ == _exp_0 then | |
return version ~= self.spec | |
elseif self.__class.KIND_CARET == _exp_0 then | |
return self.spec <= version and version < self.spec:next_major() | |
elseif self.__class.KIND_TILDE == _exp_0 then | |
return self.spec <= version and version < self.spec:next_minor() | |
else | |
return error("Unexpected match kind: " .. tostring(self.kind)) | |
end | |
end, | |
__tostring = function(self) | |
return tostring(self.kind) .. tostring(self.spec) | |
end, | |
__eq = function(self, other) | |
return self.kind == other.kind and self.spec == other.spec | |
end | |
} | |
_base_0.__index = _base_0 | |
_class_0 = setmetatable({ | |
__init = function(self, requirementString) | |
self.kind, self.spec = unpack(self:parse(requirementString)) | |
end, | |
__base = _base_0, | |
__name = "SpecItem" | |
}, { | |
__index = _base_0, | |
__call = function(cls, ...) | |
local _self_0 = setmetatable({}, _base_0) | |
cls.__init(_self_0, ...) | |
return _self_0 | |
end | |
}) | |
_base_0.__class = _class_0 | |
local self = _class_0 | |
self.KIND_ANY = '*' | |
self.KIND_LT = '<' | |
self.KIND_LTE = '<=' | |
self.KIND_EQUAL = '==' | |
self.KIND_SHORTEQ = '=' | |
self.KIND_EMPTY = '' | |
self.KIND_GTE = '>=' | |
self.KIND_GT = '>' | |
self.KIND_NEQ = '!=' | |
self.KIND_CARET = '^' | |
self.KIND_TILDE = '~' | |
self.KIND_ALIASES = { | |
[self.__class.KIND_SHORTEQ] = self.__class.KIND_EQUAL, | |
[self.__class.KIND_EMPTY] = self.__class.KIND_EQUAL | |
} | |
self.reSpec = function(self, s) | |
local chr, v = s:match('^(.-)(%d.*)$') | |
if not (chr == '<' or chr == '<=' or chr == '' or chr == '=' or chr == '==' or chr == '>=' or chr == '>' or chr == '!=' or chr == '^' or chr == '~') then | |
return nil | |
else | |
return chr, v | |
end | |
end | |
SpecItem = _class_0 | |
end | |
local Spec | |
do | |
local _class_0 | |
local _base_0 = { | |
parse = function(self, specsString) | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for x in specsString:gmatch('[^,]+') do | |
_accum_0[_len_0] = SpecItem(x) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end, | |
match = function(self, version) | |
local _list_0 = self.specs | |
for _index_0 = 1, #_list_0 do | |
local spec = _list_0[_index_0] | |
if not spec:match(version) then | |
return false | |
end | |
end | |
return true | |
end, | |
filter = function(self, versions) | |
local i = 0 | |
return function() | |
while true do | |
i = i + 1 | |
local version = versions[i] | |
if not (version) then | |
return nil | |
end | |
if self:match(version) then | |
return version | |
end | |
end | |
end | |
end, | |
select = function(self, versions) | |
local options | |
do | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for x in self:filter(versions) do | |
_accum_0[_len_0] = x | |
_len_0 = _len_0 + 1 | |
end | |
options = _accum_0 | |
end | |
if #options > 0 then | |
local max = options[1] | |
for _index_0 = 1, #options do | |
local ver = options[_index_0] | |
if max < ver then | |
max = ver | |
end | |
end | |
return max | |
else | |
return nil | |
end | |
end, | |
__index = function(self, k) | |
if self:match(k) then | |
return true | |
else | |
return nil | |
end | |
end, | |
__pairs = function(self) | |
return pairs(self.specs) | |
end, | |
__ipairs = function(self) | |
return ipairs(self.specs) | |
end, | |
__tostring = function(self) | |
return concat((function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = self.specs | |
for _index_0 = 1, #_list_0 do | |
local spec = _list_0[_index_0] | |
_accum_0[_len_0] = tostring(spec) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)(), ',') | |
end, | |
__eq = function(self, other) | |
local _list_0 = self.specs | |
for _index_0 = 1, #_list_0 do | |
local selfSpec = _list_0[_index_0] | |
local s = false | |
local _list_1 = other.specs | |
for _index_1 = 1, #_list_1 do | |
local otherSpec = _list_1[_index_1] | |
if selfSpec == otherSpec then | |
s = true | |
break | |
end | |
end | |
if not s then | |
return false | |
end | |
end | |
return true | |
end | |
} | |
_base_0.__index = _base_0 | |
_class_0 = setmetatable({ | |
__init = function(self, specsStrings) | |
if type(specsStrings) == 'string' then | |
specsStrings = { | |
specsStrings | |
} | |
end | |
local subspecs | |
do | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for _index_0 = 1, #specsStrings do | |
local spec = specsStrings[_index_0] | |
_accum_0[_len_0] = self:parse(spec) | |
_len_0 = _len_0 + 1 | |
end | |
subspecs = _accum_0 | |
end | |
self.specs = { } | |
for _index_0 = 1, #subspecs do | |
local subspec = subspecs[_index_0] | |
for _index_1 = 1, #subspec do | |
local spec = subspec[_index_1] | |
insert(self.specs, spec) | |
end | |
end | |
end, | |
__base = _base_0, | |
__name = "Spec" | |
}, { | |
__index = _base_0, | |
__call = function(cls, ...) | |
local _self_0 = setmetatable({}, _base_0) | |
cls.__init(_self_0, ...) | |
return _self_0 | |
end | |
}) | |
_base_0.__class = _class_0 | |
Spec = _class_0 | |
end | |
local compare | |
compare = function(v1, v2) | |
return baseCmp(Version(v1, Version(v2))) | |
end | |
local match | |
match = function(spec, version) | |
return Spec(spec):match(Version(version)) | |
end | |
local validate | |
validate = function(versionString) | |
return ({ | |
Version:parse(versionString) | |
})[1] | |
end | |
return { | |
Spec = Spec, | |
SpecItem = SpecItem, | |
Version = Version, | |
compare = compare, | |
match = match, | |
validate = validate | |
} | |
end)() | |
local isAvailable | |
isAvailable = require("component").isAvailable | |
local parse, getWorkingDirectory | |
do | |
local _obj_0 = require("shell") | |
parse, getWorkingDirectory = _obj_0.parse, _obj_0.getWorkingDirectory | |
end | |
local shell = require("shell") | |
local isDirectory, exists, makeDirectory, concat, copy | |
do | |
local _obj_0 = require("filesystem") | |
isDirectory, exists, makeDirectory, concat, copy = _obj_0.isDirectory, _obj_0.exists, _obj_0.makeDirectory, _obj_0.concat, _obj_0.copy | |
end | |
local fs = require("filesystem") | |
local serialize, unserialize | |
do | |
local _obj_0 = require("serialization") | |
serialize, unserialize = _obj_0.serialize, _obj_0.unserialize | |
end | |
local pull | |
pull = require("event").pull | |
local clearLine, getCursor | |
do | |
local _obj_0 = require("term") | |
clearLine, getCursor = _obj_0.clearLine, _obj_0.getCursor | |
end | |
local exit | |
exit = os.exit | |
local write, stderr | |
do | |
local _obj_0 = io | |
write, stderr = _obj_0.write, _obj_0.stderr | |
end | |
local insert, unpack | |
do | |
local _obj_0 = table | |
insert, unpack = _obj_0.insert, _obj_0.unpack | |
end | |
local listFiles = fs.list | |
local options, args = { }, { } | |
local request = nil | |
local modules = { } | |
local config = { } | |
local modulePath = "/etc/hpm/module/" | |
local distPath = "/var/lib/hpm/dist/" | |
local exitCode = 0 | |
local CONFIG_PATH = "/etc/hpm/hpm.cfg" | |
local USAGE = [[Usage: hpm OPTIONS COMMAND | |
See `man hpm` for more info.]] | |
local DEFAULT_CONFIG = [[-- << Global settings >> ------------------------------------------------------- | |
-- A directory where package manifests will be placed. | |
-- It will be created if it doesn't exist. | |
dist = "/var/lib/hpm/dist" | |
-- A place where to search for custom hpm modules. | |
-- It will be created if it doesn't exist. | |
modules = "/etc/hpm/module" | |
-- << Settings related to the hel module >> ------------------------------------ | |
hel = {} | |
-- If set to `false`, hpm will *only* remove a package that hpm is told to | |
-- remove. Otherwise, all of its dependants will be also removed. | |
hel.remove_dependants = true | |
-- << Settings related to the oppm module >> ----------------------------------- | |
oppm = {} | |
-- A directory where package manifests will be stored for faster access. | |
oppm.cache_directory = "/var/cache/hpm/oppm" | |
-- See hel.remove_dependants above. | |
oppm.remove_dependants = true]] | |
local log = { | |
info = function(...) | |
if options.v then | |
return print(table.concat((function(...) | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = { | |
... | |
} | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
_accum_0[_len_0] = tostring(x) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)(...), "\t")) | |
end | |
end, | |
print = function(...) | |
if not (options.q) then | |
return print(table.concat((function(...) | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = { | |
... | |
} | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
_accum_0[_len_0] = tostring(x) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)(...), "\t")) | |
end | |
end, | |
error = function(...) | |
if not (options.q) then | |
return stderr:write(table.concat((function(...) | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = { | |
... | |
} | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
_accum_0[_len_0] = tostring(x) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)(...), "\t") .. '\n') | |
end | |
end, | |
fatal = function(...) | |
if not (options.q) then | |
stderr:write(table.concat((function(...) | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = { | |
... | |
} | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
_accum_0[_len_0] = tostring(x) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)(...), "\t") .. '\n') | |
end | |
return exit(1) | |
end | |
} | |
local assert | |
assert = function(statement, message) | |
if not (statement) then | |
return log.fatal(message) | |
end | |
end | |
local unimplemented | |
unimplemented = function(what) | |
return log.fatal((tostring(what)) .. ": Not implemented yet!") | |
end | |
local printUsage | |
printUsage = function() | |
write(USAGE) | |
return exit(0) | |
end | |
local try | |
try = function(result, reason) | |
if not (result) then | |
log.fatal(reason) | |
end | |
return result | |
end | |
local checkType | |
checkType = function(v, t, c) | |
if not (type(v == t)) then | |
log.fatal("Value '" .. tostring(v) .. "' is " .. tostring(type(c)) .. ", however, a " .. tostring(t) .. " is expected.") | |
end | |
return c | |
end | |
local argNumber | |
argNumber = function(v) | |
return checkType(v, "number", tonumber(v)) | |
end | |
local argString | |
argString = function(v) | |
return checkType(v, "string", tostring(v)) | |
end | |
local isin | |
isin = function(v, tbl) | |
for k, value in pairs(tbl) do | |
if value == v then | |
return true, k | |
end | |
end | |
return false | |
end | |
local tableLen | |
tableLen = function(tbl) | |
local result = 0 | |
for k, v in pairs(tbl) do | |
result = result + 1 | |
end | |
return result | |
end | |
local empty | |
empty = function(v) | |
if type(v) == "nil" then | |
return true | |
elseif type(v) == "string" then | |
return not v or #v < 1 | |
elseif type(v) == "table" then | |
return not v or tableLen(v) < 1 | |
else | |
return true | |
end | |
end | |
local all | |
all = function(vals) | |
for _index_0 = 1, #vals do | |
local v = vals[_index_0] | |
if not v then | |
return false | |
end | |
end | |
return true | |
end | |
local existsDir | |
existsDir = function(path) | |
return exists(path) and isDirectory(path) | |
end | |
local existsFile | |
existsFile = function(path) | |
return exists(path) and not isDirectory(path) | |
end | |
local plural | |
plural = function(amount) | |
return amount == 1 and "" or "s" | |
end | |
local singular | |
singular = function(amount) | |
return amount ~= 1 and "" or "s" | |
end | |
local linkingVerb | |
linkingVerb = function(amount) | |
return amount == 1 and "is" or "are" | |
end | |
local parsePackageName | |
parsePackageName = function(value) | |
return value:match("^([^:]-):?([^:@]+)@?([^:@]*)$") | |
end | |
local remove | |
remove = function(path) | |
if fs.get(shell.resolve(path)).isReadOnly() then | |
return false, "the path is readonly!" | |
elseif not exists(path) then | |
return false, "the filesystem node doesn't exist." | |
else | |
if not (isDirectory(path) or fs.isLink(path)) then | |
return fs.remove(path) | |
else | |
for file in try(listFiles(path)) do | |
remove(concat(path, file)) | |
end | |
return fs.remove(path) | |
end | |
end | |
end | |
local loadConfig | |
loadConfig = function() | |
local path = options.c or options.config or CONFIG_PATH | |
if not existsFile(path) then | |
local dirPath = fs.path(path) | |
if not existsDir(dirPath) then | |
local result, reason = makeDirectory(dirPath) | |
if not result then | |
return false, "Failed to create '" .. tostring(dirPath) .. "' directory for the config file: " .. tostring(reason) | |
end | |
end | |
local file, reason = io.open(path, "w") | |
if file then | |
file:write(DEFAULT_CONFIG) | |
file:close() | |
else | |
return false, "Failed to open config file for writing: " .. tostring(reason) | |
end | |
end | |
local file, reason = io.open(path, "r") | |
if file then | |
local content = file:read("*all") | |
file:close() | |
local globals = { } | |
(load(content, "config", "t", globals))() | |
local newUndecl | |
newUndecl = function(base) | |
if base == nil then | |
base = { } | |
end | |
return setmetatable(base, { | |
__index = { | |
get = function(k, v, createNewUndecl) | |
if type(base[k]) ~= "nil" then | |
if type(base[k]) == "table" then | |
return newUndecl(base[k]) | |
end | |
return base[k] | |
end | |
log.error("Attempt to access undeclared config field '" .. tostring(k) .. "'!") | |
if not createNewUndecl then | |
return v | |
else | |
return newUndecl(v) | |
end | |
end | |
} | |
}) | |
end | |
config = newUndecl(globals) | |
modulePath = config.get("modules", modulePath) | |
distPath = config.get("dist", distPath) | |
return config | |
else | |
return false, "Failed to open config file for reading: " .. tostring(reason) | |
end | |
end | |
local checkInternet | |
checkInternet = function() | |
if not (isAvailable("internet")) then | |
log.fatal("This command requires an internet card to run!") | |
end | |
request = request or require("internet").request | |
end | |
local download | |
download = function(url) | |
checkInternet() | |
return pcall(request, url) | |
end | |
local loadCustomModules | |
loadCustomModules = function() | |
if not existsDir(modulePath) then | |
local result, reason = makeDirectory(modulePath) | |
if not result then | |
return false, "Failed to create '" .. tostring(modulePath) .. "' directory for custom modules: " .. tostring(reason) | |
end | |
end | |
local list = try(listFiles(modulePath)) | |
for file in list do | |
local name = file:match("^(.+)%..+$") | |
local mod = (loadfile(concat(modulePath, file), "t", _ENV))() | |
if mod then | |
modules[name] = mod | |
end | |
end | |
return true | |
end | |
local findCustomCommand | |
findCustomCommand = function(name) | |
local command = name | |
local mod | |
do | |
local p1 = name:find(':') | |
if p1 then | |
command = name:sub(p1 + 1) | |
mod = name:sub(1, p1 - 1) | |
end | |
end | |
if not mod then | |
local candidates = { } | |
for modName, mod in pairs(modules) do | |
if mod[command] then | |
if type(mod[command]) == "table" and mod[command].__public == true then | |
insert(candidates, { | |
class = mod, | |
module = modName, | |
method = mod[command] | |
}) | |
end | |
end | |
end | |
if #candidates > 1 then | |
local pos = nil | |
for k, mod in pairs(candidates) do | |
if mod.module == "hel" then | |
pos = k | |
break | |
end | |
end | |
if pos then | |
candidates = { | |
candidates[pos] | |
} | |
end | |
end | |
if #candidates > 1 then | |
log.print("Ambiguous choice: method " .. tostring(command) .. " is implemented in the following modules:") | |
for _index_0 = 1, #candidates do | |
local mod = candidates[_index_0] | |
log.print(" * " .. tostring(mod.module)) | |
end | |
log.print("Choose a specific module by prepending its name with a colon, e.g., " .. tostring(candidates[1].module) .. ":" .. tostring(command) .. ".") | |
return false | |
elseif #candidates == 0 then | |
log.error("Unknown command: " .. tostring(command)) | |
return false | |
else | |
mod = candidates[1].module | |
log.info("Note, using " .. tostring(mod) .. ":" .. tostring(command) .. ".") | |
return function(...) | |
return candidates[1].method(candidates[1].class, ...) | |
end | |
end | |
else | |
if modules[mod] and empty(command) then | |
local modSpecMths = { } | |
for k, v in pairs(modules[mod]) do | |
if type(v) == "table" and v.__public == true then | |
insert(modSpecMths, tostring(k)) | |
end | |
end | |
log.print("Available module-specific commands: " .. tostring(table.concat(modSpecMths, ", "))) | |
return false | |
end | |
if not modules[mod] or not modules[mod][command] or modules[mod][command] and (type(modules[mod][command]) ~= "table" or modules[mod][command].__public ~= true) then | |
log.error("Unknown command: " .. tostring(mod) .. ":" .. tostring(command)) | |
return false | |
else | |
return function(...) | |
return modules[mod][command](modules[mod], ...) | |
end | |
end | |
end | |
end | |
local getModuleBy | |
getModuleBy = function(source) | |
if not source or source == "" then | |
source = "hel" | |
else | |
source = source | |
end | |
return modules[source] or modules.default | |
end | |
local callModuleMethod | |
callModuleMethod = function(mod, name, ...) | |
if mod == nil then | |
mod = modules.default | |
end | |
if mod[name] then | |
return mod[name](mod, ...) | |
else | |
return modules.default[name](modules.default, ...) | |
end | |
end | |
local saveManifest | |
saveManifest = function(manifest, mod, path, name) | |
if mod == nil then | |
mod = "hel" | |
end | |
if path == nil then | |
path = concat(distPath, mod) | |
end | |
if name == nil then | |
name = manifest.name | |
end | |
if not manifest then | |
return false, "'nil' given" | |
end | |
if not existsDir(path) then | |
local result, reason = makeDirectory(path) | |
if not result then | |
return false, "Failed to create '" .. tostring(concat(path, mod)) .. "' directory for manifest files: " .. tostring(reason) | |
end | |
end | |
local file, reason = io.open(concat(path, name), "w") | |
if file then | |
file:write(serialize(manifest)) | |
file:close() | |
return true | |
else | |
return false, "Failed to open file for writing: " .. tostring(reason) | |
end | |
end | |
local loadManifest | |
loadManifest = function(name, path, mod) | |
if mod == nil then | |
mod = "hel" | |
end | |
path = path or concat(distPath, mod, name) | |
if existsFile(path) then | |
local file, reason = io.open(path, "rb") | |
if file then | |
local manifest = try(unserialize(file:read("*all"))) | |
file:close() | |
return manifest | |
else | |
return false, "Failed to open manifest for '" .. tostring(name) .. "' package: " .. tostring(reason) | |
end | |
else | |
return false, "No manifest found for '" .. tostring(name) .. "' package" | |
end | |
end | |
local removeManifest | |
removeManifest = function(name, mod) | |
if mod == nil then | |
mod = "hel" | |
end | |
local path = concat(distPath, mod, name) | |
if existsFile(path) then | |
return remove(path) | |
else | |
return false, "No manifest found for '" .. tostring(name) .. "' package" | |
end | |
end | |
local public | |
public = function(func) | |
return setmetatable({ | |
__public = true | |
}, { | |
__call = function(self, ...) | |
return func(...) | |
end | |
}) | |
end | |
local wrapResponse | |
wrapResponse = function(resp, file) | |
return function() | |
local result, chunk = pcall(resp) | |
if not (result) then | |
return false, "Could not download '" .. tostring(file) .. "': " .. tostring(chunk) | |
else | |
return chunk | |
end | |
end | |
end | |
local recv | |
recv = function(url, connectError, downloadError) | |
if connectError == nil then | |
connectError = "Could not download '%s': %s" | |
end | |
if downloadError == nil then | |
downloadError = "Could not download '%s': %s" | |
end | |
local result, response, reason = download(url) | |
if not (result and response) then | |
return false, connectError:format(url, reason) | |
end | |
local data = "" | |
for chunk, reason in wrapResponse(response) do | |
if chunk then | |
data = data .. chunk | |
else | |
return false, downloadError:format(url, reason) | |
end | |
end | |
return data | |
end | |
local confirm | |
confirm = function() | |
if not (options.y) then | |
io.write("Press [ENTER] to continue...") | |
local key = select(3, pull("key_down")) | |
if key == 13 then | |
clearLine() | |
return true | |
else | |
io.write("\n") | |
return false | |
end | |
else | |
return true | |
end | |
end | |
local pkgPlan | |
pkgPlan = function(plan) | |
local complexity = 0 | |
local msg = { } | |
if not (empty(plan.install)) then | |
local m = { | |
"Packages to INSTALL:", | |
table.concat(plan.install, " ") | |
} | |
insert(msg, m) | |
complexity = complexity + #plan.install | |
else | |
plan.install = { } | |
end | |
if not (empty(plan.reinstall)) then | |
local m = { | |
"Packages to REINSTALL:", | |
table.concat(plan.reinstall, " ") | |
} | |
insert(msg, m) | |
complexity = complexity + #plan.reinstall | |
else | |
plan.reinstall = { } | |
end | |
if not (empty(plan.upgrade)) then | |
local m = { | |
"Packages to UPGRADE:", | |
table.concat(plan.upgrade, " ") | |
} | |
insert(msg, m) | |
complexity = complexity + #plan.upgrade | |
else | |
plan.upgrade = { } | |
end | |
if not (empty(plan.remove)) then | |
local m = { | |
"Packages to REMOVE:", | |
table.concat(plan.remove, " ") | |
} | |
insert(msg, m) | |
complexity = complexity + #plan.remove | |
else | |
plan.remove = { } | |
end | |
do | |
local m = { | |
tostring(#plan.install) .. " to INSTALL, " .. tostring(#plan.reinstall) .. " to REINSTALL, " .. tostring(#plan.upgrade) .. " to UPGRADE, " .. tostring(#plan.remove) .. " to REMOVE." | |
} | |
insert(msg, m) | |
end | |
for num, i in pairs(msg) do | |
for num, line in pairs(i) do | |
if num == 1 then | |
log.print(line) | |
else | |
log.print(" " .. tostring(line)) | |
end | |
end | |
if num ~= #msg then | |
log.print("") | |
end | |
end | |
if complexity > 1 then | |
if not (confirm()) then | |
return exit(7) | |
end | |
end | |
end | |
do | |
local _class_0 | |
local _base_0 = { } | |
_base_0.__index = _base_0 | |
_class_0 = setmetatable({ | |
__init = function() end, | |
__base = _base_0, | |
__name = "default" | |
}, { | |
__index = _base_0, | |
__call = function(cls, ...) | |
local _self_0 = setmetatable({}, _base_0) | |
cls.__init(_self_0, ...) | |
return _self_0 | |
end | |
}) | |
_base_0.__class = _class_0 | |
local self = _class_0 | |
self.install = function() | |
return log.fatal("Incorrect source is provided! No default 'install' implementation.") | |
end | |
self.remove = function(self, manifest, mod) | |
if mod == nil then | |
mod = "hel" | |
end | |
if manifest then | |
if manifest.files then | |
for i, file in pairs(manifest.files) do | |
local path = concat(file.dir, file.name) | |
local result, reason = remove(path) | |
if not (result) then | |
return false, "Failed to remove '" .. tostring(path) .. "': " .. tostring(reason) | |
end | |
end | |
end | |
return removeManifest(manifest.name, mod) | |
else | |
return false, "Package can't be removed: the manifest is empty." | |
end | |
end | |
self.save = function() | |
return log.fatal("Incorrect source is provided! No default 'save' implementation.") | |
end | |
modules.default = _class_0 | |
end | |
do | |
local _class_0 | |
local _parent_0 = modules.default | |
local _base_0 = { } | |
_base_0.__index = _base_0 | |
setmetatable(_base_0, _parent_0.__base) | |
_class_0 = setmetatable({ | |
__init = function(self, ...) | |
return _class_0.__parent.__init(self, ...) | |
end, | |
__base = _base_0, | |
__name = "hel", | |
__parent = _parent_0 | |
}, { | |
__index = function(cls, name) | |
local val = rawget(_base_0, name) | |
if val == nil then | |
local parent = rawget(cls, "__parent") | |
if parent then | |
return parent[name] | |
end | |
else | |
return val | |
end | |
end, | |
__call = function(cls, ...) | |
local _self_0 = setmetatable({}, _base_0) | |
cls.__init(_self_0, ...) | |
return _self_0 | |
end | |
}) | |
_base_0.__class = _class_0 | |
local self = _class_0 | |
self.URL = "https://hel-roottree.rhcloud.com/" | |
self.parsePackageJSON = function(self, decoded, spec) | |
if spec == nil then | |
spec = semver.Spec("*") | |
end | |
local selectedVersion = nil | |
local versions = { } | |
for number, data in pairs(decoded.versions) do | |
local v = semver.Version(number) | |
if not (v) then | |
log.fatal("Could not parse the version in package: " .. tostring(v)) | |
end | |
versions[v] = data | |
end | |
local success, bestMatch = pcall(function() | |
return spec:select((function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for version, data in pairs(versions) do | |
_accum_0[_len_0] = version | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)()) | |
end) | |
if not (success) then | |
log.fatal("Could not select the best version: " .. tostring(bestMatch)) | |
end | |
selectedVersion = tostring(bestMatch) | |
if not (bestMatch) then | |
log.fatal("No candidate for version specification '" .. tostring(spec) .. "' found!") | |
end | |
local data = { | |
name = decoded.name, | |
version = selectedVersion, | |
files = { }, | |
dependencies = { } | |
} | |
for url, file in pairs(versions[bestMatch].files) do | |
local dir = file.dir | |
local name = file.name | |
insert(data.files, { | |
url = url, | |
dir = dir, | |
name = name | |
}) | |
end | |
for depName, depData in pairs(versions[bestMatch].depends) do | |
local version = depData.version | |
local depType = depData.type | |
insert(data.dependencies, { | |
name = depName, | |
version = version, | |
type = depType | |
}) | |
end | |
return data | |
end | |
self.getPackageSpec = function(self, name) | |
log.info("Downloading package data for " .. tostring(name) .. " ...") | |
local status, response = download(self.URL .. "packages/" .. name) | |
if not (status) then | |
log.fatal("HTTP request error: " .. response) | |
end | |
local jsonData = "" | |
for chunk in response do | |
jsonData = jsonData .. chunk | |
end | |
local decoded = json:decode(jsonData) | |
if not (decoded) then | |
log.fatal("Incorrect JSON format!\n" .. tostring(jsonData)) | |
end | |
return decoded.data | |
end | |
self.rawInstall = function(self, pkgData, isManuallyInstalled, save) | |
if isManuallyInstalled == nil then | |
isManuallyInstalled = false | |
end | |
if save == nil then | |
save = false | |
end | |
local prefix | |
if save then | |
prefix = concat(getWorkingDirectory(), pkgData.name) | |
else | |
prefix = "/" | |
end | |
if save and not existsDir(prefix) then | |
local result, response = makeDirectory(prefix) | |
if not (result) then | |
log.fatal("Failed creating '" .. tostring(prefix) .. "' directory for package '" .. tostring(pkgData.name) .. "'! \n" .. tostring(response)) | |
end | |
elseif not save then | |
local manifest = loadManifest(pkgData.name, nil, "hel") | |
if manifest then | |
if manifest.version == tostring(pkgData.version) then | |
log.print("'" .. tostring(pkgData.name) .. "@" .. tostring(manifest.version) .. "' is already installed, skipping...") | |
return manifest | |
else | |
log.fatal("'" .. tostring(pkgData.name) .. "@" .. tostring(pkgData.version) .. "' was attempted to install, however, another version of the same package is already installed: '" .. tostring(pkgData.name) .. "@" .. tostring(manifest.version) .. "'") | |
end | |
end | |
end | |
for key, file in pairs(pkgData.files) do | |
log.info("Fetching '" .. tostring(file.name) .. "' ...") | |
local contents = try(recv(file.url)) | |
local path = concat(prefix, file.dir) | |
if not existsDir(path) then | |
local result, response = makeDirectory(path) | |
if not (result) then | |
log.fatal("Failed to create '" .. tostring(path) .. "' directory for '" .. tostring(file.name) .. "'! \n" .. tostring(response)) | |
end | |
end | |
do | |
local reason | |
file, reason = io.open(concat(path, file.name), "w") | |
if not (file) then | |
log.fatal("Could not open '" .. tostring(concat(path, file.name)) .. "' for writing: " .. tostring(reason)) | |
end | |
file:write(contents) | |
file:close() | |
end | |
end | |
return { | |
name = pkgData.name, | |
version = tostring(pkgData.version), | |
files = pkgData.files, | |
dependencies = pkgData.dependencies, | |
manual = isManuallyInstalled | |
} | |
end | |
self.save = function(self, name, version) | |
return self:install(name, version, false, true) | |
end | |
self.resolveDependencies = function(self, packages, resolved, unresolved) | |
if resolved == nil then | |
resolved = { } | |
end | |
if unresolved == nil then | |
unresolved = { } | |
end | |
for _index_0 = 1, #packages do | |
local _des_0 = packages[_index_0] | |
local name, version | |
name, version = _des_0.name, _des_0.version | |
insert(unresolved, { | |
name = name, | |
version = "" | |
}) | |
local manifest = loadManifest(name, nil, "hel") | |
if not manifest or not version:match(semver.Version(manifest.version)) then | |
local spec = self:getPackageSpec(name) | |
local data = self:parsePackageJSON(spec, version) | |
unresolved[#unresolved].version = data.version | |
local _list_0 = data.dependencies | |
for _index_1 = 1, #_list_0 do | |
local dep = _list_0[_index_1] | |
local isResolved = false | |
for _index_2 = 1, #resolved do | |
local pkg = resolved[_index_2] | |
if pkg.pkg.name == dep.name then | |
isResolved = true | |
break | |
end | |
end | |
if not isResolved then | |
local key = nil | |
for k, pkg in pairs(unresolved) do | |
if pkg.name == dep.name then | |
key = k | |
break | |
end | |
end | |
if key then | |
if unresolved[key].version == dep.version then | |
log.fatal("Circular dependencies detected: '" .. tostring(name) .. "@" .. tostring(data.version) .. "' depends on '" .. tostring(dep.name) .. "@" .. tostring(dep.version) .. "', and '" .. tostring(unresolved[key].name) .. "@" .. tostring(unresolved[key].version) .. "' depends on '" .. tostring(name) .. "@" .. tostring(data.version) .. "'.") | |
else | |
log.fatal("Attempted to install two versions of the same package: '" .. tostring(dep.name) .. "@" .. tostring(dep.version) .. "' and '" .. tostring(unresolved[key].name) .. "@" .. tostring(unresolved[key].version) .. "' when resolving dependencies for '" .. tostring(name) .. "@" .. tostring(data.version) .. "'.") | |
end | |
end | |
self:resolveDependencies({ | |
{ | |
name = dep.name, | |
version = semver.Spec(dep.version) | |
} | |
}, resolved, unresolved) | |
end | |
end | |
insert(resolved, { | |
pkg = data | |
}) | |
else | |
insert(resolved, { | |
pkg = manifest | |
}) | |
end | |
unresolved[#unresolved] = nil | |
end | |
return resolved | |
end | |
self.getPackageDependants = function(self, name, resolved, unresolved) | |
if resolved == nil then | |
resolved = { } | |
end | |
if unresolved == nil then | |
unresolved = { } | |
end | |
insert(unresolved, { | |
name = name | |
}) | |
local manifest = loadManifest(name, nil, "hel") | |
if manifest then | |
insert(resolved, { | |
name = name, | |
manifest = manifest | |
}) | |
local list = try(listFiles(concat(distPath, "hel"))) | |
for file in list do | |
manifest = try(loadManifest(file, nil, "hel")) | |
local _list_0 = manifest.dependencies | |
for _index_0 = 1, #_list_0 do | |
local dep = _list_0[_index_0] | |
if dep.name == name then | |
local isResolved = false | |
for _index_1 = 1, #resolved do | |
local pkg = resolved[_index_1] | |
if pkg.name == file then | |
isResolved = true | |
break | |
end | |
end | |
if not isResolved then | |
for _index_1 = 1, #unresolved do | |
local pkg = unresolved[_index_1] | |
if pkg.name == file then | |
log.fatal("Circular dependencies detected: " .. tostring(file)) | |
end | |
end | |
self:getPackageDependants(file, resolved, unresolved) | |
end | |
end | |
end | |
end | |
else | |
log.fatal("Package " .. tostring(name) .. " is referenced as a dependant of another package, however, this package isn't installed.") | |
end | |
unresolved[#unresolved] = nil | |
return resolved | |
end | |
self.install = public(function(self, ...) | |
if options.l or options["local"] then | |
local path = shell.resolve(...) | |
local manifest = try(loadManifest(path, concat(path, "manifest"))) | |
local dependencyGraph = self:resolveDependencies(manifest.depends, nil) | |
local onlyDeps = options.d or options.onlyDeps | |
local toInstall = { } | |
for _index_0 = 1, #dependencyGraph do | |
local node = dependencyGraph[_index_0] | |
insert(toInstall, tostring(node.pkg.name) .. "@" .. tostring(node.pkg.version)) | |
end | |
if not (onlyDeps) then | |
insert(toInstall, tostring(manifest.name) .. "@" .. tostring(manifest.version)) | |
end | |
pkgPlan({ | |
install = toInstall | |
}) | |
for i = 1, #dependencyGraph, 1 do | |
local node = dependencyGraph[i] | |
log.print("Installing '" .. tostring(node.pkg.name) .. "@" .. tostring(node.pkg.version) .. "'...") | |
manifest = self:rawInstall(node.pkg, false, false) | |
local success, reason = saveManifest(manifest, "hel") | |
if success then | |
log.info("Saved the manifest of '" .. tostring(manifest.name) .. "'.") | |
else | |
log.fatal("Couldn't save the manifest of '" .. tostring(manifest.name) .. "': " .. tostring(reason) .. ".") | |
end | |
end | |
if not onlyDeps then | |
log.print("Installing '" .. tostring(manifest.name) .. "@" .. tostring(manifest.version) .. "'...") | |
for key, file in pairs(manifest.files) do | |
if not existsDir(concat(file.dir, file.name)) then | |
makeDirectory(file.dir) | |
end | |
local result, reason = copy(concat(path, file.url), concat(file.dir, file.name)) | |
if not (result) then | |
log.fatal("Cannot copy file '" .. tostring(file.name) .. "': " .. tostring(reason)) | |
end | |
end | |
local success, reason = saveManifest(manifest, "hel") | |
if success then | |
log.info("Saved the manifest of '" .. tostring(manifest.name) .. "'.") | |
else | |
log.fatal("Couldn't save the manifest of '" .. tostring(manifest.name) .. "': " .. tostring(reason) .. ".") | |
end | |
end | |
end | |
local packages = { } | |
local _list_0 = { | |
... | |
} | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
local name, version = x:match("(.+)@?(.-)") | |
if empty(version) then | |
version = "*" | |
end | |
log.info("Creating version specification for " .. tostring(version) .. " ...") | |
local success, spec = pcall(function() | |
return semver.Spec(version) | |
end) | |
if not (success) then | |
log.fatal("Could not parse the version specification: " .. tostring(spec) .. "!") | |
end | |
insert(packages, { | |
name = name, | |
version = spec | |
}) | |
end | |
return self:_install(packages, false) | |
end) | |
self._install = function(self, packages, save) | |
if save == nil then | |
save = false | |
end | |
local reinstall = options.r or options.reinstall | |
local dependencyGraph = self:resolveDependencies(packages) | |
local toReinstall = { } | |
local toInstall = { } | |
for _index_0 = 1, #dependencyGraph do | |
local _continue_0 = false | |
repeat | |
local node = dependencyGraph[_index_0] | |
if reinstall then | |
local found = false | |
for _index_1 = 1, #packages do | |
local pkg = packages[_index_1] | |
if pkg.name == node.pkg.name then | |
found = true | |
break | |
end | |
end | |
if found then | |
insert(toReinstall, tostring(node.pkg.name) .. "@" .. tostring(node.pkg.version)) | |
_continue_0 = true | |
break | |
end | |
end | |
insert(toInstall, tostring(node.pkg.name) .. "@" .. tostring(node.pkg.version)) | |
_continue_0 = true | |
until true | |
if not _continue_0 then | |
break | |
end | |
end | |
pkgPlan({ | |
install = toInstall, | |
reinstall = toReinstall | |
}) | |
if reinstall then | |
for _index_0 = 1, #dependencyGraph do | |
local node = dependencyGraph[_index_0] | |
local found = false | |
for _index_1 = 1, #packages do | |
local pkg = packages[_index_1] | |
if pkg.name == node.pkg.name then | |
found = true | |
break | |
end | |
end | |
if found then | |
self:remove(node.pkg, false, true) | |
end | |
end | |
end | |
for _index_0 = 1, #dependencyGraph do | |
local node = dependencyGraph[_index_0] | |
log.print("Installing '" .. tostring(node.pkg.name) .. "@" .. tostring(node.pkg.version) .. "'...") | |
local manifest = self:rawInstall(node.pkg, isin(node.pkg.name, packages), save) | |
local success, reason = saveManifest(manifest, "hel") | |
if success then | |
log.info("Saved the manifest of '" .. tostring(manifest.name) .. "'.") | |
else | |
log.fatal("Couldn't save the manifest of '" .. tostring(manifest.name) .. "': " .. tostring(reason) .. ".") | |
end | |
end | |
end | |
self.remove = function(self, manifest, recursiveCall, noPlan) | |
if recursiveCall == nil then | |
recursiveCall = false | |
end | |
if noPlan == nil then | |
noPlan = false | |
end | |
if recursiveCall then | |
return _class_0.__parent.remove(self, manifest, "hel") | |
end | |
local deps | |
if not config.get("hel", { }, true).get("remove_dependants", true) then | |
deps = { | |
{ | |
name = manifest.name, | |
manifest = manifest | |
} | |
} | |
else | |
deps = self:getPackageDependants(manifest.name) | |
end | |
if not (noPlan) then | |
pkgPlan({ | |
remove = (function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for _index_0 = 1, #deps do | |
local node = deps[_index_0] | |
_accum_0[_len_0] = "hel:" .. tostring(node.manifest.name) .. "@" .. tostring(node.manifest.version) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)() | |
}) | |
end | |
for _index_0 = 1, #deps do | |
local dep = deps[_index_0] | |
log.print("Removing '" .. tostring(dep.manifest.name) .. "@" .. tostring(dep.manifest.version) .. "' ...") | |
try(self:remove(dep.manifest, true)) | |
end | |
return true | |
end | |
self.info = public(function(self, pkg, specString) | |
if specString == nil then | |
specString = "*" | |
end | |
if empty(pkg) then | |
log.fatal("Usage: hpm hel:info <package name> [<version specification>]") | |
end | |
if empty(specString) then | |
specString = "*" | |
end | |
log.print("Creating version specification for " .. tostring(specString) .. " ...") | |
local success, versionSpec = pcall(function() | |
return semver.Spec(specString) | |
end) | |
if not (success) then | |
log.fatal("Could not parse the version specification: " .. tostring(versionSpec) .. "!") | |
end | |
local spec = self:getPackageSpec(pkg) | |
local data = self:parsePackageJSON(spec, versionSpec) | |
local message = { } | |
insert(message, "- Package name: " .. tostring(spec.name)) | |
insert(message, "- Description:\n" .. tostring(spec.description)) | |
insert(message, "- Package owners: " .. tostring(table.concat(spec.owners, ", "))) | |
insert(message, "- Authors:\n" .. tostring(table.concat((function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = spec.authors | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
_accum_0[_len_0] = " - " .. tostring(x) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)(), "\n"))) | |
insert(message, "- License: " .. tostring(spec.license)) | |
insert(message, "- Versions: " .. tostring(tableLen(spec.versions)) .. ", latest: " .. tostring(data.version)) | |
insert(message, " - Files: " .. tostring(#data.files)) | |
insert(message, " - Depends: " .. tostring(table.concat((function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
local _list_0 = data.dependencies | |
for _index_0 = 1, #_list_0 do | |
local x = _list_0[_index_0] | |
_accum_0[_len_0] = tostring(x.name) .. "@" .. tostring(x.version) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)()))) | |
insert(message, " - Changes:\n" .. tostring(spec.versions[data.version].changes)) | |
insert(message, "- Stats:") | |
insert(message, " - Views: " .. tostring(spec.stats.views)) | |
insert(message, "- Creation date: " .. tostring(spec.stats.date.created) .. " UTC") | |
insert(message, "- Last updated: " .. tostring(spec.stats.date["last-updated"]) .. " UTC") | |
return log.print(table.concat(message, "\n")) | |
end) | |
if _parent_0.__inherited then | |
_parent_0.__inherited(_parent_0, _class_0) | |
end | |
modules.hel = _class_0 | |
end | |
do | |
local _class_0 | |
local _parent_0 = modules.default | |
local _base_0 = { } | |
_base_0.__index = _base_0 | |
setmetatable(_base_0, _parent_0.__base) | |
_class_0 = setmetatable({ | |
__init = function(self, ...) | |
return _class_0.__parent.__init(self, ...) | |
end, | |
__base = _base_0, | |
__name = "oppm", | |
__parent = _parent_0 | |
}, { | |
__index = function(cls, name) | |
local val = rawget(_base_0, name) | |
if val == nil then | |
local parent = rawget(cls, "__parent") | |
if parent then | |
return parent[name] | |
end | |
else | |
return val | |
end | |
end, | |
__call = function(cls, ...) | |
local _self_0 = setmetatable({}, _base_0) | |
cls.__init(_self_0, ...) | |
return _self_0 | |
end | |
}) | |
_base_0.__class = _class_0 | |
local self = _class_0 | |
self.REPOS = "https://raw.githubusercontent.com/OpenPrograms/openprograms.github.io/master/repos.cfg" | |
self.PACKAGES = "https://raw.githubusercontent.com/%s/master/programs.cfg" | |
self.FILES = "https://raw.githubusercontent.com/%s/%s" | |
self.DIRECTORY = "https://api.github.com/repos/%s/contents/%s?ref=%s" | |
self.DEFAULT_CACHE_DIRECTORY = "/var/cache/hpm/oppm" | |
self.cacheDirectory = function(self) | |
local dir = config.get("oppm", { }, true).get("cache_directory", self.DEFAULT_CACHE_DIRECTORY) | |
if not (existsDir(dir)) then | |
local result, reason = makeDirectory(dir) | |
if not (result) then | |
log.fatal("Could not create the cache directory at " .. tostring(dir) .. ": " .. tostring(reason)) | |
end | |
end | |
return dir | |
end | |
self.listCache = function(self) | |
local list = { } | |
local cacheDir = self:cacheDirectory() | |
local dirs = try(listFiles(cacheDir)) | |
for dir in dirs do | |
if isDirectory(concat(cacheDir, dir)) then | |
local subdirs = try(listFiles(concat(cacheDir, dir))) | |
for subdir in subdirs do | |
if isDirectory(concat(cacheDir, dir, subdir)) then | |
local pkgs = try(listFiles(concat(cacheDir, dir, subdir))) | |
for pkg in pkgs do | |
local fullPath = concat(cacheDir, dir, subdir, pkg) | |
if not (isDirectory(fullPath)) then | |
local data | |
do | |
local file, reason = io.open(fullPath, "r") | |
if not file then | |
return false, "Could not open '" .. tostring(fullPath) .. "' for reading: " .. tostring(reason) | |
end | |
all = file:read("*all") | |
data = unserialize(all) | |
file:close() | |
end | |
local repo = concat(dir, subdir) | |
insert(list, { | |
path = fullPath, | |
repo = repo, | |
pkg = pkg, | |
data = data | |
}) | |
end | |
end | |
end | |
end | |
end | |
end | |
return list | |
end | |
self.fixCache = function(self) | |
local cacheDir = self:cacheDirectory() | |
local dirs = try(listFiles(cacheDir)) | |
for dir in dirs do | |
local removeDir = true | |
local pathDir = concat(cacheDir, dir) | |
if isDirectory(pathDir) then | |
local subdirs = try(listFiles(pathDir)) | |
for subdir in subdirs do | |
local removeSubdir = true | |
local pathSubdir = concat(pathDir, subdir) | |
if isDirectory(pathSubdir) then | |
local pkgs = try(listFiles(pathSubdir)) | |
for pkg in pkgs do | |
local removePkg = true | |
local pathPkg = concat(pathSubdir, pkg) | |
if not (isDirectory(pathPkg)) then | |
removePkg, removeSubdir, removeDir = false, false, false | |
end | |
if removePkg then | |
remove(pathPkg) | |
end | |
end | |
end | |
if removeSubdir then | |
remove(pathSubdir) | |
end | |
end | |
end | |
if removeDir then | |
remove(pathDir) | |
end | |
end | |
return true | |
end | |
self.resolveDirectory = function(self, repo, branch, path) | |
local data = try(recv(self.DIRECTORY:format(repo, path, branch))) | |
data = json:decode(data) | |
if data.message then | |
return false, "Could not fetch " .. tostring(repo) .. ":" .. tostring(branch) .. "/" .. tostring(path) .. ": " .. tostring(data.message) | |
end | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for _index_0 = 1, #data do | |
local file = data[_index_0] | |
if file.type == "file" then | |
_accum_0[_len_0] = { | |
name = file.name, | |
url = file.download_url, | |
path = file.path | |
} | |
_len_0 = _len_0 + 1 | |
end | |
end | |
return _accum_0 | |
end | |
self.updateCache = function(self) | |
local cacheDir = self:cacheDirectory() | |
local oldFiles = try(self:listCache()) | |
local repos, reason = recv(self.REPOS) | |
if not (repos) then | |
return false, "Could not fetch " .. tostring(self.REPOS) .. ": " .. tostring(reason) | |
end | |
repos = unserialize(repos) | |
local programs = { } | |
for repo, repoData in pairs(repos) do | |
local _continue_0 = false | |
repeat | |
if repoData.repo then | |
log.info("Fetching '" .. tostring(repo) .. "' at '" .. tostring(repoData.repo) .. "' ...") | |
local result, response | |
result, response, reason = download(self.PACKAGES:format(repoData.repo)) | |
if not (result and response) then | |
log.error("Could not fetch '" .. tostring(repo) .. "' at '" .. tostring(repoData.repo) .. "': " .. tostring(reason)) | |
_continue_0 = true | |
break | |
end | |
local data = "" | |
for result, chunk in function() | |
return pcall(response) | |
end do | |
if not result then | |
log.error("Could not fetch '" .. tostring(repo) .. "' at '" .. tostring(repoData.repo) .. "': " .. tostring(chunk)) | |
data = false | |
break | |
else | |
if not chunk then | |
break | |
end | |
data = data .. chunk | |
end | |
end | |
if data == false then | |
_continue_0 = true | |
break | |
end | |
if empty(data) then | |
log.error("Could not fetch '" .. tostring(repo) .. "' at '" .. tostring(repoData.repo) .. "'") | |
_continue_0 = true | |
break | |
end | |
local repoPrograms | |
repoPrograms, reason = unserialize(data) | |
if not repoPrograms then | |
log.error("Manifest '" .. tostring(repo) .. "' at '" .. tostring(repoData.repo) .. "' is malformed: " .. tostring(reason)) | |
_continue_0 = true | |
break | |
end | |
for prg, prgData in pairs(repoPrograms) do | |
local _continue_1 = false | |
repeat | |
if prg:match("[^A-Za-z0-9._-]") then | |
log.error("Package name contains illegal characters: " .. tostring(repo) .. ":" .. tostring(prg) .. "!") | |
_continue_1 = true | |
break | |
end | |
insert(programs, { | |
repo = repoData.repo, | |
name = prg, | |
data = prgData | |
}) | |
_continue_1 = true | |
until true | |
if not _continue_1 then | |
break | |
end | |
end | |
end | |
_continue_0 = true | |
until true | |
if not _continue_0 then | |
break | |
end | |
end | |
local newFiles = { } | |
for _index_0 = 1, #programs do | |
local _des_0 = programs[_index_0] | |
local name, repo, data | |
name, repo, data = _des_0.name, _des_0.repo, _des_0.data | |
if isin(concat(repo, name), newFiles) then | |
log.error("There're multiple packages under the same name: " .. tostring(name) .. "!") | |
end | |
if not (existsDir(concat(cacheDir, repo))) then | |
local result | |
result, reason = makeDirectory(concat(cacheDir, repo)) | |
if not (result) then | |
return false, "Could not create directory '" .. tostring(concat(cacheDir, repo)) .. "': " .. tostring(reason) | |
end | |
end | |
local file | |
file, reason = io.open(concat(cacheDir, repo, name), "w") | |
if not (file) then | |
return false, "Could not open '" .. tostring(concat(cacheDir, repo, name)) .. "' for writing: " .. tostring(reason) | |
end | |
do | |
file:write(serialize({ | |
name = name, | |
repo = repo, | |
data = data | |
})) | |
file:close() | |
end | |
local k | |
do | |
for key, v in pairs(oldFiles) do | |
if v.repo == repo and v.pkg == name then | |
k = key | |
break | |
end | |
end | |
end | |
if k then | |
table.remove(oldFiles, k) | |
else | |
insert(newFiles, concat(repo, name)) | |
end | |
end | |
log.print("Removing old cache files ...") | |
for _index_0 = 1, #oldFiles do | |
local _des_0 = oldFiles[_index_0] | |
local path | |
path = _des_0.path | |
remove(path) | |
end | |
log.print("Fixing bad cache nodes ...") | |
self:fixCache() | |
log.print("- " .. tostring(#programs) .. " program" .. tostring(plural(#programs)) .. " cached.") | |
log.print("- " .. tostring(#newFiles) .. " package" .. tostring(plural(#newFiles)) .. " " .. tostring(linkingVerb(#newFiles)) .. " new.") | |
log.print("- " .. tostring(#oldFiles) .. " package" .. tostring(plural(#oldFiles)) .. " no longer exist" .. tostring(singular(#oldFiles)) .. ".") | |
return true | |
end | |
self.parseLocalPath = function(self, prefix, lPath) | |
if lPath:sub(1, 2) == "//" then | |
return concat(prefix, lPath:sub(3)) | |
else | |
return concat(prefix, "usr", lPath) | |
end | |
end | |
self.rawInstall = function(self, name, prefix, isManuallyInstalled, save) | |
if prefix == nil then | |
prefix = "/" | |
end | |
if isManuallyInstalled == nil then | |
isManuallyInstalled = false | |
end | |
if save == nil then | |
save = false | |
end | |
local cacheList = self:listCache() | |
local stats = { | |
filesInstalled = 0, | |
packagesInstalled = 0 | |
} | |
if save and not existsDir(prefix) then | |
local result, reason = makeDirectory(prefix) | |
if not (result) then | |
log.fatal("Failed to create '" .. tostring(prefix) .. "' directory for package '" .. tostring(name) .. "'! \n" .. tostring(reason)) | |
end | |
elseif not save then | |
local manifest = loadManifest(name, nil, "oppm") | |
if manifest then | |
log.print("'" .. tostring(name) .. "' is already installed, skipping...") | |
return manifest, stats | |
end | |
end | |
local manifest | |
for _index_0 = 1, #cacheList do | |
local package = cacheList[_index_0] | |
local path, pkg, repo, data | |
path, pkg, repo, data = package.path, package.pkg, package.repo, package.data | |
if pkg == name then | |
manifest = package | |
break | |
end | |
end | |
if not (manifest) then | |
log.fatal("No such package: " .. tostring(name)) | |
end | |
local files = { } | |
local repo = manifest.repo | |
for rPath, lPath in pairs(manifest.data.data.files) do | |
local rFiles = { } | |
if rPath:sub(1, 1) == ":" then | |
rFiles = self:resolveDirectory(repo, rPath:sub(2, rPath:find("/") - 1, nil), rPath:sub(rPath:find("/") + 1)) | |
else | |
rFiles = { | |
{ | |
name = fs.name(rPath), | |
path = rPath, | |
url = self.FILES:format(repo, rPath) | |
} | |
} | |
end | |
local name | |
for _index_0 = 1, #rFiles do | |
local _des_0 = rFiles[_index_0] | |
local path, url | |
name, path, url = _des_0.name, _des_0.path, _des_0.url | |
local contents = try(recv(url)) | |
local localPath = self:parseLocalPath(prefix, lPath) | |
if not (existsDir(localPath)) then | |
makeDirectory(localPath) | |
end | |
do | |
local file, reason = io.open(concat(localPath, name), "w") | |
if not file then | |
log.fatal("Could not open file for writing: " .. tostring(reason)) | |
end | |
file:write(contents) | |
file:close() | |
end | |
stats.filesInstalled = stats.filesInstalled + 1 | |
insert(files, { | |
name = name, | |
url = url, | |
dir = localPath | |
}) | |
end | |
end | |
local dependencies = { } | |
if manifest.data.data.dependencies then | |
for dep in pairs(manifest.data.data.dependencies) do | |
insert(dependencies, { | |
name = dep | |
}) | |
end | |
end | |
stats.packagesInstalled = stats.packagesInstalled + 1 | |
return { | |
name = name, | |
files = files, | |
dependencies = dependencies, | |
manual = isManuallyInstalled | |
}, stats | |
end | |
self.resolveDependencies = function(self, packages, resolved, unresolved) | |
if resolved == nil then | |
resolved = { } | |
end | |
if unresolved == nil then | |
unresolved = { } | |
end | |
local cacheList = self:listCache() | |
for _index_0 = 1, #packages do | |
local name = packages[_index_0] | |
unresolved[name] = true | |
local manifest = loadManifest(name, nil, "oppm") | |
if not manifest then | |
local data | |
for _index_1 = 1, #cacheList do | |
local package = cacheList[_index_1] | |
local pkg | |
pkg = package.pkg | |
if pkg == name then | |
data = package | |
break | |
end | |
end | |
if not (data) then | |
return false, "Unknown package: " .. tostring(name) | |
end | |
if data.data.data.dependencies then | |
for dep in pairs(data.data.data.dependencies) do | |
local isResolved = false | |
for _index_1 = 1, #resolved do | |
local pkg = resolved[_index_1] | |
if pkg == dep then | |
isResolved = true | |
break | |
end | |
end | |
if not (isResolved) then | |
if unresolved[dep] then | |
log.fatal("Circular dependencies detected: '" .. tostring(name) .. "' depends on '" .. tostring(dep) .. "', and '" .. tostring(dep) .. "' depends on '" .. tostring(name) .. "'.") | |
end | |
self:resolveDependencies({ | |
dep | |
}, resolved, unresolved) | |
end | |
end | |
end | |
insert(resolved, name) | |
else | |
insert(resolved, name) | |
end | |
unresolved[name] = nil | |
end | |
return resolved | |
end | |
self.getPackageDependants = function(self, name, resolved, unresolved) | |
if resolved == nil then | |
resolved = { } | |
end | |
if unresolved == nil then | |
unresolved = { } | |
end | |
insert(unresolved, { | |
name = name | |
}) | |
local manifest = loadManifest(name, nil, "oppm") | |
if manifest then | |
insert(resolved, { | |
name = name, | |
manifest = manifest | |
}) | |
local list = try(listFiles(concat(distPath, "oppm"))) | |
for file in list do | |
manifest = try(loadManifest(file, nil, "oppm")) | |
local _list_0 = manifest.dependencies | |
for _index_0 = 1, #_list_0 do | |
local dep = _list_0[_index_0] | |
if dep.name == name then | |
local isResolved = false | |
for _index_1 = 1, #resolved do | |
local pkg = resolved[_index_1] | |
if pkg.name == file then | |
isResolved = true | |
break | |
end | |
end | |
if not isResolved then | |
for _index_1 = 1, #unresolved do | |
local pkg = unresolved[_index_1] | |
if pkg.name == file then | |
log.fatal("Circular dependencies detected: " .. tostring(file)) | |
end | |
end | |
self:getPackageDependants(file, resolved, unresolved) | |
end | |
end | |
end | |
end | |
else | |
log.fatal("Package " .. tostring(name) .. " is referenced as a dependant of another package, however, this package isn't installed.") | |
end | |
unresolved[#unresolved] = nil | |
return resolved | |
end | |
self.whatDependsOn = function(self, name) | |
local manifest = try(loadManifest(name, nil, "oppm")) | |
local result = { } | |
local list = try(listFiles(concat(distPath, "oppm"))) | |
for file in list do | |
manifest = try(loadManifest(file, nil, "oppm")) | |
local _list_0 = manifest.dependencies | |
for _index_0 = 1, #_list_0 do | |
local dep = _list_0[_index_0] | |
if dep.name == name then | |
insert(result, file) | |
end | |
end | |
end | |
return result | |
end | |
self._install = function(self, packages, save) | |
if save == nil then | |
save = false | |
end | |
local reinstall = options.r or options.reinstall | |
local dependencyGraph = try(self:resolveDependencies(packages)) | |
pkgPlan({ | |
install = (function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for _index_0 = 1, #dependencyGraph do | |
local node = dependencyGraph[_index_0] | |
if not reinstall or not isin(node, packages) then | |
_accum_0[_len_0] = node | |
_len_0 = _len_0 + 1 | |
end | |
end | |
return _accum_0 | |
end)(), | |
reinstall = reinstall and (function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for _index_0 = 1, #dependencyGraph do | |
local node = dependencyGraph[_index_0] | |
if isin(node, packages) then | |
_accum_0[_len_0] = node | |
_len_0 = _len_0 + 1 | |
end | |
end | |
return _accum_0 | |
end)() or nil | |
}) | |
local manifests = { } | |
local stats = { | |
filesInstalled = 0, | |
packagesInstalled = 0 | |
} | |
if reinstall then | |
for _index_0 = 1, #packages do | |
local name = packages[_index_0] | |
local manifest = try(loadManifest(name, nil, "oppm")) | |
self:remove(manifest, false, true) | |
end | |
end | |
for _index_0 = 1, #dependencyGraph do | |
local node = dependencyGraph[_index_0] | |
log.print("Installing '" .. tostring(node) .. "'...") | |
local prefix | |
if save then | |
prefix = "./" .. tostring(node) .. "/" | |
else | |
prefix = "/" | |
end | |
local manifest, statsPart = self:rawInstall(node, prefix, isin(node, packages), save) | |
stats.filesInstalled = stats.filesInstalled + statsPart.filesInstalled | |
stats.packagesInstalled = stats.packagesInstalled + statsPart.packagesInstalled | |
if stats.packagesInstalled ~= 0 then | |
insert(manifests, manifest) | |
end | |
end | |
log.print("- " .. tostring(stats.packagesInstalled) .. " package" .. tostring(plural(stats.packagesInstalled)) .. " installed.") | |
log.print("- " .. tostring(stats.filesInstalled) .. " file" .. tostring(plural(stats.filesInstalled)) .. " installed.") | |
return manifests | |
end | |
self.install = public(function(self, ...) | |
return self:_install({ | |
... | |
}, false) | |
end) | |
self.remove = function(self, manifest, recursiveCall, noPlan) | |
if recursiveCall == nil then | |
recursiveCall = false | |
end | |
if noPlan == nil then | |
noPlan = false | |
end | |
if recursiveCall then | |
return _class_0.__parent.remove(self, manifest, "oppm") | |
end | |
local deps | |
if not config.get("oppm", { }, true).get("remove_dependants", true) then | |
deps = { | |
{ | |
name = manifest.name, | |
manifest = manifest | |
} | |
} | |
else | |
deps = self:getPackageDependants(manifest.name) | |
end | |
if not (noPlan) then | |
pkgPlan({ | |
remove = (function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for _index_0 = 1, #deps do | |
local node = deps[_index_0] | |
_accum_0[_len_0] = "oppm:" .. tostring(node.name) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)() | |
}) | |
end | |
for _index_0 = 1, #deps do | |
local dep = deps[_index_0] | |
log.print("Removing '" .. tostring(dep.manifest.name) .. "' ...") | |
try(self:remove(dep.manifest, true)) | |
end | |
return true | |
end | |
self.save = function(self, name, meta) | |
return self:install(name, meta, false, true) | |
end | |
self.cache = public(function(self, command, ...) | |
local _exp_0 = command | |
if "update" == _exp_0 then | |
log.print("Updating OpenPrograms program cache ...") | |
try(self:updateCache()) | |
return log.print("Done.") | |
elseif "fix" == _exp_0 then | |
log.print("Fixing OpenPrograms program cache ...") | |
try(self:fixCache()) | |
return log.print("Done.") | |
else | |
log.error("Unknown command.") | |
return log.print("Usage: hpm oppm:cache {update|fix}") | |
end | |
end) | |
self.autoremove = public(function(self) | |
local toRemove = { } | |
local sorted = { } | |
local list = try(listFiles(concat(distPath, "oppm"))) | |
for file in list do | |
local manifest = try(loadManifest(file, nil, "oppm")) | |
if not (manifest.manual) then | |
local deps = self:getPackageDependants(file) | |
if #deps == 1 then | |
insert(toRemove, file) | |
insert(sorted, file) | |
end | |
end | |
end | |
while true do | |
local changed = false | |
list = try(listFiles(concat(distPath, "oppm"))) | |
for file in list do | |
if not (isin(file, toRemove)) then | |
local manifest = try(loadManifest(file, nil, "oppm")) | |
if not (manifest.manual) then | |
local deps = self:getPackageDependants(file) | |
table.remove(deps, 1) | |
if all((function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for _index_0 = 1, #deps do | |
local x = deps[_index_0] | |
_accum_0[_len_0] = isin(x.name, toRemove) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)()) then | |
for _index_0 = 1, #deps do | |
local dep = deps[_index_0] | |
local _, k = isin(dep.name, sorted) | |
if k then | |
table.remove(sorted, k) | |
end | |
end | |
insert(toRemove, file) | |
insert(sorted, file) | |
changed = true | |
end | |
end | |
end | |
end | |
if not (changed) then | |
break | |
end | |
end | |
pkgPlan({ | |
remove = (function() | |
if #toRemove > 0 then | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for _index_0 = 1, #toRemove do | |
local name = toRemove[_index_0] | |
_accum_0[_len_0] = "oppm:" .. tostring(name) | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
else | |
return nil | |
end | |
end)() | |
}) | |
for _index_0 = 1, #sorted do | |
local name = sorted[_index_0] | |
self:remove(try(loadManifest(name, nil, "oppm")), false, false) | |
end | |
log.print("Done.") | |
return true | |
end) | |
if _parent_0.__inherited then | |
_parent_0.__inherited(_parent_0, _class_0) | |
end | |
modules.oppm = _class_0 | |
end | |
local removePackage | |
removePackage = function(source, name) | |
if not (name) then | |
log.fatal("Incorrect package name!") | |
end | |
if empty(source) then | |
source = "hel" | |
end | |
local manifest = try(loadManifest(name, nil, source)) | |
return try(callModuleMethod(getModuleBy(source), "remove", manifest)) | |
end | |
local installPackage | |
installPackage = function(source, name, meta) | |
if not (name) then | |
log.fatal("Incorrect package name!") | |
end | |
if empty(source) then | |
source = "hel" | |
end | |
local reinstallFlag = false | |
local manifest = loadManifest(name, nil, source) | |
if manifest then | |
if not options.r then | |
log.print("'" .. tostring(name) .. "' is already installed, skipping...") | |
return | |
else | |
reinstallFlag = true | |
end | |
end | |
local result, reason = callModuleMethod(getModuleBy(source), "install", name, meta, reinstallFlag) | |
if result then | |
for _index_0 = 1, #result do | |
local manifest = result[_index_0] | |
local success | |
success, reason = saveManifest(manifest, source) | |
if success then | |
log.info("Saved the manifest for '" .. tostring(manifest.name) .. "' package.") | |
else | |
log.error("Couldn't save the manifest for '" .. tostring(name) .. "' package: " .. tostring(reason) .. ".") | |
end | |
end | |
else | |
return log.error("Couldn't install package: " .. tostring(reason)) | |
end | |
end | |
local savePackage | |
savePackage = function(source, name, meta) | |
if not (name) then | |
log.fatal("Incorrect package name!") | |
end | |
if empty(source) then | |
source = "hel" | |
end | |
if source == "local" then | |
log.fatal("No need to save already saved package...") | |
end | |
local result, reason = callModuleMethod(getModuleBy(source), "save", name, meta) | |
if result then | |
for _index_0 = 1, #result do | |
local manifest = result[_index_0] | |
local success | |
success, reason = saveManifest(manifest, "", "./" .. tostring(manifest.name) .. "/", "manifest") | |
if success then | |
log.info("Saved the manifest for local '" .. tostring(name) .. "' package.") | |
else | |
log.error("Couldn't save manifest for local '" .. tostring(name) .. "' package: " .. tostring(reason) .. ".") | |
end | |
end | |
else | |
return log.error("Couldn't install package: " .. tostring(reason) .. ".") | |
end | |
end | |
local printPackageList | |
printPackageList = function() | |
local modList = try(listFiles(distPath)) | |
empty = true | |
for modDir in modList do | |
local mod = fs.name(modDir) | |
if isDirectory(concat(distPath, mod)) then | |
local list = try(listFiles(concat(distPath, mod))) | |
for file in list do | |
if not (isDirectory(concat(distPath, mod, file))) then | |
local manifest = try(loadManifest(file, nil, mod)) | |
log.print(mod .. ":" .. file .. (manifest.version and " @ " .. manifest.version or "")) | |
empty = false | |
end | |
end | |
end | |
end | |
if empty then | |
return log.print("No packages installed.") | |
end | |
end | |
local parseArguments | |
parseArguments = function(...) | |
args, options = parse(...) | |
if #args < 1 then | |
return printUsage() | |
end | |
end | |
local process | |
process = function() | |
local _exp_0 = args[1] | |
if "save" == _exp_0 then | |
if #args < 2 then | |
log.fatal("No package(s) provided!") | |
end | |
for i = 2, #args do | |
savePackage(parsePackageName(args[i])) | |
end | |
elseif "remove" == _exp_0 then | |
if #args < 2 then | |
log.fatal("No package(s) provided!") | |
end | |
for i = 2, #args do | |
removePackage(parsePackageName(args[i])) | |
end | |
elseif "list" == _exp_0 then | |
return printPackageList() | |
elseif "help" == _exp_0 then | |
return printUsage() | |
else | |
do | |
local cmd = findCustomCommand(args[1]) | |
if cmd then | |
return cmd(unpack((function() | |
local _accum_0 = { } | |
local _len_0 = 1 | |
for _index_0 = 2, #args do | |
local x = args[_index_0] | |
_accum_0[_len_0] = x | |
_len_0 = _len_0 + 1 | |
end | |
return _accum_0 | |
end)())) | |
end | |
end | |
end | |
end | |
parseArguments(...) | |
try(loadConfig()) | |
loadCustomModules() | |
process() | |
return exitCode |
local s=load([===[ | |
local rA5U=20160728.17 | |
local Uc06="-[ JSON.lua package by Jeffrey Friedl (http://regex.info/blog/lua/json) version 20160728.17 ]-"local lcBL={VERSION=rA5U,AUTHOR_NOTE=Uc06}local DHPxI=" " | |
local dx={pretty=true,align_keys=false,indent=DHPxI} | |
local RRuSHnxf={__tostring=function()return"JSON array"end}RRuSHnxf.__index=RRuSHnxf | |
local mcYOuT={__tostring=function()return"JSON object"end}mcYOuT.__index=mcYOuT;function lcBL:newArray(iXxD6s) | |
return setmetatable(iXxD6s or{},RRuSHnxf)end;function lcBL:newObject(oiY)return | |
setmetatable(oiY or{},mcYOuT)end;local function Rr(FsYIVlkf) | |
return | |
type(FsYIVlkf)=='number'and FsYIVlkf or FsYIVlkf.N end | |
local scRP0={__index=isNumber,__tostring=function(HLXS0Q_)return HLXS0Q_.S end,__unm=function(Kw)return | |
Rr(Kw)end,__concat=function(nvaIsNv7,vDnoL55) | |
return tostring(nvaIsNv7)..tostring(vDnoL55)end,__add=function(xlAK,zr1y)return Rr(xlAK)+Rr(zr1y)end,__sub=function(Hs,jk)return | |
Rr(Hs)-Rr(jk)end,__mul=function(qzSFyIO,Z65) | |
return Rr(qzSFyIO)*Rr(Z65)end,__div=function(umyCNfj,FT)return Rr(umyCNfj)/Rr(FT)end,__mod=function(YVLXYq,bJfct)return | |
Rr(YVLXYq)%Rr(bJfct)end,__pow=function(OhuFpq_N,Dzg)return | |
Rr(OhuFpq_N)^Rr(Dzg)end,__lt=function(_4O,C)return Rr(_4O)<Rr(C)end,__eq=function(fLI2zRe,_Fr2YU)return | |
Rr(fLI2zRe)==Rr(_Fr2YU)end,__le=function(Xfn,U)return | |
Rr(Xfn)<=Rr(U)end} | |
function lcBL:asNumber(Ebsw) | |
if getmetatable(Ebsw)==scRP0 then return Ebsw elseif | |
type(Ebsw)=='table'and | |
type(Ebsw.S)=='string'and type(Ebsw.N)=='number'then return setmetatable(Ebsw,scRP0)else | |
local UlikV={S=tostring(Ebsw),N=tonumber(Ebsw)}return setmetatable(UlikV,scRP0)end end | |
local function AI0R2TQ6(JtAjijkG) | |
if JtAjijkG<=127 then return string.char(JtAjijkG)elseif JtAjijkG<=2047 then | |
local s=math.floor(JtAjijkG/0x40)local YAtG_LV3=JtAjijkG- (0x40*s)return | |
string.char(0xC0+s,0x80+YAtG_LV3)elseif JtAjijkG<=65535 then | |
local LfEJbh_=math.floor(JtAjijkG/0x1000)local JD=JtAjijkG-0x1000*LfEJbh_ | |
local u=math.floor(JD/0x40)local pzDMZwG=JD-0x40*u;LfEJbh_=0xE0+LfEJbh_;u=0x80+u | |
pzDMZwG=0x80+pzDMZwG | |
if | |
(LfEJbh_==0xE0 and u<0xA0)or | |
(LfEJbh_==0xED and u>0x9F)or(LfEJbh_==0xF0 and u<0x90)or(LfEJbh_==0xF4 and u>0x8F)then return"?"else return string.char(LfEJbh_,u,pzDMZwG)end else local XPoQB=math.floor(JtAjijkG/0x40000) | |
local XxJ=JtAjijkG-0x40000*XPoQB;local o5sms=math.floor(XxJ/0x1000) | |
XxJ=XxJ-0x1000*o5sms;local JQi1jg=math.floor(XxJ/0x40)local wVzn=XxJ-0x40*JQi1jg | |
return string.char( | |
0xF0+XPoQB,0x80+o5sms,0x80+JQi1jg,0x80+wVzn)end end | |
function lcBL:onDecodeError(pE,RSjapQ,QJf,zC)if RSjapQ then | |
if QJf then | |
pE=string.format("%s at char %d of: %s",pE,QJf,RSjapQ)else pE=string.format("%s: %s",pE,RSjapQ)end end | |
if zC~=nil then pE=pE.." (".. | |
lcBL:encode(zC)..")"end | |
if self.assert then self.assert(false,pE)else assert(false,pE)end end;lcBL.onDecodeOfNilError=lcBL.onDecodeError | |
lcBL.onDecodeOfHTMLError=lcBL.onDecodeError | |
function lcBL:onEncodeError(pfZ3SPy_,pDNa2ox6) | |
if pDNa2ox6 ~=nil then pfZ3SPy_=pfZ3SPy_.. | |
" ("..lcBL:encode(pDNa2ox6)..")"end;if self.assert then self.assert(false,pfZ3SPy_)else | |
assert(false,pfZ3SPy_)end end | |
local function yA(Do6yo7nm,y06X3k,ivnJjrA,d3fMjkg) | |
local el=y06X3k:match('^-?[1-9]%d*',ivnJjrA)or y06X3k:match("^-?0",ivnJjrA)if not el then | |
Do6yo7nm:onDecodeError("expected number",y06X3k,ivnJjrA,d3fMjkg.etc)end | |
local Wu_uIt=ivnJjrA+el:len()local w=y06X3k:match('^%.%d+',Wu_uIt)or""Wu_uIt=Wu_uIt+ | |
w:len() | |
local sgeP=y06X3k:match('^[eE][-+]?%d+',Wu_uIt)or""Wu_uIt=Wu_uIt+sgeP:len()local CM=el..w..sgeP;if | |
d3fMjkg.decodeNumbersAsObjects then return lcBL:asNumber(CM),Wu_uIt end | |
if | |
( | |
d3fMjkg.decodeIntegerStringificationLength and(el:len()>=d3fMjkg.decodeIntegerStringificationLength or | |
sgeP:len()>0))or | |
(d3fMjkg.decodeDecimalStringificationLength and | |
( | |
w:len()>=d3fMjkg.decodeDecimalStringificationLength or sgeP:len()>0))then return CM,Wu_uIt end;local Qlmlet=tonumber(CM)if not Qlmlet then | |
Do6yo7nm:onDecodeError("bad number",y06X3k,ivnJjrA,d3fMjkg.etc)end;return Qlmlet,Wu_uIt end | |
local function XmVolesU(_,RkGFh6,hw18,nvCiFt7r)if RkGFh6:sub(hw18,hw18)~='"'then | |
_:onDecodeError("expected string's opening quote",RkGFh6,hw18,nvCiFt7r.etc)end;local xSebv5Jc=hw18+1 | |
local mMp=RkGFh6:len()local rDtVf="" | |
while xSebv5Jc<=mMp do local vj=RkGFh6:sub(xSebv5Jc,xSebv5Jc)if | |
vj=='"'then return rDtVf,xSebv5Jc+1 end | |
if vj~='\\'then rDtVf=rDtVf..vj;xSebv5Jc= | |
xSebv5Jc+1 elseif RkGFh6:match('^\\b',xSebv5Jc)then rDtVf=rDtVf.."\b"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\f',xSebv5Jc)then rDtVf=rDtVf.."\f"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\n',xSebv5Jc)then rDtVf=rDtVf.."\n"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\r',xSebv5Jc)then rDtVf=rDtVf.."\r"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\t',xSebv5Jc)then rDtVf=rDtVf.."\t"xSebv5Jc= | |
xSebv5Jc+2 else | |
local z=RkGFh6:match('^\\u([0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])',xSebv5Jc) | |
if z then xSebv5Jc=xSebv5Jc+6;local Zg=tonumber(z,16) | |
if | |
Zg>=0xD800 and Zg<=0xDBFF then | |
local ykRppH=RkGFh6:match('^\\u([dD][cdefCDEF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])',xSebv5Jc) | |
if ykRppH then xSebv5Jc=xSebv5Jc+6;Zg=0x2400+ (Zg-0xD800)*0x400+ | |
tonumber(ykRppH,16)else end end;rDtVf=rDtVf..AI0R2TQ6(Zg)else rDtVf=rDtVf.. | |
RkGFh6:match('^\\(.)',xSebv5Jc)xSebv5Jc=xSebv5Jc+2 end end end | |
_:onDecodeError("unclosed string",RkGFh6,hw18,nvCiFt7r.etc)end | |
local function eZ0l3ch(WQ6,y36Aetn)local iPL3B4cr,GI2hz6SK=WQ6:find("^[ \n\r\t]+",y36Aetn)if GI2hz6SK then | |
return GI2hz6SK+1 else return y36Aetn end end;local W_63_9 | |
local function h9dyA_4T(Oh,PG,n,O)if PG:sub(n,n)~='{'then | |
Oh:onDecodeError("expected '{'",PG,n,O.etc)end;local N5UjTN=eZ0l3ch(PG,n+1)local qLH5=Oh.strictTypes and | |
Oh:newObject{}or{}if | |
PG:sub(N5UjTN,N5UjTN)=='}'then return qLH5,N5UjTN+1 end | |
local tE=PG:len() | |
while N5UjTN<=tE do local VcV0EuD,pX4gCR=XmVolesU(Oh,PG,N5UjTN,O) | |
N5UjTN=eZ0l3ch(PG,pX4gCR)if PG:sub(N5UjTN,N5UjTN)~=':'then | |
Oh:onDecodeError("expected colon",PG,N5UjTN,O.etc)end | |
N5UjTN=eZ0l3ch(PG,N5UjTN+1)local gad4ZcL,pX4gCR=W_63_9(Oh,PG,N5UjTN,O)qLH5[VcV0EuD]=gad4ZcL | |
N5UjTN=eZ0l3ch(PG,pX4gCR)local dk=PG:sub(N5UjTN,N5UjTN) | |
if dk=='}'then return qLH5,N5UjTN+1 end;if PG:sub(N5UjTN,N5UjTN)~=','then | |
Oh:onDecodeError("expected comma or '}'",PG,N5UjTN,O.etc)end | |
N5UjTN=eZ0l3ch(PG,N5UjTN+1)end;Oh:onDecodeError("unclosed '{'",PG,n,O.etc)end | |
local function oh(E,OO,y,cR6rJlAl)if OO:sub(y,y)~='['then | |
E:onDecodeError("expected '['",OO,y,cR6rJlAl.etc)end;local M6ilzGJ=eZ0l3ch(OO,y+1)local iW6CD=E.strictTypes and | |
E:newArray{}or{}if | |
OO:sub(M6ilzGJ,M6ilzGJ)==']'then return iW6CD,M6ilzGJ+1 end | |
local wZdg=1;local BaX=OO:len() | |
while M6ilzGJ<=BaX do | |
local SJsW11k,Ki1HJT=W_63_9(E,OO,M6ilzGJ,cR6rJlAl)iW6CD[wZdg]=SJsW11k;wZdg=wZdg+1;M6ilzGJ=eZ0l3ch(OO,Ki1HJT) | |
local wjim8xCV=OO:sub(M6ilzGJ,M6ilzGJ)if wjim8xCV==']'then return iW6CD,M6ilzGJ+1 end;if | |
OO:sub(M6ilzGJ,M6ilzGJ)~=','then | |
E:onDecodeError("expected comma or '['",OO,M6ilzGJ,cR6rJlAl.etc)end | |
M6ilzGJ=eZ0l3ch(OO,M6ilzGJ+1)end | |
E:onDecodeError("unclosed '['",OO,y,cR6rJlAl.etc)end | |
W_63_9=function(E,QLam,qTDt,v)qTDt=eZ0l3ch(QLam,qTDt) | |
if qTDt>QLam:len()then E:onDecodeError("unexpected end of string",QLam, | |
nil,v.etc)end | |
if QLam:find('^"',qTDt)then return XmVolesU(E,QLam,qTDt,v.etc)elseif | |
QLam:find('^[-0123456789 ]',qTDt)then return yA(E,QLam,qTDt,v)elseif QLam:find('^%{',qTDt)then | |
return h9dyA_4T(E,QLam,qTDt,v)elseif QLam:find('^%[',qTDt)then return oh(E,QLam,qTDt,v)elseif QLam:find('^true',qTDt)then return true, | |
qTDt+4 elseif QLam:find('^false',qTDt)then return false,qTDt+5 elseif | |
QLam:find('^null',qTDt)then return nil,qTDt+4 else | |
E:onDecodeError("can't parse JSON",QLam,qTDt,v.etc)end end | |
function lcBL:decode(Ta,u,nArcvQl)if type(nArcvQl)~='table'then nArcvQl={}end;if u~=nil then | |
nArcvQl.etc=u end;if | |
type(self)~='table'or self.__index~=lcBL then | |
lcBL:onDecodeError("JSON:decode must be called in method format",nil,nil,nArcvQl.etc)end | |
if Ta==nil then | |
self:onDecodeOfNilError(string.format("nil passed to JSON:decode()"), | |
nil,nil,nArcvQl.etc)elseif type(Ta)~='string'then | |
self:onDecodeError(string.format("expected string argument to JSON:decode(), got %s",type(Ta)), | |
nil,nil,nArcvQl.etc)end;if Ta:match('^%s*$')then return nil end;if Ta:match('^%s*<')then | |
self:onDecodeOfHTMLError(string.format("html passed to JSON:decode()"),Ta, | |
nil,nArcvQl.etc)end | |
if | |
Ta:sub(1,1):byte()==0 or | |
(Ta:len()>=2 and Ta:sub(2,2):byte()==0)then | |
self:onDecodeError("JSON package groks only UTF-8, sorry",Ta,nil,nArcvQl.etc)end;if nArcvQl.decodeNumbersAsObjects==nil then | |
nArcvQl.decodeNumbersAsObjects=self.decodeNumbersAsObjects end;if | |
nArcvQl.decodeIntegerStringificationLength==nil then | |
nArcvQl.decodeIntegerStringificationLength=self.decodeIntegerStringificationLength end;if | |
nArcvQl.decodeDecimalStringificationLength==nil then | |
nArcvQl.decodeDecimalStringificationLength=self.decodeDecimalStringificationLength end | |
local h6Ub7U,Gm=pcall(W_63_9,self,Ta,1,nArcvQl)if h6Ub7U then return Gm else | |
if self.assert then self.assert(false,Gm)else assert(false,Gm)end;return nil,Gm end end | |
local function DZXGTh(YKA7cU) | |
if YKA7cU=="\n"then return"\\n"elseif YKA7cU=="\r"then return"\\r"elseif YKA7cU=="\t"then return"\\t"elseif YKA7cU=="\b"then | |
return"\\b"elseif YKA7cU=="\f"then return"\\f"elseif YKA7cU=='"'then return'\\"'elseif YKA7cU=='\\'then return'\\\\'else return | |
string.format("\\u%04x",YKA7cU:byte())end end | |
local Su9Koz='['..'"'.. | |
'%\\'..'%z'..'\001'..'-'..'\031'..']'local Uk7e=AI0R2TQ6(0x2028)local KwQCk_G=AI0R2TQ6(0x2029) | |
local function ptZa(mCsewfX,yY) | |
local Xf=mCsewfX:gsub(Su9Koz,DZXGTh)if yY.stringsAreUtf8 then | |
Xf=Xf:gsub(Uk7e,'\\u2028'):gsub(KwQCk_G,'\\u2029')end;return'"'..Xf..'"'end | |
local function PEqsd(UlFdiZ7v,U,wFeA)local JQgI={}local N={}local fs52REi=false;local PUNkgaiM | |
for X in pairs(U)do | |
if type(X)=='string'then | |
table.insert(JQgI,X)elseif type(X)=='number'then table.insert(N,X) | |
if X<=0 or X>=math.huge then | |
fs52REi=true elseif not PUNkgaiM or X>PUNkgaiM then PUNkgaiM=X end else | |
UlFdiZ7v:onEncodeError("can't encode table with a key of type "..type(X),wFeA)end end | |
if#JQgI==0 and not fs52REi then | |
if#N>0 then return nil,PUNkgaiM elseif | |
tostring(U)=="JSON array"then return nil elseif tostring(U)=="JSON object"then return{}else return nil end end;table.sort(JQgI)local s6FbB | |
if#N>0 then if UlFdiZ7v.noKeyConversion then | |
UlFdiZ7v:onEncodeError("a table with both numeric and string keys could be an object or array; aborting",wFeA)end | |
s6FbB={}for dc61,aguhyl in pairs(U)do s6FbB[dc61]=aguhyl end | |
table.sort(N) | |
for p,gOPDv in ipairs(N)do local aSdZU3=tostring(gOPDv) | |
if s6FbB[aSdZU3]==nil then | |
table.insert(JQgI,aSdZU3)s6FbB[aSdZU3]=U[gOPDv]else | |
UlFdiZ7v:onEncodeError( | |
"conflict converting table with mixed-type keys into a JSON object: key "..gOPDv.." exists both as a string and a number.",wFeA)end end end;return JQgI,nil,s6FbB end;local iSj | |
function iSj(YKDL,oFyb6OLp,oGdh_mv,WjvvK,TASVwBgU,KjUncMB,XkT) | |
if oFyb6OLp==nil or | |
(not XkT and TASVwBgU and TASVwBgU.null and oFyb6OLp== | |
TASVwBgU.null)then return'null'elseif | |
type(oFyb6OLp)=='string'then return ptZa(oFyb6OLp,TASVwBgU)elseif type(oFyb6OLp)=='number'then | |
if | |
oFyb6OLp~=oFyb6OLp then return"null"elseif oFyb6OLp>=math.huge then return"1e+9999"elseif oFyb6OLp<=-math.huge then | |
return"-1e+9999"else return tostring(oFyb6OLp)end elseif type(oFyb6OLp)=='boolean'then return tostring(oFyb6OLp)elseif type(oFyb6OLp)~= | |
'table'then | |
YKDL:onEncodeError("can't convert "..type(oFyb6OLp).." to JSON",WjvvK)elseif getmetatable(oFyb6OLp)==scRP0 then return tostring(oFyb6OLp)else | |
local c3dr=oFyb6OLp;if type(TASVwBgU)~='table'then TASVwBgU={}end;if type(KjUncMB)~= | |
'string'then KjUncMB=""end | |
if oGdh_mv[c3dr]then | |
YKDL:onEncodeError("table ".. | |
tostring(c3dr).." is a child of itself",WjvvK)else oGdh_mv[c3dr]=true end;local NGH;local tIc,MD2O,HQ=PEqsd(YKDL,c3dr,WjvvK) | |
if MD2O then local cng={}for lE=1,MD2O do | |
table.insert(cng,iSj(YKDL,c3dr[lE],oGdh_mv,WjvvK,TASVwBgU,KjUncMB))end | |
if TASVwBgU.pretty then NGH="[ ".. | |
table.concat(cng,", ").." ]"else NGH="[".. | |
table.concat(cng,",").."]"end elseif tIc then local nI2F0id=HQ or c3dr | |
if TASVwBgU.pretty then local N4aMD_P={}local pCi=0 | |
for lNOqUk8,YAnZNei in ipairs(tIc)do | |
local h8YWR44E=iSj(YKDL,tostring(YAnZNei),oGdh_mv,WjvvK,TASVwBgU,KjUncMB,true) | |
if TASVwBgU.align_keys then pCi=math.max(pCi,#h8YWR44E)end;table.insert(N4aMD_P,h8YWR44E)end | |
local NzeoQJ=KjUncMB..tostring(TASVwBgU.indent or"") | |
local AwGfFV=NzeoQJ..string.rep(" ",pCi).. | |
(TASVwBgU.align_keys and" "or"") | |
local wCRY="%s%"..string.format("%d",pCi).."s: %s"local d0uKSVw1={} | |
for VF,fTrMe in ipairs(tIc)do | |
local ypDndT8=iSj(YKDL,nI2F0id[fTrMe],oGdh_mv,WjvvK,TASVwBgU,AwGfFV) | |
table.insert(d0uKSVw1,string.format(wCRY,NzeoQJ,N4aMD_P[VF],ypDndT8))end;NGH="{\n".. | |
table.concat(d0uKSVw1,",\n").."\n"..KjUncMB.."}"else local MV65={} | |
for Y3D66Ym9,q in | |
ipairs(tIc)do | |
local PhJ=iSj(YKDL,nI2F0id[q],oGdh_mv,WjvvK,TASVwBgU,KjUncMB) | |
local h=iSj(YKDL,tostring(q),oGdh_mv,WjvvK,TASVwBgU,KjUncMB,true) | |
table.insert(MV65,string.format("%s:%s",h,PhJ))end;NGH="{"..table.concat(MV65,",").."}"end else NGH="[]"end;oGdh_mv[c3dr]=false;return NGH end end | |
function lcBL:encode(j2K,r8hgwQ,_6U)if type(self)~='table'or self.__index~=lcBL then | |
lcBL:onEncodeError("JSON:encode must be called in method format",r8hgwQ)end;if | |
type(_6U)~='table'then _6U={}end;return iSj(self,j2K,{},r8hgwQ,_6U)end | |
function lcBL:encode_pretty(GLSzBQs,c,xg)if type(self)~='table'or self.__index~=lcBL then | |
lcBL:onEncodeError("JSON:encode_pretty must be called in method format",c)end;if | |
type(xg)~='table'then xg=dx end;return iSj(self,GLSzBQs,{},c,xg)end;function lcBL.__tostring()return"JSON encode/decode package"end | |
lcBL.__index=lcBL | |
function lcBL:new(Id2KoP_G)local Y2or={}if Id2KoP_G then | |
for zN8ASHV5,iju in pairs(Id2KoP_G)do Y2or[zN8ASHV5]=iju end end | |
return setmetatable(Y2or,lcBL)end;return lcBL:new() | |
]===])() | |
local YAtG_LV3=(function() | |
local yY=[[ Copyright (c) The python-semanticversion project | |
All rights reserved. | |
Redistribution and use in source and binary forms, with or without | |
modification, are permitted provided that the following conditions are met: | |
1. Redistributions of source code must retain the above copyright notice, this | |
list of conditions and the following disclaimer. | |
2. Redistributions in binary form must reproduce the above copyright notice, | |
this list of conditions and the following disclaimer in the documentation | |
and/or other materials provided with the distribution. | |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | |
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
]] | |
yY=[[ The use of the library is similar to the original one, | |
check the documentation here: https://python-semanticversion.readthedocs.io/en/latest/ | |
]]local Xf,UlFdiZ7v,U;do local aSdZU3=table | |
Xf,UlFdiZ7v,U=aSdZU3.concat,aSdZU3.insert,aSdZU3.unpack end;local wFeA | |
wFeA=function(YKDL) | |
do local oFyb6OLp=tonumber(YKDL)if | |
oFyb6OLp then return oFyb6OLp,true else return YKDL,false end end end;local JQgI | |
JQgI=function(oGdh_mv)return oGdh_mv and oGdh_mv[1]=='0'and | |
tonumber(oGdh_mv and oGdh_mv~='0')end;local N | |
N=function(WjvvK,TASVwBgU)if WjvvK==TASVwBgU then return 0 end | |
if WjvvK>TASVwBgU then return 1 end;if WjvvK<TASVwBgU then return-1 end end;local fs52REi | |
fs52REi=function(KjUncMB,XkT)local c3dr,NGH=wFeA(KjUncMB)local tIc,MD2O=wFeA(XkT) | |
if NGH and MD2O then | |
return N(c3dr,tIc)elseif NGH then return-1 elseif MD2O then return 1 else return N(c3dr,tIc)end end;local PUNkgaiM | |
PUNkgaiM=function(HQ,cng)local lE;do local nI2F0id={}for N4aMD_P=1,#HQ do if cng[N4aMD_P]then | |
nI2F0id[HQ[N4aMD_P]]=cng[N4aMD_P]end end | |
lE=nI2F0id end | |
for pCi,NzeoQJ in pairs(lE)do | |
local AwGfFV=fs52REi(pCi,NzeoQJ)if AwGfFV~=0 then return AwGfFV end end;return N(#HQ,#cng)end;local s6FbB | |
do local wCRY | |
local d0uKSVw1={_coerce=function(YAnZNei,h8YWR44E,VF)if VF==nil then VF=false end | |
if h8YWR44E==nil and VF then return h8YWR44E end;return tonumber(h8YWR44E)end,next_major=function(fTrMe) | |
if | |
fTrMe.prerelease and fTrMe.minor==0 and fTrMe.patch==0 then | |
return | |
s6FbB(Xf((function()local ypDndT8={}local MV65=1 | |
local Y3D66Ym9={fTrMe.major,fTrMe.minor,fTrMe.patch}for q=1,#Y3D66Ym9 do local PhJ=Y3D66Ym9[q]ypDndT8[MV65]=tostring(PhJ) | |
MV65=MV65+1 end;return ypDndT8 end)(),'.'))else | |
return | |
s6FbB(Xf((function()local h={}local j2K=1;local r8hgwQ={fTrMe.major+1,0,0} | |
for _6U=1,#r8hgwQ do | |
local GLSzBQs=r8hgwQ[_6U]h[j2K]=tostring(GLSzBQs)j2K=j2K+1 end;return h end)(),'.'))end end,next_minor=function(c)if | |
not(c.minor)then | |
error("Partial version doesn't contain the minor component!")end | |
if c.prerelease and c.patch==0 then | |
return | |
s6FbB(Xf((function() | |
local xg={}local Id2KoP_G=1;local Y2or={c.major,c.minor,c.patch} | |
for zN8ASHV5=1,#Y2or do | |
local iju=Y2or[zN8ASHV5]xg[Id2KoP_G]=tostring(iju)Id2KoP_G=Id2KoP_G+1 end;return xg end)(),'.'))else | |
return | |
s6FbB(Xf((function()local XsWgh={}local l4Hdz=1;local NSXCgSH={c.major,c.minor+1,0} | |
for Wq=1,#NSXCgSH do | |
local SbOQ=NSXCgSH[Wq]XsWgh[l4Hdz]=tostring(SbOQ)l4Hdz=l4Hdz+1 end;return XsWgh end)(),'.'))end end,next_patch=function(IiuHGo)if | |
not(IiuHGo.patch)then | |
error("Partial version doesn't contain the patch component!")end | |
if IiuHGo.prerelease then | |
return | |
s6FbB(Xf((function()local cGqxtYr={} | |
local bgJFKeeZ=1;local yu9fg0nN={IiuHGo.major,IiuHGo.minor,IiuHGo.patch} | |
for wgx=1,# | |
yu9fg0nN do local zlU7X=yu9fg0nN[wgx] | |
cGqxtYr[bgJFKeeZ]=tostring(zlU7X)bgJFKeeZ=bgJFKeeZ+1 end;return cGqxtYr end)(),'.'))else | |
return | |
s6FbB(Xf((function()local t={}local f6qbO=1 | |
local kk={IiuHGo.major,IiuHGo.minor,IiuHGo.patch+1} | |
for QrubIAv=1,#kk do local bLHDW=kk[QrubIAv]t[f6qbO]=tostring(bLHDW)f6qbO=f6qbO+1 end;return t end)(),'.'))end end,coerce=function(YjFd7b,jZgPYb,zN2)if | |
zN2 ==nil then zN2=false end;local IN69pa5 | |
IN69pa5=function(OVx_mN) | |
local lB,byE=OVx_mN:match('^(%d+)(.*)$')if not(lB)then return nil end;local bITCI=lB | |
local K,F5dtVpnN=byE:match('^%.(%d+)(.*)$')if K then byE=F5dtVpnN;bITCI=bITCI.. ('.'..K)end;local kxeBp | |
kxeBp,F5dtVpnN=byE:match('^%.(%d+)(.*)$') | |
if kxeBp then byE=F5dtVpnN;bITCI=bITCI.. ('.'..kxeBp)end;return OVx_mN,bITCI end;local UOWJ,WtalJw=IN69pa5(jZgPYb)if not(UOWJ)then | |
error("Version string lacks a numerical component: ".. | |
tostring(jZgPYb))end | |
local JYrf2=jZgPYb:sub(1,#WtalJw) | |
if not zN2 then while({JYrf2:gsub('.','')})[2]<2 do JYrf2= | |
JYrf2 ..'.0'end end;if#WtalJw==#jZgPYb then return s6FbB(JYrf2,zN2)end;local KHDOUlRY=jZgPYb:sub( | |
#WtalJw+1) | |
KHDOUlRY=KHDOUlRY:gsub('[^a-zA-Z0-9+.-]','-')local I0JvPpn,Ce4ZE=nil,nil | |
if KHDOUlRY:sub(1,1)=='+'then I0JvPpn='' | |
Ce4ZE=KHDOUlRY:sub(2)elseif KHDOUlRY:sub(1,1)=='.'then I0JvPpn=''Ce4ZE=KHDOUlRY:sub(2)elseif | |
KHDOUlRY:sub(1,1)=='-'then KHDOUlRY=KHDOUlRY:sub(2) | |
do | |
local a=KHDOUlRY:find('+')if a then | |
I0JvPpn,Ce4ZE=KHDOUlRY:sub(1,a-1),KHDOUlRY:sub(a+1,-1)else I0JvPpn,Ce4ZE=KHDOUlRY,''end end else do local kQ=KHDOUlRY:find('+') | |
if kQ then I0JvPpn,Ce4ZE=KHDOUlRY:sub(1,kQ-1),KHDOUlRY:sub( | |
kQ+1,-1)else I0JvPpn,Ce4ZE=KHDOUlRY,''end end end;Ce4ZE=Ce4ZE:gsub('+','.')if I0JvPpn and I0JvPpn~=''then JYrf2=JYrf2 .. | |
('-'..I0JvPpn)end;if | |
Ce4ZE and Ce4ZE~=''then JYrf2=JYrf2 .. ('+'..Ce4ZE)end;return | |
YjFd7b.__class(JYrf2,zN2)end,parse=function(EE9LAE,iVx,eg,AQviNt)if | |
eg==nil then eg=false end;if AQviNt==nil then AQviNt=false end;if not iVx or | |
type(iVx)~='string'or iVx==''then | |
error("Invalid empty version string: ".. | |
tostring(tostring(iVx)))end;local T6 | |
if eg then | |
T6=EE9LAE.__class.partialVersionRe else T6=EE9LAE.__class.versionRe end;local NviN0i,BlMQce,o,dpRE,fEiXwWq=T6(EE9LAE.__class,iVx)if not NviN0i then | |
error( | |
"Invalid version string: "..tostring(iVx))end;if JQgI(NviN0i)then | |
error("Invalid leading zero in major: ".. | |
tostring(iVx))end;if JQgI(BlMQce)then | |
error("Invalid leading zero in minor: ".. | |
tostring(iVx))end;if JQgI(o)then | |
error("Invalid leading zero in patch: ".. | |
tostring(iVx))end;NviN0i=tonumber(NviN0i) | |
BlMQce=EE9LAE:_coerce(BlMQce,eg)o=EE9LAE:_coerce(o,eg) | |
if dpRE==nil then if eg and fEiXwWq==nil then return | |
{NviN0i,BlMQce,o,nil,nil}else dpRE={}end elseif dpRE==''then dpRE={}else | |
do | |
local r3JzMga6={}local Tuyw=1 | |
for FYLcr2nu in dpRE:gmatch('[^.]+')do r3JzMga6[Tuyw]=FYLcr2nu;Tuyw=Tuyw+1 end;dpRE=r3JzMga6 end;EE9LAE:_validateIdentifiers(dpRE,false)end | |
if fEiXwWq==nil then if eg then fEiXwWq=nil else fEiXwWq={}end elseif fEiXwWq==''then fEiXwWq={}else do | |
local ioS69={}local AiP=1 | |
for S2jwpoi in fEiXwWq:gmatch('[^.]+')do ioS69[AiP]=S2jwpoi;AiP=AiP+1 end;fEiXwWq=ioS69 end | |
EE9LAE:_validateIdentifiers(fEiXwWq,true)end;return{NviN0i,BlMQce,o,dpRE,fEiXwWq}end,_validateIdentifiers=function(_WX9u,u0riyU,UH)if | |
UH==nil then UH=false end | |
for WNph=1,#u0riyU do local ytF=u0riyU[WNph]if not ytF then | |
error( | |
"Invalid empty identifier ".. | |
tostring(ytF).." in "..tostring(Xf(u0riyU,'.')))end;if | |
ytF:sub(1,1)=='0'and | |
tonumber(ytF)and ytF~='0'and not UH then | |
error("Invalid leading zero in identifier "..tostring(ytF))end end end,__pairs=function(d)return | |
pairs({d.major,d.minor,d.patch,d.prerelease,d.build})end,__ipairs=function(gRm)return | |
ipairs({gRm.major,gRm.minor,gRm.patch,gRm.prerelease,gRm.build})end,__tostring=function(LPX0) | |
local g=tostring(LPX0.major) | |
if LPX0.minor~=nil then g=g.. ('.'..LPX0.minor)end | |
if LPX0.patch~=nil then g=g.. ('.'..LPX0.patch)end | |
if LPX0.prerelease and#LPX0.prerelease>0 or | |
LPX0.partial and LPX0.prerelease and#LPX0.prerelease==0 and LPX0.build==nil then g=g.. ('-'.. | |
Xf(LPX0.prerelease,'.'))end | |
if | |
LPX0.build and#LPX0.build>0 or LPX0.partial and LPX0.build and# | |
LPX0.build==0 then g=g.. ('+'..Xf(LPX0.build,'.'))end;return g end,_comparsionFunctions=function(_l,qao)if | |
qao==nil then qao=false end;local ipUPIzc | |
ipUPIzc=function(J7nsK,dXbd) | |
if J7nsK and dXbd then | |
return PUNkgaiM(J7nsK,dXbd)elseif J7nsK then return-1 elseif dXbd then return 1 else return 0 end end;local N8 | |
N8=function(vQj,sVBxyy)if vQj==sVBxyy then return 0 else return'not implemented'end end;local Gzk | |
Gzk=function(N9d)local S7 | |
S7=function(bJtvRSR,aBhZK5)if bJtvRSR==nil or aBhZK5 ==nil then return 0 else | |
return N9d(bJtvRSR,aBhZK5)end end;return S7 end;if qao then return{N,Gzk(N),Gzk(N),Gzk(ipUPIzc),Gzk(N8)}else return | |
{N,N,N,ipUPIzc,N8}end end,__compare=function(Jz8JUscj,OtGmbAgE) | |
local oU_r=Jz8JUscj:_comparsionFunctions( | |
Jz8JUscj.partial or OtGmbAgE.partial) | |
local n_lv={{oU_r[1],Jz8JUscj.major,OtGmbAgE.major},{oU_r[2],Jz8JUscj.minor,OtGmbAgE.minor},{oU_r[3],Jz8JUscj.patch,OtGmbAgE.patch},{oU_r[4],Jz8JUscj.prerelease,OtGmbAgE.prerelease},{oU_r[5],Jz8JUscj.build,OtGmbAgE.build}} | |
for UYQF=1,#n_lv do local WXx=n_lv[UYQF]local W4EuxJXi,BlYNd61h,XDPndG=U(WXx) | |
local sJYFQIP4=W4EuxJXi(BlYNd61h,XDPndG)if sJYFQIP4 ~=0 then return sJYFQIP4 end end;return 0 end,__compareHelper=function(Ogq0S2,n8Cw3SR,GJqd7gt,slE5aDm2) | |
local aL_g=Ogq0S2:__compare(n8Cw3SR)if aL_g=='not implemented'then return slE5aDm2 end | |
return GJqd7gt(aL_g)end,__eq=function(IMUI10L,vPA) | |
local pUXZ6G4;pUXZ6G4=function(mk)return mk==0 end;return | |
IMUI10L:__compareHelper(vPA,pUXZ6G4,false)end,__lt=function(OeQex1U4,i0cV9) | |
local EGD;EGD=function(VWiGCreH)return VWiGCreH<0 end;return | |
OeQex1U4:__compareHelper(i0cV9,EGD,false)end,__le=function(B_kkL,uEO6Y) | |
local i_053JPY;i_053JPY=function(l)return l<=0 end;return | |
B_kkL:__compareHelper(uEO6Y,i_053JPY,false)end}d0uKSVw1.__index=d0uKSVw1 | |
wCRY=setmetatable({__init=function(UK,NzaICo,k1X83nYm) | |
if k1X83nYm==nil then k1X83nYm=false end;local xxzxfj,_ad1m4I,H1QsS,rIMx,TiA=U(UK:parse(NzaICo,k1X83nYm)) | |
UK.major,UK.minor,UK.patch,UK.prerelease,UK.build,UK.partial=xxzxfj,_ad1m4I,H1QsS,rIMx,TiA,k1X83nYm end,__base=d0uKSVw1,__name="Version"},{__index=d0uKSVw1,__call=function(Y51P,...) | |
local ichL=setmetatable({},d0uKSVw1)Y51P.__init(ichL,...)return ichL end})d0uKSVw1.__class=wCRY;local lNOqUk8=wCRY | |
lNOqUk8.versionRe=function(lNOqUk8,NOK) | |
local Alv,YeLO2,CkrmO,ooovsSJe=NOK:match('^(%d+)%.(%d+)%.(%d+)(.*)$')if not(Alv)then return nil end | |
local s5IsD,KvYEVoXt=ooovsSJe:match('^%-([0-9a-zA-z.-]+)(.*)$')if s5IsD then ooovsSJe=KvYEVoXt end;local VWWD_P | |
VWWD_P,KvYEVoXt=ooovsSJe:match('^%+([0-9a-zA-Z.-]+)(.*)$')if VWWD_P then ooovsSJe=KvYEVoXt end;if#ooovsSJe>0 then return nil end;return | |
Alv,YeLO2,CkrmO,s5IsD,VWWD_P end | |
lNOqUk8.partialVersionRe=function(lNOqUk8,zsMuNkv)local aXxi,Q18a7QTy=zsMuNkv:match('^(%d+)(.*)$')if | |
not(aXxi)then return nil end | |
local K5Rp6,GTIA=Q18a7QTy:match('^%.(%d+)(.*)$')if K5Rp6 then Q18a7QTy=GTIA end;local gdPUe | |
gdPUe,GTIA=Q18a7QTy:match('^%.(%d+)(.*)$')if gdPUe then Q18a7QTy=GTIA end;local _bxEn | |
_bxEn,GTIA=Q18a7QTy:match('^%-([0-9a-zA-Z.-]*)(.*)$')if _bxEn then Q18a7QTy=GTIA end;local pcN_ceXY | |
pcN_ceXY,GTIA=Q18a7QTy:match('^%+([0-9a-zA-Z.-]*)(.*)$')if pcN_ceXY then Q18a7QTy=GTIA end;if#Q18a7QTy>0 then return nil end;return aXxi, | |
K5Rp6,gdPUe,_bxEn,pcN_ceXY end;s6FbB=wCRY end;local X | |
do local _P | |
local rq={parse=function(I,RAAJAsR)if | |
not RAAJAsR or type(RAAJAsR)~='string'or RAAJAsR==''then | |
error("Invalid empty requirement specification: "..tostring(tostring(RAAJAsR)))end;if RAAJAsR== | |
'*'then return{I.__class.KIND_ANY,''}end | |
local c1pjj7,BMv=I.__class:reSpec(RAAJAsR)if not c1pjj7 then | |
error("Invalid requirement specification: "..tostring(RAAJAsR))end;c1pjj7= | |
I.__class.KIND_ALIASES[c1pjj7]or c1pjj7;local NQh8=s6FbB(BMv,true) | |
if | |
NQh8.build~=nil and c1pjj7 ~=I.__class.KIND_EQUAL and c1pjj7 ~= | |
I.__class.KIND_NEQ then | |
error( | |
"Invalid requirement specification "..tostring(RAAJAsR)..": build numbers have no ordering")end;return{c1pjj7,NQh8}end,match=function(P,bkTe) | |
local ohmPbyDd=P.kind | |
if P.__class.KIND_ANY==ohmPbyDd then return true elseif P.__class.KIND_LT==ohmPbyDd then return bkTe< | |
P.spec elseif P.__class.KIND_LTE==ohmPbyDd then return bkTe<=P.spec elseif | |
P.__class.KIND_EQUAL==ohmPbyDd then return bkTe==P.spec elseif P.__class.KIND_GTE==ohmPbyDd then return bkTe>= | |
P.spec elseif P.__class.KIND_GT==ohmPbyDd then return bkTe>P.spec elseif | |
P.__class.KIND_NEQ==ohmPbyDd then return bkTe~=P.spec elseif P.__class.KIND_CARET==ohmPbyDd then | |
return | |
P.spec<=bkTe and bkTe<P.spec:next_major()elseif P.__class.KIND_TILDE==ohmPbyDd then return P.spec<=bkTe and | |
bkTe<P.spec:next_minor()else return | |
error("Unexpected match kind: "..tostring(P.kind))end end,__tostring=function(D)return | |
tostring(D.kind)..tostring(D.spec)end,__eq=function(DfDLWkT,MTU8HP4d)return | |
DfDLWkT.kind==MTU8HP4d.kind and DfDLWkT.spec==MTU8HP4d.spec end}rq.__index=rq | |
_P=setmetatable({__init=function(hIM_cG0i,jD) | |
hIM_cG0i.kind,hIM_cG0i.spec=U(hIM_cG0i:parse(jD))end,__base=rq,__name="SpecItem"},{__index=rq,__call=function(me,...) | |
local sgU5HAMG=setmetatable({},rq)me.__init(sgU5HAMG,...)return sgU5HAMG end})rq.__class=_P;local mo=_P;mo.KIND_ANY='*'mo.KIND_LT='<'mo.KIND_LTE='<=' | |
mo.KIND_EQUAL='=='mo.KIND_SHORTEQ='='mo.KIND_EMPTY=''mo.KIND_GTE='>='mo.KIND_GT='>' | |
mo.KIND_NEQ='!='mo.KIND_CARET='^'mo.KIND_TILDE='~' | |
mo.KIND_ALIASES={[mo.__class.KIND_SHORTEQ]=mo.__class.KIND_EQUAL,[mo.__class.KIND_EMPTY]=mo.__class.KIND_EQUAL} | |
mo.reSpec=function(mo,FDydY)local PEZ_,c=FDydY:match('^(.-)(%d.*)$') | |
if not | |
( | |
PEZ_=='<'or PEZ_=='<='or PEZ_==''or PEZ_=='='or PEZ_=='=='or PEZ_=='>='or PEZ_=='>'or PEZ_=='!='or PEZ_=='^'or PEZ_=='~')then return nil else | |
return PEZ_,c end end;X=_P end;local dc61 | |
do local ElbTbcZG | |
local r3={parse=function(pUiVYRok,jvPsY9)local tEBmuypm={}local hW=1;for iOcgdUx in jvPsY9:gmatch('[^,]+')do | |
tEBmuypm[hW]=X(iOcgdUx)hW=hW+1 end;return tEBmuypm end,match=function(kCwLIk,_l) | |
local rjQ=kCwLIk.specs | |
for Euo0=1,#rjQ do local LIV=rjQ[Euo0]if not LIV:match(_l)then return false end end;return true end,filter=function(vydlAbZ3,BXxv5z) | |
local mKLU=0 | |
return function() | |
while true do mKLU=mKLU+1;local Him=BXxv5z[mKLU]if not(Him)then return nil end;if | |
vydlAbZ3:match(Him)then return Him end end end end,select=function(cPDhu,UQnOS) | |
local tRWU | |
do local X2Zy_nb={}local ITtw3N7E=1;for yozOp in cPDhu:filter(UQnOS)do X2Zy_nb[ITtw3N7E]=yozOp;ITtw3N7E= | |
ITtw3N7E+1 end;tRWU=X2Zy_nb end | |
if#tRWU>0 then local wxU=tRWU[1]for kOmS5sy=1,#tRWU do local CLSdD=tRWU[kOmS5sy] | |
if wxU<CLSdD then wxU=CLSdD end end;return wxU else return nil end end,__index=function(Fh,IlAPA)if | |
Fh:match(IlAPA)then return true else return nil end end,__pairs=function(jLKMpQuK)return | |
pairs(jLKMpQuK.specs)end,__ipairs=function(sUQpby)return ipairs(sUQpby.specs)end,__tostring=function(mbA) | |
return | |
Xf((function() | |
local _qPhpaFx={}local zex=1;local pPGcdu=mbA.specs;for rjp=1,#pPGcdu do local cT2z=pPGcdu[rjp] | |
_qPhpaFx[zex]=tostring(cT2z)zex=zex+1 end;return _qPhpaFx end)(),',')end,__eq=function(zke1tWps,gRFA) | |
local jX9a0tJX=zke1tWps.specs | |
for YFy4TGc=1,#jX9a0tJX do local YjpbYkCb=jX9a0tJX[YFy4TGc]local L1p7luJ=false;local eH=gRFA.specs | |
for WpOZ=1,#eH do | |
local fD2289=eH[WpOZ]if YjpbYkCb==fD2289 then L1p7luJ=true;break end end;if not L1p7luJ then return false end end;return true end}r3.__index=r3 | |
ElbTbcZG=setmetatable({__init=function(folfO,vtsK) | |
if type(vtsK)=='string'then vtsK={vtsK}end;local E1p4Mv | |
do local IHap={}local rDvV=1;for RX1L2q=1,#vtsK do local bCBtWguf=vtsK[RX1L2q] | |
IHap[rDvV]=folfO:parse(bCBtWguf)rDvV=rDvV+1 end;E1p4Mv=IHap end;folfO.specs={} | |
for q=1,#E1p4Mv do local e1sXUN4f=E1p4Mv[q]for x=1,#e1sXUN4f do local VP=e1sXUN4f[x] | |
UlFdiZ7v(folfO.specs,VP)end end end,__base=r3,__name="Spec"},{__index=r3,__call=function(IQwqq,...) | |
local Xcc4=setmetatable({},r3)IQwqq.__init(Xcc4,...)return Xcc4 end})r3.__class=ElbTbcZG;dc61=ElbTbcZG end;local aguhyl | |
aguhyl=function(fqw5,qnVfOeRE)return N(s6FbB(fqw5,s6FbB(qnVfOeRE)))end;local p | |
p=function(YIiSKsxK,Ua)return dc61(YIiSKsxK):match(s6FbB(Ua))end;local gOPDv;gOPDv=function(qeJtG) | |
return({s6FbB:parse(qeJtG)})[1]end;return | |
{Spec=dc61,SpecItem=X,Version=s6FbB,compare=aguhyl,match=p,validate=gOPDv}end)()local LfEJbh_;LfEJbh_=require("component").isAvailable;local JD,u | |
do | |
local pdpNgBcZ=require("shell")JD,u=pdpNgBcZ.parse,pdpNgBcZ.getWorkingDirectory end;local pzDMZwG=require("shell")local XPoQB,XxJ,o5sms,JQi1jg,wVzn;do | |
local wV=require("filesystem") | |
XPoQB,XxJ,o5sms,JQi1jg,wVzn=wV.isDirectory,wV.exists,wV.makeDirectory,wV.concat,wV.copy end | |
local pE=require("filesystem")local RSjapQ,QJf;do local rLd=require("serialization") | |
RSjapQ,QJf=rLd.serialize,rLd.unserialize end;local zC | |
zC=require("event").pull;local pfZ3SPy_,pDNa2ox6,Do6yo7nm;do local z8oF=require("term") | |
pfZ3SPy_,pDNa2ox6,Do6yo7nm=z8oF.clearLine,z8oF.getCursor,z8oF.clear end;local y06X3k;y06X3k=os.exit | |
local ivnJjrA,d3fMjkg | |
do local DB6A7N=io;ivnJjrA,d3fMjkg=DB6A7N.write,DB6A7N.stderr end;local el,Wu_uIt | |
do local VhYX=table;el,Wu_uIt=VhYX.insert,VhYX.unpack end;local w=pE.list;local sgeP,CM={},{}local Qlmlet=nil;local _={}local RkGFh6={}local hw18={} | |
local nvCiFt7r="/etc/hpm/module/"local xSebv5Jc="/var/lib/hpm/dist/"local mMp=0;local rDtVf="/etc/hpm/hpm.cfg" | |
local vj=[[Usage: hpm OPTIONS COMMAND | |
See `man hpm` for more info.]] | |
local z=[[-- << Global settings >> ------------------------------------------------------- | |
-- A directory where package manifests will be placed. | |
-- It will be created if it doesn't exist. | |
dist = "/var/lib/hpm/dist" | |
-- A place where to search for custom hpm modules. | |
-- It will be created if it doesn't exist. | |
modules = "/etc/hpm/module" | |
-- << Settings related to the hel module >> ------------------------------------ | |
hel = {} | |
-- If set to `false`, hpm will *only* remove a package that hpm is told to | |
-- remove. Otherwise, all of its dependants will be also removed. | |
hel.remove_dependants = true | |
-- << Settings related to the oppm module >> ----------------------------------- | |
oppm = {} | |
-- A directory where package manifests will be stored for faster access. | |
oppm.cache_directory = "/var/cache/hpm/oppm" | |
-- See hel.remove_dependants above. | |
oppm.remove_dependants = true]] | |
local Zg={info=function(...) | |
if sgeP.v then | |
return | |
print(table.concat((function(...)local Ha7ErH={}local rjU95v=1;local sxBl={...}for m=1,#sxBl do local nD4LhX6z=sxBl[m] | |
Ha7ErH[rjU95v]=tostring(nD4LhX6z)rjU95v=rjU95v+1 end;return Ha7ErH end)(...),"\t"))end end,print=function(...) | |
if | |
not(sgeP.q)then | |
return | |
print(table.concat((function(...)local iN={}local Lq=1;local s9tW={...}for R61K=1,#s9tW do local Jf4os=s9tW[R61K] | |
iN[Lq]=tostring(Jf4os)Lq=Lq+1 end;return iN end)(...),"\t"))end end,error=function(...) | |
if | |
not(sgeP.q)then | |
return | |
d3fMjkg:write( | |
table.concat((function(...)local a4xc={}local e=1;local la5={...}for i=1,#la5 do local R=la5[i] | |
a4xc[e]=tostring(R)e=e+1 end;return a4xc end)(...),"\t")..'\n')end end,fatal=function(...) | |
if | |
not(sgeP.q)then | |
d3fMjkg:write( | |
table.concat((function(...)local xWVu={}local Yw8Yxix=1;local i={...} | |
for VoXG=1,#i do | |
local JL0I04c=i[VoXG]xWVu[Yw8Yxix]=tostring(JL0I04c)Yw8Yxix=Yw8Yxix+1 end;return xWVu end)(...),"\t")..'\n')end;return y06X3k(1)end}local ykRppH | |
ykRppH=function(En6r_K97,T4AA)if not(En6r_K97)then return Zg.fatal(T4AA)end end;local WQ6 | |
WQ6=function(VnuCKTdu)return | |
Zg.fatal((tostring(VnuCKTdu))..": Not implemented yet!")end;local y36Aetn | |
y36Aetn=function()ivnJjrA(vj)return y06X3k(0)end;local iPL3B4cr | |
iPL3B4cr=function(XnNgn,H1JD)if not(XnNgn)then Zg.fatal(H1JD)end;return XnNgn end;local GI2hz6SK | |
GI2hz6SK=function(gEEa9I,ULLLDUm,e4F3) | |
if not(type(gEEa9I==ULLLDUm))then | |
Zg.fatal("Value '".. | |
tostring(gEEa9I).. | |
"' is "..tostring(type(e4F3)).. | |
", however, a "..tostring(ULLLDUm).." is expected.")end;return e4F3 end;local Oh;Oh=function(GsfNt7) | |
return GI2hz6SK(GsfNt7,"number",tonumber(GsfNt7))end;local PG | |
PG=function(fF0)return | |
GI2hz6SK(fF0,"string",tostring(fF0))end;local n | |
n=function(YWPfQKb2,r) | |
for OS0Zp3i,BK in pairs(r)do if BK==YWPfQKb2 then return true,OS0Zp3i end end;return false end;local O | |
O=function(Idjbe70)local B=0;for nDjt,NVWt in pairs(Idjbe70)do B=B+1 end;return B end;local N5UjTN | |
N5UjTN=function(efuUGMh) | |
if type(efuUGMh)=="nil"then return true elseif type(efuUGMh)=="string"then return | |
not efuUGMh or#efuUGMh<1 elseif type(efuUGMh)=="table"then return | |
not efuUGMh or O(efuUGMh)<1 else return true end end;local qLH5 | |
qLH5=function(p4nNp) | |
for VW=1,#p4nNp do local Zt=p4nNp[VW]if not Zt then return false end end;return true end;local tE | |
tE=function(V)return XxJ(V)and XPoQB(V)end;local VcV0EuD | |
VcV0EuD=function(mzeTI)return XxJ(mzeTI)and not XPoQB(mzeTI)end;local pX4gCR | |
pX4gCR=function(sy4J)return sy4J==1 and""or"s"end;local gad4ZcL | |
gad4ZcL=function(ztJhP_u8)return ztJhP_u8 ~=1 and""or"s"end;local dk | |
dk=function(D)return D==1 and"is"or"are"end;local E | |
E=function(XIcl)return XIcl:match("^([^:]-):?([^:@]+)@?([^:@]*)$")end;local OO | |
OO=function(ys) | |
if | |
pE.get(pzDMZwG.resolve(ys)).isReadOnly()then return false,"the path is readonly!"elseif not XxJ(ys)then | |
return false,"the filesystem node doesn't exist."else | |
if not(XPoQB(ys)or pE.isLink(ys))then | |
return pE.remove(ys)else | |
for rMQ1um8 in iPL3B4cr(w(ys))do OO(JQi1jg(ys,rMQ1um8))end;return pE.remove(ys)end end end;local y | |
y=function()local U2=sgeP.c or sgeP.config or rDtVf | |
if | |
not VcV0EuD(U2)then local Z=pE.path(U2) | |
if not tE(Z)then local B58,PYVzrNl=o5sms(Z)if not B58 then | |
return false,"Failed to create '".. | |
tostring(Z).."' directory for the config file: "..tostring(PYVzrNl)end end;local ZDICnKE,L=io.open(U2,"w")if ZDICnKE then ZDICnKE:write(z) | |
ZDICnKE:close()else | |
return false,"Failed to open config file for writing: "..tostring(L)end end;local X,zLtWO09=io.open(U2,"r") | |
if X then local KTVmRC=X:read("*all")X:close() | |
local Pa={};(load(KTVmRC,"config","t",Pa))() | |
local bmK | |
bmK=function(OJPc3R)if OJPc3R==nil then OJPc3R={}end | |
return | |
setmetatable(OJPc3R,{__index={get=function(j,vMgKnGj,M9K)if | |
type(OJPc3R[j])~="nil"then | |
if type(OJPc3R[j])=="table"then return bmK(OJPc3R[j])end;return OJPc3R[j]end | |
Zg.error( | |
"Attempt to access undeclared config field '"..tostring(j).."'!")if not M9K then return vMgKnGj else return bmK(vMgKnGj)end end}})end;RkGFh6=bmK(Pa)nvCiFt7r=RkGFh6.get("modules",nvCiFt7r) | |
xSebv5Jc=RkGFh6.get("dist",xSebv5Jc)return RkGFh6 else return false, | |
"Failed to open config file for reading: "..tostring(zLtWO09)end end;local cR6rJlAl | |
cR6rJlAl=function()if not(LfEJbh_("internet"))then | |
Zg.fatal("This command requires an internet card to run!")end;Qlmlet=Qlmlet or | |
require("internet").request end;local M6ilzGJ | |
M6ilzGJ=function(Zeu)cR6rJlAl()return pcall(Qlmlet,Zeu)end;local iW6CD | |
iW6CD=function() | |
if not tE(nvCiFt7r)then local W0iTcMIt,N=o5sms(nvCiFt7r)if not W0iTcMIt then | |
return false, | |
"Failed to create '".. | |
tostring(nvCiFt7r).."' directory for custom modules: "..tostring(N)end end;local Q2_d=iPL3B4cr(w(nvCiFt7r)) | |
for Hald6SO in Q2_d do | |
hw18.name=Hald6SO:match("^(.+)%..+$") | |
(iPL3B4cr(loadfile(JQi1jg(nvCiFt7r,Hald6SO),"t",hw18)))()hw18.name=nil end;return true end;local wZdg | |
wZdg=function(Dq)local y3Ur=Dq;local GL70F7uL;do local lqANrrJA=Dq:find(':') | |
if lqANrrJA then | |
y3Ur=Dq:sub(lqANrrJA+1)GL70F7uL=Dq:sub(1,lqANrrJA-1)end end | |
if not GL70F7uL then local WUFTXBy6={} | |
for aEZf,GL70F7uL in | |
pairs(_)do | |
if GL70F7uL[y3Ur]then if type(GL70F7uL[y3Ur])=="table"and | |
GL70F7uL[y3Ur].__public==true then | |
el(WUFTXBy6,{class=GL70F7uL,module=aEZf,method=GL70F7uL[y3Ur]})end end end | |
if#WUFTXBy6 >1 then local QjQ_o=nil;for wDiq_,GL70F7uL in pairs(WUFTXBy6)do if GL70F7uL.module=="hel"then QjQ_o=wDiq_ | |
break end end;if | |
QjQ_o then WUFTXBy6={WUFTXBy6[QjQ_o]}end end | |
if#WUFTXBy6 >1 then | |
Zg.print("Ambiguous choice: method ".. | |
tostring(y3Ur).." is implemented in the following modules:") | |
for QYA5WJOY=1,#WUFTXBy6 do local GL70F7uL=WUFTXBy6[QYA5WJOY]Zg.print(" * ".. | |
tostring(GL70F7uL.module))end | |
Zg.print("Choose a specific module by prepending its name with a colon, e.g., ".. | |
tostring(WUFTXBy6[1].module)..":"..tostring(y3Ur)..".")return false elseif#WUFTXBy6 ==0 then | |
Zg.error("Unknown command: "..tostring(y3Ur))return false else GL70F7uL=WUFTXBy6[1].module | |
Zg.info("Note, using "..tostring(GL70F7uL)..":".. | |
tostring(y3Ur)..".")return function(...) | |
return WUFTXBy6[1].method(WUFTXBy6[1].class,...)end end else | |
if _[GL70F7uL]and N5UjTN(y3Ur)then local yliV8={} | |
for rjpKFl,YUGQovw in pairs(_[GL70F7uL])do if | |
type(YUGQovw)=="table"and YUGQovw.__public==true then | |
el(yliV8,tostring(rjpKFl))end end | |
Zg.print("Available module-specific commands: "..tostring(table.concat(yliV8,", ")))return false end | |
if | |
not _[GL70F7uL]or not _[GL70F7uL][y3Ur]or | |
_[GL70F7uL][y3Ur]and | |
(type(_[GL70F7uL][y3Ur])~="table"or | |
_[GL70F7uL][y3Ur].__public~=true)then | |
Zg.error("Unknown command: "..tostring(GL70F7uL)..":"..tostring(y3Ur))return false else return function(...) | |
return _[GL70F7uL][y3Ur](_[GL70F7uL],...)end end end end;local BaX | |
BaX=function(XZt7GyF) | |
if not XZt7GyF or XZt7GyF==""then XZt7GyF="hel"else XZt7GyF=XZt7GyF end;return _[XZt7GyF]or _.default end;local SJsW11k | |
SJsW11k=function(Zn3SC,D4,...)if Zn3SC==nil then Zn3SC=_.default end | |
if Zn3SC[D4]then return | |
Zn3SC[D4](Zn3SC,...)else return _.default[D4](_.default,...)end end;local Ki1HJT | |
Ki1HJT=function(crA9EKx,IcsJ,A,Wp9xT)if IcsJ==nil then IcsJ="hel"end;if A==nil then | |
A=JQi1jg(xSebv5Jc,IcsJ)end;if Wp9xT==nil then Wp9xT=crA9EKx.name end;if | |
not crA9EKx then return false,"'nil' given"end | |
if not tE(A)then local jLsxpw,x=o5sms(A) | |
if not | |
jLsxpw then return false, | |
"Failed to create '"..tostring(JQi1jg(A,IcsJ)).. | |
"' directory for manifest files: "..tostring(x)end end;local P,o0_XG8FI=io.open(JQi1jg(A,Wp9xT),"w") | |
if P then | |
P:write(RSjapQ(crA9EKx))P:close()return true else return false, | |
"Failed to open file for writing: "..tostring(o0_XG8FI)end end;local wjim8xCV | |
wjim8xCV=function(AXNfV,cX,iyx)if iyx==nil then iyx="hel"end | |
cX=cX or JQi1jg(xSebv5Jc,iyx,AXNfV) | |
if VcV0EuD(cX)then local bxvn,mWYrzB=io.open(cX,"rb") | |
if bxvn then | |
local O7kX=iPL3B4cr(QJf(bxvn:read("*all")))bxvn:close()return O7kX else return false, | |
"Failed to open manifest for '"..tostring(AXNfV).."' package: ".. | |
tostring(mWYrzB)end else return false, | |
"No manifest found for '"..tostring(AXNfV).."' package"end end;local EQLam | |
EQLam=function(Q4XSpdY,fzTyrQ9F)if fzTyrQ9F==nil then fzTyrQ9F="hel"end | |
local fAumJ0i=JQi1jg(xSebv5Jc,fzTyrQ9F,Q4XSpdY) | |
if VcV0EuD(fAumJ0i)then return OO(fAumJ0i)else return false,"No manifest found for '".. | |
tostring(Q4XSpdY).."' package"end end;local qTDt | |
qTDt=function(i0)return | |
setmetatable({__public=true},{__call=function(tZliF4,...)return i0(...)end})end;local v | |
v=function(jlmopoj,R) | |
return | |
function()local uS_N6,o5SLRA=pcall(jlmopoj)if not(uS_N6)then | |
return false,"Could not download '"..tostring(R).."': ".. | |
tostring(o5SLRA)else return o5SLRA end end end;local Ta | |
Ta=function(ztwXaCR,M2WtMgiq,FgfME) | |
if M2WtMgiq==nil then M2WtMgiq="Could not download '%s': %s"end;if FgfME==nil then FgfME="Could not download '%s': %s"end | |
local ylH9o,CC4Kfjh,k=M6ilzGJ(ztwXaCR)if not(ylH9o and CC4Kfjh)then | |
return false,M2WtMgiq:format(ztwXaCR,k)end;local eUQ0x=""for r0OR,k in v(CC4Kfjh)do | |
if r0OR then | |
eUQ0x=eUQ0x..r0OR else return false,FgfME:format(ztwXaCR,k)end end;return eUQ0x end;local unArcvQl | |
unArcvQl=function() | |
if not(sgeP.y)then | |
io.write("Press [ENTER] to continue...")local pYHkv=select(3,zC("key_down"))if pYHkv==13 then pfZ3SPy_() | |
return true else io.write("\n")return false end else return true end end;local h6Ub7U | |
h6Ub7U=function(hxZHlgP)local zct=0;local WQk6Wkd={} | |
if | |
not(N5UjTN(hxZHlgP.install))then | |
local t={"Packages to INSTALL:",table.concat(hxZHlgP.install," ")}el(WQk6Wkd,t)zct=zct+#hxZHlgP.install else | |
hxZHlgP.install={}end | |
if not(N5UjTN(hxZHlgP.reinstall))then | |
local pRCHPl={"Packages to REINSTALL:",table.concat(hxZHlgP.reinstall," ")}el(WQk6Wkd,pRCHPl)zct=zct+#hxZHlgP.reinstall else | |
hxZHlgP.reinstall={}end | |
if not(N5UjTN(hxZHlgP.upgrade))then | |
local sCffg4HK={"Packages to UPGRADE:",table.concat(hxZHlgP.upgrade," ")}el(WQk6Wkd,sCffg4HK)zct=zct+#hxZHlgP.upgrade else | |
hxZHlgP.upgrade={}end | |
if not(N5UjTN(hxZHlgP.remove))then | |
local EyljhkFp={"Packages to REMOVE:",table.concat(hxZHlgP.remove," ")}el(WQk6Wkd,EyljhkFp)zct=zct+#hxZHlgP.remove else | |
hxZHlgP.remove={}end | |
do | |
local uGDn542={tostring(#hxZHlgP.install).. | |
" to INSTALL, ".. | |
tostring(#hxZHlgP.reinstall).." to REINSTALL, ".. | |
tostring(#hxZHlgP.upgrade).." to UPGRADE, ".. | |
tostring(#hxZHlgP.remove).." to REMOVE."}el(WQk6Wkd,uGDn542)end | |
for DQ,s6Ahlni_ in pairs(WQk6Wkd)do | |
for DQ,T6dNu in pairs(s6Ahlni_)do if DQ==1 then Zg.print(T6dNu)else | |
Zg.print(" "..tostring(T6dNu))end end;if DQ~=#WQk6Wkd then Zg.print("")end end | |
if zct>0 then if not(unArcvQl())then return y06X3k(7)end end end | |
do local H;local YlzZm={}YlzZm.__index=YlzZm | |
H=setmetatable({__init=function()end,__base=YlzZm,__name="default"},{__index=YlzZm,__call=function(cotcYZ1f,...) | |
local FRcmT=setmetatable({},YlzZm)cotcYZ1f.__init(FRcmT,...)return FRcmT end})YlzZm.__class=H;local vj9879b5=H | |
vj9879b5.install=function()return | |
Zg.fatal("Incorrect source is provided! No default 'install' implementation.")end | |
vj9879b5.remove=function(vj9879b5,zfl,itxD)if itxD==nil then itxD="hel"end | |
if zfl then | |
if zfl.files then | |
for JPHs7A,yzYgnMtr in pairs(zfl.files)do | |
local o=JQi1jg(yzYgnMtr.dir,yzYgnMtr.name)local wmkJ,I1=OO(o) | |
if not(wmkJ)then return false,"Failed to remove '".. | |
tostring(o).."': "..tostring(I1)end end end;return EQLam(zfl.name,itxD)else | |
return false,"Package can't be removed: the manifest is empty."end end | |
vj9879b5.save=function()return | |
Zg.fatal("Incorrect source is provided! No default 'save' implementation.")end;_.default=H end | |
do local gXu5hG;local R60Ru4bj=_.default;local eQWRf={}eQWRf.__index=eQWRf | |
setmetatable(eQWRf,R60Ru4bj.__base) | |
gXu5hG=setmetatable({__init=function(_AvO,...)return gXu5hG.__parent.__init(_AvO,...)end,__base=eQWRf,__name="hel",__parent=R60Ru4bj},{__index=function(qEO,q) | |
local WUY7=rawget(eQWRf,q)if WUY7 ==nil then local _puepou=rawget(qEO,"__parent") | |
if _puepou then return _puepou[q]end else return WUY7 end end,__call=function(DYLeJ,...) | |
local udbF=setmetatable({},eQWRf)DYLeJ.__init(udbF,...)return udbF end})eQWRf.__class=gXu5hG;local WT2AX=gXu5hG | |
WT2AX.URL="https://hel-roottree.rhcloud.com/" | |
WT2AX.parsePackageJSON=function(WT2AX,dt1,V7eMEiVW) | |
if V7eMEiVW==nil then V7eMEiVW=YAtG_LV3.Spec("*")end;local Co1tUVas=nil;local B={} | |
for nCwsa,IPPy in pairs(dt1.versions)do | |
local zYGA2q2=YAtG_LV3.Version(nCwsa)if not(zYGA2q2)then | |
Zg.fatal("Could not parse the version in package: "..tostring(zYGA2q2))end;B[zYGA2q2]=IPPy end | |
local UjlBMb,PKWIJ9=pcall(function()return | |
V7eMEiVW:select((function()local I9Mw={}local e=1 | |
for BUtIET,NvAj in pairs(B)do I9Mw[e]=BUtIET;e=e+1 end;return I9Mw end)())end)if not(UjlBMb)then | |
Zg.fatal("Could not select the best version: "..tostring(PKWIJ9))end;Co1tUVas=tostring(PKWIJ9)if not | |
(PKWIJ9)then | |
Zg.fatal("No candidate for version specification '"..tostring(V7eMEiVW).."' found!")end | |
local rQYWEt={name=dt1.name,version=Co1tUVas,files={},dependencies={}}for Icg,PzMsk in pairs(B[PKWIJ9].files)do local axLuO=PzMsk.dir;local j=PzMsk.name | |
el(rQYWEt.files,{url=Icg,dir=axLuO,name=j})end;for As,JmCzKm in | |
pairs(B[PKWIJ9].depends)do local Mwhc=JmCzKm.version;local A6z=JmCzKm.type | |
el(rQYWEt.dependencies,{name=As,version=Mwhc,type=A6z})end;return | |
rQYWEt end | |
WT2AX.getPackageSpec=function(WT2AX,_Mk) | |
Zg.info("Downloading package data for "..tostring(_Mk).." ...") | |
local PXrrrSid,L9=M6ilzGJ(WT2AX.URL.."packages/".._Mk)if not(PXrrrSid)then | |
Zg.fatal("HTTP request error: "..L9)end;local _KZPScl="" | |
for R4f819q in L9 do _KZPScl=_KZPScl..R4f819q end;local dbTwy=s:decode(_KZPScl)if not(dbTwy)then | |
Zg.fatal("Incorrect JSON format!\n".. | |
tostring(_KZPScl))end;return dbTwy.data end | |
WT2AX.rawInstall=function(WT2AX,Kj1I,nTUMgqomA,Id5sIM)if nTUMgqomA==nil then nTUMgqomA=false end;if Id5sIM==nil then | |
Id5sIM=false end;local gZM2ANLt;if Id5sIM then gZM2ANLt=JQi1jg(u(),Kj1I.name)else | |
gZM2ANLt="/"end | |
if Id5sIM and not tE(gZM2ANLt)then | |
local aC72qEnu,B60J=o5sms(gZM2ANLt)if not(aC72qEnu)then | |
Zg.fatal("Failed creating '"..tostring(gZM2ANLt).. | |
"' directory for package '".. | |
tostring(Kj1I.name).."'! \n"..tostring(B60J))end elseif not | |
Id5sIM then local Y4=wjim8xCV(Kj1I.name,nil,"hel") | |
if Y4 then | |
if Y4.version== | |
tostring(Kj1I.version)then | |
Zg.print("'".. | |
tostring(Kj1I.name).."@"..tostring(Y4.version).. | |
"' is already installed, skipping...")return Y4 else | |
Zg.fatal("'".. | |
tostring(Kj1I.name).. | |
"@".. | |
tostring(Kj1I.version).. | |
"' was attempted to install, however, another version of the same package is already installed: '".. | |
tostring(Kj1I.name).."@"..tostring(Y4.version).."'")end end end | |
for f,yeCnvcd6 in pairs(Kj1I.files)do | |
Zg.info("Fetching '"..tostring(yeCnvcd6.name).."' ...")local Iq93c6cA=iPL3B4cr(Ta(yeCnvcd6.url)) | |
local nsM0h=JQi1jg(gZM2ANLt,yeCnvcd6.dir) | |
if not tE(nsM0h)then local Czi,IlxN=o5sms(nsM0h)if not(Czi)then | |
Zg.fatal("Failed to create '".. | |
tostring(nsM0h).."' directory for '".. | |
tostring(yeCnvcd6.name).."'! \n"..tostring(IlxN))end end | |
do local EA_3x01A | |
yeCnvcd6,EA_3x01A=io.open(JQi1jg(nsM0h,yeCnvcd6.name),"w")if not(yeCnvcd6)then | |
Zg.fatal("Could not open '".. | |
tostring(JQi1jg(nsM0h,yeCnvcd6.name)).."' for writing: "..tostring(EA_3x01A))end | |
yeCnvcd6:write(Iq93c6cA)yeCnvcd6:close()end end;return | |
{name=Kj1I.name,version=tostring(Kj1I.version),files=Kj1I.files,dependencies=Kj1I.dependencies,manual=nTUMgqomA}end | |
WT2AX.resolveDependencies=function(WT2AX,m54tY2,WJWMdKI,AhbP,QHFgYUN)if WJWMdKI==nil then WJWMdKI={}end | |
if AhbP==nil then AhbP={}end;if QHFgYUN==nil then QHFgYUN={}end | |
for RoEsr7So=1,#m54tY2 do local dX=m54tY2[RoEsr7So] | |
local Rz,j177r;Rz,j177r=dX.name,dX.version;local j=false | |
for qCaFw=1,#WJWMdKI do local syvPi=WJWMdKI[qCaFw]if | |
syvPi.pkg.name==Rz then j=true;break end end | |
if not(j)then el(AhbP,{name=Rz,version=""}) | |
local NrgSK2=wjim8xCV(Rz,nil,"hel") | |
if not NrgSK2 or not | |
j177r:match(YAtG_LV3.Version(NrgSK2.version))then | |
local wIH=WT2AX:getPackageSpec(Rz)local TYWkpc=WT2AX:parsePackageJSON(wIH,j177r) | |
AhbP[#AhbP].version=TYWkpc.version;local k=TYWkpc.dependencies | |
for J=1,#k do local gtlO9=k[J]j=false;for Lun=1,#WJWMdKI do | |
local beUJXhjw=WJWMdKI[Lun] | |
if beUJXhjw.pkg.name==gtlO9.name then j=true;break end end | |
if not j then local zY7adu=nil | |
for Nlvw,K55 in | |
pairs(AhbP)do if K55.name==gtlO9.name then zY7adu=Nlvw;break end end | |
if zY7adu then | |
if AhbP[zY7adu].version==gtlO9.version then | |
Zg.fatal("Circular dependencies detected: '".. | |
tostring(Rz).. | |
"@".. | |
tostring(TYWkpc.version).. | |
"' depends on '".. | |
tostring(gtlO9.name).. | |
"@".. | |
tostring(gtlO9.version).."', and '".. | |
tostring(AhbP[zY7adu].name).."@".. | |
tostring(AhbP[zY7adu].version).."' depends on '"..tostring(Rz).. | |
"@"..tostring(TYWkpc.version).."'.")else | |
Zg.fatal("Attempted to install two versions of the same package: '".. | |
tostring(gtlO9.name).. | |
"@".. | |
tostring(gtlO9.version).. | |
"' and '".. | |
tostring(AhbP[zY7adu].name).."@".. | |
tostring(AhbP[zY7adu].version).."' when resolving dependencies for '"..tostring(Rz).. | |
"@"..tostring(TYWkpc.version).."'.")end end | |
WT2AX:resolveDependencies({{name=gtlO9.name,version=YAtG_LV3.Spec(gtlO9.version)}},WJWMdKI,AhbP,QHFgYUN)end end;el(WJWMdKI,{pkg=TYWkpc})el(QHFgYUN,{pkg=TYWkpc})else | |
el(WJWMdKI,{pkg=NrgSK2})end;AhbP[#AhbP]=nil end end;return QHFgYUN end | |
WT2AX.getPackageDependants=function(WT2AX,BJcMTdMi,f1MKKJ,nFf)if f1MKKJ==nil then f1MKKJ={}end | |
if nFf==nil then nFf={}end | |
for EIqL41=1,#BJcMTdMi do local iv=BJcMTdMi[EIqL41]local rfmMR4=false | |
for Tq2I=1,#f1MKKJ do | |
local GNo=f1MKKJ[Tq2I]if GNo.name==iv then rfmMR4=true;break end end | |
if not(rfmMR4)then el(nFf,{name=iv})local e5x=wjim8xCV(iv,nil,"hel") | |
if e5x then | |
el(f1MKKJ,{name=iv,manifest=e5x}) | |
local QrONvWGq=iPL3B4cr(w(JQi1jg(xSebv5Jc,"hel"))) | |
for D94fnZaa in QrONvWGq do | |
e5x=iPL3B4cr(wjim8xCV(D94fnZaa,nil,"hel"))local XI=e5x.dependencies | |
for FNi=1,#XI do local pRW2nEmK=XI[FNi] | |
if pRW2nEmK.name==iv then rfmMR4=false;for OR=1,# | |
f1MKKJ do local Arww=f1MKKJ[OR] | |
if Arww.name==D94fnZaa then rfmMR4=true;break end end | |
if not rfmMR4 then | |
for BYH=1,#nFf do | |
local o7E8TLH=nFf[BYH]if o7E8TLH.name==D94fnZaa then | |
Zg.fatal("Circular dependencies detected: "..tostring(D94fnZaa))end end | |
WT2AX:getPackageDependants({D94fnZaa},f1MKKJ,nFf)end end end end else | |
Zg.fatal("Package ".. | |
tostring(iv).." is referenced as a dependant of another package, however, this package isn't installed.")end;nFf[#nFf]=nil end end;return f1MKKJ end | |
WT2AX.install=qTDt(function(WT2AX,...) | |
if sgeP.l or sgeP["local"]then | |
local P=pzDMZwG.resolve(...) | |
local F4AWvI=iPL3B4cr(wjim8xCV(P,JQi1jg(P,"manifest"))) | |
local GYVN=WT2AX:resolveDependencies((function()local QFUU10K={}local xNPDtul=1;local k8=F4AWvI.dependencies | |
for HmgRk=1,#k8 do | |
local UuCdpVi=k8[HmgRk]local fghe,vFXf;fghe,vFXf=UuCdpVi.name,UuCdpVi.version | |
QFUU10K[xNPDtul]={name=fghe,version=YAtG_LV3.Spec(vFXf)}xNPDtul=xNPDtul+1 end;return QFUU10K end)())local DNlB1V=sgeP.d or sgeP.onlyDeps;local erb6G_E={}for CA0uX7n=1,#GYVN do | |
local ze5Vpc3=GYVN[CA0uX7n] | |
el(erb6G_E,tostring(ze5Vpc3.pkg.name).."@".. | |
tostring(ze5Vpc3.pkg.version))end;if | |
not(DNlB1V)then | |
el(erb6G_E,tostring(F4AWvI.name).."@"..tostring(F4AWvI.version))end | |
h6Ub7U({install=erb6G_E}) | |
for vwK8=1,#GYVN,1 do local Sk_SiC=GYVN[vwK8] | |
Zg.print("Installing '".. | |
tostring(Sk_SiC.pkg.name).."@".. | |
tostring(Sk_SiC.pkg.version).."'...")local X0bgPvA=WT2AX:rawInstall(Sk_SiC.pkg,false,false) | |
local M9CyqH,z0x4qSAN=Ki1HJT(X0bgPvA,"hel") | |
if M9CyqH then | |
Zg.info("Saved the manifest of '"..tostring(X0bgPvA.name).."'.")else | |
Zg.fatal("Couldn't save the manifest of '"..tostring(X0bgPvA.name).."': ".. | |
tostring(z0x4qSAN)..".")end end | |
if not DNlB1V then | |
Zg.print("Installing '"..tostring(F4AWvI.name).."@".. | |
tostring(F4AWvI.version).."'...") | |
for k,Oc in pairs(F4AWvI.files)do if not tE(JQi1jg(Oc.dir,Oc.name))then | |
o5sms(Oc.dir)end | |
local IHovU,e_wDQjk=wVzn(JQi1jg(P,Oc.url),JQi1jg(Oc.dir,Oc.name))if not(IHovU)then | |
Zg.fatal("Cannot copy file '".. | |
tostring(Oc.name).."': "..tostring(e_wDQjk))end end;local X0GTupeV,rQ=Ki1HJT(F4AWvI,"hel") | |
if X0GTupeV then | |
Zg.info("Saved the manifest of '".. | |
tostring(F4AWvI.name).."'.")else | |
Zg.fatal("Couldn't save the manifest of '"..tostring(F4AWvI.name).. | |
"': "..tostring(rQ)..".")end end;return true end;local N5N27Jd={}local m={...} | |
for ClglY=1,#m do local S=m[ClglY] | |
local NKetZhs,EFLZ0N1=S:match("^(.+)@(.+)$")or S;if N5UjTN(EFLZ0N1)then EFLZ0N1="*"end | |
Zg.info("Creating version specification for ".. | |
tostring(EFLZ0N1).." ...") | |
local gL,m4=pcall(function()return YAtG_LV3.Spec(EFLZ0N1)end)if not(gL)then | |
Zg.fatal("Could not parse the version specification: "..tostring(m4).."!")end | |
el(N5N27Jd,{name=NKetZhs,version=m4})end;local nK=sgeP.r or sgeP.reinstall | |
local _zr=sgeP.s or sgeP.save;local f5=WT2AX:resolveDependencies(N5N27Jd)local UAc={}local Ef={} | |
for rNOL8G=1,#f5 do | |
local q=false | |
repeat local lKO=f5[rNOL8G] | |
if nK then local hcwgu=false | |
for omgCdqp8=1,#N5N27Jd do local X17eHTx=N5N27Jd[omgCdqp8]if | |
X17eHTx.name==lKO.pkg.name then hcwgu=true;break end end;if hcwgu then | |
el(UAc,tostring(lKO.pkg.name).. | |
"@"..tostring(lKO.pkg.version))q=true;break end end | |
el(Ef,tostring(lKO.pkg.name).."@"..tostring(lKO.pkg.version))q=true until true;if not q then break end end;h6Ub7U({install=Ef,reinstall=UAc}) | |
if nK then local SGF | |
do local myIHU={}local xxNCdF=1 | |
for _cl1b=1,# | |
N5N27Jd do local Xz18nk=N5N27Jd[_cl1b] | |
myIHU[xxNCdF]=iPL3B4cr(wjim8xCV(Xz18nk.name,nil,"hel"))xxNCdF=xxNCdF+1 end;SGF=myIHU end;WT2AX:_remove(SGF,true,false)end | |
for P=1,#f5 do local sTX4=f5[P] | |
Zg.print("Installing '"..tostring(sTX4.pkg.name).."@".. | |
tostring(sTX4.pkg.version).."'...")local A0TJx=false | |
for wYZ=1,#N5N27Jd do local aMd=N5N27Jd[wYZ]if aMd.name==sTX4.pkg.name then | |
A0TJx=true;break end end;local Nqdkw=WT2AX:rawInstall(sTX4.pkg,A0TJx,_zr) | |
local t,QbMO=Ki1HJT(Nqdkw,"hel") | |
if t then | |
Zg.info("Saved the manifest of '"..tostring(Nqdkw.name).."'.")else | |
Zg.fatal("Couldn't save the manifest of '"..tostring(Nqdkw.name).. | |
"': "..tostring(QbMO)..".")end end end) | |
WT2AX.remove=qTDt(function(WT2AX,...)local o0pf={...}local tx1LD={}for N3ROeR=1,#o0pf do local I1oQVnUd=o0pf[N3ROeR] | |
local oTX=iPL3B4cr(wjim8xCV(I1oQVnUd,nil,"hel"))el(tx1LD,oTX)end;return | |
WT2AX:_remove(tx1LD,false)end) | |
WT2AX._remove=function(WT2AX,WZlF4,IxqPDOWH,GZqV)if IxqPDOWH==nil then IxqPDOWH=false end | |
if GZqV==nil then GZqV=true end;local OVubrDw_ | |
if not | |
RkGFh6.get("hel",{},true).get("remove_dependants",true)or not GZqV then | |
do | |
local G2_TeR8={}local yk=1;for OPSPMfr_=1,#WZlF4 do local QnNOl=WZlF4[OPSPMfr_] | |
G2_TeR8[yk]={name=QnNOl.name,manifest=QnNOl}yk=yk+1 end | |
OVubrDw_=G2_TeR8 end else | |
OVubrDw_=WT2AX:getPackageDependants((function()local aQs={}local uow_0tb=1;for tykg=1,#WZlF4 do local C_pPyW=WZlF4[tykg] | |
aQs[uow_0tb]=C_pPyW.name;uow_0tb=uow_0tb+1 end;return aQs end)())end | |
if not(IxqPDOWH)then | |
h6Ub7U({remove=(function()local mgb4b={}local LOBqxO=1 | |
for m8=1,#OVubrDw_ do local mcoAHO=OVubrDw_[m8] | |
mgb4b[LOBqxO]= | |
"hel:"..tostring(mcoAHO.manifest.name).."@".. | |
tostring(mcoAHO.manifest.version)LOBqxO=LOBqxO+1 end;return mgb4b end)()})end | |
for d3gFWO=1,#OVubrDw_ do local D=OVubrDw_[d3gFWO] | |
Zg.print("Removing '".. | |
tostring(D.manifest.name).. | |
"@"..tostring(D.manifest.version).."' ...") | |
iPL3B4cr(gXu5hG.__parent.remove(WT2AX,D.manifest,"hel"))end;return true end | |
WT2AX.upgrade=qTDt(function(WT2AX)local obodPKnu={} | |
for MP in | |
iPL3B4cr(w(JQi1jg(xSebv5Jc,"hel")))do if | |
not(XPoQB(JQi1jg(xSebv5Jc,"hel",MP)))then | |
el(obodPKnu,iPL3B4cr(wjim8xCV(MP,nil,"hel")))end end;local kgdzk={} | |
for jb=1,#obodPKnu do local uKSj=obodPKnu[jb] | |
local YXgXQB,bvL1X4=pcall(WT2AX.getPackageSpec,WT2AX,uKSj.name) | |
if YXgXQB then local PPNahh=WT2AX:parsePackageJSON(bvL1X4) | |
uKSj.latest={spec=bvL1X4,data=PPNahh} | |
if YAtG_LV3.Version(uKSj.latest.data.version)> | |
YAtG_LV3.Version(uKSj.version)then el(kgdzk,uKSj)end end end | |
local oVSp=WT2AX:resolveDependencies((function()local z2g={}local m9JTkVv6=1 | |
for Q=1,#kgdzk do local bWkP=kgdzk[Q] | |
z2g[m9JTkVv6]={name=bWkP.name,version=YAtG_LV3.Spec(bWkP.latest.data.version)}m9JTkVv6=m9JTkVv6+1 end;return z2g end)())local uBJ | |
do local JtFj={}local PQ3=1 | |
for _xCtN=1,#kgdzk do local JVpe=kgdzk[_xCtN] | |
JtFj[PQ3]=tostring(JVpe.name).. | |
"@{".. | |
tostring(JVpe.version).." => "..tostring(JVpe.latest.data.version).. | |
"}"PQ3=PQ3+1 end;uBJ=JtFj end;local A={} | |
for nG36XmZC=1,#oVSp do local Vf26=oVSp[nG36XmZC]local xUGt=true | |
for _U=1,#kgdzk do local hkI39=kgdzk[_U]if | |
hkI39.name==Vf26.pkg.name then xUGt=false;break end end;if xUGt then | |
el(A,tostring(Vf26.pkg.name).. | |
"@"..tostring(Vf26.pkg.version))end end;h6Ub7U({upgrade=uBJ,install=A}) | |
for MwwN=1,#oVSp do local oZ9=oVSp[MwwN] | |
local OXlT0=false;local V=false | |
for I7=1,#kgdzk do local Upw=kgdzk[I7]if Upw.name==oZ9.pkg.name then OXlT0=Upw | |
V=Upw.manual;break end end | |
if OXlT0 then WT2AX:_remove({OXlT0},true,false)end | |
Zg.print("Installing '"..tostring(oZ9.pkg.name).."@".. | |
tostring(oZ9.pkg.version).."'...")local zIYNIXy1=WT2AX:rawInstall(oZ9.pkg,V,false) | |
local c,mReHt4h=Ki1HJT(zIYNIXy1,"hel") | |
if c then | |
Zg.info("Saved the manifest of '"..tostring(zIYNIXy1.name).."'.")else | |
Zg.fatal("Couldn't save the manifest of '"..tostring(zIYNIXy1.name).."': ".. | |
tostring(mReHt4h)..".")end end end) | |
WT2AX.info=qTDt(function(WT2AX,nqBfKL,gs3a)if gs3a==nil then gs3a="*"end;if N5UjTN(nqBfKL)then | |
Zg.fatal("Usage: hpm hel:info <package name> [<version specification>]")end | |
if N5UjTN(gs3a)then gs3a="*"end | |
Zg.print("Creating version specification for "..tostring(gs3a).." ...") | |
local AkKaBC,OmRH8=pcall(function()return YAtG_LV3.Spec(gs3a)end)if not(AkKaBC)then | |
Zg.fatal("Could not parse the version specification: "..tostring(OmRH8).."!")end | |
local GY=WT2AX:getPackageSpec(nqBfKL)local oukM79R=WT2AX:parsePackageJSON(GY,OmRH8)local D_j={} | |
el(D_j, | |
"- Package name: "..tostring(GY.name)) | |
el(D_j,"- Description:\n"..tostring(GY.description)) | |
el(D_j,"- Package owners: "..tostring(table.concat(GY.owners,", "))) | |
el(D_j,"- Authors:\n".. | |
tostring(table.concat((function()local mZPe4w={}local OvZ=1;local cBOpf=GY.authors | |
for KZYA5y=1,#cBOpf do | |
local YoCAN7OU=cBOpf[KZYA5y]mZPe4w[OvZ]=" - "..tostring(YoCAN7OU)OvZ=OvZ+1 end;return mZPe4w end)(),"\n"))) | |
el(D_j,"- License: "..tostring(GY.license)) | |
el(D_j,"- Versions: "..tostring(O(GY.versions))..", latest: ".. | |
tostring(oukM79R.version)) | |
el(D_j," - Files: "..tostring(#oukM79R.files)) | |
el(D_j," - Depends: ".. | |
tostring(table.concat((function()local FoP={}local jqtWXY=1;local XgRb=oukM79R.dependencies | |
for G3e=1,#XgRb do | |
local GoP6=XgRb[G3e] | |
FoP[jqtWXY]=tostring(GoP6.name).."@"..tostring(GoP6.version)jqtWXY=jqtWXY+1 end;return FoP end)()))) | |
el(D_j," - Changes:\n".. | |
tostring(GY.versions[oukM79R.version].changes))el(D_j,"- Stats:") | |
el(D_j," - Views: "..tostring(GY.stats.views)) | |
el(D_j,"- Creation date: ".. | |
tostring(GY.stats.date.created).." UTC") | |
el(D_j,"- Last updated: ".. | |
tostring(GY.stats.date["last-updated"]).." UTC")return Zg.print(table.concat(D_j,"\n"))end) | |
WT2AX.search=qTDt(function(WT2AX,...)local cZ_=0 | |
while true do local NYc8={}local Dff8=WT2AX.URL.."packages" | |
if...then | |
Dff8=Dff8 .. | |
("?q=".. | |
table.concat((function(...) | |
local Wvs3rd6o={}local UdVlP=1;local N={...} | |
for v9mB_RUi=1,#N do local hX=N[v9mB_RUi]Wvs3rd6o[UdVlP]='"'.. | |
hX:gsub("\"","")..'"'UdVlP=UdVlP+1 end;return Wvs3rd6o end)(...)," "):gsub("&",""))end;Dff8=Dff8 .."?offset="..tostring(cZ_) | |
local lEYwsOG9,M=M6ilzGJ(Dff8)if not(lEYwsOG9)then | |
Zg.fatal("HTTP request error: "..M)end;local Vt95q2G="" | |
for AVU in M do Vt95q2G=Vt95q2G..AVU end;local jsPbwU=s:decode(Vt95q2G)if not(jsPbwU)then | |
Zg.fatal("Incorrect JSON format!\n".. | |
tostring(Vt95q2G))end;NYc8=jsPbwU.data.list;for I=1,#NYc8 do | |
local _x5O1=NYc8[I] | |
Zg.print(tostring(_x5O1.name).. | |
": "..tostring(_x5O1.short_description))end | |
if | |
#NYc8 ==0 and cZ_==0 then Zg.print("No packages found.")break end | |
if jsPbwU.data.truncated and jsPbwU.data.sent+jsPbwU.data.offset< | |
jsPbwU.data.total then cZ_= | |
jsPbwU.data.offset+jsPbwU.data.sent else break end end end) | |
if R60Ru4bj.__inherited then R60Ru4bj.__inherited(R60Ru4bj,gXu5hG)end;_.hel=gXu5hG end | |
do local eFI8dI3;local i=_.default;local l6xUetCb={}l6xUetCb.__index=l6xUetCb | |
setmetatable(l6xUetCb,i.__base) | |
eFI8dI3=setmetatable({__init=function(VspvGB9V,...) | |
return eFI8dI3.__parent.__init(VspvGB9V,...)end,__base=l6xUetCb,__name="oppm",__parent=i},{__index=function(LrFLp5,GfB7) | |
local Iz_w1j=rawget(l6xUetCb,GfB7)if Iz_w1j==nil then local G=rawget(LrFLp5,"__parent") | |
if G then return G[GfB7]end else return Iz_w1j end end,__call=function(X7YKzX,...) | |
local od0VOF=setmetatable({},l6xUetCb)X7YKzX.__init(od0VOF,...)return od0VOF end})l6xUetCb.__class=eFI8dI3;local lOb_Sv=eFI8dI3 | |
lOb_Sv.REPOS="https://raw.githubusercontent.com/OpenPrograms/openprograms.github.io/master/repos.cfg" | |
lOb_Sv.PACKAGES="https://raw.githubusercontent.com/%s/master/programs.cfg"lOb_Sv.FILES="https://raw.githubusercontent.com/%s/%s" | |
lOb_Sv.DIRECTORY="https://api.github.com/repos/%s/contents/%s?ref=%s"lOb_Sv.DEFAULT_CACHE_DIRECTORY="/var/cache/hpm/oppm" | |
lOb_Sv.cacheDirectory=function(lOb_Sv) | |
local oO6SbZ=RkGFh6.get("oppm",{},true).get("cache_directory",lOb_Sv.DEFAULT_CACHE_DIRECTORY) | |
if not(tE(oO6SbZ))then local UE_vrsNx,kef2zBS=o5sms(oO6SbZ)if not(UE_vrsNx)then | |
Zg.fatal( | |
"Could not create the cache directory at "..tostring(oO6SbZ)..": "..tostring(kef2zBS))end end;return oO6SbZ end | |
lOb_Sv.listCache=function(lOb_Sv)local Z={}local ze0=lOb_Sv:cacheDirectory() | |
local ylW3uC0=iPL3B4cr(w(ze0)) | |
for N_G1 in ylW3uC0 do | |
if XPoQB(JQi1jg(ze0,N_G1))then | |
local wkGNE=iPL3B4cr(w(JQi1jg(ze0,N_G1))) | |
for ccK in wkGNE do | |
if XPoQB(JQi1jg(ze0,N_G1,ccK))then | |
local BV=iPL3B4cr(w(JQi1jg(ze0,N_G1,ccK))) | |
for HnLY in BV do local cm51CH1n=JQi1jg(ze0,N_G1,ccK,HnLY) | |
if | |
not(XPoQB(cm51CH1n))then local iWrSgT | |
do local YK1,t96Qtz=io.open(cm51CH1n,"r") | |
if not YK1 then return false, | |
"Could not open '".. | |
tostring(cm51CH1n).."' for reading: "..tostring(t96Qtz)end;qLH5=YK1:read("*all")iWrSgT=QJf(qLH5)YK1:close()end;local C=JQi1jg(N_G1,ccK) | |
el(Z,{path=cm51CH1n,repo=C,pkg=HnLY,data=iWrSgT})end end end end end end;return Z end | |
lOb_Sv.fixCache=function(lOb_Sv)local HjKNi=lOb_Sv:cacheDirectory() | |
local Ub9iqg=iPL3B4cr(w(HjKNi)) | |
for r_S8HFRo in Ub9iqg do local qIF4RFBv=true;local wNbC65Ta=JQi1jg(HjKNi,r_S8HFRo) | |
if XPoQB(wNbC65Ta)then | |
local xOiPW=iPL3B4cr(w(wNbC65Ta)) | |
for Z9j in xOiPW do local r=true;local OnJ1=JQi1jg(wNbC65Ta,Z9j) | |
if XPoQB(OnJ1)then | |
local KFU0=iPL3B4cr(w(OnJ1)) | |
for Pvuq in KFU0 do local lOpDJ=true;local YLe=JQi1jg(OnJ1,Pvuq)if not(XPoQB(YLe))then | |
lOpDJ,r,qIF4RFBv=false,false,false end;if lOpDJ then OO(YLe)end end end;if r then OO(OnJ1)end end end;if qIF4RFBv then OO(wNbC65Ta)end end;return true end | |
lOb_Sv.resolveDirectory=function(lOb_Sv,lTH,JL,FpU_E) | |
local JWtwnQ2t=iPL3B4cr(Ta(lOb_Sv.DIRECTORY:format(lTH,FpU_E,JL)))JWtwnQ2t=s:decode(JWtwnQ2t) | |
if JWtwnQ2t.message then return false, | |
"Could not fetch "..tostring(lTH).. | |
":".. | |
tostring(JL).."/".. | |
tostring(FpU_E)..": "..tostring(JWtwnQ2t.message)end;local uEKPPpj_={}local aYO4NN=1 | |
for CtG9nSQL=1,#JWtwnQ2t do local uZtK5yX=JWtwnQ2t[CtG9nSQL] | |
if | |
uZtK5yX.type=="file"then | |
uEKPPpj_[aYO4NN]={name=uZtK5yX.name,url=uZtK5yX.download_url,path=uZtK5yX.path}aYO4NN=aYO4NN+1 end end;return uEKPPpj_ end | |
lOb_Sv.updateCache=function(lOb_Sv)local kr2CYaS=lOb_Sv:cacheDirectory() | |
local hXgSzEI=iPL3B4cr(lOb_Sv:listCache())local AUQ,B=Ta(lOb_Sv.REPOS)if not(AUQ)then | |
return false,"Could not fetch ".. | |
tostring(lOb_Sv.REPOS)..": "..tostring(B)end;AUQ=QJf(AUQ)local J={} | |
for wm,_O in | |
pairs(AUQ)do local smj=false | |
repeat | |
if _O.repo then | |
Zg.info("Fetching '"..tostring(wm).. | |
"' at '"..tostring(_O.repo).."' ...")local obBu,cbQlG | |
obBu,cbQlG,B=M6ilzGJ(lOb_Sv.PACKAGES:format(_O.repo)) | |
if not(obBu and cbQlG)then | |
Zg.error("Could not fetch '".. | |
tostring(wm).."' at '".. | |
tostring(_O.repo).."': "..tostring(B))smj=true;break end;local YZQu1DR4="" | |
for obBu,CvGDk_2 in function()return pcall(cbQlG)end do | |
if not obBu then | |
Zg.error("Could not fetch '".. | |
tostring(wm).. | |
"' at '"..tostring(_O.repo).."': "..tostring(CvGDk_2))YZQu1DR4=false;break else if not CvGDk_2 then break end | |
YZQu1DR4=YZQu1DR4 ..CvGDk_2 end end;if YZQu1DR4 ==false then smj=true;break end;if N5UjTN(YZQu1DR4)then | |
Zg.error( | |
"Could not fetch '".. | |
tostring(wm).."' at '"..tostring(_O.repo).."'")smj=true;break end;local kza | |
kza,B=QJf(YZQu1DR4) | |
if not kza then | |
Zg.error("Manifest '".. | |
tostring(wm).."' at '"..tostring(_O.repo).. | |
"' is malformed: "..tostring(B))smj=true;break end | |
for EGpun,LNlhK in pairs(kza)do local cnx_1g=false | |
repeat | |
if EGpun:match("[^A-Za-z0-9._-]")then | |
Zg.error( | |
"Package name contains illegal characters: "..tostring(wm)..":"..tostring(EGpun).."!")cnx_1g=true;break end;el(J,{repo=_O.repo,name=EGpun,data=LNlhK}) | |
cnx_1g=true until true;if not cnx_1g then break end end end;smj=true until true;if not smj then break end end;local coSiE={} | |
for eV=1,#J do local DGQnw=J[eV]local yLgHuF,fpL,k6 | |
yLgHuF,fpL,k6=DGQnw.name,DGQnw.repo,DGQnw.data;if n(JQi1jg(fpL,yLgHuF),coSiE)then | |
Zg.error("There're multiple packages under the same name: ".. | |
tostring(yLgHuF).."!")end | |
if not | |
(tE(JQi1jg(kr2CYaS,fpL)))then local gC;gC,B=o5sms(JQi1jg(kr2CYaS,fpL))if not(gC)then | |
return | |
false,"Could not create directory '".. | |
tostring(JQi1jg(kr2CYaS,fpL)).."': "..tostring(B)end end;local m | |
m,B=io.open(JQi1jg(kr2CYaS,fpL,yLgHuF),"w") | |
if not(m)then return false, | |
"Could not open '"..tostring(JQi1jg(kr2CYaS,fpL,yLgHuF)).."' for writing: ".. | |
tostring(B)end;do | |
m:write(RSjapQ({name=yLgHuF,repo=fpL,data=k6}))m:close()end;local rvNhq6v | |
do for QO,VvzMQHj in pairs(hXgSzEI)do | |
if | |
VvzMQHj.repo==fpL and VvzMQHj.pkg==yLgHuF then rvNhq6v=QO;break end end end;if rvNhq6v then table.remove(hXgSzEI,rvNhq6v)else | |
el(coSiE,JQi1jg(fpL,yLgHuF))end end;Zg.print("Removing old cache files ...") | |
for fSYJX=1,#hXgSzEI do | |
local WV=hXgSzEI[fSYJX]local yUho4MXRx;yUho4MXRx=WV.path;OO(yUho4MXRx)end;Zg.print("Fixing bad cache nodes ...") | |
lOb_Sv:fixCache() | |
Zg.print("- "..tostring(#J).. | |
" program"..tostring(pX4gCR(#J)).." cached.") | |
Zg.print("- "..tostring(#coSiE).. | |
" package"..tostring(pX4gCR(#coSiE)).." ".. | |
tostring(dk(#coSiE)).." new.") | |
Zg.print("- "..tostring(#hXgSzEI).. | |
" package"..tostring(pX4gCR(#hXgSzEI)).. | |
" no longer exist"..tostring(gad4ZcL(#hXgSzEI))..".")return true end | |
lOb_Sv.parseLocalPath=function(lOb_Sv,J2,hgrBfz0w) | |
if hgrBfz0w:sub(1,2)=="//"then return | |
JQi1jg(J2,hgrBfz0w:sub(3))else return JQi1jg(J2,"usr",hgrBfz0w)end end | |
lOb_Sv.rawInstall=function(lOb_Sv,Gi,wpv1,I9IMuWm,a)if wpv1 ==nil then wpv1="/"end | |
if I9IMuWm==nil then I9IMuWm=false end;if a==nil then a=false end;local rZ=lOb_Sv:listCache() | |
local VKTNfzUf={filesInstalled=0,packagesInstalled=0} | |
if a and not tE(wpv1)then local pglFz82w,RkeCL=o5sms(wpv1)if not(pglFz82w)then | |
Zg.fatal( | |
"Failed to create '".. | |
tostring(wpv1).."' directory for package '".. | |
tostring(Gi).."'! \n"..tostring(RkeCL))end elseif not a then local LoW_7e=wjim8xCV(Gi, | |
nil,"oppm")if LoW_7e then | |
Zg.print("'".. | |
tostring(Gi).."' is already installed, skipping...")return LoW_7e,VKTNfzUf end end;local Oms4 | |
for mLgQ=1,#rZ do local ng=rZ[mLgQ]local Pp_NboV,owAp3u2G,OH0C,kmQkm9cr | |
Pp_NboV,owAp3u2G,OH0C,kmQkm9cr=ng.path,ng.pkg,ng.repo,ng.data;if owAp3u2G==Gi then Oms4=ng;break end end;if not(Oms4)then | |
Zg.fatal("No such package: "..tostring(Gi))end;local JfA={}local CPu1=Oms4.repo | |
for IE97m,wey in | |
pairs(Oms4.data.data.files)do local hThO6={} | |
if IE97m:sub(1,1)==":"then | |
hThO6=lOb_Sv:resolveDirectory(CPu1,IE97m:sub(2, | |
IE97m:find("/")-1,nil),IE97m:sub(IE97m:find("/")+1))else | |
hThO6={{name=pE.name(IE97m),path=IE97m,url=lOb_Sv.FILES:format(CPu1,IE97m)}}end;local Gi | |
for zXU=1,#hThO6 do local HmJym2=hThO6[zXU]local Jjb7Am5,UwqY7A | |
Gi,Jjb7Am5,UwqY7A=HmJym2.name,HmJym2.path,HmJym2.url;local k=iPL3B4cr(Ta(UwqY7A)) | |
local d7gPKcw=lOb_Sv:parseLocalPath(wpv1,wey)if not(tE(d7gPKcw))then o5sms(d7gPKcw)end | |
do | |
local naeNp,gA=io.open(JQi1jg(d7gPKcw,Gi),"w")if not naeNp then | |
Zg.fatal("Could not open file for writing: "..tostring(gA))end;naeNp:write(k) | |
naeNp:close()end;VKTNfzUf.filesInstalled=VKTNfzUf.filesInstalled+1 | |
el(JfA,{name=Gi,url=UwqY7A,dir=d7gPKcw})end end;local pfyhF={} | |
if Oms4.data.data.dependencies then for r in | |
pairs(Oms4.data.data.dependencies)do el(pfyhF,{name=r})end end | |
VKTNfzUf.packagesInstalled=VKTNfzUf.packagesInstalled+1;return{name=Gi,files=JfA,dependencies=pfyhF,manual=I9IMuWm},VKTNfzUf end | |
lOb_Sv.resolveDependencies=function(lOb_Sv,LWe,_3Tq,Rq1hByv,iFk)if _3Tq==nil then _3Tq={}end | |
if Rq1hByv==nil then Rq1hByv={}end;if iFk==nil then iFk={}end;local sEFtmNgB=lOb_Sv:listCache() | |
for qxiez0Cn=1,#LWe do | |
local Ck_H=LWe[qxiez0Cn]local Sc=false;for _QFw_It=1,#_3Tq do local WLqHf=_3Tq[_QFw_It] | |
if WLqHf==Ck_H then Sc=true;break end end | |
if not(Sc)then Rq1hByv[Ck_H]=true;local vN=wjim8xCV(Ck_H, | |
nil,"oppm") | |
if not vN then local BIwW6_ | |
for Vdfc3=1,#sEFtmNgB do | |
local CzM7PG=sEFtmNgB[Vdfc3]local RKf6s5;RKf6s5=CzM7PG.pkg;if RKf6s5 ==Ck_H then BIwW6_=CzM7PG;break end end;if not(BIwW6_)then | |
return false,"Unknown package: "..tostring(Ck_H)end | |
if BIwW6_.data.data.dependencies then | |
for tP9E_ in | |
pairs(BIwW6_.data.data.dependencies)do Sc=false | |
for Y1WX=1,#_3Tq do local G06Z2=_3Tq[Y1WX]if G06Z2 ==tP9E_ then Sc=true;break end end | |
if not(Sc)then | |
if Rq1hByv[tP9E_]then | |
Zg.fatal("Circular dependencies detected: '".. | |
tostring(Ck_H).."' depends on '".. | |
tostring(tP9E_).."', and '".. | |
tostring(tP9E_).."' depends on '"..tostring(Ck_H).."'.")end | |
lOb_Sv:resolveDependencies({tP9E_},_3Tq,Rq1hByv,iFk)end end end;el(iFk,Ck_H)end;el(_3Tq,Ck_H)Rq1hByv[Ck_H]=nil end end;return iFk end | |
lOb_Sv.getPackageDependants=function(lOb_Sv,K,tQx9TV,FL7g2o)if tQx9TV==nil then tQx9TV={}end | |
if FL7g2o==nil then FL7g2o={}end | |
for dkh7Tt9=1,#K do local XiNd_H=K[dkh7Tt9]local Q_c4px86=false | |
for _F6VYt=1,#tQx9TV do local ITv3PH1i=tQx9TV[_F6VYt]if | |
ITv3PH1i.name==XiNd_H then Q_c4px86=true;break end end | |
if not(Q_c4px86)then el(FL7g2o,{name=XiNd_H}) | |
local _5fF=wjim8xCV(XiNd_H,nil,"oppm") | |
if _5fF then el(tQx9TV,{name=XiNd_H,manifest=_5fF}) | |
local OUQqQp=iPL3B4cr(w(JQi1jg(xSebv5Jc,"oppm"))) | |
for OyOfzTWn in OUQqQp do | |
_5fF=iPL3B4cr(wjim8xCV(OyOfzTWn,nil,"oppm"))local rx=_5fF.dependencies | |
for ijvSrZA1=1,#rx do local STNuSN6=rx[ijvSrZA1] | |
if STNuSN6.name==XiNd_H then | |
Q_c4px86=false | |
for PYOeGnAZ=1,#tQx9TV do local s10ar5XH=tQx9TV[PYOeGnAZ]if s10ar5XH.name==OyOfzTWn then | |
Q_c4px86=true;break end end | |
if not Q_c4px86 then | |
for YoKhvIs=1,#FL7g2o do local I2ipE=FL7g2o[YoKhvIs]if I2ipE.name==OyOfzTWn then | |
Zg.fatal( | |
"Circular dependencies detected: "..tostring(OyOfzTWn))end end | |
lOb_Sv:getPackageDependants({OyOfzTWn},tQx9TV,FL7g2o)end end end end else | |
Zg.fatal("Package ".. | |
tostring(XiNd_H).." is referenced as a dependant of another package, however, this package isn't installed.")end;FL7g2o[#FL7g2o]=nil end end;return tQx9TV end | |
lOb_Sv.whatDependsOn=function(lOb_Sv,qS730I) | |
local PYEbnua=iPL3B4cr(wjim8xCV(qS730I,nil,"oppm"))local Um4ZYiT={} | |
local AF=iPL3B4cr(w(JQi1jg(xSebv5Jc,"oppm"))) | |
for shIHW in AF do PYEbnua=iPL3B4cr(wjim8xCV(shIHW,nil,"oppm")) | |
local H5=PYEbnua.dependencies;for HYY=1,#H5 do local C3=H5[HYY] | |
if C3.name==qS730I then el(Um4ZYiT,shIHW)end end end;return Um4ZYiT end | |
lOb_Sv.install=qTDt(function(lOb_Sv,...)local SkCMMH={...}local kvvs=sgeP.r or sgeP.reinstall;local _yTx3S94=sgeP.s or | |
sgeP.save | |
local Mm=iPL3B4cr(lOb_Sv:resolveDependencies(SkCMMH)) | |
h6Ub7U({install=(function()local WUdVeYc={}local lHep6wo=1;for BKZsJ=1,#Mm do local Sw=Mm[BKZsJ] | |
if | |
not kvvs or not n(Sw,SkCMMH)then WUdVeYc[lHep6wo]=Sw;lHep6wo=lHep6wo+1 end end;return WUdVeYc end)(),reinstall= | |
kvvs and | |
(function()local W67mm9p6={}local oBxdTi6u=1 | |
for T7hLe5j=1,#Mm do local I_=Mm[T7hLe5j]if n(I_,SkCMMH)then | |
W67mm9p6[oBxdTi6u]=I_;oBxdTi6u=oBxdTi6u+1 end end;return W67mm9p6 end)()or nil})local g524={filesInstalled=0,packagesInstalled=0} | |
if kvvs then local J2Jin | |
do local Rvg={}local HpdA=1;for DsAJbW=1,#SkCMMH do | |
local AXfX=SkCMMH[DsAJbW]Rvg[HpdA]=iPL3B4cr(wjim8xCV(AXfX,nil,"oppm"))HpdA= | |
HpdA+1 end;J2Jin=Rvg end;lOb_Sv:_remove(J2Jin,true,false)end | |
for btcUUhB=1,#Mm do local iw0S=Mm[btcUUhB] | |
Zg.print("Installing '"..tostring(iw0S).."'...")local Tjg | |
if _yTx3S94 then Tjg="./"..tostring(iw0S).."/"else Tjg="/"end | |
local n2srE7H,Rf=lOb_Sv:rawInstall(iw0S,Tjg,n(iw0S,SkCMMH),_yTx3S94) | |
g524.filesInstalled=g524.filesInstalled+Rf.filesInstalled | |
g524.packagesInstalled=g524.packagesInstalled+Rf.packagesInstalled | |
if g524.packagesInstalled~=0 then local X9ZjrTz,tYFIuD=Ki1HJT(n2srE7H,"oppm") | |
if X9ZjrTz then | |
Zg.info( | |
"Saved the manifest of '"..tostring(n2srE7H.name).."'.")else | |
Zg.fatal("Couldn't save the manifest of '"..tostring(n2srE7H.name).."': ".. | |
tostring(tYFIuD)..".")end end end | |
Zg.print("- ".. | |
tostring(g524.packagesInstalled).." package".. | |
tostring(pX4gCR(g524.packagesInstalled)).." installed.")return | |
Zg.print("- ".. | |
tostring(g524.filesInstalled).." file".. | |
tostring(pX4gCR(g524.filesInstalled)).." installed.")end) | |
lOb_Sv.remove=qTDt(function(lOb_Sv,...)local Ht5Ge={...}local l={}for IO=1,#Ht5Ge do local YDJY=Ht5Ge[IO] | |
local t=iPL3B4cr(wjim8xCV(YDJY,nil,"oppm"))el(l,t)end;return | |
lOb_Sv:_remove(l,false)end) | |
lOb_Sv._remove=function(lOb_Sv,Rdi8NIft,J0uTkQ9,sd6k)if J0uTkQ9 ==nil then J0uTkQ9=false end | |
if sd6k==nil then sd6k=true end;local a | |
if not | |
RkGFh6.get("oppm",{},true).get("remove_dependants",true)or not sd6k then | |
do | |
local lK7={}local KWMxs7a=1 | |
for T=1,#Rdi8NIft do local LBIp4=Rdi8NIft[T] | |
lK7[KWMxs7a]={name=LBIp4.name,manifest=LBIp4}KWMxs7a=KWMxs7a+1 end;a=lK7 end else | |
a=lOb_Sv:getPackageDependants((function()local A5={}local PV168s0f=1;for bjK=1,#Rdi8NIft do local Us1Xh=Rdi8NIft[bjK] | |
A5[PV168s0f]=Us1Xh.name;PV168s0f=PV168s0f+1 end | |
return A5 end)())end | |
if not(J0uTkQ9)then | |
h6Ub7U({remove=(function()local rs59={}local R=1;for rGa2MaGH=1,#a do local i6=a[rGa2MaGH] | |
rs59[R]=tostring(i6.name)R=R+1 end;return rs59 end)()})end | |
for u33wPQT=1,#a do local aNrMnPZ=a[u33wPQT] | |
Zg.print("Removing '".. | |
tostring(aNrMnPZ.manifest.name).."' ...") | |
iPL3B4cr(eFI8dI3.__parent.remove(lOb_Sv,aNrMnPZ.manifest,"oppm"))end;return true end | |
lOb_Sv.cache=qTDt(function(lOb_Sv,fC,...)local Kl=fC | |
if"update"==Kl then | |
Zg.print("Updating OpenPrograms program cache ...")iPL3B4cr(lOb_Sv:updateCache()) | |
return Zg.print("Done.")elseif"fix"==Kl then | |
Zg.print("Fixing OpenPrograms program cache ...")iPL3B4cr(lOb_Sv:fixCache()) | |
return Zg.print("Done.")else Zg.error("Unknown command.")return | |
Zg.print("Usage: hpm oppm:cache {update|fix}")end end) | |
lOb_Sv.autoremove=qTDt(function(lOb_Sv)local EmJGBwA={}local _E3={} | |
local j3=iPL3B4cr(w(JQi1jg(xSebv5Jc,"oppm"))) | |
for f in j3 do local jy=iPL3B4cr(wjim8xCV(f,nil,"oppm")) | |
if | |
not(jy.manual)then local Ifev2bUE=lOb_Sv:getPackageDependants(f)if#Ifev2bUE==1 then | |
el(EmJGBwA,f)el(_E3,f)end end end | |
while true do local ZY=false | |
j3=iPL3B4cr(w(JQi1jg(xSebv5Jc,"oppm"))) | |
for KCpJbzHT in j3 do | |
if not(n(KCpJbzHT,EmJGBwA))then | |
local g=iPL3B4cr(wjim8xCV(KCpJbzHT,nil,"oppm")) | |
if not(g.manual)then | |
local dQl0xvy2=lOb_Sv:getPackageDependants(KCpJbzHT)table.remove(dQl0xvy2,1) | |
if | |
qLH5((function()local hX={}local wYTrvPn=1 | |
for pB6K=1,#dQl0xvy2 do | |
local YV=dQl0xvy2[pB6K]hX[wYTrvPn]=n(YV.name,EmJGBwA)wYTrvPn=wYTrvPn+1 end;return hX end)())then | |
for zPm=1,#dQl0xvy2 do local JmEyZ5=dQl0xvy2[zPm]local FGvy,KpnA=n(JmEyZ5.name,_E3)if KpnA then | |
table.remove(_E3,KpnA)end end;el(EmJGBwA,KCpJbzHT)el(_E3,KCpJbzHT)ZY=true end end end end;if not(ZY)then break end end | |
h6Ub7U({remove=(function() | |
if#EmJGBwA>0 then local j_F9c={}local q=1 | |
for b7G0ciz=1,#EmJGBwA do local rF2te=EmJGBwA[b7G0ciz]j_F9c[q]= | |
"oppm:"..tostring(rF2te)q=q+1 end;return j_F9c else return nil end end)()})for KG_EjN=1,#_E3 do local aIrjXeB=_E3[KG_EjN] | |
lOb_Sv:_remove({iPL3B4cr(wjim8xCV(aIrjXeB,nil,"oppm"))},false)end | |
Zg.print("Done.")return true end) | |
lOb_Sv.search=qTDt(function(lOb_Sv,...)local sZdri=lOb_Sv:listCache()local pT={} | |
if...then | |
for XgkgIR9=1,#sZdri do | |
local sm2=sZdri[XgkgIR9]local cz;cz=sm2.data;local pSL=cz.data;local ifrP9={...} | |
for Iynmp=#ifrP9,1,-1 do local PFvHX=ifrP9[Iynmp]if | |
cz.name:find(PFvHX)then table.remove(ifrP9,Iynmp)break end;if | |
pSL.name and pSL.name:find(PFvHX)then | |
table.remove(ifrP9,Iynmp)break end | |
if pSL.description and | |
pSL.description:find(PFvHX)then table.remove(ifrP9,Iynmp)break end;if pSL.note and pSL.note:find(PFvHX)then | |
table.remove(ifrP9,Iynmp)break end end;if#ifrP9 ==0 then el(pT,cz)end end else do local sP={}local Y=1 | |
for QHxdp58D=1,#sZdri do local efdknL=sZdri[QHxdp58D]sP[Y]=efdknL.data;Y=Y+1 end;pT=sP end end | |
for YUdva=1,#pT do local x8FBS=pT[YUdva] | |
Zg.print(tostring(x8FBS.name).. | |
" - "..tostring(x8FBS.data.name or | |
x8FBS.name).. | |
": "..tostring(x8FBS.data.description))end end) | |
lOb_Sv.info=qTDt(function(lOb_Sv,LGBr)if N5UjTN(LGBr)then | |
Zg.fatal("Usage: hpm oppm:info <package name>")end;local M=lOb_Sv:listCache()local I=nil | |
for W=1, | |
#M do local Dx5GC=M[W]if Dx5GC.pkg==LGBr then I=Dx5GC;break end end;if not(I)then Zg.fatal("No such package.")end | |
Zg.print( | |
"- Package name: "..tostring(I.pkg))if I.data.data.name then | |
Zg.print(" "..tostring(I.data.data.name))end;if I.data.data.description then | |
Zg.print( | |
"- Description:\n"..tostring(I.data.data.description))end;if I.data.data.authors then | |
Zg.print( | |
"- Authors:\n"..tostring(I.data.data.authors))end;if I.data.data.files then | |
Zg.print("- Files: ".. | |
tostring(O(I.data.data.files)))end | |
if I.data.data.dependencies then | |
Zg.print( | |
"- Depends: ".. | |
tostring(table.concat((function()local kwZhI={}local T0h=1;for H0 in pairs(I.data.data.dependencies)do | |
kwZhI[T0h]=H0;T0h=T0h+1 end;return kwZhI end)())))end;if I.data.data.note then | |
Zg.print("- Note:\n"..tostring(I.data.data.note))end | |
return Zg.print("- Repository: https://github.com/".. | |
tostring(I.repo))end)if i.__inherited then i.__inherited(i,eFI8dI3)end | |
_.oppm=eFI8dI3 end;local Gm | |
Gm=function()local Mrz66=iPL3B4cr(w(xSebv5Jc))N5UjTN=true | |
for A in Mrz66 do | |
local RR=pE.name(A) | |
if XPoQB(JQi1jg(xSebv5Jc,RR))then | |
local Oj4B=iPL3B4cr(w(JQi1jg(xSebv5Jc,RR))) | |
for aT in Oj4B do | |
if not(XPoQB(JQi1jg(xSebv5Jc,RR,aT)))then local ZN0brC=iPL3B4cr(wjim8xCV(aT, | |
nil,RR)) | |
Zg.print(RR..":"..aT.. | |
(ZN0brC.version and" @ ".. | |
ZN0brC.version or""))N5UjTN=false end end end end | |
if N5UjTN then return Zg.print("No packages installed.")end end;local YKA7cU | |
YKA7cU=function(...)CM,sgeP=JD(...)if#CM<1 then return y36Aetn()end end;local mCsewfX | |
mCsewfX=function()local g=CM[1] | |
if"list"==g then return Gm()elseif"help"==g then return y36Aetn()else | |
do | |
local iYIip_rt=wZdg(CM[1]) | |
if iYIip_rt then return | |
iYIip_rt(Wu_uIt((function()local WoJla={}local jk=1 | |
for Y=2,#CM do local sM=CM[Y]WoJla[jk]=sM;jk=jk+1 end;return WoJla end)()))end end end end | |
hw18.semver={Version=YAtG_LV3.Version,Spec=YAtG_LV3.Spec,SpecItem=YAtG_LV3.SpecItem,compare=YAtG_LV3.compare,match=YAtG_LV3.match,validate=YAtG_LV3.validate}hw18.json=s;hw18.CONFIG_PATH=rDtVf;hw18.USAGE=vj;hw18.DEFAULT_CONFIG=z | |
hw18.options=sgeP;hw18.args=CM;hw18.request=Qlmlet;hw18.modules=_;hw18.config=RkGFh6 | |
hw18.modulePath=nvCiFt7r;hw18.distPath=xSebv5Jc;hw18.exitCode=mMp;hw18.log=Zg;hw18.assert=ykRppH | |
hw18.unimplemented=WQ6;hw18.printUsage=y36Aetn;hw18.try=iPL3B4cr;hw18.checkType=GI2hz6SK | |
hw18.argNumber=Oh;hw18.argString=PG;hw18.isin=n;hw18.tableLen=O;hw18.empty=N5UjTN | |
hw18.all=qLH5;hw18.existsDir=tE;hw18.existsFile=VcV0EuD;hw18.plural=pX4gCR | |
hw18.singular=gad4ZcL;hw18.linkingVerb=dk;hw18.remove=OO;hw18.loadConfig=y | |
hw18.checkInternet=cR6rJlAl;hw18.download=M6ilzGJ;hw18.findCustomCommand=wZdg;hw18.getModuleBy=BaX | |
hw18.callModuleMethod=SJsW11k;hw18.saveManifest=Ki1HJT;hw18.loadManifest=wjim8xCV | |
hw18.removeManifest=EQLam;hw18.public=qTDt;hw18.wrapResponse=v;hw18.recv=Ta;hw18.confirm=unArcvQl | |
hw18.pkgPlan=h6Ub7U;hw18.printPackageList=Gm;hw18.parseArguments=YKA7cU;hw18.process=mCsewfX;for MMJEx,EB in | |
pairs(_G)do hw18[MMJEx]=EB end;YKA7cU(...) | |
iPL3B4cr(y())iW6CD()mCsewfX()return mMp |
local s=load([===[ | |
local rA5U=20160728.17 | |
local Uc06="-[ JSON.lua package by Jeffrey Friedl (http://regex.info/blog/lua/json) version 20160728.17 ]-"local lcBL={VERSION=rA5U,AUTHOR_NOTE=Uc06}local DHPxI=" " | |
local dx={pretty=true,align_keys=false,indent=DHPxI} | |
local RRuSHnxf={__tostring=function()return"JSON array"end}RRuSHnxf.__index=RRuSHnxf | |
local mcYOuT={__tostring=function()return"JSON object"end}mcYOuT.__index=mcYOuT;function lcBL:newArray(iXxD6s) | |
return setmetatable(iXxD6s or{},RRuSHnxf)end;function lcBL:newObject(oiY)return | |
setmetatable(oiY or{},mcYOuT)end;local function Rr(FsYIVlkf) | |
return | |
type(FsYIVlkf)=='number'and FsYIVlkf or FsYIVlkf.N end | |
local scRP0={__index=isNumber,__tostring=function(HLXS0Q_)return HLXS0Q_.S end,__unm=function(Kw)return | |
Rr(Kw)end,__concat=function(nvaIsNv7,vDnoL55) | |
return tostring(nvaIsNv7)..tostring(vDnoL55)end,__add=function(xlAK,zr1y)return Rr(xlAK)+Rr(zr1y)end,__sub=function(Hs,jk)return | |
Rr(Hs)-Rr(jk)end,__mul=function(qzSFyIO,Z65) | |
return Rr(qzSFyIO)*Rr(Z65)end,__div=function(umyCNfj,FT)return Rr(umyCNfj)/Rr(FT)end,__mod=function(YVLXYq,bJfct)return | |
Rr(YVLXYq)%Rr(bJfct)end,__pow=function(OhuFpq_N,Dzg)return | |
Rr(OhuFpq_N)^Rr(Dzg)end,__lt=function(_4O,C)return Rr(_4O)<Rr(C)end,__eq=function(fLI2zRe,_Fr2YU)return | |
Rr(fLI2zRe)==Rr(_Fr2YU)end,__le=function(Xfn,U)return | |
Rr(Xfn)<=Rr(U)end} | |
function lcBL:asNumber(Ebsw) | |
if getmetatable(Ebsw)==scRP0 then return Ebsw elseif | |
type(Ebsw)=='table'and | |
type(Ebsw.S)=='string'and type(Ebsw.N)=='number'then return setmetatable(Ebsw,scRP0)else | |
local UlikV={S=tostring(Ebsw),N=tonumber(Ebsw)}return setmetatable(UlikV,scRP0)end end | |
local function AI0R2TQ6(JtAjijkG) | |
if JtAjijkG<=127 then return string.char(JtAjijkG)elseif JtAjijkG<=2047 then | |
local s=math.floor(JtAjijkG/0x40)local YAtG_LV3=JtAjijkG- (0x40*s)return | |
string.char(0xC0+s,0x80+YAtG_LV3)elseif JtAjijkG<=65535 then | |
local LfEJbh_=math.floor(JtAjijkG/0x1000)local JD=JtAjijkG-0x1000*LfEJbh_ | |
local u=math.floor(JD/0x40)local pzDMZwG=JD-0x40*u;LfEJbh_=0xE0+LfEJbh_;u=0x80+u | |
pzDMZwG=0x80+pzDMZwG | |
if | |
(LfEJbh_==0xE0 and u<0xA0)or | |
(LfEJbh_==0xED and u>0x9F)or(LfEJbh_==0xF0 and u<0x90)or(LfEJbh_==0xF4 and u>0x8F)then return"?"else return string.char(LfEJbh_,u,pzDMZwG)end else local XPoQB=math.floor(JtAjijkG/0x40000) | |
local XxJ=JtAjijkG-0x40000*XPoQB;local o5sms=math.floor(XxJ/0x1000) | |
XxJ=XxJ-0x1000*o5sms;local JQi1jg=math.floor(XxJ/0x40)local wVzn=XxJ-0x40*JQi1jg | |
return string.char( | |
0xF0+XPoQB,0x80+o5sms,0x80+JQi1jg,0x80+wVzn)end end | |
function lcBL:onDecodeError(pE,RSjapQ,QJf,zC)if RSjapQ then | |
if QJf then | |
pE=string.format("%s at char %d of: %s",pE,QJf,RSjapQ)else pE=string.format("%s: %s",pE,RSjapQ)end end | |
if zC~=nil then pE=pE.." (".. | |
lcBL:encode(zC)..")"end | |
if self.assert then self.assert(false,pE)else assert(false,pE)end end;lcBL.onDecodeOfNilError=lcBL.onDecodeError | |
lcBL.onDecodeOfHTMLError=lcBL.onDecodeError | |
function lcBL:onEncodeError(pfZ3SPy_,pDNa2ox6) | |
if pDNa2ox6 ~=nil then pfZ3SPy_=pfZ3SPy_.. | |
" ("..lcBL:encode(pDNa2ox6)..")"end;if self.assert then self.assert(false,pfZ3SPy_)else | |
assert(false,pfZ3SPy_)end end | |
local function yA(Do6yo7nm,y06X3k,ivnJjrA,d3fMjkg) | |
local el=y06X3k:match('^-?[1-9]%d*',ivnJjrA)or y06X3k:match("^-?0",ivnJjrA)if not el then | |
Do6yo7nm:onDecodeError("expected number",y06X3k,ivnJjrA,d3fMjkg.etc)end | |
local Wu_uIt=ivnJjrA+el:len()local w=y06X3k:match('^%.%d+',Wu_uIt)or""Wu_uIt=Wu_uIt+ | |
w:len() | |
local sgeP=y06X3k:match('^[eE][-+]?%d+',Wu_uIt)or""Wu_uIt=Wu_uIt+sgeP:len()local CM=el..w..sgeP;if | |
d3fMjkg.decodeNumbersAsObjects then return lcBL:asNumber(CM),Wu_uIt end | |
if | |
( | |
d3fMjkg.decodeIntegerStringificationLength and(el:len()>=d3fMjkg.decodeIntegerStringificationLength or | |
sgeP:len()>0))or | |
(d3fMjkg.decodeDecimalStringificationLength and | |
( | |
w:len()>=d3fMjkg.decodeDecimalStringificationLength or sgeP:len()>0))then return CM,Wu_uIt end;local Qlmlet=tonumber(CM)if not Qlmlet then | |
Do6yo7nm:onDecodeError("bad number",y06X3k,ivnJjrA,d3fMjkg.etc)end;return Qlmlet,Wu_uIt end | |
local function XmVolesU(_,RkGFh6,hw18,nvCiFt7r)if RkGFh6:sub(hw18,hw18)~='"'then | |
_:onDecodeError("expected string's opening quote",RkGFh6,hw18,nvCiFt7r.etc)end;local xSebv5Jc=hw18+1 | |
local mMp=RkGFh6:len()local rDtVf="" | |
while xSebv5Jc<=mMp do local vj=RkGFh6:sub(xSebv5Jc,xSebv5Jc)if | |
vj=='"'then return rDtVf,xSebv5Jc+1 end | |
if vj~='\\'then rDtVf=rDtVf..vj;xSebv5Jc= | |
xSebv5Jc+1 elseif RkGFh6:match('^\\b',xSebv5Jc)then rDtVf=rDtVf.."\b"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\f',xSebv5Jc)then rDtVf=rDtVf.."\f"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\n',xSebv5Jc)then rDtVf=rDtVf.."\n"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\r',xSebv5Jc)then rDtVf=rDtVf.."\r"xSebv5Jc= | |
xSebv5Jc+2 elseif RkGFh6:match('^\\t',xSebv5Jc)then rDtVf=rDtVf.."\t"xSebv5Jc= | |
xSebv5Jc+2 else | |
local z=RkGFh6:match('^\\u([0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])',xSebv5Jc) | |
if z then xSebv5Jc=xSebv5Jc+6;local Zg=tonumber(z,16) | |
if | |
Zg>=0xD800 and Zg<=0xDBFF then | |
local ykRppH=RkGFh6:match('^\\u([dD][cdefCDEF][0123456789aAbBcCdDeEfF][0123456789aAbBcCdDeEfF])',xSebv5Jc) | |
if ykRppH then xSebv5Jc=xSebv5Jc+6;Zg=0x2400+ (Zg-0xD800)*0x400+ | |
tonumber(ykRppH,16)else end end;rDtVf=rDtVf..AI0R2TQ6(Zg)else rDtVf=rDtVf.. | |
RkGFh6:match('^\\(.)',xSebv5Jc)xSebv5Jc=xSebv5Jc+2 end end end | |
_:onDecodeError("unclosed string",RkGFh6,hw18,nvCiFt7r.etc)end | |
local function eZ0l3ch(WQ6,y36Aetn)local iPL3B4cr,GI2hz6SK=WQ6:find("^[ \n\r\t]+",y36Aetn)if GI2hz6SK then | |
return GI2hz6SK+1 else return y36Aetn end end;local W_63_9 | |
local function h9dyA_4T(Oh,PG,n,O)if PG:sub(n,n)~='{'then | |
Oh:onDecodeError("expected '{'",PG,n,O.etc)end;local N5UjTN=eZ0l3ch(PG,n+1)local qLH5=Oh.strictTypes and | |
Oh:newObject{}or{}if | |
PG:sub(N5UjTN,N5UjTN)=='}'then return qLH5,N5UjTN+1 end | |
local tE=PG:len() | |
while N5UjTN<=tE do local VcV0EuD,pX4gCR=XmVolesU(Oh,PG,N5UjTN,O) | |
N5UjTN=eZ0l3ch(PG,pX4gCR)if PG:sub(N5UjTN,N5UjTN)~=':'then | |
Oh:onDecodeError("expected colon",PG,N5UjTN,O.etc)end | |
N5UjTN=eZ0l3ch(PG,N5UjTN+1)local gad4ZcL,pX4gCR=W_63_9(Oh,PG,N5UjTN,O)qLH5[VcV0EuD]=gad4ZcL | |
N5UjTN=eZ0l3ch(PG,pX4gCR)local dk=PG:sub(N5UjTN,N5UjTN) | |
if dk=='}'then return qLH5,N5UjTN+1 end;if PG:sub(N5UjTN,N5UjTN)~=','then | |
Oh:onDecodeError("expected comma or '}'",PG,N5UjTN,O.etc)end | |
N5UjTN=eZ0l3ch(PG,N5UjTN+1)end;Oh:onDecodeError("unclosed '{'",PG,n,O.etc)end | |
local function oh(E,OO,y,cR6rJlAl)if OO:sub(y,y)~='['then | |
E:onDecodeError("expected '['",OO,y,cR6rJlAl.etc)end;local M6ilzGJ=eZ0l3ch(OO,y+1)local iW6CD=E.strictTypes and | |
E:newArray{}or{}if | |
OO:sub(M6ilzGJ,M6ilzGJ)==']'then return iW6CD,M6ilzGJ+1 end | |
local wZdg=1;local BaX=OO:len() | |
while M6ilzGJ<=BaX do | |
local SJsW11k,Ki1HJT=W_63_9(E,OO,M6ilzGJ,cR6rJlAl)iW6CD[wZdg]=SJsW11k;wZdg=wZdg+1;M6ilzGJ=eZ0l3ch(OO,Ki1HJT) | |
local wjim8xCV=OO:sub(M6ilzGJ,M6ilzGJ)if wjim8xCV==']'then return iW6CD,M6ilzGJ+1 end;if | |
OO:sub(M6ilzGJ,M6ilzGJ)~=','then | |
E:onDecodeError("expected comma or '['",OO,M6ilzGJ,cR6rJlAl.etc)end | |
M6ilzGJ=eZ0l3ch(OO,M6ilzGJ+1)end | |
E:onDecodeError("unclosed '['",OO,y,cR6rJlAl.etc)end | |
W_63_9=function(E,QLam,qTDt,v)qTDt=eZ0l3ch(QLam,qTDt) | |
if qTDt>QLam:len()then E:onDecodeError("unexpected end of string",QLam, | |
nil,v.etc)end | |
if QLam:find('^"',qTDt)then return XmVolesU(E,QLam,qTDt,v.etc)elseif | |
QLam:find('^[-0123456789 ]',qTDt)then return yA(E,QLam,qTDt,v)elseif QLam:find('^%{',qTDt)then | |
return h9dyA_4T(E,QLam,qTDt,v)elseif QLam:find('^%[',qTDt)then return oh(E,QLam,qTDt,v)elseif QLam:find('^true',qTDt)then return true, | |
qTDt+4 elseif QLam:find('^false',qTDt)then return false,qTDt+5 elseif | |
QLam:find('^null',qTDt)then return nil,qTDt+4 else | |
E:onDecodeError("can't parse JSON",QLam,qTDt,v.etc)end end | |
function lcBL:decode(Ta,u,nArcvQl)if type(nArcvQl)~='table'then nArcvQl={}end;if u~=nil then | |
nArcvQl.etc=u end;if | |
type(self)~='table'or self.__index~=lcBL then | |
lcBL:onDecodeError("JSON:decode must be called in method format",nil,nil,nArcvQl.etc)end | |
if Ta==nil then | |
self:onDecodeOfNilError(string.format("nil passed to JSON:decode()"), | |
nil,nil,nArcvQl.etc)elseif type(Ta)~='string'then | |
self:onDecodeError(string.format("expected string argument to JSON:decode(), got %s",type(Ta)), | |
nil,nil,nArcvQl.etc)end;if Ta:match('^%s*$')then return nil end;if Ta:match('^%s*<')then | |
self:onDecodeOfHTMLError(string.format("html passed to JSON:decode()"),Ta, | |
nil,nArcvQl.etc)end | |
if | |
Ta:sub(1,1):byte()==0 or | |
(Ta:len()>=2 and Ta:sub(2,2):byte()==0)then | |
self:onDecodeError("JSON package groks only UTF-8, sorry",Ta,nil,nArcvQl.etc)end;if nArcvQl.decodeNumbersAsObjects==nil then | |
nArcvQl.decodeNumbersAsObjects=self.decodeNumbersAsObjects end;if | |
nArcvQl.decodeIntegerStringificationLength==nil then | |
nArcvQl.decodeIntegerStringificationLength=self.decodeIntegerStringificationLength end;if | |
nArcvQl.decodeDecimalStringificationLength==nil then | |
nArcvQl.decodeDecimalStringificationLength=self.decodeDecimalStringificationLength end | |
local h6Ub7U,Gm=pcall(W_63_9,self,Ta,1,nArcvQl)if h6Ub7U then return Gm else | |
if self.assert then self.assert(false,Gm)else assert(false,Gm)end;return nil,Gm end end | |
local function DZXGTh(YKA7cU) | |
if YKA7cU=="\n"then return"\\n"elseif YKA7cU=="\r"then return"\\r"elseif YKA7cU=="\t"then return"\\t"elseif YKA7cU=="\b"then | |
return"\\b"elseif YKA7cU=="\f"then return"\\f"elseif YKA7cU=='"'then return'\\"'elseif YKA7cU=='\\'then return'\\\\'else return | |
string.format("\\u%04x",YKA7cU:byte())end end | |
local Su9Koz='['..'"'.. | |
'%\\'..'%z'..'\001'..'-'..'\031'..']'local Uk7e=AI0R2TQ6(0x2028)local KwQCk_G=AI0R2TQ6(0x2029) | |
local function ptZa(mCsewfX,yY) | |
local Xf=mCsewfX:gsub(Su9Koz,DZXGTh)if yY.stringsAreUtf8 then | |
Xf=Xf:gsub(Uk7e,'\\u2028'):gsub(KwQCk_G,'\\u2029')end;return'"'..Xf..'"'end | |
local function PEqsd(UlFdiZ7v,U,wFeA)local JQgI={}local N={}local fs52REi=false;local PUNkgaiM | |
for X in pairs(U)do | |
if type(X)=='string'then | |
table.insert(JQgI,X)elseif type(X)=='number'then table.insert(N,X) | |
if X<=0 or X>=math.huge then | |
fs52REi=true elseif not PUNkgaiM or X>PUNkgaiM then PUNkgaiM=X end else | |
UlFdiZ7v:onEncodeError("can't encode table with a key of type "..type(X),wFeA)end end | |
if#JQgI==0 and not fs52REi then | |
if#N>0 then return nil,PUNkgaiM elseif | |
tostring(U)=="JSON array"then return nil elseif tostring(U)=="JSON object"then return{}else return nil end end;table.sort(JQgI)local s6FbB | |
if#N>0 then if UlFdiZ7v.noKeyConversion then | |
UlFdiZ7v:onEncodeError("a table with both numeric and string keys could be an object or array; aborting",wFeA)end | |
s6FbB={}for dc61,aguhyl in pairs(U)do s6FbB[dc61]=aguhyl end | |
table.sort(N) | |
for p,gOPDv in ipairs(N)do local aSdZU3=tostring(gOPDv) | |
if s6FbB[aSdZU3]==nil then | |
table.insert(JQgI,aSdZU3)s6FbB[aSdZU3]=U[gOPDv]else | |
UlFdiZ7v:onEncodeError( | |
"conflict converting table with mixed-type keys into a JSON object: key "..gOPDv.." exists both as a string and a number.",wFeA)end end end;return JQgI,nil,s6FbB end;local iSj | |
function iSj(YKDL,oFyb6OLp,oGdh_mv,WjvvK,TASVwBgU,KjUncMB,XkT) | |
if oFyb6OLp==nil or | |
(not XkT and TASVwBgU and TASVwBgU.null and oFyb6OLp== | |
TASVwBgU.null)then return'null'elseif | |
type(oFyb6OLp)=='string'then return ptZa(oFyb6OLp,TASVwBgU)elseif type(oFyb6OLp)=='number'then | |
if | |
oFyb6OLp~=oFyb6OLp then return"null"elseif oFyb6OLp>=math.huge then return"1e+9999"elseif oFyb6OLp<=-math.huge then | |
return"-1e+9999"else return tostring(oFyb6OLp)end elseif type(oFyb6OLp)=='boolean'then return tostring(oFyb6OLp)elseif type(oFyb6OLp)~= | |
'table'then | |
YKDL:onEncodeError("can't convert "..type(oFyb6OLp).." to JSON",WjvvK)elseif getmetatable(oFyb6OLp)==scRP0 then return tostring(oFyb6OLp)else | |
local c3dr=oFyb6OLp;if type(TASVwBgU)~='table'then TASVwBgU={}end;if type(KjUncMB)~= | |
'string'then KjUncMB=""end | |
if oGdh_mv[c3dr]then | |
YKDL:onEncodeError("table ".. | |
tostring(c3dr).." is a child of itself",WjvvK)else oGdh_mv[c3dr]=true end;local NGH;local tIc,MD2O,HQ=PEqsd(YKDL,c3dr,WjvvK) | |
if MD2O then local cng={}for lE=1,MD2O do | |
table.insert(cng,iSj(YKDL,c3dr[lE],oGdh_mv,WjvvK,TASVwBgU,KjUncMB))end | |
if TASVwBgU.pretty then NGH="[ ".. | |
table.concat(cng,", ").." ]"else NGH="[".. | |
table.concat(cng,",").."]"end elseif tIc then local nI2F0id=HQ or c3dr | |
if TASVwBgU.pretty then local N4aMD_P={}local pCi=0 | |
for lNOqUk8,YAnZNei in ipairs(tIc)do | |
local h8YWR44E=iSj(YKDL,tostring(YAnZNei),oGdh_mv,WjvvK,TASVwBgU,KjUncMB,true) | |
if TASVwBgU.align_keys then pCi=math.max(pCi,#h8YWR44E)end;table.insert(N4aMD_P,h8YWR44E)end | |
local NzeoQJ=KjUncMB..tostring(TASVwBgU.indent or"") | |
local AwGfFV=NzeoQJ..string.rep(" ",pCi).. | |
(TASVwBgU.align_keys and" "or"") | |
local wCRY="%s%"..string.format("%d",pCi).."s: %s"local d0uKSVw1={} | |
for VF,fTrMe in ipairs(tIc)do | |
local ypDndT8=iSj(YKDL,nI2F0id[fTrMe],oGdh_mv,WjvvK,TASVwBgU,AwGfFV) | |
table.insert(d0uKSVw1,string.format(wCRY,NzeoQJ,N4aMD_P[VF],ypDndT8))end;NGH="{\n".. | |
table.concat(d0uKSVw1,",\n").."\n"..KjUncMB.."}"else local MV65={} | |
for Y3D66Ym9,q in | |
ipairs(tIc)do | |
local PhJ=iSj(YKDL,nI2F0id[q],oGdh_mv,WjvvK,TASVwBgU,KjUncMB) | |
local h=iSj(YKDL,tostring(q),oGdh_mv,WjvvK,TASVwBgU,KjUncMB,true) | |
table.insert(MV65,string.format("%s:%s",h,PhJ))end;NGH="{"..table.concat(MV65,",").."}"end else NGH="[]"end;oGdh_mv[c3dr]=false;return NGH end end | |
function lcBL:encode(j2K,r8hgwQ,_6U)if type(self)~='table'or self.__index~=lcBL then | |
lcBL:onEncodeError("JSON:encode must be called in method format",r8hgwQ)end;if | |
type(_6U)~='table'then _6U={}end;return iSj(self,j2K,{},r8hgwQ,_6U)end | |
function lcBL:encode_pretty(GLSzBQs,c,xg)if type(self)~='table'or self.__index~=lcBL then | |
lcBL:onEncodeError("JSON:encode_pretty must be called in method format",c)end;if | |
type(xg)~='table'then xg=dx end;return iSj(self,GLSzBQs,{},c,xg)end;function lcBL.__tostring()return"JSON encode/decode package"end | |
lcBL.__index=lcBL | |
function lcBL:new(Id2KoP_G)local Y2or={}if Id2KoP_G then | |
for zN8ASHV5,iju in pairs(Id2KoP_G)do Y2or[zN8ASHV5]=iju end end | |
return setmetatable(Y2or,lcBL)end;return lcBL:new() | |
]===])() | |
local YAtG_LV3=(function() | |
local yY=[[ Copyright (c) The python-semanticversion project | |
All rights reserved. | |
Redistribution and use in source and binary forms, with or without | |
modification, are permitted provided that the following conditions are met: | |
1. Redistributions of source code must retain the above copyright notice, this | |
list of conditions and the following disclaimer. | |
2. Redistributions in binary form must reproduce the above copyright notice, | |
this list of conditions and the following disclaimer in the documentation | |
and/or other materials provided with the distribution. | |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | |
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
]] | |
yY=[[ The use of the library is similar to the original one, | |
check the documentation here: https://python-semanticversion.readthedocs.io/en/latest/ | |
]]local Xf,UlFdiZ7v,U;do local aSdZU3=table | |
Xf,UlFdiZ7v,U=aSdZU3.concat,aSdZU3.insert,aSdZU3.unpack end;local wFeA | |
wFeA=function(YKDL) | |
do local oFyb6OLp=tonumber(YKDL)if | |
oFyb6OLp then return oFyb6OLp,true else return YKDL,false end end end;local JQgI | |
JQgI=function(oGdh_mv)return oGdh_mv and oGdh_mv[1]=='0'and | |
tonumber(oGdh_mv and oGdh_mv~='0')end;local N | |
N=function(WjvvK,TASVwBgU)if WjvvK==TASVwBgU then return 0 end | |
if WjvvK>TASVwBgU then return 1 end;if WjvvK<TASVwBgU then return-1 end end;local fs52REi | |
fs52REi=function(KjUncMB,XkT)local c3dr,NGH=wFeA(KjUncMB)local tIc,MD2O=wFeA(XkT) | |
if NGH and MD2O then | |
return N(c3dr,tIc)elseif NGH then return-1 elseif MD2O then return 1 else return N(c3dr,tIc)end end;local PUNkgaiM | |
PUNkgaiM=function(HQ,cng)local lE;do local nI2F0id={}for N4aMD_P=1,#HQ do if cng[N4aMD_P]then | |
nI2F0id[HQ[N4aMD_P]]=cng[N4aMD_P]end end | |
lE=nI2F0id end | |
for pCi,NzeoQJ in pairs(lE)do | |
local AwGfFV=fs52REi(pCi,NzeoQJ)if AwGfFV~=0 then return AwGfFV end end;return N(#HQ,#cng)end;local s6FbB | |
do local wCRY | |
local d0uKSVw1={_coerce=function(YAnZNei,h8YWR44E,VF)if VF==nil then VF=false end | |
if h8YWR44E==nil and VF then return h8YWR44E end;return tonumber(h8YWR44E)end,next_major=function(fTrMe) | |
if | |
fTrMe.prerelease and fTrMe.minor==0 and fTrMe.patch==0 then | |
return | |
s6FbB(Xf((function()local ypDndT8={}local MV65=1 | |
local Y3D66Ym9={fTrMe.major,fTrMe.minor,fTrMe.patch}for q=1,#Y3D66Ym9 do local PhJ=Y3D66Ym9[q]ypDndT8[MV65]=tostring(PhJ) | |
MV65=MV65+1 end;return ypDndT8 end)(),'.'))else | |
return | |
s6FbB(Xf((function()local h={}local j2K=1;local r8hgwQ={fTrMe.major+1,0,0} | |
for _6U=1,#r8hgwQ do | |
local GLSzBQs=r8hgwQ[_6U]h[j2K]=tostring(GLSzBQs)j2K=j2K+1 end;return h end)(),'.'))end end,next_minor=function(c)if | |
not(c.minor)then | |
error("Partial version doesn't contain the minor component!")end | |
if c.prerelease and c.patch==0 then | |
return | |
s6FbB(Xf((function() | |
local xg={}local Id2KoP_G=1;local Y2or={c.major,c.minor,c.patch} | |
for zN8ASHV5=1,#Y2or do | |
local iju=Y2or[zN8ASHV5]xg[Id2KoP_G]=tostring(iju)Id2KoP_G=Id2KoP_G+1 end;return xg end)(),'.'))else | |
return | |
s6FbB(Xf((function()local XsWgh={}local l4Hdz=1;local NSXCgSH={c.major,c.minor+1,0} | |
for Wq=1,#NSXCgSH do | |
local SbOQ=NSXCgSH[Wq]XsWgh[l4Hdz]=tostring(SbOQ)l4Hdz=l4Hdz+1 end;return XsWgh end)(),'.'))end end,next_patch=function(IiuHGo)if | |
not(IiuHGo.patch)then | |
error("Partial version doesn't contain the patch component!")end | |
if IiuHGo.prerelease then | |
return | |
s6FbB(Xf((function()local cGqxtYr={} | |
local bgJFKeeZ=1;local yu9fg0nN={IiuHGo.major,IiuHGo.minor,IiuHGo.patch} | |
for wgx=1,# | |
yu9fg0nN do local zlU7X=yu9fg0nN[wgx] | |
cGqxtYr[bgJFKeeZ]=tostring(zlU7X)bgJFKeeZ=bgJFKeeZ+1 end;return cGqxtYr end)(),'.'))else | |
return | |
s6FbB(Xf((function()local t={}local f6qbO=1 | |
local kk={IiuHGo.major,IiuHGo.minor,IiuHGo.patch+1} | |
for QrubIAv=1,#kk do local bLHDW=kk[QrubIAv]t[f6qbO]=tostring(bLHDW)f6qbO=f6qbO+1 end;return t end)(),'.'))end end,coerce=function(YjFd7b,jZgPYb,zN2)if | |
zN2 ==nil then zN2=false end;local IN69pa5 | |
IN69pa5=function(OVx_mN) | |
local lB,byE=OVx_mN:match('^(%d+)(.*)$')if not(lB)then return nil end;local bITCI=lB | |
local K,F5dtVpnN=byE:match('^%.(%d+)(.*)$')if K then byE=F5dtVpnN;bITCI=bITCI.. ('.'..K)end;local kxeBp | |
kxeBp,F5dtVpnN=byE:match('^%.(%d+)(.*)$') | |
if kxeBp then byE=F5dtVpnN;bITCI=bITCI.. ('.'..kxeBp)end;return OVx_mN,bITCI end;local UOWJ,WtalJw=IN69pa5(jZgPYb)if not(UOWJ)then | |
error("Version string lacks a numerical component: ".. | |
tostring(jZgPYb))end | |
local JYrf2=jZgPYb:sub(1,#WtalJw) | |
if not zN2 then while({JYrf2:gsub('.','')})[2]<2 do JYrf2= | |
JYrf2 ..'.0'end end;if#WtalJw==#jZgPYb then return s6FbB(JYrf2,zN2)end;local KHDOUlRY=jZgPYb:sub( | |
#WtalJw+1) | |
KHDOUlRY=KHDOUlRY:gsub('[^a-zA-Z0-9+.-]','-')local I0JvPpn,Ce4ZE=nil,nil | |
if KHDOUlRY:sub(1,1)=='+'then I0JvPpn='' | |
Ce4ZE=KHDOUlRY:sub(2)elseif KHDOUlRY:sub(1,1)=='.'then I0JvPpn=''Ce4ZE=KHDOUlRY:sub(2)elseif | |
KHDOUlRY:sub(1,1)=='-'then KHDOUlRY=KHDOUlRY:sub(2) | |
do | |
local a=KHDOUlRY:find('+')if a then | |
I0JvPpn,Ce4ZE=KHDOUlRY:sub(1,a-1),KHDOUlRY:sub(a+1,-1)else I0JvPpn,Ce4ZE=KHDOUlRY,''end end else do local kQ=KHDOUlRY:find('+') | |
if kQ then I0JvPpn,Ce4ZE=KHDOUlRY:sub(1,kQ-1),KHDOUlRY:sub( | |
kQ+1,-1)else I0JvPpn,Ce4ZE=KHDOUlRY,''end end end;Ce4ZE=Ce4ZE:gsub('+','.')if I0JvPpn and I0JvPpn~=''then JYrf2=JYrf2 .. | |
('-'..I0JvPpn)end;if | |
Ce4ZE and Ce4ZE~=''then JYrf2=JYrf2 .. ('+'..Ce4ZE)end;return | |
YjFd7b.__class(JYrf2,zN2)end,parse=function(EE9LAE,iVx,eg,AQviNt)if | |
eg==nil then eg=false end;if AQviNt==nil then AQviNt=false end;if not iVx or | |
type(iVx)~='string'or iVx==''then | |
error("Invalid empty version string: ".. | |
tostring(tostring(iVx)))end;local T6 | |
if eg then | |
T6=EE9LAE.__class.partialVersionRe else T6=EE9LAE.__class.versionRe end;local NviN0i,BlMQce,o,dpRE,fEiXwWq=T6(EE9LAE.__class,iVx)if not NviN0i then | |
error( | |
"Invalid version string: "..tostring(iVx))end;if JQgI(NviN0i)then | |
error("Invalid leading zero in major: ".. | |
tostring(iVx))end;if JQgI(BlMQce)then | |
error("Invalid leading zero in minor: ".. | |
tostring(iVx))end;if JQgI(o)then | |
error("Invalid leading zero in patch: ".. | |
tostring(iVx))end;NviN0i=tonumber(NviN0i) | |
BlMQce=EE9LAE:_coerce(BlMQce,eg)o=EE9LAE:_coerce(o,eg) | |
if dpRE==nil then if eg and fEiXwWq==nil then return | |
{NviN0i,BlMQce,o,nil,nil}else dpRE={}end elseif dpRE==''then dpRE={}else | |
do | |
local r3JzMga6={}local Tuyw=1 | |
for FYLcr2nu in dpRE:gmatch('[^.]+')do r3JzMga6[Tuyw]=FYLcr2nu;Tuyw=Tuyw+1 end;dpRE=r3JzMga6 end;EE9LAE:_validateIdentifiers(dpRE,false)end | |
if fEiXwWq==nil then if eg then fEiXwWq=nil else fEiXwWq={}end elseif fEiXwWq==''then fEiXwWq={}else do | |
local ioS69={}local AiP=1 | |
for S2jwpoi in fEiXwWq:gmatch('[^.]+')do ioS69[AiP]=S2jwpoi;AiP=AiP+1 end;fEiXwWq=ioS69 end | |
EE9LAE:_validateIdentifiers(fEiXwWq,true)end;return{NviN0i,BlMQce,o,dpRE,fEiXwWq}end,_validateIdentifiers=function(_WX9u,u0riyU,UH)if | |
UH==nil then UH=false end | |
for WNph=1,#u0riyU do local ytF=u0riyU[WNph]if not ytF then | |
error( | |
"Invalid empty identifier ".. | |
tostring(ytF).." in "..tostring(Xf(u0riyU,'.')))end;if | |
ytF:sub(1,1)=='0'and | |
tonumber(ytF)and ytF~='0'and not UH then | |
error("Invalid leading zero in identifier "..tostring(ytF))end end end,__pairs=function(d)return | |
pairs({d.major,d.minor,d.patch,d.prerelease,d.build})end,__ipairs=function(gRm)return | |
ipairs({gRm.major,gRm.minor,gRm.patch,gRm.prerelease,gRm.build})end,__tostring=function(LPX0) | |
local g=tostring(LPX0.major) | |
if LPX0.minor~=nil then g=g.. ('.'..LPX0.minor)end | |
if LPX0.patch~=nil then g=g.. ('.'..LPX0.patch)end | |
if LPX0.prerelease and#LPX0.prerelease>0 or | |
LPX0.partial and LPX0.prerelease and#LPX0.prerelease==0 and LPX0.build==nil then g=g.. ('-'.. | |
Xf(LPX0.prerelease,'.'))end | |
if | |
LPX0.build and#LPX0.build>0 or LPX0.partial and LPX0.build and# | |
LPX0.build==0 then g=g.. ('+'..Xf(LPX0.build,'.'))end;return g end,_comparsionFunctions=function(_l,qao)if | |
qao==nil then qao=false end;local ipUPIzc | |
ipUPIzc=function(J7nsK,dXbd) | |
if J7nsK and dXbd then | |
return PUNkgaiM(J7nsK,dXbd)elseif J7nsK then return-1 elseif dXbd then return 1 else return 0 end end;local N8 | |
N8=function(vQj,sVBxyy)if vQj==sVBxyy then return 0 else return'not implemented'end end;local Gzk | |
Gzk=function(N9d)local S7 | |
S7=function(bJtvRSR,aBhZK5)if bJtvRSR==nil or aBhZK5 ==nil then return 0 else | |
return N9d(bJtvRSR,aBhZK5)end end;return S7 end;if qao then return{N,Gzk(N),Gzk(N),Gzk(ipUPIzc),Gzk(N8)}else return | |
{N,N,N,ipUPIzc,N8}end end,__compare=function(Jz8JUscj,OtGmbAgE) | |
local oU_r=Jz8JUscj:_comparsionFunctions( | |
Jz8JUscj.partial or OtGmbAgE.partial) | |
local n_lv={{oU_r[1],Jz8JUscj.major,OtGmbAgE.major},{oU_r[2],Jz8JUscj.minor,OtGmbAgE.minor},{oU_r[3],Jz8JUscj.patch,OtGmbAgE.patch},{oU_r[4],Jz8JUscj.prerelease,OtGmbAgE.prerelease},{oU_r[5],Jz8JUscj.build,OtGmbAgE.build}} | |
for UYQF=1,#n_lv do local WXx=n_lv[UYQF]local W4EuxJXi,BlYNd61h,XDPndG=U(WXx) | |
local sJYFQIP4=W4EuxJXi(BlYNd61h,XDPndG)if sJYFQIP4 ~=0 then return sJYFQIP4 end end;return 0 end,__compareHelper=function(Ogq0S2,n8Cw3SR,GJqd7gt,slE5aDm2) | |
local aL_g=Ogq0S2:__compare(n8Cw3SR)if aL_g=='not implemented'then return slE5aDm2 end | |
return GJqd7gt(aL_g)end,__eq=function(IMUI10L,vPA) | |
local pUXZ6G4;pUXZ6G4=function(mk)return mk==0 end;return | |
IMUI10L:__compareHelper(vPA,pUXZ6G4,false)end,__lt=function(OeQex1U4,i0cV9) | |
local EGD;EGD=function(VWiGCreH)return VWiGCreH<0 end;return | |
OeQex1U4:__compareHelper(i0cV9,EGD,false)end,__le=function(B_kkL,uEO6Y) | |
local i_053JPY;i_053JPY=function(l)return l<=0 end;return | |
B_kkL:__compareHelper(uEO6Y,i_053JPY,false)end}d0uKSVw1.__index=d0uKSVw1 | |
wCRY=setmetatable({__init=function(UK,NzaICo,k1X83nYm) | |
if k1X83nYm==nil then k1X83nYm=false end;local xxzxfj,_ad1m4I,H1QsS,rIMx,TiA=U(UK:parse(NzaICo,k1X83nYm)) | |
UK.major,UK.minor,UK.patch,UK.prerelease,UK.build,UK.partial=xxzxfj,_ad1m4I,H1QsS,rIMx,TiA,k1X83nYm end,__base=d0uKSVw1,__name="Version"},{__index=d0uKSVw1,__call=function(Y51P,...) | |
local ichL=setmetatable({},d0uKSVw1)Y51P.__init(ichL,...)return ichL end})d0uKSVw1.__class=wCRY;local lNOqUk8=wCRY | |
lNOqUk8.versionRe=function(lNOqUk8,NOK) | |
local Alv,YeLO2,CkrmO,ooovsSJe=NOK:match('^(%d+)%.(%d+)%.(%d+)(.*)$')if not(Alv)then return nil end | |
local s5IsD,KvYEVoXt=ooovsSJe:match('^%-([0-9a-zA-z.-]+)(.*)$')if s5IsD then ooovsSJe=KvYEVoXt end;local VWWD_P | |
VWWD_P,KvYEVoXt=ooovsSJe:match('^%+([0-9a-zA-Z.-]+)(.*)$')if VWWD_P then ooovsSJe=KvYEVoXt end;if#ooovsSJe>0 then return nil end;return | |
Alv,YeLO2,CkrmO,s5IsD,VWWD_P end | |
lNOqUk8.partialVersionRe=function(lNOqUk8,zsMuNkv)local aXxi,Q18a7QTy=zsMuNkv:match('^(%d+)(.*)$')if | |
not(aXxi)then return nil end | |
local K5Rp6,GTIA=Q18a7QTy:match('^%.(%d+)(.*)$')if K5Rp6 then Q18a7QTy=GTIA end;local gdPUe | |
gdPUe,GTIA=Q18a7QTy:match('^%.(%d+)(.*)$')if gdPUe then Q18a7QTy=GTIA end;local _bxEn | |
_bxEn,GTIA=Q18a7QTy:match('^%-([0-9a-zA-Z.-]*)(.*)$')if _bxEn then Q18a7QTy=GTIA end;local pcN_ceXY | |
pcN_ceXY,GTIA=Q18a7QTy:match('^%+([0-9a-zA-Z.-]*)(.*)$')if pcN_ceXY then Q18a7QTy=GTIA end;if#Q18a7QTy>0 then return nil end;return aXxi, | |
K5Rp6,gdPUe,_bxEn,pcN_ceXY end;s6FbB=wCRY end;local X | |
do local _P | |
local rq={parse=function(I,RAAJAsR)if | |
not RAAJAsR or type(RAAJAsR)~='string'or RAAJAsR==''then | |
error("Invalid empty requirement specification: "..tostring(tostring(RAAJAsR)))end;if RAAJAsR== | |
'*'then return{I.__class.KIND_ANY,''}end | |
local c1pjj7,BMv=I.__class:reSpec(RAAJAsR)if not c1pjj7 then | |
error("Invalid requirement specification: "..tostring(RAAJAsR))end;c1pjj7= | |
I.__class.KIND_ALIASES[c1pjj7]or c1pjj7;local NQh8=s6FbB(BMv,true) | |
if | |
NQh8.build~=nil and c1pjj7 ~=I.__class.KIND_EQUAL and c1pjj7 ~= | |
I.__class.KIND_NEQ then | |
error( | |
"Invalid requirement specification "..tostring(RAAJAsR)..": build numbers have no ordering")end;return{c1pjj7,NQh8}end,match=function(P,bkTe) | |
local ohmPbyDd=P.kind | |
if P.__class.KIND_ANY==ohmPbyDd then return true elseif P.__class.KIND_LT==ohmPbyDd then return bkTe< | |
P.spec elseif P.__class.KIND_LTE==ohmPbyDd then return bkTe<=P.spec elseif | |
P.__class.KIND_EQUAL==ohmPbyDd then return bkTe==P.spec elseif P.__class.KIND_GTE==ohmPbyDd then return bkTe>= | |
P.spec elseif P.__class.KIND_GT==ohmPbyDd then return bkTe>P.spec elseif | |
P.__class.KIND_NEQ==ohmPbyDd then return bkTe~=P.spec elseif P.__class.KIND_CARET==ohmPbyDd then | |
return | |
P.spec<=bkTe and bkTe<P.spec:next_major()elseif P.__class.KIND_TILDE==ohmPbyDd then return P.spec<=bkTe and | |
bkTe<P.spec:next_minor()else return | |
error("Unexpected match kind: "..tostring(P.kind))end end,__tostring=function(D)return | |
tostring(D.kind)..tostring(D.spec)end,__eq=function(DfDLWkT,MTU8HP4d)return | |
DfDLWkT.kind==MTU8HP4d.kind and DfDLWkT.spec==MTU8HP4d.spec end}rq.__index=rq | |
_P=setmetatable({__init=function(hIM_cG0i,jD) | |
hIM_cG0i.kind,hIM_cG0i.spec=U(hIM_cG0i:parse(jD))end,__base=rq,__name="SpecItem"},{__index=rq,__call=function(me,...) | |
local sgU5HAMG=setmetatable({},rq)me.__init(sgU5HAMG,...)return sgU5HAMG end})rq.__class=_P;local mo=_P;mo.KIND_ANY='*'mo.KIND_LT='<'mo.KIND_LTE='<=' | |
mo.KIND_EQUAL='=='mo.KIND_SHORTEQ='='mo.KIND_EMPTY=''mo.KIND_GTE='>='mo.KIND_GT='>' | |
mo.KIND_NEQ='!='mo.KIND_CARET='^'mo.KIND_TILDE='~' | |
mo.KIND_ALIASES={[mo.__class.KIND_SHORTEQ]=mo.__class.KIND_EQUAL,[mo.__class.KIND_EMPTY]=mo.__class.KIND_EQUAL} | |
mo.reSpec=function(mo,FDydY)local PEZ_,c=FDydY:match('^(.-)(%d.*)$') | |
if not | |
( | |
PEZ_=='<'or PEZ_=='<='or PEZ_==''or PEZ_=='='or PEZ_=='=='or PEZ_=='>='or PEZ_=='>'or PEZ_=='!='or PEZ_=='^'or PEZ_=='~')then return nil else | |
return PEZ_,c end end;X=_P end;local dc61 | |
do local ElbTbcZG | |
local r3={parse=function(pUiVYRok,jvPsY9)local tEBmuypm={}local hW=1;for iOcgdUx in jvPsY9 |
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)
(Sorry about that, but we can’t show files that are this big right now.)