View difference between Paste ID: ra3tXRgU and DE1SzCmC
SHOW: | | - or go back to the newest paste.
1-
local eaiIiiIlIl11lIiI1liII = assert local ealIIIil1II1ilI1l1I1l = select local eai1ilIl1iIlil111Illi = tonumber local ealIl11iliI1I1Il1lllliI = unpack local ealIl1Ii1IiiIiI1iI1I11l = pcall local eaIlllli111llliIll1li = setfenv local eailI1liiIiiiIii11I1i = setmetatable local eal11il1lIIl11lI1llIl = type local eallIiIiII1IIll1lI1I1 = getfenv local eaill1iIIi1llIliiIlil = tostring local ealIllli1iliiII1iliI1II = error local eaIIi1l1iIIiIiIllI1ll = string.sub local eai1I1iIlI1i11ll1lil1 = string.byte local eaiIliIiIilI1IiIiIII1 = string.char local ealliIiilI1Iil111lliI = string.rep local eai1iIlIi1Il1II1lliii = string.gsub local eal1ii11lliIIIIiii1II = string.match local ealiIIll1lIiIIl1l1I11 = eai1I1iIlI1i11ll1lil1("V", 1) local ealIiiil1lIIIIIi1111I, ealIil11ililIi1lI1l11 = #{4434}, #{ 3491, 4598, 5324, 3371, 2500, 2971, 456, 3451, 854, 2486, 1101, 4178, 2064, 2357, 1562, 6701, 6022, 6605, 1706, 2465, 614, 1732, 1286 } + ealiIIll1lIiIIl1l1I11 + 130962 local eaIl11liil1liIi1lliii = {} local ealIl1lIllili1Ill1iii1I = 1 local function eal1ilill111iiIl111I1(eal1III1illIi11I1i1lI, ealI111l1Ill1I1I11iiI) local eaIlIiiii11l1ll1iIIiI eal1III1illIi11I1i1lI = eai1iIlIi1Il1II1lliii(eaIIi1l1iIIiIiIllI1ll(eal1III1illIi11I1i1lI, 5), "..", function(eaIlIIi11I1lIi1lIilii) if eai1I1iIlI1i11ll1lil1(eaIlIIi11I1lIi1lIilii, 2) == 72 then eaIlIiiii11l1ll1iIIiI = eai1ilIl1iIlil111Illi(eaIIi1l1iIIiIiIllI1ll(eaIlIIi11I1lIi1lIilii, 1, 1)) return "" else local ealIllIlI1Il11il111llii = eaiIliIiIilI1IiIiIII1(eai1ilIl1iIlil111Illi(eaIlIIi11I1lIi1lIilii, 16)) if eaIlIiiii11l1ll1iIIiI then local eaiIiiilIl1ll11IlIiII = ealliIiilI1Iil111lliI(ealIllIlI1Il11il111llii, eaIlIiiii11l1ll1iIIiI) eaIlIiiii11l1ll1iIIiI = nil return eaiIiiilIl1ll11IlIiII else return ealIllIlI1Il11il111llii end end end) local function ealllIIl11iIliliillil() local ealIll11lIll11I1lII1I1I = eai1I1iIlI1i11ll1lil1(eal1III1illIi11I1i1lI, ealIl1lIllili1Ill1iii1I, ealIl1lIllili1Ill1iii1I) ealIl1lIllili1Ill1iii1I = ealIl1lIllili1Ill1iii1I + 1 return ealIll11lIll11I1lII1I1I end local function ealIlililiIIIIi1lIliI1I() local ealIll11lIll11I1lII1I1I, ealIllIlI1Il11il111llii, eaiIiiilIl1ll11IlIiII, eallIll11IiiilIl11lII = eai1I1iIlI1i11ll1lil1(eal1III1illIi11I1i1lI, ealIl1lIllili1Ill1iii1I, ealIl1lIllili1Ill1iii1I + 3) ealIl1lIllili1Ill1iii1I = ealIl1lIllili1Ill1iii1I + 4 return eallIll11IiiilIl11lII * 16777216 + eaiIiiilIl1ll11IlIiII * 65536 + ealIllIlI1Il11il111llii * 256 + ealIll11lIll11I1lII1I1I end local function ealIlil1iil11IilI1IIIII(eaIliIIl1III11II1llii, ealIli1l111iIililiii1li, ealII1iIlIiIliiii1lli) if ealII1iIlIiIliiii1lli then local eaI1Ilill1Iil11illI11, ealIlIilIIlillll1iIilll = 0, 0 for eaIIl1iIiI11iiIIIiii1 = ealIli1l111iIililiii1li, ealII1iIlIiIliiii1lli do eaI1Ilill1Iil11illI11 = eaI1Ilill1Iil11illI11 + 2 ^ ealIlIilIIlillll1iIilll * ealIlil1iil11IilI1IIIII(eaIliIIl1III11II1llii, eaIIl1iIiI11iiIIIiii1) ealIlIilIIlillll1iIilll = ealIlIilIIlillll1iIilll + 1 end return eaI1Ilill1Iil11illI11 else local eaIlIll1l1iiIIiIIlIil = 2 ^ (ealIli1l111iIililiii1li - 1) return eaIlIll1l1iiIIiIIlIil <= eaIliIIl1III11II1llii % (eaIlIll1l1iiIIiIIlIil + eaIlIll1l1iiIIiIIlIil) and 1 or 0 end end local function ealIllII1iil1iIiiIlIiII() local ealIll11lIll11I1lII1I1I, ealIllIlI1Il11il111llii = ealIlililiIIIIi1lIliI1I(), ealIlililiIIIIi1lIliI1I() if ealIll11lIll11I1lII1I1I == 0 and ealIllIlI1Il11il111llii == 0 then return 0 end return (-2 * ealIlil1iil11IilI1IIIII(ealIllIlI1Il11il111llii, 32) + 1) * 2 ^ (ealIlil1iil11IilI1IIIII(ealIllIlI1Il11il111llii, 21, 31) - 1023) * ((ealIlil1iil11IilI1IIIII(ealIllIlI1Il11il111llii, 1, 20) * 4294967296 + ealIll11lIll11I1lII1I1I) / 4503599627370496 + 1) end local function ealIll11iIIiiIiIil11iII(eaiIIi1l1IllII1IIiII1) local ealIli1iiiliI1I1iiI1ll1 = { eai1I1iIlI1i11ll1lil1(eal1III1illIi11I1i1lI, ealIl1lIllili1Ill1iii1I, ealIl1lIllili1Ill1iii1I + 3) } ealIl1lIllili1Ill1iii1I = ealIl1lIllili1Ill1iii1I + 4 local ealllIIlliiIIiII1II1l = { nil, nil, nil, nil, nil, nil, nil, nil } for eaIIl1iIiI11iiIIIiii1 = 1, 8 do ealllIIlliiIIiII1II1l[eaIIl1iIiI11iiIIIiii1] = ealIlil1iil11IilI1IIIII(eaiIIi1l1IllII1IIiII1, eaIIl1iIiI11iiIIIiii1) end local ealIlIIiiiIIiil1i1111il = "" for eaIIl1iIiI11iiIIIiii1 = 1, 4 do local eaI1Ilill1Iil11illI11, ealIlIilIIlillll1iIilll = 0, 0 for ealIllII1lIl1iiiliIliI1 = 1, 8 do local eaili1i1l1I1lIlIl1lI1 = ealIlil1iil11IilI1IIIII(ealIli1iiiliI1I1iiI1ll1[eaIIl1iIiI11iiIIIiii1], ealIllII1lIl1iiiliIliI1) if ealllIIlliiIIiII1II1l[ealIllII1lIl1iiiliIliI1] == 1 then eaili1i1l1I1lIlIl1lI1 = eaili1i1l1I1lIlIl1lI1 == 1 and 0 or 1 end eaI1Ilill1Iil11illI11 = eaI1Ilill1Iil11illI11 + 2 ^ ealIlIilIIlillll1iIilll * eaili1i1l1I1lIlIl1lI1 ealIlIilIIlillll1iIilll = ealIlIilIIlillll1iIilll + 1 end ealIlIIiiiIIiil1i1111il = ealIlIIiiiIIiil1i1111il .. ealIlIIiiiIIiil1i1111il.char(eaI1Ilill1Iil11illI11) end local ealIll11lIll11I1lII1I1I, ealIllIlI1Il11il111llii, eaiIiiilIl1ll11IlIiII, eallIll11IiiilIl11lII = eai1I1iIlI1i11ll1lil1(ealIlIIiiiIIiil1i1111il, 1, 4) return eallIll11IiiilIl11lII * 16777216 + eaiIiiilIl1ll11IlIiII * 65536 + ealIllIlI1Il11il111llii * 256 + ealIll11lIll11I1lII1I1I end local function eai11i1ii1II11I1iIi1I(eaiIIi1l1IllII1IIiII1) local ealIllIIi1l1lIlil1I1l = ealIlililiIIIIi1lIliI1I() ealIl1lIllili1Ill1iii1I = ealIl1lIllili1Ill1iii1I + ealIllIIi1l1lIlil1I1l local ealllIIlliiIIiII1II1l = { nil, nil, nil, nil, nil, nil, nil, nil } for eaIIl1iIiI11iiIIIiii1 = 1, 8 do ealllIIlliiIIiII1II1l[eaIIl1iIiI11iiIIIiii1] = ealIlil1iil11IilI1IIIII(eaiIIi1l1IllII1IIiII1, eaIIl1iIiI11iiIIIiii1) end local ealIlIIiiiIIiil1i1111il = "" for eaIIl1iIiI11iiIIIiii1 = 1, ealIllIIi1l1lIlil1I1l do local eaI1Ilill1Iil11illI11, ealIlIilIIlillll1iIilll = 0, 0 for ealIllII1lIl1iiiliIliI1 = 1, 8 do local eaili1i1l1I1lIlIl1lI1 = ealIlil1iil11IilI1IIIII(eai1I1iIlI1i11ll1lil1(eal1III1illIi11I1i1lI, ealIl1lIllili1Ill1iii1I - ealIllIIi1l1lIlil1I1l + eaIIl1iIiI11iiIIIiii1 - 1), ealIllII1lIl1iiiliIliI1) if ealllIIlliiIIiII1II1l[ealIllII1lIl1iiiliIliI1] == 1 then eaili1i1l1I1lIlIl1lI1 = eaili1i1l1I1lIlIl1lI1 == 1 and 0 or 1 end eaI1Ilill1Iil11illI11 = eaI1Ilill1Iil11illI11 + 2 ^ ealIlIilIIlillll1iIilll * eaili1i1l1I1lIlIl1lI1 ealIlIilIIlillll1iIilll = ealIlIilIIlillll1iIilll + 1 end ealIlIIiiiIIiil1i1111il = ealIlIIiiiIIiil1i1111il .. ealIlIIiiiIIiil1i1111il.char(eaI1Ilill1Iil11illI11) end return ealIlIIiiiIIiil1i1111il end local eai11ll1IIiliI1ii1lIi = ealllIIl11iIliliillil() local eai1Iii1I1l1I11li1lIl = ealllIIl11iIliliillil() local function ealIlllli11ll1IliI11I1l() local ealIlIl1IIi111l1111i1II = { [71754] = {}, [92566] = {}, [107141] = {}, [85701] = {} } ealllIIl11iIliliillil() local eaililllIII1111111iII = ealIlililiIIIIi1lIliI1I() - (#{ 3457, 2793, 4265, 6283, 3448, 2384, 4530, 416, 6807, 5936, 1703, 5188, 5965, 2175, 543, 38, 3926, 1530, 2422, 6827, 4495, 3235, 3467, 2008 } + ealiIIll1lIiIIl1l1I11 + 133654) for eaIIl1iIiI11iiIIIiii1 = ealIiiil1lIIIIIi1111I, eaililllIII1111111iII do local eaII1liIliilIiiIii1I1 = {} local eal11il1lIIl11lI1llIl = ealllIIl11iIliliillil() if eal11il1lIIl11lI1llIl == #{ 611, 6760, 6746, 198, 650, 6639, 1436, 2827, 5060, 6713, 2886, 3975, 1302, 3260, 6893, 5035, 1957 } then eaII1liIliilIiiIii1I1[12660] = #{ 2008, 5016, 3571, 1579, 5725, 6034, 6099, 6317, 5802, 5654, 1601, 6872, 6056, 6230, 2542, 1761, 3750, 5647, 1390, 1559, 3374, 4966 } + ealiIIll1lIiIIl1l1I11 + 14708 == #{ 5380, 1771, 1417, 6876, 425, 542, 5730, 2164, 4739, 5318, 2023, 4077, 3088, 4486, 1707, 3458, 3948, 2387, 511, 5437, 6803, 1850, 6687, 893 } + ealiIIll1lIiIIl1l1I11 + 53329 end if eal11il1lIIl11lI1llIl == #{ 3286, 2052, 6705, 4588, 6030, 3481, 2516, 6683, 6240, 1940, 1173, 4258, 5637, 620, 1545, 4522, 759, 3864, 5492, 1142, 3952, 974 } + ealiIIll1lIiIIl1l1I11 + 133 then eaII1liIliilIiiIii1I1[12660] = #{ 5747, 4244, 5898, 5002, 5108, 4351, 1975, 3825, 5, 6844, 4794, 6846, 457, 4489, 4648, 4133, 4948, 3245, 6153, 4874, 3190, 1724, 6719, 3330 } + ealiIIll1lIiIIl1l1I11 + 19841 == #{ 5747, 4244, 5898, 5002, 5108, 4351, 1975, 3825, 5, 6844, 4794, 6846, 457, 4489, 4648, 4133, 4948, 3245, 6153, 4874, 3190, 1724, 6719, 3330 } + ealiIIll1lIiIIl1l1I11 + 19841 end if eal11il1lIIl11lI1llIl == #{ 3331, 3013, 2578, 5325, 6382, 4183, 5149, 3520, 5005, 6664, 4582, 2046, 5217, 1538, 6910, 4158, 3170, 6864, 5794, 5129, 6043, 1855, 552 } + ealiIIll1lIiIIl1l1I11 + 38 then eaII1liIliilIiiIii1I1[12660] = ealIllII1iil1iIiiIlIiII() + ealIllII1iil1iIiiIlIiII() end if eal11il1lIIl11lI1llIl == #{ 2914, 3216, 3301, 1067, 3930, 1182, 5463, 1807, 6802, 5507, 6543, 3928, 5238, 596, 4109, 2651, 3534, 4620, 111, 6887, 4403, 5981 } + ealiIIll1lIiIIl1l1I11 + -52 then eaII1liIliilIiiIii1I1[12660] = ealllIIl11iIliliillil() end if eal11il1lIIl11lI1llIl == #{ 6638, 425, 4671, 3190, 693, 4863, 997, 4884, 6288, 3138, 5694, 3059, 2509, 246, 3710, 370, 4562, 4864, 6872, 1382, 1953, 662 } + ealiIIll1lIiIIl1l1I11 + 67 then eaII1liIliilIiiIii1I1[12660] = ealllIIl11iIliliillil() + ealIlililiIIIIi1lIliI1I() + ealIllII1iil1iIiiIlIiII() end if eal11il1lIIl11lI1llIl == #{ 5224, 1502, 2879, 2925, 2324, 2862, 5580, 5814, 372, 2492, 2497, 5246, 704, 1039, 2049, 3749, 1237, 4514, 601, 317 } + ealiIIll1lIiIIl1l1I11 + -76 then eaII1liIliilIiiIii1I1[12660] = ealIllII1iil1iIiiIlIiII() end if eal11il1lIIl11lI1llIl == #{ 4607, 5015, 4096, 5764, 4031, 83, 4572, 722, 6008, 5772, 3013, 4145, 1723, 5726, 3, 4491, 5117, 3577, 6659, 5941, 5756, 2768 } + ealiIIll1lIiIIl1l1I11 + 125 then eaII1liIliilIiiIii1I1[12660] = ealIllII1iil1iIiiIlIiII() + ealIllII1iil1iIiiIlIiII() end if eal11il1lIIl11lI1llIl == #{ 6046, 430, 693, 4979, 366, 6699, 5305, 1236, 421, 1089, 3310, 2220, 1147, 25, 3188, 2781, 5754, 5681, 5953, 6523, 4550, 4930, 1290, 4841 } + ealiIIll1lIiIIl1l1I11 + -31 then eaII1liIliilIiiIii1I1[12660] = eai11i1ii1II11I1iIi1I(eai11ll1IIiliI1ii1lIi) end if eal11il1lIIl11lI1llIl == #{ 1171, 6405, 2291, 3499 } then eaII1liIliilIiiIii1I1[12660] = ealllIIl11iIliliillil() + ealIlililiIIIIi1lIliI1I() + ealIllII1iil1iIiiIlIiII() end ealIlIl1IIi111l1111i1II[85701][eaIIl1iIiI11iiIIIiii1 - ealIiiil1lIIIIIi1111I] = eaII1liIliilIiiIii1I1 end ealIlIl1IIi111l1111i1II[18519] = ealllIIl11iIliliillil() ealIlililiIIIIi1lIliI1I() ealllIIl11iIliliillil() local eaililllIII1111111iII = ealIlililiIIIIi1lIliI1I() - (#{ 4780, 6088, 642, 58, 3716, 1595, 1193, 4617, 2754, 6260, 1035, 2245, 977, 4845, 4180, 4455, 6949, 4365, 2872, 1934 } + ealiIIll1lIiIIl1l1I11 + 133674) for eaIIl1iIiI11iiIIIiii1 = ealIiiil1lIIIIIi1111I, eaililllIII1111111iII do local eai1lll1liilIllllliI1 = {} local eaIliI1l1III11IIIl1iI = ealIll11iIIiiIiIil11iII(eai1Iii1I1l1I11li1lIl) eai1lll1liilIllllliI1[42229] = ealIlil1iil11IilI1IIIII(eaIliI1l1III11IIIl1iI, #{3089}, #{ 3787, 5255, 2541, 208, 6086, 3740, 5979, 5045, 3195, 503, 151, 779, 1719, 4342, 1253, 5763, 5513, 6251 }) eai1lll1liilIllllliI1[43892] = ealIlil1iil11IilI1IIIII(eaIliI1l1III11IIIl1iI, #{ 4137, 2400, 5377, 4296, 2391, 386, 4329, 5387, 3223, 917, 1414, 5502, 6861, 3029, 6142, 4349, 5132, 54, 2925 }, #{ 6728, 4390, 255, 3353, 4095, 5135, 6212, 5996, 5691, 2875, 2886, 4351, 1898, 3519, 2845, 908, 6327, 2747, 4941, 384, 3228, 2116, 504, 34 } + ealiIIll1lIiIIl1l1I11 + -84) eai1lll1liilIllllliI1[92248] = ealIlil1iil11IilI1IIIII(eaIliI1l1III11IIIl1iI, #{5737}, #{ 5328, 1036, 5900, 6527, 822, 2531, 2146, 2351, 6796 }) eai1lll1liilIllllliI1[43212] = ealIlil1iil11IilI1IIIII(eaIliI1l1III11IIIl1iI, #{ 742, 1832, 4245, 4637, 1073, 5053, 3855, 4629, 2437, 6322, 4863, 2183, 33, 316, 2077, 1109, 4762, 6563, 2300, 6160, 4402 } + ealiIIll1lIiIIl1l1I11 + -80, #{ 1588, 5995, 6783, 3397, 1945, 2630, 4146, 3429, 2589, 3873, 6428, 5907, 195, 4878, 6656, 5789, 3098, 1436, 3594, 6942, 3004, 2981, 3096 } + ealiIIll1lIiIIl1l1I11 + -77) eai1lll1liilIllllliI1[99507] = ealIlil1iil11IilI1IIIII(eaIliI1l1III11IIIl1iI, #{ 1516, 618, 1746, 3724, 6022, 4627, 6734, 2329, 751, 3272 }, #{ 5709, 1229, 432, 4732, 183, 6035, 1459, 3599, 6725, 6716, 3717, 4053, 5692, 6882, 6301, 1676, 1212, 6905 }) eai1lll1liilIllllliI1[133222] = ealIlil1iil11IilI1IIIII(eaIliI1l1III11IIIl1iI, #{4922}, #{ 642, 1133, 3690, 5365, 2370, 3751, 5325, 2973, 4558 }) ealIlIl1IIi111l1111i1II[92566][eaIIl1iIiI11iiIIIiii1] = eai1lll1liilIllllliI1 end ealIlililiIIIIi1lIliI1I() ealIlIl1IIi111l1111i1II[78849] = ealllIIl11iIliliillil() local eaililllIII1111111iII = ealIlililiIIIIi1lIliI1I() for eaIIl1iIiI11iiIIIiii1 = ealIiiil1lIIIIIi1111I, eaililllIII1111111iII do ealIlIl1IIi111l1111i1II[107141][eaIIl1iIiI11iiIIIiii1 - ealIiiil1lIIIIIi1111I] = ealIlllli11ll1IliI11I1l() end ealIlililiIIIIi1lIliI1I() ealIlililiIIIIi1lIliI1I() ealllIIl11iIliliillil() local eaililllIII1111111iII = ealIlililiIIIIi1lIliI1I() for eaIIl1iIiI11iiIIIiii1 = ealIiiil1lIIIIIi1111I, eaililllIII1111111iII do ealIlIl1IIi111l1111i1II[71754][eaIIl1iIiI11iiIIIiii1] = ealIlililiIIIIi1lIliI1I() end ealllIIl11iIliliillil() ealIlIl1IIi111l1111i1II[110398] = ealllIIl11iIliliillil() return ealIlIl1IIi111l1111i1II end local function eaIIliIIIIll11IlIliiI(ealIlIl1IIi111l1111i1II, ealI111l1Ill1I1I11iiI, eal111llIlIll11I1lI1I) local eall1Il11IiIl1l1liI1l, ealIiiIiiiIll1ilIiI1l = -1, -1 local eaI1ll111l1i1i1ill11l = ealIlIl1IIi111l1111i1II[92566] local ealIlli1i11iIilIil1I1Ii = eailI1liiIiiiIii11I1i({}, { __index = function(eail111iiiI1lilIIliII, eaIiIllllliI1IliIIlll) local ealIlIIiiiIIiil1i1111il = ealIlIl1IIi111l1111i1II[85701][eaIiIllllliI1IliIIlll] if eaIIi1l1iIIiIiIllI1ll(eal11il1lIIl11lI1llIl(ealIlIIiiiIIiil1i1111il[12660]), 1, 1) == "s" then return { [12660] = eaIIi1l1iIIiIiIllI1ll(ealIlIIiiiIIiil1i1111il[12660], 6) } end return ealIlIIiiiIIiil1i1111il end }) local ealIliiiiiiiil1IIiiiliI = 18519 local ealiI1iilIii1l1I1Illi = ealIlIl1IIi111l1111i1II[107141] local ealllIlil1ll1I1iilIII = 12660 local eaiil11illIIli1iIlIIl = ealIlIl1IIi111l1111i1II[110398] local eaIlIllIIiIli1liii11I = 43212 local eaIllI1iIliiiIiliiIIl = ealIlIl1IIi111l1111i1II[71754] local eaIiliililIlil1iiI1I1 = 92248 local function ealIll11IiiIiIlll11iII1(...) local ealllili1lIiIIii1llIl = 0 local eaIi1lll11I1ilIl1i1iI = { ealIl11iliI1I1Il1lllliI({}, 1, ealIlIl1IIi111l1111i1II[78849]) } local eaI1ilIi11iilIIII1lil = 1 local eallIiI1iil1liil1iiii = {} local ealIll1lIIiIiIlI1l1llI1 = {} local ealIil1II1iil1IlIiIII = 1 local ealI111l1Ill1I1I11iiI = eallIiIiII1IIll1lI1I1() local ealIliIli1llI1illIiiIil = { ... } local ealliIlii1il1Ii11Il1l = #ealIliIli1llI1illIiiIil - 1 for eaIIl1iIiI11iiIIIiii1 = 0, ealliIlii1il1Ii11Il1l do if eaIIl1iIiI11iiIIIiii1 < eaiil11illIIli1iIlIIl then eaIi1lll11I1ilIl1i1iI[eaIIl1iIiI11iiIIIiii1] = ealIliIli1llI1illIiiIil[eaIIl1iIiI11iiIIIiii1 + 1] end end local function ealIIIIIIl1llIli1lili(...) local eaiIiiilIl1ll11IlIiII = ealIIIil1II1ilI1l1I1l("#", ...) local eail111iiiI1lilIIliII = { ... } return eaiIiiilIl1ll11IlIiII, eail111iiiI1lilIIliII end local function eaIIiililIlilIll1i11I() while true do local ealIlillill1111Iill11ii = eaI1ll111l1i1i1ill11l[eaI1ilIi11iilIIII1lil] local ealIlIilil1IiiIIlliilli = ealIlillill1111Iill11ii[43212] eaI1ilIi11iilIIII1lil = eaI1ilIi11iilIIII1lil + 1 local eailI1II1l1i11iiiili1 = ealIlillill1111Iill11ii[99507] local ealIliilIlli1liI1I1iI11 = ealIlillill1111Iill11ii[42229] - ealIil11ililIi1lI1l11 local ealI11I1IiIiIilli1ili = ealIlillill1111Iill11ii[42229] local eaI1ii1l11lliiiIii1II = ealIlillill1111Iill11ii[43892] local eai11liI1iilIli1lllll = ealIlillill1111Iill11ii[92248] if ealIlIilil1IiiIIlliilli < 7 then if ealIlIilil1IiiIIlliilli < 3 then if ealIlIilil1IiiIIlliilli >= 1 then if ealIlIilil1IiiIIlliilli == 2 then if eai11liI1iilIli1lllll > 255 then eai11liI1iilIli1lllll = ealIlli1i11iIilIil1I1Ii[eai11liI1iilIli1lllll - 256][ealllIlil1ll1I1iilIII] else eai11liI1iilIli1lllll = eaIi1lll11I1ilIl1i1iI[eai11liI1iilIli1lllll] end if eailI1II1l1i11iiiili1 > 255 then eailI1II1l1i11iiiili1 = ealIlli1i11iIilIil1I1Ii[eailI1II1l1i11iiiili1 - 256][ealllIlil1ll1I1iilIII] else eailI1II1l1i11iiiili1 = eaIi1lll11I1ilIl1i1iI[eailI1II1l1i11iiiili1] end eaIi1lll11I1ilIl1i1iI[eaI1ii1l11lliiiIii1II] = eai11liI1iilIli1lllll * eailI1II1l1i11iiiili1 else eaI1ilIi11iilIIII1lil = eaI1ilIi11iilIIII1lil + ealIliilIlli1liI1I1iI11 end else eaIi1lll11I1ilIl1i1iI[eaI1ii1l11lliiiIii1II] = ealIlli1i11iIilIil1I1Ii[ealI11I1IiIiIilli1ili][ealllIlil1ll1I1iilIII] end elseif ealIlIilil1IiiIIlliilli >= 5 then if ealIlIilil1IiiIIlliilli ~= 6 then ealI111l1Ill1I1I11iiI[ealIlli1i11iIilIil1I1Ii[ealI11I1IiIiIilli1ili][ealllIlil1ll1I1iilIII]] = eaIi1lll11I1ilIl1i1iI[eaI1ii1l11lliiiIii1II] else local ealIll1liIl1l1ilIi1iilI = eaIi1lll11I1ilIl1i1iI[eai11liI1iilIli1lllll] for eaIIl1iIiI11iiIIIiii1 = eai11liI1iilIli1lllll + 1, eailI1II1l1i11iiiili1 do ealIll1liIl1l1ilIi1iilI = ealIll1liIl1l1ilIi1iilI .. eaIi1lll11I1ilIl1i1iI[eaIIl1iIiI11iiIIIiii1] end eaIi1lll11I1ilIl1i1iI[eaI1ii1l11lliiiIii1II] = ealIll1liIl1l1ilIi1iilI end elseif ealIlIilil1IiiIIlliilli ~= 4 then local eaiilllIIiI1I1lilIIll = ealiI1iilIii1l1I1Illi[ealI11I1IiIiIilli1ili] local eaI1lIilli11IIIl1iiIi = {} if eaiilllIIiI1I1lilIIll[ealIliiiiiiiil1IIiiiliI] > 0 then do local ealIiilIil1Ii11i1ilii = {} eaI1lIilli11IIIl1iiIi = eailI1liiIiiiIii11I1i({}, { __index = function(eail111iiiI1lilIIliII, eaIiIllllliI1IliIIlll) local eaiii1iIl1l11IlliIlIi = ealIiilIil1Ii11i1ilii[eaIiIllllliI1IliIIlll] return eaiii1iIl1l11IlliIlIi[1][eaiii1iIl1l11IlliIlIi[2]] end, __newindex = function(eail111iiiI1lilIIliII, eaIiIllllliI1IliIIlll, eailiII1Ill1IiIlllIiI) local eaiii1iIl1l11IlliIlIi = ealIiilIil1Ii11i1ilii[eaIiIllllliI1IliIIlll] eaiii1iIl1l11IlliIlIi[1][eaiii1iIl1l11IlliIlIi[2]] = eailiII1Ill1IiIlllIiI end }) for eaIIl1iIiI11iiIIIiii1 = 1, eaiilllIIiI1I1lilIIll[ealIliiiiiiiil1IIiiiliI] do local ealllllllilIlllIillii = eaI1ll111l1i1i1ill11l[eaI1ilIi11iilIIII1lil] if ealllllllilIlllIillii[eaIlIllIIiIli1liii11I] == eall1Il11IiIl1l1liI1l then ealIiilIil1Ii11i1ilii[eaIIl1iIiI11iiIIIiii1 - 1] = { eaIi1lll11I1ilIl1i1iI, ealllllllilIlllIillii[eaIiliililIlil1iiI1I1] } elseif ealllllllilIlllIillii[eaIlIllIIiIli1liii11I] == ealIiiIiiiIll1ilIiI1l then ealIiilIil1Ii11i1ilii[eaIIl1iIiI11iiIIIiii1 - 1] = { eal111llIlIll11I1lI1I, ealllllllilIlllIillii[eaIiliililIlil1iiI1I1] } end eaI1ilIi11iilIIII1lil = eaI1ilIi11iilIIII1lil + 1 end eallIiI1iil1liil1iiii[#eallIiI1iil1liil1iiii + 1] = ealIiilIil1Ii11i1ilii end end local eaiii1l1ili1I1I1I1Il1 = eaIIliIIIIll11IlIliiI(eaiilllIIiI1I1lilIIll, ealI111l1Ill1I1I11iiI, eaI1lIilli11IIIl1iiIi) eaIi1lll11I1ilIl1i1iI[eaI1ii1l11lliiiIii1II] = eaiii1l1ili1I1I1I1Il1 elseif eailI1II1l1i11iiiili1 == 29 then eaI1ilIi11iilIIII1lil = eaI1ilIi11iilIIII1lil - 1 eaI1ll111l1i1i1ill11l[eaI1ilIi11iilIIII1lil] = { [43212] = 12, [43892] = (eaI1ii1l11lliiiIii1II - 62) % 256, [92248] = (eai11liI1iilIli1lllll - 62) % 256, [42229] = 0 } else eaIi1lll11I1ilIl1i1iI[eaI1ii1l11lliiiIii1II] = not eaIi1lll11I1ilIl1i1iI[eai11liI1iilIli1lllll] end elseif ealIlIilil1IiiIIlliilli < 10 then if ealIlIilil1IiiIIlliilli < 8 then eaIi1lll11I1ilIl1i1iI[eaI1ii1l11lliiiIii1II] = ealI111l1Ill1I1I11iiI[ealIlli1i11iIilIil1I1Ii[ealI11I1IiIiIilli1ili][ealllIlil1ll1I1iilIII]] elseif ealIlIilil1IiiIIlliilli == 9 then local ealIlIIIIII1IIl1iilll1i, ealIllIlllli1iI11ll1IiI if eai11liI1iilIli1lllll ~= 1 then if eai11liI1iilIli1lllll ~= 0 then ealIllIlllli1iI11ll1IiI = eaI1ii1l11lliiiIii1II + eai11liI1iilIli1lllll - 1 else ealIllIlllli1iI11ll1IiI = ealllili1lIiIIii1llIl end ealIllIlllli1iI11ll1IiI, ealIlIIIIII1IIl1iilll1i = ealIIIIIIl1llIli1lili(eaIi1lll11I1ilIl1i1iI[eaI1ii1l11lliiiIii1II](ealIl11iliI1I1Il1lllliI(eaIi1lll11I1ilIl1i1iI, eaI1ii1l11lliiiIii1II + 1, ealIllIlllli1iI11ll1IiI))) else ealIllIlllli1iI11ll1IiI, ealIlIIIIII1IIl1iilll1i = ealIIIIIIl1llIli1lili(eaIi1lll11I1ilIl1i1iI[eaI1ii1l11lliiiIii1II]()) end eaIi1lll11I1ilIl1i1iI = ealIlIIIIII1IIl1iilll1i return true, 1, ealIllIlllli1iI11ll1IiI else if eai11liI1iilIli1lllll > 255 then eai11liI1iilIli1lllll = ealIlli1i11iIilIil1I1Ii[eai11liI1iilIli1lllll - 256][ealllIlil1ll1I1iilIII] else eai11liI1iilIli1lllll = eaIi1lll11I1ilIl1i1iI[eai11liI1iilIli1lllll] end if eailI1II1l1i11iiiili1 > 255 then eailI1II1l1i11iiiili1 = ealIlli1i11iIilIil1I1Ii[eailI1II1l1i11iiiili1 - 256][ealllIlil1ll1I1iilIII] else eailI1II1l1i11iiiili1 = eaIi1lll11I1ilIl1i1iI[eailI1II1l1i11iiiili1] end eaIi1lll11I1ilIl1i1iI[eaI1ii1l11lliiiIii1II] = eai11liI1iilIli1lllll - eailI1II1l1i11iiiili1 end elseif ealIlIilil1IiiIIlliilli >= 12 then if ealIlIilil1IiiIIlliilli ~= 13 then if eai11liI1iilIli1lllll == 1 then return true end local ealIllIlllli1iI11ll1IiI = eaI1ii1l11lliiiIii1II + eai11liI1iilIli1lllll - 2 if eai11liI1iilIli1lllll == 0 then ealIllIlllli1iI11ll1IiI = ealllili1lIiIIii1llIl end return true, eaI1ii1l11lliiiIii1II, ealIllIlllli1iI11ll1IiI else eaIi1lll11I1ilIl1i1iI[eaI1ii1l11lliiiIii1II] = eai11liI1iilIli1lllll ~= 0 if eailI1II1l1i11iiiili1 ~= 0 then eaI1ilIi11iilIIII1lil = eaI1ilIi11iilIIII1lil + 1 end end elseif ealIlIilil1IiiIIlliilli == 11 then local ealIlIIIIII1IIl1iilll1i, ealIllIlllli1iI11ll1IiI, eaIIiililIlilIll1i11I if eai11liI1iilIli1lllll ~= 1 then if eai11liI1iilIli1lllll ~= 0 then ealIllIlllli1iI11ll1IiI = eaI1ii1l11lliiiIii1II + eai11liI1iilIli1lllll - 1 else ealIllIlllli1iI11ll1IiI = ealllili1lIiIIii1llIl end ealIllIlllli1iI11ll1IiI, ealIlIIIIII1IIl1iilll1i = ealIIIIIIl1llIli1lili(eaIi1lll11I1ilIl1i1iI[eaI1ii1l11lliiiIii1II](ealIl11iliI1I1Il1lllliI(eaIi1lll11I1ilIl1i1iI, eaI1ii1l11lliiiIii1II + 1, ealIllIlllli1iI11ll1IiI))) else ealIllIlllli1iI11ll1IiI, ealIlIIIIII1IIl1iilll1i = ealIIIIIIl1llIli1lili(eaIi1lll11I1ilIl1i1iI[eaI1ii1l11lliiiIii1II]()) end if eailI1II1l1i11iiiili1 ~= 1 then if eailI1II1l1i11iiiili1 ~= 0 then ealIllIlllli1iI11ll1IiI = eaI1ii1l11lliiiIii1II + eailI1II1l1i11iiiili1 - 2 else ealIllIlllli1iI11ll1IiI = ealIllIlllli1iI11ll1IiI + eaI1ii1l11lliiiIii1II end eaIIiililIlilIll1i11I = 0 for eaIIl1iIiI11iiIIIiii1 = eaI1ii1l11lliiiIii1II, ealIllIlllli1iI11ll1IiI do eaIIiililIlilIll1i11I = eaIIiililIlilIll1i11I + 1 eaIi1lll11I1ilIl1i1iI[eaIIl1iIiI11iiIIIiii1] = ealIlIIIIII1IIl1iilll1i[eaIIiililIlilIll1i11I] end end ealllili1lIiIIii1llIl = ealIllIlllli1iI11ll1IiI - 1 else for eaIIl1iIiI11iiIIIiii1 = eaI1ii1l11lliiiIii1II, eai11liI1iilIli1lllll do eaIi1lll11I1ilIl1i1iI[eaIIl1iIiI11iiIIIiii1] = nil end end end end local eail1lli11I1i1iilIIII, ealIlIIiiiIIiil1i1111il, ealIlI1lIi11i1llIili1Ii, eaIi1lIIl1li1iiI11iil = ealIl1Ii1IiiIiI1iI1I11l(eaIIiililIlilIll1i11I) if eail1lli11I1i1iilIIII then if ealIlI1lIi11i1llIili1Ii then return ealIl11iliI1I1Il1lllliI(eaIi1lll11I1ilIl1i1iI, ealIlI1lIi11i1llIili1Ii, eaIi1lIIl1li1iiI11iil) end else local eaIl1l1Illi11iilI1lil = eai1iIlIi1Il1II1lliii("Luraph Script:" .. (eaIllI1iIliiiIiliiIIl[eaI1ilIi11iilIIII1lil - 1] or "") .. ": " .. eaill1iIIi1llIliiIlil(ealIlIIiiiIIiil1i1111il), "[^:]+:%d*: ", function(eaIlIIi11I1lIi1lIilii) if not eal1ii11lliIIIIiii1II(eaIlIIi11I1lIi1lIilii, "Luraph Script:%d") then return "" end end) ealIllli1iliiII1iliI1II(eaIl1l1Illi11iilI1lil, 0) end end eaIlllli111llliIll1li(ealIll11IiiIiIlll11iII1, ealI111l1Ill1I1I11iiI) return ealIll11IiiIiIlll11iII1 end local eaIi1I1ilIllIlil1lIIl = ealIlllli11ll1IliI11I1l() return eaIIliIIIIll11IlIliiI(eaIi1I1ilIllIlil1lIIl, ealI111l1Ill1I1I11iiI)() end eal1ilill111iiIl111I1("LPH!744D6A850A02001E5H00E4944000A89F5B62509B0A02002H4D4F494C2H4D413H4D413H4D593H4D514C2H4D613H4D7DC72F133C00013H0079880A02004F053H005H741E5H00E494404F0A3H005H7404061D1A004F0C3H005H74121500541A1D13007A99006B7DA80A02004C4D4F492H4F4D617277B55D4C4D4F493H4D414C2H4D514F2H4D512H4D4F494C2H4D514E4D494DB8B24C49794C4D65B1B24C498B3FE84C8F7A1C47C19791544225DF405B338B69A3C98C6F96508179496E8A3A024H0020136014E0AD3D45660D7H00013H00019H006H00019H002H00019H006H006B001B4ADE7AB5F1EE46234H00E900", eallIiIiII1IIll1lI1I1())
1+
local unpack = unpack or table.unpack
2
3
os.unloadAPI("backpack")
4
5
local args = {...}
6
7
local opwords = {
8
	install = true,
9
	remove = true,
10
	update = true,
11
	["install-help"] = true,
12
	["remove-help"] = true,
13
	["update-help"] = true,
14
	list = true,
15
	search = true,
16
	bootstrap = true,
17
}
18
19
local argwords = {
20
	fetch = true,
21
	force = true,
22
	auto = true,
23
	--target = 1,
24
}
25
26
if #args < 1 or (not opwords[args[1]] and not argwords[args[1]]) then
27
	io.write("Usage:\n")
28
	io.write("packman [options] install <package name[s]>\n")
29
	io.write("packman [options] update <package name[s]>\n")
30
	io.write("packman [options] remove <package name[s]>\n")
31
	io.write("packman [options] list [pattern]\n")
32
	io.write("packman [options] search [pattern]\n")
33
	io.write("packman bootstrap\n")
34
	io.write("packman [options] install-help <package name[s]>\n")
35
	io.write("packman [options] update-help <package name[s]>\n")
36
	io.write("packman [options] remove-help <package name[s]>\n")
37
	io.write("\n")
38
	io.write("Options:\n")
39
	io.write("fetch\n")
40
	io.write("  Update repository and package lists before performing operations (can be used without an operation)\n")
41
	io.write("force\n")
42
	io.write("  Force requested operation, even if it appears to be unnecessary; answer all questions with yes\n")
43
	io.write("auto\n")
44
	io.write("  Automatically answer yes when manipulating packages\n")
45
	--io.write("target <directory>\n")
46
	--io.write("  Set root directory to install packages in\n")
47
	return
48
end
49
50
local config = {}
51
52
function loadConfig()
53
	local path = "/etc/packman/packman.conf"
54
	--load a configuration file, given a fully-resolved path and an optional environment.
55
	if not fs.exists(path) or fs.isDir(path) then return nil, "not a file" end
56
	local env
57
	if not _env then
58
		--if we were not provided an environment, create one.
59
		env = setmetatable({}, {__index = _G})
60
	else
61
		env = _env
62
	end
63
	local fn, err = loadfile(path)
64
	if fn then
65
		setfenv(fn, env)
66
		local success, err = pcall(fn)
67
		if success then
68
			--strip the metatable from the environment before returning it.
69
			config = setmetatable(env, {})
70
		else
71
			return nil, err
72
		end
73
	else
74
		return nil, err
75
	end
76
end
77
78
function saveConfig()
79
	local path = "/etc/packman/packman.conf"
80
	if not config or type(config) ~= "table" then return nil, "Not a configuration" end
81
	local handle = io.open(path, "w")
82
	if handle then
83
		for k, v in pairs(config) do
84
			local success, str = pcall(textutils.serialize, v)
85
			if success then
86
				handle:write(k.." = "..str.."\n\n")
87
			end
88
		end
89
		handle:close()
90
	else
91
		return nil, "Could not write configuration."
92
	end
93
end
94
95
loadConfig()
96
97
local mode = ""
98
local forced = false
99
local target = "/"
100
local fetch = false
101
local auto = false
102
local argState = nil
103
local argCount = 0
104
local operation = {options = {}, arguments = {}}
105
106
--lower all arguments
107
for i = 1, #args do
108
	args[i] = string.lower(args[i])
109
	if argState == nil and args[i] == "fetch" then fetch = true end
110
	if argState == nil and args[i] == "force" then forced = true end
111
	if argState == nil and args[i] == "auto" then auto = true end
112
113
	if argwords[args[i]] and type(argwords[args[i]]) == "number" then
114
		operation.options[args[i]] = {}
115
		argState = args[i]
116
		argCount = argwords[args[i]]
117
	elseif opwords[args[i]] then
118
		mode = args[i]
119
		if mode == "bootstrap" then fetch = false break end
120
		argState = "arguments"
121
		argCount = 0
122
	elseif argState and argCount > 0 then
123
		--option arguments
124
		table.insert(operation.options[argState], args[i])
125
		argCount = argCount - 1
126
		if argCount == 0 then argState = nil end
127
	elseif argState == "arguments" then
128
		--operation arguments
129
		table.insert(operation.arguments, args[i])
130
	end
131
end
132
133
if operation.options.target then
134
	target = operation.options.target[1]
135
end
136
137
local function resetScreen()
138
	term.setTextColor(colors.white)
139
	term.setBackgroundColor(colors.black)
140
end
141
142
local function printError(errorText)
143
	if term.isColor() then term.setTextColor(colors.red) end
144
	io.write(errorText.."\n")
145
	term.setTextColor(colors.white)
146
	error()
147
end
148
149
local function printWarning(warningText)
150
	if term.isColor() then term.setTextColor(colors.yellow) end
151
	io.write(warningText.."\n")
152
	term.setTextColor(colors.white)
153
end
154
155
local function printInformation(infoText)
156
	if term.isColor() then term.setTextColor(colors.lime) end
157
	io.write(infoText.."\n")
158
	term.setTextColor(colors.white)
159
end
160
161
local function getUserInput(default)
162
	if auto then
163
		return default
164
	else
165
		return io.read()
166
	end
167
end
168
169
local function loadPackageAPI()
170
	if not backpack then if shell.resolveProgram("backpack") then os.loadAPI(shell.resolveProgram("backpack")) elseif fs.exists("usr/apis/backpack") then os.loadAPI("usr/apis/backpack") elseif not (fetch or mode == "bootstrap") then error("Could not load backpack API!") end end
171
172
	if backpack then
173
		resetScreen()
174
		io.write("Loading database...\n")
175
		backpack.installRoot = target
176
177
		local co = coroutine.create(backpack.load)
178
		local event, filter, passback = {}
179
		while true do
180
			if (filter and (filter == event[1] or event[1] == "terminate")) or not filter then
181
				passback = {coroutine.resume(co, unpack(event))}
182
			end
183
			if passback[1] == false then printWarning(passback[2]) end
184
			if coroutine.status(co) == "dead" then break end
185
			filter = nil
186
			if passback and passback[1] and passback[2] then
187
				filter = passback[2]
188
			end
189
			event = {os.pullEventRaw()}
190
			if event[1] == "package_status" then
191
				if event[2] == "info" then
192
					printInformation(event[3])
193
				elseif event[2] == "warning" then
194
					printWarning(event[3])
195
				elseif event[2] == "error" then
196
					printError(event[3])
197
				end
198
			end
199
		end
200
	end
201
end
202
203
loadPackageAPI()
204
205
local categoryList = {}
206
local categorySorted = {}
207
208
if fetch then
209
	local queue
210
	if backpack then
211
		queue = backpack.newTransactionQueue("main/backpack")
212
	end
213
	io.write("Fetching Repository List\n")
214
	local repolistContent = ""
215
	remoteHandle = http.get("https://raw.githubusercontent.com/lyqyd/cc-packman/master/repolist")
216
	if remoteHandle then
217
		repolistContent = remoteHandle.readAll()
218
		if queue then
219
			queue:makeDir("/etc")
220
			queue:addFile("/etc/repolist", repolistContent)
221
		else
222
			local fileHandle = io.open("/etc/repolist", "w")
223
			if fileHandle then
224
				fileHandle:write(repolistContent)
225
				fileHandle:close()
226
			else
227
				printWarning("Could not write file /etc/repolist")
228
			end
229
		end
230
		remoteHandle.close()
231
	else
232
		printWarning("Could not retrieve remote file.")
233
	end
234
235
	if fs.exists("/etc/custom-repolist") then
236
		local fileHandle = io.open("/etc/custom-repolist", "r")
237
		if fileHandle then
238
			repolistContent = repolistContent.."\n"..fileHandle:read("*a")
239
			fileHandle:close()
240
		end
241
	end
242
243
	if repolistContent then
244
		if queue then
245
			queue:makeDir("/etc/repositories")
246
		else
247
			if not fs.exists("/etc/repositories") then fs.makeDir("/etc/repositories") end
248
		end
249
250
		for line in string.gmatch(repolistContent, "([^\n]+)\n?") do
251
			local file, url = string.match(line, "^(%S*)%s*(.*)")
252
			if file and url then
253
				io.write("Fetching Repository: "..file.."\n")
254
				local remoteHandle = http.get(url)
255
				if remoteHandle then
256
					if queue then
257
						queue:addFile(fs.combine("/etc/repositories", file), remoteHandle.readAll())
258
					else
259
						local fileHandle = io.open(fs.combine("/etc/repositories", file), "w")
260
						if fileHandle then
261
							fileHandle:write(remoteHandle.readAll())
262
							fileHandle:close()
263
						else
264
							printWarning("Could not write file: "..fs.combine("/etc/repositories", file))
265
						end
266
					end
267
					remoteHandle.close()
268
				else
269
					printWarning("Could not retrieve remote file: "..file)
270
				end
271
			end
272
		end
273
	end
274
275
	if queue then
276
		queue:finish()
277
	end
278
279
	fetch = false
280
281
	if #mode > 0 then
282
		--reload backpack API.
283
		os.unloadAPI("backpack")
284
		loadPackageAPI()
285
	end
286
end
287
288
if #mode > 0 and backpack then
289
	for n, v in pairs(backpack.list) do
290
		if v.category then
291
			for category in pairs(v.category) do
292
				if not categoryList[category] then
293
					categoryList[category] = {[n] = true}
294
					table.insert(categorySorted, category)
295
				else
296
					categoryList[category][n] = true
297
				end
298
			end
299
		end
300
	end
301
	table.sort(categorySorted)
302
303
	local badPackages = {}
304
	--flesh out dependencies
305
	for pName, pData in pairs(backpack.list) do
306
		if pData.dependencies then
307
			dependencies, errmsg = backpack.findDependencies(pName, {})
308
			if not dependencies then
309
				--if dependencies could not be resolved, remove the backpack.
310
				printWarning("Could not resolve dependency on "..errmsg.." in package "..pName)
311
				table.insert(badPackages, pName)
312
			else
313
				pData.dependencies = dependencies
314
			end
315
		end
316
	end
317
	--actual package removal and short-name lookup cleanup.
318
	for _, pack in pairs(badPackages) do
319
		local entry = backpack.list[pack]
320
		local name = entry.name
321
		local others, key = false
322
		for k, v in pairs(backpack.list[name]) do
323
			if v == entry then
324
				key = k
325
			else
326
				others = true
327
			end
328
		end
329
		if others then
330
			backpack.list[name][key] = nil
331
		else
332
			backpack.list[name] = nil
333
		end
334
		backpack.list[pack] = nil
335
	end
336
end
337
338
local function lookupPackage(name, installedOnly)
339
	if backpack.list[name] and not backpack.list[name].dependencies then
340
		local options = {}
341
		if installedOnly and backpack.installed[name] then
342
			for name, pack in pairs(backpack.installed[name]) do
343
				table.insert(options, name)
344
			end
345
		elseif installedOnly then
346
			--using installedOnly, but no packages of that name are installed.
347
			return false
348
		else
349
			for name, pack in pairs(backpack.list[name]) do
350
				table.insert(options, name)
351
			end
352
		end
353
		if #options > 1 then
354
			io.write("Package "..name.." is ambiguous.\n")
355
			for i = 1, #options do
356
				write(tostring(i)..": "..options[i].."  ")
357
			end
358
			io.write("\n")
359
			io.write("Select option: \n")
360
			local selection = getUserInput("1")
361
			if tonumber(selection) and options[tonumber(selection)] then
362
				return options[tonumber(selection)].."/"..name
363
			end
364
		elseif #options == 1 then
365
			return options[1].."/"..name
366
		else
367
			return false
368
		end
369
	elseif backpack.list[name] then
370
		--since it must have a dependencies table, the name is already fully unique.
371
		return name
372
	else
373
		return false
374
	end
375
end
376
377
local function raw_package_operation(name, funcName)
378
	local pack = backpack.list[name]
379
	if not pack then return nil, "No such package" end
380
	local co = coroutine.create(function() return pack[funcName](pack, getfenv()) end)
381
	local event, filter, passback = {}
382
	while true do
383
		if (filter and (filter == event[1] or event[1] == "terminate")) or not filter then
384
			passback = {coroutine.resume(co, unpack(event))}
385
		end
386
		if passback[1] == false then printWarning(passback[2]) end
387
		if coroutine.status(co) == "dead" then return unpack(passback, 2) end
388
		filter = nil
389
		if passback and passback[1] and passback[2] then
390
			filter = passback[2]
391
		end
392
		event = {os.pullEventRaw()}
393
		if event[1] == "package_status" then
394
			if event[2] == "info" then
395
				printInformation(event[3])
396
			elseif event[2] == "warning" then
397
				printWarning(event[3])
398
			elseif event[2] == "error" then
399
				printError(event[3])
400
			end
401
		end
402
	end
403
end
404
405
local function install(name)
406
	if config.manageHelp then
407
		return raw_package_operation(name, "installFiles") and raw_package_operation(name, "installHelp") and raw_package_operation(name, "finalizeInstall")
408
	else
409
		return raw_package_operation(name, "install")
410
	end
411
end
412
413
local function installHelp(name)
414
	return raw_package_operation(name, "installHelp")
415
end
416
417
local function remove(name)
418
	if config.manageHelp then
419
		return raw_package_operation(name, "removeHelp") and raw_package_operation(name, "remove")
420
	else
421
		return raw_package_operation(name, "remove")
422
	end
423
end
424
425
local function removeHelp(name)
426
	return raw_package_operation(name, "removeHelp")
427
end
428
429
local function upgrade(name)
430
	if config.manageHelp then
431
		return raw_package_operation(name, "upgradeFiles") and raw_package_operation(name, "upgradeHelp") and raw_package_operation(name, "finalizeUpgrade")
432
	else
433
		return raw_package_operation(name, "upgrade")
434
	end
435
end
436
437
local function upgradeHelp(name)
438
	return raw_package_operation(name, "upgradeHelp")
439
end
440
441
if mode == "bootstrap" then
442
	--initial setup, results in main/packman and main/backpack packages being installed
443
	if not backpack or backpack.list["main/packman"] == nil then
444
		--grab the backpack API, since we have no transaction queue yet.
445
		io.write("Updating Backpack API\n")
446
		remoteHandle = http.get("https://raw.githubusercontent.com/lyqyd/cc-packman/master/backpack")
447
		local apiContents = ""
448
		if remoteHandle then
449
			if not fs.exists("/usr/apis") then fs.makeDir("/usr/apis") end
450
			local fileHandle = io.open("/usr/apis/backpack", "w")
451
			if fileHandle then
452
				apiContents = remoteHandle.readAll()
453
				fileHandle:write(apiContents)
454
				fileHandle:close()
455
			else
456
				printWarning("Could not write file /usr/apis/backpack")
457
			end
458
			remoteHandle.close()
459
		else
460
			printWarning("Could not retrieve remote file.")
461
		end
462
463
		io.write("Fetching main package list\n")
464
		remoteHandle = http.get("https://raw.githubusercontent.com/lyqyd/cc-packman/master/packlist")
465
		local packlistContents = ""
466
		if remoteHandle then
467
			if not fs.exists("/etc/repositories") then fs.makeDir("/etc/repositories") end
468
			local fileHandle = io.open("/etc/repositories/main", "w")
469
			if fileHandle then
470
				packlistContents = remoteHandle.readAll()
471
				fileHandle:write(packlistContents)
472
				fileHandle:close()
473
			else
474
				printWarning("Could not write file /etc/repositories/main")
475
			end
476
			remoteHandle.close()
477
		else
478
			printWarning("Could not retrieve remote file.")
479
		end
480
481
		os.unloadAPI("backpack")
482
		loadPackageAPI()
483
		if not backpack then printError("Backpack API required for bootstrap!") end
484
485
		--re-do the file writes for the files above so they end up in the package file list.
486
		local queue = backpack.newTransactionQueue("main/backpack")
487
		queue:makeDir("/usr")
488
		queue:makeDir("/usr/apis")
489
		queue:addFile("/usr/apis/backpack", apiContents)
490
		queue:makeDir("/etc")
491
		queue:makeDir("/etc/repositories")
492
		queue:addFile("/etc/repositories/main", packlistContents)
493
		queue:finish()
494
	end
495
496
	backpack.list["main/packman"]:install(getfenv())
497
498
	--reload backpack API.
499
	os.unloadAPI("backpack")
500
	loadPackageAPI()
501
502
	config.manageHelp = false
503
	saveConfig()
504
elseif mode == "install" then
505
	if #operation.arguments >= 1 then
506
		local installList = {}
507
		for packageNumber, packageName in ipairs(operation.arguments) do
508
			local result = lookupPackage(packageName)
509
			if not result then
510
				printWarning("Could not install package "..packageName..".")
511
			else
512
				for k,v in pairs(backpack.list[result].dependencies) do
513
					if not backpack.installed[k] then
514
						installList[k] = true
515
					else
516
						if k == result then
517
							printInformation("Package "..k.." already installed")
518
						else
519
							printInformation("Dependency "..k.." already installed")
520
						end
521
					end
522
				end
523
			end
524
		end
525
		local installString = ""
526
		for k, v in pairs(installList) do
527
			installString = installString..k.." "
528
		end
529
		if #installString > 0 then
530
			if not forced then
531
				io.write("The following packages will be installed: "..installString.."\n")
532
				io.write("Continue? (Y/n)\n")
533
				local input = getUserInput("y")
534
				if string.sub(input:lower(), 1, 1) == "n" then
535
					return true
536
				end
537
			end
538
			for packageName in pairs(installList) do
539
				if not install(packageName) then
540
					printWarning("Could not "..mode.." package "..packageName)
541
				end
542
			end
543
		end
544
	end
545
elseif mode == "update" then
546
	local updateList = {}
547
	local installList = {}
548
	if #operation.arguments >= 1 then
549
		for _, name in ipairs(operation.arguments) do
550
			local result = lookupPackage(name, true)
551
			if result then
552
				table.insert(updateList, result)
553
			end
554
		end
555
	else
556
		for k, v in pairs(backpack.installed) do
557
			if v.files then
558
				--filters out the disambiguation entries.
559
				table.insert(updateList, k)
560
				for name, info in pairs(backpack.list[k].dependencies) do
561
					if not backpack.installed[name] then
562
						installList[name] = true
563
					end
564
				end
565
			end
566
		end
567
	end
568
	local installString = ""
569
	for k, v in pairs(installList) do
570
		installString = installString..k.." "
571
	end
572
	if not forced then
573
		for i = #updateList, 1, -1 do
574
			if backpack.installed[updateList[i]].version == backpack.list[updateList[i]].version then
575
				table.remove(updateList, i)
576
			end
577
		end
578
	end
579
	if #updateList > 0 or #installString > 0 then
580
		local updateString = ""
581
		for i = 1, #updateList do
582
			updateString = updateString..updateList[i].." "
583
		end
584
		if not forced then
585
			io.write("The following packages will be updated: "..updateString.."\n")
586
			if #installString > 0 then
587
				io.write("The following packages will also be installed: "..installString.."\n")
588
			end
589
			io.write("Continue? (Y/n)\n")
590
			local input = getUserInput("y")
591
			if string.sub(input:lower(), 1, 1) == "n" then
592
				return true
593
			end
594
		end
595
		local failureCount = 0
596
		for packageName in pairs(installList) do
597
			if not install(packageName) then
598
				printWarning("Could not install package "..packageName)
599
			end
600
		end
601
		for _, packageName in pairs(updateList) do
602
			if not upgrade(packageName) then
603
				printWarning("Package "..packageName.." failed to update.")
604
				failureCount = failureCount + 1
605
			end
606
		end
607
		if failureCount > 0 then
608
			printWarning(failureCount.." packages failed to update.")
609
		else
610
			printInformation("Update complete!")
611
		end
612
	else
613
		io.write("Nothing to do!\n")
614
		return true
615
	end
616
elseif mode == "remove" then
617
	if #operation.arguments >= 1 then
618
		local packageList = {}
619
		for _, name in ipairs(operation.arguments) do
620
			local result = lookupPackage(name, true)
621
			if result then
622
				table.insert(packageList, result)
623
			end
624
		end
625
		dependeesList = {}
626
		--find packages which depend on the packages we are removing.
627
		for pName, pData in pairs(backpack.installed) do
628
			if pData.version then
629
				if not packageList[pName] then
630
					for dName in pairs(backpack.list[pName].dependencies) do
631
						for _, packName in pairs(packageList) do
632
							if packName == dName then
633
								dependeesList[pName] = true
634
								break
635
							end
636
						end
637
						if dependeesList[pName] then
638
							break
639
						end
640
					end
641
				end
642
			end
643
		end
644
		local removeString = ""
645
		local dependeesString = ""
646
		for i = 1, #packageList do
647
			removeString = removeString..packageList[i].." "
648
			if dependeesList[packageList[i]] then
649
				dependeesList[packageList[i]] = nil
650
			end
651
		end
652
		for dName in pairs(dependeesList) do
653
			dependeesString = dependeesString..dName.." "
654
		end
655
		if #removeString > 0 then
656
			if not forced then
657
				io.write("The following packages will be removed: "..removeString.."\n")
658
				if #dependeesString > 0 then
659
					io.write("The following packages will also be removed due to missing dependencies: "..dependeesString.."\n")
660
				end
661
				io.write("Continue? (y/N)\n")
662
				local input = getUserInput("y")
663
				if string.sub(input:lower(), 1, 1) ~= "y" then
664
					return true
665
				end
666
			end
667
			for pName in pairs(dependeesList) do
668
				printInformation("Removing "..pName)
669
				remove(pName)
670
			end
671
			for _, pName in pairs(packageList) do
672
				printInformation("Removing "..pName)
673
				remove(pName)
674
			end
675
		else
676
			io.write("Nothing to do!\n")
677
		end
678
	end
679
elseif mode == "install-help" then
680
	if #operation.arguments >= 1 then
681
		local installString = ""
682
		for packageNumber, packageName in ipairs(operation.arguments) do
683
			local result = lookupPackage(packageName)
684
			if not result then
685
				printWarning("Could not find package "..packageName..".")
686
			else
687
				installString = installString..result.." "
688
			end
689
		end
690
		if #installString > 0 then
691
			if not forced then
692
				io.write("The following packages' help files will be installed: "..installString.."\n")
693
				io.write("Continue? (Y/n)\n")
694
				local input = getUserInput("y")
695
				if string.sub(input:lower(), 1, 1) == "n" then
696
					return true
697
				end
698
			end
699
			for packageName in string.gmatch(installString, "%S+") do
700
				if not installHelp(packageName) then
701
					printWarning("Could not install help files for package "..packageName)
702
				end
703
			end
704
		end
705
	end
706
elseif mode == "upgrade-help" then
707
	if #operation.arguments >= 1 then
708
		local upgradeString = ""
709
		for packageNumber, packageName in ipairs(operation.arguments) do
710
			local result = lookupPackage(packageName)
711
			if not result then
712
				printWarning("Could not find package "..packageName..".")
713
			else
714
				upgradeString = upgradeString..result.." "
715
			end
716
		end
717
		if #upgradeString > 0 then
718
			if not forced then
719
				io.write("The following packages' help files will be installed: "..upgradeString.."\n")
720
				io.write("Continue? (Y/n)\n")
721
				local input = getUserInput("y")
722
				if string.sub(input:lower(), 1, 1) == "n" then
723
					return true
724
				end
725
			end
726
			for packageName in string.gmatch(upgradeString, "%S+") do
727
				if not installHelp(packageName) then
728
					printWarning("Could not install help files for package "..packageName)
729
				end
730
			end
731
		end
732
	end
733
elseif mode == "remove-help" then
734
	if #operation.arguments >= 1 then
735
		local removeString = ""
736
		for _, name in ipairs(operation.arguments) do
737
			local result = lookupPackage(name, true)
738
			if not result then
739
				printWarning("Could not find package "..name)
740
			else
741
				removeString = removeString..result.." "
742
			end
743
		end
744
		if #removeString > 0 then
745
			if not forced then
746
				io.write("The following packages' help files will be removed: "..removeString.."\n")
747
				io.write("Continue? (y/N)\n")
748
				local input = getUserInput("y")
749
				if string.sub(input:lower(), 1, 1) ~= "y" then
750
					return true
751
				end
752
			end
753
			for packageName in string.gmatch(removeString, "%S+") do
754
				printInformation("Removing help files for package "..packageName)
755
				removeHelp(packageName)
756
			end
757
		else
758
			io.write("Nothing to do!\n")
759
		end
760
	end
761
elseif mode == "list" then
762
	--list all installed packages
763
	local match = ".*"
764
	if #operation.arguments == 1 then
765
		--list with matching.
766
		match = operation.arguments[1]
767
	end
768
	for name, info in pairs(backpack.installed) do
769
		if info.version then
770
			if string.match(name, match) then
771
				io.write(name.." "..info.version.."\n")
772
			end
773
		end
774
	end
775
elseif mode == "search" then
776
	--search all available packages
777
	local match = ".*"
778
	if #operation.arguments == 1 then
779
		--search using a match
780
		match = operation.arguments[1]
781
	end
782
	for name, info in pairs(backpack.list) do
783
		if info.version then
784
			if string.match(name, match) then
785
				io.write((backpack.installed[name] and "I " or "A " )..name.." "..info.version.."\n")
786
			end
787
		end
788
	end
789
end