zahar0401

Orbital

Sep 7th, 2019
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 346.02 KB | None | 0 0
  1. {
  2.   "D:bin",
  3.   "{\
  4.  \"F:bg\",\
  5.  \"\\\"\\\\\\\
  6. if not shell.launchProcess then\\\\\\\
  7.    printError( \\\\\\\"Requires multishell\\\\\\\" )\\\\\\\
  8.    return\\\\\\\
  9. end\\\\\\\
  10. \\\\\\\
  11. local tArgs = { ... }\\\\\\\
  12. if #tArgs > 0 then\\\\\\\
  13.    shell.launchProcess( table.unpack( tArgs ) )\\\\\\\
  14. else\\\\\\\
  15.    shell.launchProcess( \\\\\\\"shell\\\\\\\" )\\\\\\\
  16. end\\\"\",\
  17.  \"F:cat\",\
  18.  \"\\\"local tArgs = {...}\\\\\\\
  19. \\\\\\\
  20. if #tArgs >= 1 then\\\\\\\
  21. path = shell.resolve(tArgs[1])\\\\\\\
  22. if fs.isReadOnly(path) then\\\\\\\
  23.  --return\\\\\\\
  24. end\\\\\\\
  25. if not fs.exists(path) or fs.isDir(path) then\\\\\\\
  26.  print(\\\\\\\"File does not exist\\\\\\\")\\\\\\\
  27. else\\\\\\\
  28.  textutils.pagedPrint(kreadfile(path))\\\\\\\
  29. end\\\\\\\
  30. else\\\\\\\
  31. print(\\\\\\\"Filename not specified\\\\\\\")\\\\\\\
  32. end\\\\\\\
  33. \\\"\",\
  34.  \"F:df\",\
  35.  \"\\\"local sz = fs.getSize(shell.dir())\\\\\\\
  36. local fspc = fs.getFreeSpace(shell.dir())\\\\\\\
  37. print(\\\\\\\"Type: \\\\\\\"..fs.getDrive(shell.dir()))\\\\\\\
  38. print(\\\\\\\"Size: \\\\\\\", tostring(sz)..\\\\\\\" B\\\\\\\")\\\\\\\
  39. print(\\\\\\\"Free space: \\\\\\\", tostring(fspc)..\\\\\\\" B\\\\\\\")\\\"\",\
  40.  \"F:dism\",\
  41.  \"\\\"local tArgs = {...}\\\\\\\
  42. \\\\\\\
  43. local FFormat = \\\\\\\".odi\\\\\\\"\\\\\\\
  44. local nFile, nDir, size = 0, 0\\\\\\\
  45. \\\\\\\
  46. local function getPath(input)\\\\\\\
  47. if string.sub(input, 1, 1)==\\\\\\\"/\\\\\\\" then\\\\\\\
  48.  path = input\\\\\\\
  49. else\\\\\\\
  50.  path=(\\\\\\\"/\\\\\\\" .. shell.dir() .. \\\\\\\"/\\\\\\\" .. input)\\\\\\\
  51. end\\\\\\\
  52. return path\\\\\\\
  53. end\\\\\\\
  54. \\\\\\\
  55. local function fopen(path, mode)\\\\\\\
  56.  local f = fs.open(path, mode)\\\\\\\
  57.  if not f then \\\\\\\
  58.    stderr(\\\\\\\"ERROR: Could not open \\\\\\\"..path..\\\\\\\" with mode \\\\\\\\\\\\\\\"\\\\\\\"..mode..\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\")\\\\\\\
  59.    exit()\\\\\\\
  60.  end\\\\\\\
  61.  return f\\\\\\\
  62. end\\\\\\\
  63. \\\\\\\
  64. local function skip(df)\\\\\\\
  65.  local skip = {\\\\\\\"rom\\\\\\\", \\\\\\\"treasure\\\\\\\", \\\\\\\"tmp\\\\\\\"}\\\\\\\
  66.  for _,v in ipairs(skip) do\\\\\\\
  67.    if fs.getName(df) == v then\\\\\\\
  68. \\\\009  return true\\\\\\\
  69. \\\\009end\\\\\\\
  70.  end\\\\\\\
  71.  return false\\\\\\\
  72. end\\\\\\\
  73. \\\\\\\
  74. local function zip(file)\\\\\\\
  75.  print(\\\\\\\"[DISM] Capturing from FS: \\\\\\\".. file)\\\\\\\
  76.  local f = fopen(file, \\\\\\\"r\\\\\\\")\\\\\\\
  77.  local z = textutils.serialize(f.readAll())\\\\\\\
  78.  f.close()\\\\\\\
  79.  return z\\\\\\\
  80. end\\\\\\\
  81. \\\\\\\
  82. local function capture(path)\\\\\\\
  83.  local list = fs.list(path)\\\\\\\
  84.  local array = {}\\\\\\\
  85.  local t, name, d = 0, \\\\\\\"\\\\\\\", 0\\\\\\\
  86.  \\\\\\\
  87.  for i = 2, #list * 2, 2 do\\\\\\\
  88.    t = i/2\\\\\\\
  89.    local tpath = path..\\\\\\\"/\\\\\\\"..list[t]\\\\\\\
  90.    if fs.isDir(tpath) then\\\\\\\
  91.      if not skip(tpath) then\\\\\\\
  92.        name = \\\\\\\"D:\\\\\\\"..list[t]\\\\\\\
  93.        array[i] = capture(tpath)\\\\\\\
  94.        nDir = nDir + 1\\\\\\\
  95.      end\\\\\\\
  96.    else\\\\\\\
  97.      name = \\\\\\\"F:\\\\\\\"..list[t]\\\\\\\
  98.      array[i] = zip(tpath)\\\\\\\
  99.      nFile = nFile + 1\\\\\\\
  100.    end\\\\\\\
  101.    array[i - 1] = name\\\\\\\
  102.  end\\\\\\\
  103.  \\\\\\\
  104.  return textutils.serialize(array)\\\\\\\
  105. end\\\\\\\
  106. \\\\\\\
  107. local function unzip(text, path)\\\\\\\
  108.  print(\\\\\\\"[DISM] Applying to FS: \\\\\\\"..path)\\\\\\\
  109.  local f = fopen(path, \\\\\\\"w\\\\\\\")\\\\\\\
  110.  f.write(textutils.unserialize(text))\\\\\\\
  111.  f.close()\\\\\\\
  112. end\\\\\\\
  113. \\\\\\\
  114. local function apply(text, path)\\\\\\\
  115.  local array = textutils.unserialize(text)\\\\\\\
  116.  local unz, dp\\\\\\\
  117.  local d = 0\\\\\\\
  118.  for i = 2, #array, 2 do\\\\\\\
  119.    if string.sub(array[i-1], 1, 1) == \\\\\\\"D\\\\\\\" then\\\\\\\
  120.      dp = string.sub(array[i-1], 3, #array[i-1])\\\\\\\
  121.      fs.makeDir(path..\\\\\\\"/\\\\\\\"..dp)\\\\\\\
  122.      apply(array[i], path..\\\\\\\"/\\\\\\\"..dp)\\\\\\\
  123.      nDir = nDir + 1\\\\\\\
  124.    elseif string.sub(array[i-1], 1, 1) == \\\\\\\"F\\\\\\\" then\\\\\\\
  125.      local p = string.sub(array[i-1], 3, #array[i-1])\\\\\\\
  126.      unzip(array[i], path..\\\\\\\"/\\\\\\\"..p)\\\\\\\
  127.      nFile = nFile + 1\\\\\\\
  128.    end\\\\\\\
  129.  end\\\\\\\
  130. end\\\\\\\
  131. \\\\\\\
  132. local function result()\\\\\\\
  133.  print(\\\\\\\"Operation completed.\\\\\\\"\\\\\\\
  134.    ..\\\\\\\"\\\\\\\\n   size: \\\\\\\"\\\\\\\
  135.    ..tostring(size).. \\\\\\\" B   \\\\\\\"\\\\\\\
  136.    ..tostring(math.floor(size/1024)).. \\\\\\\" KB\\\\\\\"\\\\\\\
  137.    ..\\\\\\\"\\\\\\\\n   Files:   \\\\\\\".. tostring(nFile)\\\\\\\
  138.    ..\\\\\\\"\\\\\\\\n   Folders: \\\\\\\".. tostring(nDir)\\\\\\\
  139.  )\\\\\\\
  140. end\\\\\\\
  141. \\\\\\\
  142. local outStr = \\\\\\\"Deployment Image Servicing and Management \\\\\\\\n\\\\\\\\n\\\\\\\"\\\\\\\
  143. \\\\\\\
  144. if tArgs[2] then\\\\\\\
  145. tArgs[2]=getPath(tArgs[2])\\\\\\\
  146. end\\\\\\\
  147. \\\\\\\
  148. if #tArgs < 3 then \\\\\\\
  149.  outStr = outStr..[[\\\\\\\
  150. Usage:\\\\\\\
  151. dism capture <source directory> <output image>\\\\\\\
  152.     OR\\\\\\\
  153.     apply <source image> <target directory>\\\\\\\
  154.     \\\\\\\
  155.     Original code by 1Ridav.\\\\\\\
  156.     Modified for Orbital by minebuild02.\\\\\\\
  157. ]]\\\\\\\
  158. end\\\\\\\
  159. \\\\\\\
  160. print(outStr)\\\\\\\
  161. \\\\\\\
  162. if tArgs[1] == \\\\\\\"capture\\\\\\\" then\\\\\\\
  163.  if fs.exists(tArgs[2]) and fs.isDir(tArgs[2]) then\\\\\\\
  164.    local zipped = capture(shell.resolve(tArgs[2]))\\\\\\\
  165.    local f = fs.open(tArgs[3]..FFormat, \\\\\\\"w\\\\\\\")\\\\\\\
  166.    f.write(zipped)\\\\\\\
  167.    f.close()\\\\\\\
  168.    zipped = nil\\\\\\\
  169.    size = fs.getSize(tArgs[3]..FFormat)\\\\\\\
  170.    result()   \\\\\\\
  171.  end\\\\\\\
  172.  \\\\\\\
  173. elseif tArgs[1] == \\\\\\\"apply\\\\\\\" then\\\\\\\
  174.    local f = fopen(tArgs[2], \\\\\\\"r\\\\\\\")\\\\\\\
  175.    if not fs.exists(tArgs[3]) then \\\\\\\
  176.      fs.makeDir(tArgs[3]) \\\\\\\
  177.    end\\\\\\\
  178.    apply(f.readAll(), tArgs[3])\\\\\\\
  179.    size = fs.getSize(tArgs[2])\\\\\\\
  180.    result()\\\\\\\
  181. end\\\"\",\
  182.  \"F:fg\",\
  183.  \"\\\"\\\\\\\
  184. if not shell.launchProcess then\\\\\\\
  185.    printError( \\\\\\\"Requires multishell\\\\\\\" )\\\\\\\
  186.    return\\\\\\\
  187. end\\\\\\\
  188. \\\\\\\
  189. local tArgs = { ... }\\\\\\\
  190. if #tArgs > 0 then\\\\\\\
  191.    local nTask = shell.launchProcess( table.unpack( tArgs ) )\\\\\\\
  192.    if nTask then\\\\\\\
  193.        shell.setProcessFocus( nTask )\\\\\\\
  194.    end\\\\\\\
  195. else\\\\\\\
  196.    local nTask = shell.launchProcess( \\\\\\\"shell\\\\\\\" )\\\\\\\
  197.    if nTask then\\\\\\\
  198.        shell.setProcessFocus( nTask )\\\\\\\
  199.    end\\\\\\\
  200. end\\\"\",\
  201.  \"F:lc\",\
  202.  \"\\\"-- Lua compiler for the Orbital SDK\\\\\\\
  203. -- Takes the input file and converts it to Lua bytecode\\\\\\\
  204. \\\\\\\
  205. local oex_template = \\\\\\\"!LC!\\\\\\\\\\\\\\\\|/%s\\\\\\\\\\\\\\\\|/%s\\\\\\\"\\\\\\\
  206. \\\\\\\
  207. local function compileString(s)\\\\\\\
  208. local func, err = loadstring(s)\\\\\\\
  209. if func ~= nil then\\\\\\\
  210.  return string.dump(func)\\\\\\\
  211. else\\\\\\\
  212.  return nil\\\\\\\
  213. end\\\\\\\
  214. end\\\\\\\
  215. \\\\\\\
  216. local function compileFile(p)\\\\\\\
  217. local func, err = loadstring(kreadfile(p))\\\\\\\
  218. if func ~= nil then\\\\\\\
  219.  local h = fs.open(p..\\\\\\\".bin\\\\\\\", fs.AF_WRITE)\\\\\\\
  220.  h.write(string.dump(func))\\\\\\\
  221.  h.close()\\\\\\\
  222.  return true\\\\\\\
  223. else\\\\\\\
  224.  return false\\\\\\\
  225. end\\\\\\\
  226. end\\\\\\\
  227. \\\\\\\
  228. local tArgs = {...}\\\\\\\
  229. \\\\\\\
  230. if #tArgs >= 1 then\\\\\\\
  231. path = shell.resolve(tArgs[1])\\\\\\\
  232. if not fs.exists(path) or fs.isDir(path) then\\\\\\\
  233.  UI.outputInfo(\\\\\\\"lc\\\\\\\", \\\\\\\"file does not exist\\\\\\\")\\\\\\\
  234. else\\\\\\\
  235.  UI.outputInfo(\\\\\\\"lc\\\\\\\", \\\\\\\"compiling to bytecode\\\\\\\")\\\\\\\
  236.  compileFile(path)\\\\\\\
  237. end\\\\\\\
  238. else\\\\\\\
  239. UI.outputInfo(\\\\\\\"lc\\\\\\\", \\\\\\\"lc <input file> [format]\\\\\\\")\\\\\\\
  240. end\\\\\\\
  241. \\\"\",\
  242.  \"F:msh\",\
  243.  \"\\\"\\\\\\\
  244. local process = process\\\\\\\
  245. local parentShell = shell\\\\\\\
  246. local parentTerm = term.current()\\\\\\\
  247. \\\\\\\
  248. if process then\\\\\\\
  249.    process.setTitle( process.getCurrent(), \\\\\\\"shell\\\\\\\" )\\\\\\\
  250. end\\\\\\\
  251. \\\\\\\
  252. local bExit = false\\\\\\\
  253. local sDir = (parentShell and parentShell.dir()) or \\\\\\\"\\\\\\\"\\\\\\\
  254. local sPath = (parentShell and parentShell.path()) or \\\\\\\".:/rom/programs\\\\\\\"\\\\\\\
  255. local tAliases = (parentShell and parentShell.aliases()) or {}\\\\\\\
  256. local tCompletionInfo = (parentShell and parentShell.getCompletionInfo()) or {}\\\\\\\
  257. local tProgramStack = {}\\\\\\\
  258. \\\\\\\
  259. local shell = {}\\\\\\\
  260. local function createShellEnv( sDir )\\\\\\\
  261.    local tEnv = {}\\\\\\\
  262.    tEnv[ \\\\\\\"shell\\\\\\\" ] = shell\\\\\\\
  263.    tEnv[ \\\\\\\"process\\\\\\\" ] = process\\\\\\\
  264. \\\\\\\
  265.    local package = {}\\\\\\\
  266.    package.loaded = {\\\\\\\
  267.        _G = _G,\\\\\\\
  268.        bit32 = bit32,\\\\\\\
  269.        coroutine = coroutine,\\\\\\\
  270.        math = math,\\\\\\\
  271.        package = package,\\\\\\\
  272.        string = string,\\\\\\\
  273.        table = table,\\\\\\\
  274.    }\\\\\\\
  275.    package.path = \\\\\\\"?;?.lua;?/init.lua;/rom/modules/main/?;/rom/modules/main/?.lua;/rom/modules/main/?/init.lua\\\\\\\"\\\\\\\
  276.    if turtle then\\\\\\\
  277.        package.path = package.path..\\\\\\\";/rom/modules/turtle/?;/rom/modules/turtle/?.lua;/rom/modules/turtle/?/init.lua\\\\\\\"\\\\\\\
  278.    elseif command then\\\\\\\
  279.        package.path = package.path..\\\\\\\";/rom/modules/command/?;/rom/modules/command/?.lua;/rom/modules/command/?/init.lua\\\\\\\"\\\\\\\
  280.    end\\\\\\\
  281.    package.config = \\\\\\\"/\\\\\\\\n;\\\\\\\\n?\\\\\\\\n!\\\\\\\\n-\\\\\\\"\\\\\\\
  282.    package.preload = {}\\\\\\\
  283.    package.loaders = {\\\\\\\
  284.        function( name )\\\\\\\
  285.            if package.preload[name] then\\\\\\\
  286.                return package.preload[name]\\\\\\\
  287.            else\\\\\\\
  288.                return nil, \\\\\\\"no field package.preload['\\\\\\\" .. name .. \\\\\\\"']\\\\\\\"\\\\\\\
  289.            end\\\\\\\
  290.        end,\\\\\\\
  291.        function( name )\\\\\\\
  292.            local fname = string.gsub(name, \\\\\\\"%.\\\\\\\", \\\\\\\"/\\\\\\\")\\\\\\\
  293.            local sError = \\\\\\\"\\\\\\\"\\\\\\\
  294.            for pattern in string.gmatch(package.path, \\\\\\\"[^;]+\\\\\\\") do\\\\\\\
  295.                local sPath = string.gsub(pattern, \\\\\\\"%?\\\\\\\", fname)\\\\\\\
  296.                if sPath:sub(1,1) ~= \\\\\\\"/\\\\\\\" then\\\\\\\
  297.                    sPath = fs.combine(sDir, sPath)\\\\\\\
  298.                end\\\\\\\
  299.                if fs.exists(sPath) and not fs.isDir(sPath) then\\\\\\\
  300.                    local fnFile, sError = loadfile( sPath, tEnv )\\\\\\\
  301.                    if fnFile then\\\\\\\
  302.                        return fnFile, sPath\\\\\\\
  303.                    else\\\\\\\
  304.                        return nil, sError\\\\\\\
  305.                    end\\\\\\\
  306.                else\\\\\\\
  307.                    if #sError > 0 then\\\\\\\
  308.                        sError = sError .. \\\\\\\"\\\\\\\\n\\\\\\\"\\\\\\\
  309.                    end\\\\\\\
  310.                    sError = sError .. \\\\\\\"no file '\\\\\\\" .. sPath .. \\\\\\\"'\\\\\\\"\\\\\\\
  311.                end\\\\\\\
  312.            end\\\\\\\
  313.            return nil, sError\\\\\\\
  314.        end\\\\\\\
  315.    }\\\\\\\
  316. \\\\\\\
  317.    local sentinel = {}\\\\\\\
  318.    local function require( name )\\\\\\\
  319.        if type( name ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
  320.            error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( name ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  321.        end\\\\\\\
  322.        if package.loaded[name] == sentinel then\\\\\\\
  323.            error(\\\\\\\"Loop detected requiring '\\\\\\\" .. name .. \\\\\\\"'\\\\\\\", 0)\\\\\\\
  324.        end\\\\\\\
  325.        if package.loaded[name] then\\\\\\\
  326.            return package.loaded[name]\\\\\\\
  327.        end\\\\\\\
  328. \\\\\\\
  329.        local sError = \\\\\\\"Error loading module '\\\\\\\" .. name .. \\\\\\\"':\\\\\\\"\\\\\\\
  330.        for n,searcher in ipairs(package.loaders) do\\\\\\\
  331.            local loader, err = searcher(name)\\\\\\\
  332.            if loader then\\\\\\\
  333.                package.loaded[name] = sentinel\\\\\\\
  334.                local result = loader( err )\\\\\\\
  335.                if result ~= nil then\\\\\\\
  336.                    package.loaded[name] = result\\\\\\\
  337.                    return result\\\\\\\
  338.                else\\\\\\\
  339.                    package.loaded[name] = true\\\\\\\
  340.                    return true\\\\\\\
  341.                end\\\\\\\
  342.            else\\\\\\\
  343.                sError = sError .. \\\\\\\"\\\\\\\\n\\\\\\\" .. err\\\\\\\
  344.            end\\\\\\\
  345.        end\\\\\\\
  346.        error(sError, 2)\\\\\\\
  347.    end\\\\\\\
  348. \\\\\\\
  349.    tEnv[\\\\\\\"package\\\\\\\"] = package\\\\\\\
  350.    tEnv[\\\\\\\"require\\\\\\\"] = require\\\\\\\
  351. \\\\\\\
  352.    return tEnv\\\\\\\
  353. end\\\\\\\
  354. \\\\\\\
  355. -- Colours\\\\\\\
  356. local promptColour, textColour, bgColour\\\\\\\
  357. if term.isColour() then\\\\\\\
  358.    promptColour = colours.yellow\\\\\\\
  359.    textColour = colours.white\\\\\\\
  360.    bgColour = colours.black\\\\\\\
  361. else\\\\\\\
  362.    promptColour = colours.white\\\\\\\
  363.    textColour = colours.white\\\\\\\
  364.    bgColour = colours.black\\\\\\\
  365. end\\\\\\\
  366. \\\\\\\
  367. local function run( _sCommand, ... )\\\\\\\
  368.    local sPath = shell.resolveProgram( _sCommand )\\\\\\\
  369.    if sPath ~= nil then\\\\\\\
  370.        tProgramStack[#tProgramStack + 1] = sPath\\\\\\\
  371.        if process then\\\\\\\
  372.            local sTitle = fs.getName( sPath )\\\\\\\
  373.            if sTitle:sub(-4) == \\\\\\\".lua\\\\\\\" then\\\\\\\
  374.                sTitle = sTitle:sub(1,-5)\\\\\\\
  375.            end\\\\\\\
  376.            process.setTitle( process.getCurrent(), sTitle )\\\\\\\
  377.        end\\\\\\\
  378.        local sDir = fs.getDir( sPath )\\\\\\\
  379.        local result = os.run( createShellEnv( sDir ), sPath, ... )\\\\\\\
  380.        tProgramStack[#tProgramStack] = nil\\\\\\\
  381.        if process then\\\\\\\
  382.            if #tProgramStack > 0 then\\\\\\\
  383.                local sTitle = fs.getName( tProgramStack[#tProgramStack] )\\\\\\\
  384.                if sTitle:sub(-4) == \\\\\\\".lua\\\\\\\" then\\\\\\\
  385.                    sTitle = sTitle:sub(1,-5)\\\\\\\
  386.                end\\\\\\\
  387.                process.setTitle( process.getCurrent(), sTitle )\\\\\\\
  388.            else\\\\\\\
  389.                process.setTitle( process.getCurrent(), \\\\\\\"shell\\\\\\\" )\\\\\\\
  390.            end\\\\\\\
  391.        end\\\\\\\
  392.        return result\\\\\\\
  393.       else\\\\\\\
  394.        printError( \\\\\\\"No such program\\\\\\\" )\\\\\\\
  395.        return false\\\\\\\
  396.    end\\\\\\\
  397. end\\\\\\\
  398. \\\\\\\
  399. local function tokenise( ... )\\\\\\\
  400.    local sLine = table.concat( { ... }, \\\\\\\" \\\\\\\" )\\\\\\\
  401.    local tWords = {}\\\\\\\
  402.    local bQuoted = false\\\\\\\
  403.    for match in string.gmatch( sLine .. \\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\", \\\\\\\"(.-)\\\\\\\\\\\\\\\"\\\\\\\" ) do\\\\\\\
  404.        if bQuoted then\\\\\\\
  405.            table.insert( tWords, match )\\\\\\\
  406.        else\\\\\\\
  407.            for m in string.gmatch( match, \\\\\\\"[^ \\\\\\\\t]+\\\\\\\" ) do\\\\\\\
  408.                table.insert( tWords, m )\\\\\\\
  409.            end\\\\\\\
  410.        end\\\\\\\
  411.        bQuoted = not bQuoted\\\\\\\
  412.    end\\\\\\\
  413.    return tWords\\\\\\\
  414. end\\\\\\\
  415. \\\\\\\
  416. -- Install shell API\\\\\\\
  417. function shell.run( ... )\\\\\\\
  418.    local tWords = tokenise( ... )\\\\\\\
  419.    local sCommand = tWords[1]\\\\\\\
  420.    if sCommand then\\\\\\\
  421.        return run( sCommand, table.unpack( tWords, 2 ) )\\\\\\\
  422.    end\\\\\\\
  423.    return false\\\\\\\
  424. end\\\\\\\
  425. \\\\\\\
  426. function shell.exit()\\\\\\\
  427.    bExit = true\\\\\\\
  428. end\\\\\\\
  429. \\\\\\\
  430. function shell.dir()\\\\\\\
  431.    return sDir\\\\\\\
  432. end\\\\\\\
  433. \\\\\\\
  434. function shell.setDir( _sDir )\\\\\\\
  435.    if type( _sDir ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
  436.        error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( _sDir ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  437.    end\\\\\\\
  438.    if not fs.isDir( _sDir ) then\\\\\\\
  439.        error( \\\\\\\"Not a directory\\\\\\\", 2 )\\\\\\\
  440.    end\\\\\\\
  441.    sDir = _sDir\\\\\\\
  442. end\\\\\\\
  443. \\\\\\\
  444. function shell.path()\\\\\\\
  445.    return sPath\\\\\\\
  446. end\\\\\\\
  447. \\\\\\\
  448. function shell.setPath( _sPath )\\\\\\\
  449.    if type( _sPath ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
  450.        error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( _sPath ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  451.    end\\\\\\\
  452.    sPath = _sPath\\\\\\\
  453. end\\\\\\\
  454. \\\\\\\
  455. function shell.resolve( _sPath )\\\\\\\
  456.    if type( _sPath ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
  457.        error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( _sPath ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  458.    end\\\\\\\
  459.    local sStartChar = string.sub( _sPath, 1, 1 )\\\\\\\
  460.    if sStartChar == \\\\\\\"/\\\\\\\" or sStartChar == \\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\
  461.        return fs.combine( \\\\\\\"\\\\\\\", _sPath )\\\\\\\
  462.    else\\\\\\\
  463.        return fs.combine( sDir, _sPath )\\\\\\\
  464.    end\\\\\\\
  465. end\\\\\\\
  466. \\\\\\\
  467. local function pathWithExtension( _sPath, _sExt )\\\\\\\
  468.    local nLen = #sPath\\\\\\\
  469.    local sEndChar = string.sub( _sPath, nLen, nLen )\\\\\\\
  470.    -- Remove any trailing slashes so we can add an extension to the path safely\\\\\\\
  471.    if sEndChar == \\\\\\\"/\\\\\\\" or sEndChar == \\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\
  472.        _sPath = string.sub( _sPath, 1, nLen - 1 )\\\\\\\
  473.    end\\\\\\\
  474.    return _sPath .. \\\\\\\".\\\\\\\" .. _sExt\\\\\\\
  475. end\\\\\\\
  476. \\\\\\\
  477. function shell.resolveProgram( _sCommand )\\\\\\\
  478.    if type( _sCommand ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
  479.        error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( _sCommand ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  480.    end\\\\\\\
  481.    -- Substitute aliases firsts\\\\\\\
  482.    if tAliases[ _sCommand ] ~= nil then\\\\\\\
  483.        _sCommand = tAliases[ _sCommand ]\\\\\\\
  484.    end\\\\\\\
  485. \\\\\\\
  486.    -- If the path is a global path, use it directly\\\\\\\
  487.    local sStartChar = string.sub( _sCommand, 1, 1 )\\\\\\\
  488.    if sStartChar == \\\\\\\"/\\\\\\\" or sStartChar == \\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\
  489.        local sPath = fs.combine( \\\\\\\"\\\\\\\", _sCommand )\\\\\\\
  490.        if fs.exists( sPath ) and not fs.isDir( sPath ) then\\\\\\\
  491.            return sPath\\\\\\\
  492.        else\\\\\\\
  493.            local sPathLua = pathWithExtension( sPath, \\\\\\\"lua\\\\\\\" )\\\\\\\
  494.            if fs.exists( sPathLua ) and not fs.isDir( sPathLua ) then\\\\\\\
  495.                return sPathLua\\\\\\\
  496.            end\\\\\\\
  497.        end\\\\\\\
  498.        return nil\\\\\\\
  499.    end\\\\\\\
  500.    \\\\\\\
  501.     -- Otherwise, look on the path variable\\\\\\\
  502.    for sPath in string.gmatch(sPath, \\\\\\\"[^:]+\\\\\\\") do\\\\\\\
  503.        sPath = fs.combine( shell.resolve( sPath ), _sCommand )\\\\\\\
  504.        if fs.exists( sPath ) and not fs.isDir( sPath ) then\\\\\\\
  505.            return sPath\\\\\\\
  506.        else\\\\\\\
  507.            local sPathLua = pathWithExtension( sPath, \\\\\\\"lua\\\\\\\" )\\\\\\\
  508.            if fs.exists( sPathLua ) and not fs.isDir( sPathLua ) then\\\\\\\
  509.                return sPathLua\\\\\\\
  510.            end\\\\\\\
  511.        end\\\\\\\
  512.    end\\\\\\\
  513.    \\\\\\\
  514.    -- Not found\\\\\\\
  515.    return nil\\\\\\\
  516. end\\\\\\\
  517. \\\\\\\
  518. function shell.programs( _bIncludeHidden )\\\\\\\
  519.    local tItems = {}\\\\\\\
  520.    \\\\\\\
  521.    -- Add programs from the path\\\\\\\
  522.    for sPath in string.gmatch(sPath, \\\\\\\"[^:]+\\\\\\\") do\\\\\\\
  523.        sPath = shell.resolve( sPath )\\\\\\\
  524.        if fs.isDir( sPath ) then\\\\\\\
  525.            local tList = fs.list( sPath )\\\\\\\
  526.            for n=1,#tList do\\\\\\\
  527.                local sFile = tList[n]\\\\\\\
  528.                if not fs.isDir( fs.combine( sPath, sFile ) ) and\\\\\\\
  529.                   (_bIncludeHidden or string.sub( sFile, 1, 1 ) ~= \\\\\\\".\\\\\\\") then\\\\\\\
  530.                    if #sFile > 4 and sFile:sub(-4) == \\\\\\\".lua\\\\\\\" then\\\\\\\
  531.                        sFile = sFile:sub(1,-5)\\\\\\\
  532.                    end\\\\\\\
  533.                    tItems[ sFile ] = true\\\\\\\
  534.                end\\\\\\\
  535.            end\\\\\\\
  536.        end\\\\\\\
  537.    end    \\\\\\\
  538. \\\\\\\
  539.    -- Sort and return\\\\\\\
  540.    local tItemList = {}\\\\\\\
  541.    for sItem, b in pairs( tItems ) do\\\\\\\
  542.        table.insert( tItemList, sItem )\\\\\\\
  543.    end\\\\\\\
  544.    table.sort( tItemList )\\\\\\\
  545.    return tItemList\\\\\\\
  546. end\\\\\\\
  547. \\\\\\\
  548. local function completeProgram( sLine )\\\\\\\
  549.    if #sLine > 0 and string.sub( sLine, 1, 1 ) == \\\\\\\"/\\\\\\\" then\\\\\\\
  550.        -- Add programs from the root\\\\\\\
  551.        return fs.complete( sLine, \\\\\\\"\\\\\\\", true, false )\\\\\\\
  552. \\\\\\\
  553.    else\\\\\\\
  554.        local tResults = {}\\\\\\\
  555.        local tSeen = {}\\\\\\\
  556. \\\\\\\
  557.        -- Add aliases\\\\\\\
  558.        for sAlias, sCommand in pairs( tAliases ) do\\\\\\\
  559.            if #sAlias > #sLine and string.sub( sAlias, 1, #sLine ) == sLine then\\\\\\\
  560.                local sResult = string.sub( sAlias, #sLine + 1 )\\\\\\\
  561.                if not tSeen[ sResult ] then\\\\\\\
  562.                    table.insert( tResults, sResult )\\\\\\\
  563.                    tSeen[ sResult ] = true\\\\\\\
  564.                end\\\\\\\
  565.            end\\\\\\\
  566.        end\\\\\\\
  567. \\\\\\\
  568.        -- Add programs from the path\\\\\\\
  569.        local tPrograms = shell.programs()\\\\\\\
  570.        for n=1,#tPrograms do\\\\\\\
  571.            local sProgram = tPrograms[n]\\\\\\\
  572.            if #sProgram > #sLine and string.sub( sProgram, 1, #sLine ) == sLine then\\\\\\\
  573.                local sResult = string.sub( sProgram, #sLine + 1 )\\\\\\\
  574.                if not tSeen[ sResult ] then\\\\\\\
  575.                    table.insert( tResults, sResult )\\\\\\\
  576.                    tSeen[ sResult ] = true\\\\\\\
  577.                end\\\\\\\
  578.            end\\\\\\\
  579.        end\\\\\\\
  580. \\\\\\\
  581.        -- Sort and return\\\\\\\
  582.        table.sort( tResults )\\\\\\\
  583.        return tResults\\\\\\\
  584.    end\\\\\\\
  585. end\\\\\\\
  586. \\\\\\\
  587. local function completeProgramArgument( sProgram, nArgument, sPart, tPreviousParts )\\\\\\\
  588.    local tInfo = tCompletionInfo[ sProgram ]\\\\\\\
  589.    if tInfo then\\\\\\\
  590.        return tInfo.fnComplete( shell, nArgument, sPart, tPreviousParts )\\\\\\\
  591.    end\\\\\\\
  592.    return nil\\\\\\\
  593. end\\\\\\\
  594. \\\\\\\
  595. function shell.complete( sLine )\\\\\\\
  596.    if type( sLine ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
  597.        error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( sLine ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  598.    end\\\\\\\
  599.    if #sLine > 0 then\\\\\\\
  600.        local tWords = tokenise( sLine )\\\\\\\
  601.        local nIndex = #tWords\\\\\\\
  602.        if string.sub( sLine, #sLine, #sLine ) == \\\\\\\" \\\\\\\" then\\\\\\\
  603.            nIndex = nIndex + 1\\\\\\\
  604.        end\\\\\\\
  605.        if nIndex == 1 then\\\\\\\
  606.            local sBit = tWords[1] or \\\\\\\"\\\\\\\"\\\\\\\
  607.            local sPath = shell.resolveProgram( sBit )\\\\\\\
  608.            if tCompletionInfo[ sPath ] then\\\\\\\
  609.                return { \\\\\\\" \\\\\\\" }\\\\\\\
  610.            else\\\\\\\
  611.                local tResults = completeProgram( sBit )\\\\\\\
  612.                for n=1,#tResults do\\\\\\\
  613.                    local sResult = tResults[n]\\\\\\\
  614.                    local sPath = shell.resolveProgram( sBit .. sResult )\\\\\\\
  615.                    if tCompletionInfo[ sPath ] then\\\\\\\
  616.                        tResults[n] = sResult .. \\\\\\\" \\\\\\\"\\\\\\\
  617.                    end\\\\\\\
  618.                end\\\\\\\
  619.                return tResults\\\\\\\
  620.            end\\\\\\\
  621. \\\\\\\
  622.        elseif nIndex > 1 then\\\\\\\
  623.            local sPath = shell.resolveProgram( tWords[1] )\\\\\\\
  624.            local sPart = tWords[nIndex] or \\\\\\\"\\\\\\\"\\\\\\\
  625.            local tPreviousParts = tWords\\\\\\\
  626.            tPreviousParts[nIndex] = nil\\\\\\\
  627.            return completeProgramArgument( sPath , nIndex - 1, sPart, tPreviousParts )\\\\\\\
  628. \\\\\\\
  629.        end\\\\\\\
  630.    end\\\\\\\
  631.    return nil\\\\\\\
  632. end\\\\\\\
  633. \\\\\\\
  634. function shell.completeProgram( sProgram )\\\\\\\
  635.    if type( sProgram ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
  636.        error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( sProgram ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  637.    end\\\\\\\
  638.    return completeProgram( sProgram )\\\\\\\
  639. end\\\\\\\
  640. \\\\\\\
  641. function shell.setCompletionFunction( sProgram, fnComplete )\\\\\\\
  642.    if type( sProgram ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
  643.        error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( sProgram ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  644.    end\\\\\\\
  645.    if type( fnComplete ) ~= \\\\\\\"function\\\\\\\" then\\\\\\\
  646.        error( \\\\\\\"bad argument #2 (expected function, got \\\\\\\" .. type( fnComplete ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  647.    end\\\\\\\
  648.    tCompletionInfo[ sProgram ] = {\\\\\\\
  649.        fnComplete = fnComplete\\\\\\\
  650.    }\\\\\\\
  651. end\\\\\\\
  652. \\\\\\\
  653. function shell.getCompletionInfo()\\\\\\\
  654.    return tCompletionInfo\\\\\\\
  655. end\\\\\\\
  656. \\\\\\\
  657. function shell.getRunningProgram()\\\\\\\
  658.    if #tProgramStack > 0 then\\\\\\\
  659.        return tProgramStack[#tProgramStack]\\\\\\\
  660.    end\\\\\\\
  661.    return nil\\\\\\\
  662. end\\\\\\\
  663. \\\\\\\
  664. function shell.setAlias( _sCommand, _sProgram )\\\\\\\
  665.    if type( _sCommand ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
  666.        error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( _sCommand ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  667.    end\\\\\\\
  668.    if type( _sProgram ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
  669.        error( \\\\\\\"bad argument #2 (expected string, got \\\\\\\" .. type( _sProgram ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  670.    end\\\\\\\
  671.    tAliases[ _sCommand ] = _sProgram\\\\\\\
  672. end\\\\\\\
  673. \\\\\\\
  674. function shell.clearAlias( _sCommand )\\\\\\\
  675.    if type( _sCommand ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
  676.        error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( _sCommand ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  677.    end\\\\\\\
  678.    tAliases[ _sCommand ] = nil\\\\\\\
  679. end\\\\\\\
  680. \\\\\\\
  681. function shell.aliases()\\\\\\\
  682.    -- Copy aliases\\\\\\\
  683.    local tCopy = {}\\\\\\\
  684.    for sAlias, sCommand in pairs( tAliases ) do\\\\\\\
  685.        tCopy[sAlias] = sCommand\\\\\\\
  686.    end\\\\\\\
  687.    return tCopy\\\\\\\
  688. end\\\\\\\
  689. \\\\\\\
  690. if process then\\\\\\\
  691.    function shell.launchProcess( ... )\\\\\\\
  692.        local tWords = tokenise( ... )\\\\\\\
  693.        local sCommand = tWords[1]\\\\\\\
  694.        if sCommand then\\\\\\\
  695.            local sPath = shell.resolveProgram( sCommand )\\\\\\\
  696.            if sPath == \\\\\\\"system/bin/sh\\\\\\\" then\\\\\\\
  697.                return process.launch( createShellEnv( \\\\\\\"rom/programs\\\\\\\" ), sPath, table.unpack( tWords, 2 ) )\\\\\\\
  698.            elseif sPath ~= nil then\\\\\\\
  699.                return process.launch( createShellEnv( \\\\\\\"rom/programs\\\\\\\" ), \\\\\\\"rom/programs/shell.lua\\\\\\\", sCommand, table.unpack( tWords, 2 ) )\\\\\\\
  700.            else\\\\\\\
  701.                printError( \\\\\\\"No such program\\\\\\\" )\\\\\\\
  702.            end\\\\\\\
  703.        end\\\\\\\
  704.    end\\\\\\\
  705. \\\\\\\
  706.    function shell.setProcessFocus( nID )\\\\\\\
  707.        if type( nID ) ~= \\\\\\\"number\\\\\\\" then\\\\\\\
  708.            error( \\\\\\\"bad argument #1 (expected number, got \\\\\\\" .. type( nID ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  709.        end\\\\\\\
  710.        process.setFocus( nID )\\\\\\\
  711.    end\\\\\\\
  712. end\\\\\\\
  713. \\\\\\\
  714. local tArgs = { ... }\\\\\\\
  715. if #tArgs > 0 then\\\\\\\
  716.    -- \\\\\\\"shell x y z\\\\\\\"\\\\\\\
  717.    -- Run the program specified on the commandline\\\\\\\
  718.    shell.run( ... )\\\\\\\
  719. \\\\\\\
  720. else\\\\\\\
  721.    -- \\\\\\\"shell\\\\\\\"\\\\\\\
  722.    -- Print the header\\\\\\\
  723.    term.setBackgroundColor( bgColour )\\\\\\\
  724.    term.setTextColour( promptColour )\\\\\\\
  725.    print( os.version() )\\\\\\\
  726.    term.setTextColour( textColour )\\\\\\\
  727. \\\\\\\
  728.    -- Run the startup program\\\\\\\
  729.    if parentShell == nil then\\\\\\\
  730.        shell.run( \\\\\\\"/rom/startup.lua\\\\\\\" )\\\\\\\
  731.    end\\\\\\\
  732.    sPath = sPath..\\\\\\\":/bin\\\\\\\"\\\\\\\
  733. \\\\\\\
  734.    -- Read commands and execute them\\\\\\\
  735.    local tCommandHistory = {}\\\\\\\
  736.    while not bExit do\\\\\\\
  737.        term.redirect( parentTerm )\\\\\\\
  738.        term.setBackgroundColor( bgColour )\\\\\\\
  739.        term.setTextColour( promptColour )\\\\\\\
  740.        write( shell.dir() .. \\\\\\\"> \\\\\\\" )\\\\\\\
  741.        term.setTextColour( textColour )\\\\\\\
  742. \\\\\\\
  743. \\\\\\\
  744.        local sLine\\\\\\\
  745.        if settings.get( \\\\\\\"shell.autocomplete\\\\\\\" ) then\\\\\\\
  746.            sLine = read( nil, tCommandHistory, shell.complete )\\\\\\\
  747.        else\\\\\\\
  748.            sLine = read( nil, tCommandHistory )\\\\\\\
  749.        end\\\\\\\
  750.        if sLine:match(\\\\\\\"%S\\\\\\\") and tCommandHistory[#tCommandHistory] ~= sLine then\\\\\\\
  751.            table.insert( tCommandHistory, sLine )\\\\\\\
  752.        end\\\\\\\
  753.        shell.run( sLine )\\\\\\\
  754.    end\\\\\\\
  755. end\\\"\",\
  756.  \"F:sh\",\
  757.  \"\\\"\\\\\\\
  758. local multishell = multishell\\\\\\\
  759. local parentShell = shell\\\\\\\
  760. local parentTerm = term.current()\\\\\\\
  761. \\\\\\\
  762. if multishell then\\\\\\\
  763.    multishell.setTitle( multishell.getCurrent(), \\\\\\\"shell\\\\\\\" )\\\\\\\
  764. end\\\\\\\
  765. \\\\\\\
  766. local bExit = false\\\\\\\
  767. local sDir = (parentShell and parentShell.dir()) or \\\\\\\"\\\\\\\"\\\\\\\
  768. local sPath = (parentShell and parentShell.path()) or \\\\\\\".:/rom/programs\\\\\\\"\\\\\\\
  769. local tAliases = (parentShell and parentShell.aliases()) or {}\\\\\\\
  770. local tCompletionInfo = (parentShell and parentShell.getCompletionInfo()) or {}\\\\\\\
  771. local tProgramStack = {}\\\\\\\
  772. \\\\\\\
  773. local shell = {}\\\\\\\
  774. local function createShellEnv( sDir )\\\\\\\
  775.    local tEnv = {}\\\\\\\
  776.    tEnv[ \\\\\\\"shell\\\\\\\" ] = shell\\\\\\\
  777.    tEnv[ \\\\\\\"multishell\\\\\\\" ] = multishell\\\\\\\
  778. \\\\\\\
  779.    local package = {}\\\\\\\
  780.    package.loaded = {\\\\\\\
  781.        _G = _G,\\\\\\\
  782.        bit32 = bit32,\\\\\\\
  783.        coroutine = coroutine,\\\\\\\
  784.        math = math,\\\\\\\
  785.        package = package,\\\\\\\
  786.        string = string,\\\\\\\
  787.        table = table,\\\\\\\
  788.    }\\\\\\\
  789. \\\\009package.standard_libraries = {}\\\\\\\
  790. \\\\009package.standard_libraries.stdlib = \\\\\\\"/lib/libstdlua.2.so\\\\\\\"\\\\\\\
  791. \\\\009package.standard_libraries.UI = \\\\\\\"/lib/libuser.2.so\\\\\\\"\\\\\\\
  792. \\\\009package.standard_libraries.debug = \\\\\\\"/lib/libdebug.1.so\\\\\\\"\\\\\\\
  793. \\\\009package.standard_libraries.cryptlib = \\\\\\\"/lib/libcrypt.1.so\\\\\\\"\\\\\\\
  794. \\\\009package.standard_libraries.dism = \\\\\\\"/lib/libdism.1.so\\\\\\\"\\\\\\\
  795.    package.path = \\\\\\\"?;?.lua;?/init.lua;/rom/modules/main/?;/rom/modules/main/?.lua;/rom/modules/main/?/init.lua\\\\\\\"\\\\\\\
  796.    if turtle then\\\\\\\
  797.        package.path = package.path..\\\\\\\";/rom/modules/turtle/?;/rom/modules/turtle/?.lua;/rom/modules/turtle/?/init.lua\\\\\\\"\\\\\\\
  798.    elseif command then\\\\\\\
  799.        package.path = package.path..\\\\\\\";/rom/modules/command/?;/rom/modules/command/?.lua;/rom/modules/command/?/init.lua\\\\\\\"\\\\\\\
  800.    end\\\\\\\
  801.    package.config = \\\\\\\"/\\\\\\\\n;\\\\\\\\n?\\\\\\\\n!\\\\\\\\n-\\\\\\\"\\\\\\\
  802.    package.preload = {}\\\\\\\
  803.    package.loaders = {\\\\\\\
  804.        function( name )\\\\\\\
  805.            if package.preload[name] then\\\\\\\
  806.                return package.preload[name]\\\\\\\
  807.            else\\\\\\\
  808.                return nil, \\\\\\\"no field package.preload['\\\\\\\" .. name .. \\\\\\\"']\\\\\\\"\\\\\\\
  809.            end\\\\\\\
  810.        end,\\\\\\\
  811.        function( name )\\\\\\\
  812.            local fname = string.gsub(name, \\\\\\\"%.\\\\\\\", \\\\\\\"/\\\\\\\")\\\\\\\
  813.            local sError = \\\\\\\"\\\\\\\"\\\\\\\
  814.            for pattern in string.gmatch(package.path, \\\\\\\"[^;]+\\\\\\\") do\\\\\\\
  815.                local sPath = string.gsub(pattern, \\\\\\\"%?\\\\\\\", fname)\\\\\\\
  816.                if sPath:sub(1,1) ~= \\\\\\\"/\\\\\\\" then\\\\\\\
  817.                    sPath = fs.combine(sDir, sPath)\\\\\\\
  818.                end\\\\\\\
  819.                if fs.exists(sPath) and not fs.isDir(sPath) then\\\\\\\
  820.                    local fnFile, sError = loadfile( sPath, tEnv )\\\\\\\
  821.                    if fnFile then\\\\\\\
  822.                        return fnFile, sPath\\\\\\\
  823.                    else\\\\\\\
  824.                        return nil, sError\\\\\\\
  825.                    end\\\\\\\
  826.                else\\\\\\\
  827.                    if #sError > 0 then\\\\\\\
  828.                        sError = sError .. \\\\\\\"\\\\\\\\n\\\\\\\"\\\\\\\
  829.                    end\\\\\\\
  830.                    sError = sError .. \\\\\\\"no file '\\\\\\\" .. sPath .. \\\\\\\"'\\\\\\\"\\\\\\\
  831.                end\\\\\\\
  832.            end\\\\\\\
  833.            return nil, sError\\\\\\\
  834.        end\\\\\\\
  835.    }\\\\\\\
  836. \\\\\\\
  837.    local sentinel = {}\\\\\\\
  838.    local function require( name )\\\\\\\
  839.        if type( name ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
  840.            error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( name ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  841.        end\\\\\\\
  842.        if package.loaded[name] == sentinel then\\\\\\\
  843.            error(\\\\\\\"Loop detected requiring '\\\\\\\" .. name .. \\\\\\\"'\\\\\\\", 0)\\\\\\\
  844.        end\\\\\\\
  845.        if package.loaded[name] then\\\\\\\
  846.            return package.loaded[name]\\\\\\\
  847.        end\\\\\\\
  848. \\\\\\\
  849.        local sError = \\\\\\\"Error loading module '\\\\\\\" .. name .. \\\\\\\"':\\\\\\\"\\\\\\\
  850.        for n,searcher in ipairs(package.loaders) do\\\\\\\
  851.            local loader, err = searcher(name)\\\\\\\
  852.            if loader then\\\\\\\
  853.                package.loaded[name] = sentinel\\\\\\\
  854.                local result = loader( err )\\\\\\\
  855.                if result ~= nil then\\\\\\\
  856.                    package.loaded[name] = result\\\\\\\
  857.                    return result\\\\\\\
  858.                else\\\\\\\
  859.                    package.loaded[name] = true\\\\\\\
  860.                    return true\\\\\\\
  861.                end\\\\\\\
  862.            else\\\\\\\
  863.                sError = sError .. \\\\\\\"\\\\\\\\n\\\\\\\" .. err\\\\\\\
  864.            end\\\\\\\
  865.        end\\\\\\\
  866.        error(sError, 2)\\\\\\\
  867.    end\\\\\\\
  868. \\\\\\\
  869.    tEnv[\\\\\\\"package\\\\\\\"] = package\\\\\\\
  870.    tEnv[\\\\\\\"require\\\\\\\"] = require\\\\\\\
  871. \\\\\\\
  872.    return tEnv\\\\\\\
  873. end\\\\\\\
  874. \\\\\\\
  875. -- Colours\\\\\\\
  876. local promptColour, textColour, bgColour\\\\\\\
  877. if term.isColour() then\\\\\\\
  878.    promptColour = colours.yellow\\\\\\\
  879.    textColour = colours.white\\\\\\\
  880.    bgColour = colours.black\\\\\\\
  881. else\\\\\\\
  882.    promptColour = colours.white\\\\\\\
  883.    textColour = colours.white\\\\\\\
  884.    bgColour = colours.black\\\\\\\
  885. end\\\\\\\
  886. \\\\\\\
  887. local function run( _sCommand, ... )\\\\\\\
  888.    local sPath = shell.resolveProgram( _sCommand )\\\\\\\
  889.    if sPath ~= nil then\\\\\\\
  890.        tProgramStack[#tProgramStack + 1] = sPath\\\\\\\
  891.        if multishell then\\\\\\\
  892.            local sTitle = fs.getName( sPath )\\\\\\\
  893.            if sTitle:sub(-4) == \\\\\\\".lua\\\\\\\" then\\\\\\\
  894.                sTitle = sTitle:sub(1,-5)\\\\\\\
  895.            end\\\\\\\
  896.            multishell.setTitle( multishell.getCurrent(), sTitle )\\\\\\\
  897.        end\\\\\\\
  898.        local sDir = fs.getDir( sPath )\\\\\\\
  899.        local result = os.run( createShellEnv( sDir ), sPath, ... )\\\\\\\
  900.        tProgramStack[#tProgramStack] = nil\\\\\\\
  901.        if multishell then\\\\\\\
  902.            if #tProgramStack > 0 then\\\\\\\
  903.                local sTitle = fs.getName( tProgramStack[#tProgramStack] )\\\\\\\
  904.                if sTitle:sub(-4) == \\\\\\\".lua\\\\\\\" then\\\\\\\
  905.                    sTitle = sTitle:sub(1,-5)\\\\\\\
  906.                end\\\\\\\
  907.                multishell.setTitle( multishell.getCurrent(), sTitle )\\\\\\\
  908.            else\\\\\\\
  909.                multishell.setTitle( multishell.getCurrent(), \\\\\\\"shell\\\\\\\" )\\\\\\\
  910.            end\\\\\\\
  911.        end\\\\\\\
  912.        return result\\\\\\\
  913.       else\\\\\\\
  914.        printError( \\\\\\\"No such program\\\\\\\" )\\\\\\\
  915.        return false\\\\\\\
  916.    end\\\\\\\
  917. end\\\\\\\
  918. \\\\\\\
  919. local function tokenise( ... )\\\\\\\
  920.    local sLine = table.concat( { ... }, \\\\\\\" \\\\\\\" )\\\\\\\
  921.    local tWords = {}\\\\\\\
  922.    local bQuoted = false\\\\\\\
  923.    for match in string.gmatch( sLine .. \\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\", \\\\\\\"(.-)\\\\\\\\\\\\\\\"\\\\\\\" ) do\\\\\\\
  924.        if bQuoted then\\\\\\\
  925.            table.insert( tWords, match )\\\\\\\
  926.        else\\\\\\\
  927.            for m in string.gmatch( match, \\\\\\\"[^ \\\\\\\\t]+\\\\\\\" ) do\\\\\\\
  928.                table.insert( tWords, m )\\\\\\\
  929.            end\\\\\\\
  930.        end\\\\\\\
  931.        bQuoted = not bQuoted\\\\\\\
  932.    end\\\\\\\
  933.    return tWords\\\\\\\
  934. end\\\\\\\
  935. \\\\\\\
  936. -- Install shell API\\\\\\\
  937. function shell.run( ... )\\\\\\\
  938.    local tWords = tokenise( ... )\\\\\\\
  939.    local sCommand = tWords[1]\\\\\\\
  940.    if sCommand then\\\\\\\
  941.        return run( sCommand, table.unpack( tWords, 2 ) )\\\\\\\
  942.    end\\\\\\\
  943.    return false\\\\\\\
  944. end\\\\\\\
  945. \\\\\\\
  946. function shell.exit()\\\\\\\
  947.    bExit = true\\\\\\\
  948. end\\\\\\\
  949. \\\\\\\
  950. function shell.dir()\\\\\\\
  951.    return sDir\\\\\\\
  952. end\\\\\\\
  953. \\\\\\\
  954. function shell.setDir( _sDir )\\\\\\\
  955.    if type( _sDir ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
  956.        error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( _sDir ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  957.    end\\\\\\\
  958.    if not fs.isDir( _sDir ) then\\\\\\\
  959.        error( \\\\\\\"Not a directory\\\\\\\", 2 )\\\\\\\
  960.    end\\\\\\\
  961.    sDir = _sDir\\\\\\\
  962. end\\\\\\\
  963. \\\\\\\
  964. function shell.path()\\\\\\\
  965.    return sPath\\\\\\\
  966. end\\\\\\\
  967. \\\\\\\
  968. function shell.setPath( _sPath )\\\\\\\
  969.    if type( _sPath ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
  970.        error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( _sPath ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  971.    end\\\\\\\
  972.    sPath = _sPath\\\\\\\
  973. end\\\\\\\
  974. \\\\\\\
  975. function shell.resolve( _sPath )\\\\\\\
  976.    if type( _sPath ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
  977.        error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( _sPath ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  978.    end\\\\\\\
  979.    local sStartChar = string.sub( _sPath, 1, 1 )\\\\\\\
  980.    if sStartChar == \\\\\\\"/\\\\\\\" or sStartChar == \\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\
  981.        return fs.combine( \\\\\\\"\\\\\\\", _sPath )\\\\\\\
  982.    else\\\\\\\
  983.        return fs.combine( sDir, _sPath )\\\\\\\
  984.    end\\\\\\\
  985. end\\\\\\\
  986. \\\\\\\
  987. local function pathWithExtension( _sPath, _sExt )\\\\\\\
  988.    local nLen = #sPath\\\\\\\
  989.    local sEndChar = string.sub( _sPath, nLen, nLen )\\\\\\\
  990.    -- Remove any trailing slashes so we can add an extension to the path safely\\\\\\\
  991.    if sEndChar == \\\\\\\"/\\\\\\\" or sEndChar == \\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\
  992.        _sPath = string.sub( _sPath, 1, nLen - 1 )\\\\\\\
  993.    end\\\\\\\
  994.    return _sPath .. \\\\\\\".\\\\\\\" .. _sExt\\\\\\\
  995. end\\\\\\\
  996. \\\\\\\
  997. function shell.resolveProgram( _sCommand )\\\\\\\
  998.    if type( _sCommand ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
  999.        error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( _sCommand ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  1000.    end\\\\\\\
  1001.    -- Substitute aliases firsts\\\\\\\
  1002.    if tAliases[ _sCommand ] ~= nil then\\\\\\\
  1003.        _sCommand = tAliases[ _sCommand ]\\\\\\\
  1004.    end\\\\\\\
  1005. \\\\\\\
  1006.    -- If the path is a global path, use it directly\\\\\\\
  1007.    local sStartChar = string.sub( _sCommand, 1, 1 )\\\\\\\
  1008.    if sStartChar == \\\\\\\"/\\\\\\\" or sStartChar == \\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\
  1009.        local sPath = fs.combine( \\\\\\\"\\\\\\\", _sCommand )\\\\\\\
  1010.        if fs.exists( sPath ) and not fs.isDir( sPath ) then\\\\\\\
  1011.            return sPath\\\\\\\
  1012.        else\\\\\\\
  1013.            local sPathLua = pathWithExtension( sPath, \\\\\\\"lua\\\\\\\" )\\\\\\\
  1014.            if fs.exists( sPathLua ) and not fs.isDir( sPathLua ) then\\\\\\\
  1015.                return sPathLua\\\\\\\
  1016.            end\\\\\\\
  1017.        end\\\\\\\
  1018.        return nil\\\\\\\
  1019.    end\\\\\\\
  1020.    \\\\\\\
  1021.     -- Otherwise, look on the path variable\\\\\\\
  1022.    for sPath in string.gmatch(sPath, \\\\\\\"[^:]+\\\\\\\") do\\\\\\\
  1023.        sPath = fs.combine( shell.resolve( sPath ), _sCommand )\\\\\\\
  1024.        if fs.exists( sPath ) and not fs.isDir( sPath ) then\\\\\\\
  1025.            return sPath\\\\\\\
  1026.        else\\\\\\\
  1027.            local sPathLua = pathWithExtension( sPath, \\\\\\\"lua\\\\\\\" )\\\\\\\
  1028.            if fs.exists( sPathLua ) and not fs.isDir( sPathLua ) then\\\\\\\
  1029.                return sPathLua\\\\\\\
  1030.            end\\\\\\\
  1031.        end\\\\\\\
  1032.    end\\\\\\\
  1033.    \\\\\\\
  1034.    -- Not found\\\\\\\
  1035.    return nil\\\\\\\
  1036. end\\\\\\\
  1037. \\\\\\\
  1038. function shell.programs( _bIncludeHidden )\\\\\\\
  1039.    local tItems = {}\\\\\\\
  1040.    \\\\\\\
  1041.    -- Add programs from the path\\\\\\\
  1042.    for sPath in string.gmatch(sPath, \\\\\\\"[^:]+\\\\\\\") do\\\\\\\
  1043.        sPath = shell.resolve( sPath )\\\\\\\
  1044.        if fs.isDir( sPath ) then\\\\\\\
  1045.            local tList = fs.list( sPath )\\\\\\\
  1046.            for n=1,#tList do\\\\\\\
  1047.                local sFile = tList[n]\\\\\\\
  1048.                if not fs.isDir( fs.combine( sPath, sFile ) ) and\\\\\\\
  1049.                   (_bIncludeHidden or string.sub( sFile, 1, 1 ) ~= \\\\\\\".\\\\\\\") then\\\\\\\
  1050.                    if #sFile > 4 and sFile:sub(-4) == \\\\\\\".lua\\\\\\\" then\\\\\\\
  1051.                        sFile = sFile:sub(1,-5)\\\\\\\
  1052.                    end\\\\\\\
  1053.                    tItems[ sFile ] = true\\\\\\\
  1054.                end\\\\\\\
  1055.            end\\\\\\\
  1056.        end\\\\\\\
  1057.    end    \\\\\\\
  1058. \\\\\\\
  1059.    -- Sort and return\\\\\\\
  1060.    local tItemList = {}\\\\\\\
  1061.    for sItem, b in pairs( tItems ) do\\\\\\\
  1062.        table.insert( tItemList, sItem )\\\\\\\
  1063.    end\\\\\\\
  1064.    table.sort( tItemList )\\\\\\\
  1065.    return tItemList\\\\\\\
  1066. end\\\\\\\
  1067. \\\\\\\
  1068. local function completeProgram( sLine )\\\\\\\
  1069.    if #sLine > 0 and string.sub( sLine, 1, 1 ) == \\\\\\\"/\\\\\\\" then\\\\\\\
  1070.        -- Add programs from the root\\\\\\\
  1071.        return fs.complete( sLine, \\\\\\\"\\\\\\\", true, false )\\\\\\\
  1072. \\\\\\\
  1073.    else\\\\\\\
  1074.        local tResults = {}\\\\\\\
  1075.        local tSeen = {}\\\\\\\
  1076. \\\\\\\
  1077.        -- Add aliases\\\\\\\
  1078.        for sAlias, sCommand in pairs( tAliases ) do\\\\\\\
  1079.            if #sAlias > #sLine and string.sub( sAlias, 1, #sLine ) == sLine then\\\\\\\
  1080.                local sResult = string.sub( sAlias, #sLine + 1 )\\\\\\\
  1081.                if not tSeen[ sResult ] then\\\\\\\
  1082.                    table.insert( tResults, sResult )\\\\\\\
  1083.                    tSeen[ sResult ] = true\\\\\\\
  1084.                end\\\\\\\
  1085.            end\\\\\\\
  1086.        end\\\\\\\
  1087. \\\\\\\
  1088.        -- Add programs from the path\\\\\\\
  1089.        local tPrograms = shell.programs()\\\\\\\
  1090.        for n=1,#tPrograms do\\\\\\\
  1091.            local sProgram = tPrograms[n]\\\\\\\
  1092.            if #sProgram > #sLine and string.sub( sProgram, 1, #sLine ) == sLine then\\\\\\\
  1093.                local sResult = string.sub( sProgram, #sLine + 1 )\\\\\\\
  1094.                if not tSeen[ sResult ] then\\\\\\\
  1095.                    table.insert( tResults, sResult )\\\\\\\
  1096.                    tSeen[ sResult ] = true\\\\\\\
  1097.                end\\\\\\\
  1098.            end\\\\\\\
  1099.        end\\\\\\\
  1100. \\\\\\\
  1101.        -- Sort and return\\\\\\\
  1102.        table.sort( tResults )\\\\\\\
  1103.        return tResults\\\\\\\
  1104.    end\\\\\\\
  1105. end\\\\\\\
  1106. \\\\\\\
  1107. local function completeProgramArgument( sProgram, nArgument, sPart, tPreviousParts )\\\\\\\
  1108.    local tInfo = tCompletionInfo[ sProgram ]\\\\\\\
  1109.    if tInfo then\\\\\\\
  1110.        return tInfo.fnComplete( shell, nArgument, sPart, tPreviousParts )\\\\\\\
  1111.    end\\\\\\\
  1112.    return nil\\\\\\\
  1113. end\\\\\\\
  1114. \\\\\\\
  1115. function shell.complete( sLine )\\\\\\\
  1116.    if type( sLine ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
  1117.        error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( sLine ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  1118.    end\\\\\\\
  1119.    if #sLine > 0 then\\\\\\\
  1120.        local tWords = tokenise( sLine )\\\\\\\
  1121.        local nIndex = #tWords\\\\\\\
  1122.        if string.sub( sLine, #sLine, #sLine ) == \\\\\\\" \\\\\\\" then\\\\\\\
  1123.            nIndex = nIndex + 1\\\\\\\
  1124.        end\\\\\\\
  1125.        if nIndex == 1 then\\\\\\\
  1126.            local sBit = tWords[1] or \\\\\\\"\\\\\\\"\\\\\\\
  1127.            local sPath = shell.resolveProgram( sBit )\\\\\\\
  1128.            if tCompletionInfo[ sPath ] then\\\\\\\
  1129.                return { \\\\\\\" \\\\\\\" }\\\\\\\
  1130.            else\\\\\\\
  1131.                local tResults = completeProgram( sBit )\\\\\\\
  1132.                for n=1,#tResults do\\\\\\\
  1133.                    local sResult = tResults[n]\\\\\\\
  1134.                    local sPath = shell.resolveProgram( sBit .. sResult )\\\\\\\
  1135.                    if tCompletionInfo[ sPath ] then\\\\\\\
  1136.                        tResults[n] = sResult .. \\\\\\\" \\\\\\\"\\\\\\\
  1137.                    end\\\\\\\
  1138.                end\\\\\\\
  1139.                return tResults\\\\\\\
  1140.            end\\\\\\\
  1141. \\\\\\\
  1142.        elseif nIndex > 1 then\\\\\\\
  1143.            local sPath = shell.resolveProgram( tWords[1] )\\\\\\\
  1144.            local sPart = tWords[nIndex] or \\\\\\\"\\\\\\\"\\\\\\\
  1145.            local tPreviousParts = tWords\\\\\\\
  1146.            tPreviousParts[nIndex] = nil\\\\\\\
  1147.            return completeProgramArgument( sPath , nIndex - 1, sPart, tPreviousParts )\\\\\\\
  1148. \\\\\\\
  1149.        end\\\\\\\
  1150.    end\\\\\\\
  1151.    return nil\\\\\\\
  1152. end\\\\\\\
  1153. \\\\\\\
  1154. function shell.completeProgram( sProgram )\\\\\\\
  1155.    if type( sProgram ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
  1156.        error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( sProgram ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  1157.    end\\\\\\\
  1158.    return completeProgram( sProgram )\\\\\\\
  1159. end\\\\\\\
  1160. \\\\\\\
  1161. function shell.setCompletionFunction( sProgram, fnComplete )\\\\\\\
  1162.    if type( sProgram ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
  1163.        error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( sProgram ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  1164.    end\\\\\\\
  1165.    if type( fnComplete ) ~= \\\\\\\"function\\\\\\\" then\\\\\\\
  1166.        error( \\\\\\\"bad argument #2 (expected function, got \\\\\\\" .. type( fnComplete ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  1167.    end\\\\\\\
  1168.    tCompletionInfo[ sProgram ] = {\\\\\\\
  1169.        fnComplete = fnComplete\\\\\\\
  1170.    }\\\\\\\
  1171. end\\\\\\\
  1172. \\\\\\\
  1173. function shell.getCompletionInfo()\\\\\\\
  1174.    return tCompletionInfo\\\\\\\
  1175. end\\\\\\\
  1176. \\\\\\\
  1177. function shell.getRunningProgram()\\\\\\\
  1178.    if #tProgramStack > 0 then\\\\\\\
  1179.        return tProgramStack[#tProgramStack]\\\\\\\
  1180.    end\\\\\\\
  1181.    return nil\\\\\\\
  1182. end\\\\\\\
  1183. \\\\\\\
  1184. function shell.setAlias( _sCommand, _sProgram )\\\\\\\
  1185.    if type( _sCommand ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
  1186.        error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( _sCommand ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  1187.    end\\\\\\\
  1188.    if type( _sProgram ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
  1189.        error( \\\\\\\"bad argument #2 (expected string, got \\\\\\\" .. type( _sProgram ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  1190.    end\\\\\\\
  1191.    tAliases[ _sCommand ] = _sProgram\\\\\\\
  1192. end\\\\\\\
  1193. \\\\\\\
  1194. function shell.clearAlias( _sCommand )\\\\\\\
  1195.    if type( _sCommand ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
  1196.        error( \\\\\\\"bad argument #1 (expected string, got \\\\\\\" .. type( _sCommand ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  1197.    end\\\\\\\
  1198.    tAliases[ _sCommand ] = nil\\\\\\\
  1199. end\\\\\\\
  1200. \\\\\\\
  1201. function shell.aliases()\\\\\\\
  1202.    -- Copy aliases\\\\\\\
  1203.    local tCopy = {}\\\\\\\
  1204.    for sAlias, sCommand in pairs( tAliases ) do\\\\\\\
  1205.        tCopy[sAlias] = sCommand\\\\\\\
  1206.    end\\\\\\\
  1207.    return tCopy\\\\\\\
  1208. end\\\\\\\
  1209. \\\\\\\
  1210. if multishell then\\\\\\\
  1211.    function shell.openTab( ... )\\\\\\\
  1212.        local tWords = tokenise( ... )\\\\\\\
  1213.        local sCommand = tWords[1]\\\\\\\
  1214.        if sCommand then\\\\\\\
  1215.            local sPath = shell.resolveProgram( sCommand )\\\\\\\
  1216.            if sPath == \\\\\\\"rom/programs/shell.lua\\\\\\\" then\\\\\\\
  1217.                return multishell.launch( createShellEnv( \\\\\\\"rom/programs\\\\\\\" ), sPath, table.unpack( tWords, 2 ) )\\\\\\\
  1218.            elseif sPath ~= nil then\\\\\\\
  1219.                return multishell.launch( createShellEnv( \\\\\\\"rom/programs\\\\\\\" ), \\\\\\\"rom/programs/shell.lua\\\\\\\", sCommand, table.unpack( tWords, 2 ) )\\\\\\\
  1220.            else\\\\\\\
  1221.                printError( \\\\\\\"No such program\\\\\\\" )\\\\\\\
  1222.            end\\\\\\\
  1223.        end\\\\\\\
  1224.    end\\\\\\\
  1225. \\\\\\\
  1226.    function shell.switchTab( nID )\\\\\\\
  1227.        if type( nID ) ~= \\\\\\\"number\\\\\\\" then\\\\\\\
  1228.            error( \\\\\\\"bad argument #1 (expected number, got \\\\\\\" .. type( nID ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  1229.        end\\\\\\\
  1230.        multishell.setFocus( nID )\\\\\\\
  1231.    end\\\\\\\
  1232. end\\\\\\\
  1233. \\\\\\\
  1234. function shell.executeScript(path)\\\\\\\
  1235. if not fs.exists(path) or fs.isDir(path) then\\\\\\\
  1236.  return \\\\\\\"file does not exist\\\\\\\"\\\\\\\
  1237. else\\\\\\\
  1238.  local t = kernel.iterateFileLines(path)\\\\\\\
  1239.  if t[1] == \\\\\\\"@ #handler /system/bin/sh\\\\\\\" then\\\\\\\
  1240.   for _,cmd in pairs(t) do\\\\\\\
  1241.    shell.run(cmd)\\\\\\\
  1242.   end\\\\\\\
  1243.  else\\\\\\\
  1244.   return \\\\\\\"script header is missing or corrupt\\\\\\\" \\\\\\\
  1245.  end\\\\\\\
  1246. end\\\\\\\
  1247. end\\\\\\\
  1248. \\\\\\\
  1249. local tArgs = { ... }\\\\\\\
  1250. if #tArgs > 0 then\\\\\\\
  1251.    -- \\\\\\\"shell x y z\\\\\\\"\\\\\\\
  1252.    -- Run the program specified on the commandline\\\\\\\
  1253.    shell.run( ... )\\\\\\\
  1254. \\\\\\\
  1255. else\\\\\\\
  1256.    -- \\\\\\\"shell\\\\\\\"\\\\\\\
  1257.    -- Print the header\\\\\\\
  1258.    term.setBackgroundColor( bgColour )\\\\\\\
  1259.    term.setTextColour( promptColour )\\\\\\\
  1260.    print( os.version() )\\\\\\\
  1261.    term.setTextColour( textColour )\\\\\\\
  1262. \\\\\\\
  1263.    -- Run the startup program\\\\\\\
  1264.    if parentShell == nil then\\\\\\\
  1265.        shell.run( \\\\\\\"/rom/startup.lua\\\\\\\" )\\\\\\\
  1266.    end\\\\\\\
  1267.    sPath = sPath..\\\\\\\":/bin\\\\\\\"\\\\\\\
  1268. \\\\\\\
  1269.    -- Read commands and execute them\\\\\\\
  1270.    local tCommandHistory = {}\\\\\\\
  1271.    while not bExit do\\\\\\\
  1272.        term.redirect( parentTerm )\\\\\\\
  1273.        term.setBackgroundColor( bgColour )\\\\\\\
  1274.        term.setTextColour( promptColour )\\\\\\\
  1275. \\\\009\\\\009if __DEBUG then\\\\\\\
  1276.            stdout( \\\\\\\"/\\\\\\\" .. shell.dir() .. \\\\\\\" # \\\\\\\" )\\\\\\\
  1277. \\\\009\\\\009else\\\\\\\
  1278.            stdout( \\\\\\\"/\\\\\\\" .. shell.dir() .. \\\\\\\" $ \\\\\\\" )\\\\\\\
  1279. \\\\009\\\\009end\\\\\\\
  1280.        term.setTextColour( textColour )\\\\\\\
  1281. \\\\\\\
  1282. \\\\\\\
  1283.        local sLine\\\\\\\
  1284.        sLine = read( nil, tCommandHistory, shell.complete )\\\\\\\
  1285.        if sLine:match(\\\\\\\"%S\\\\\\\") and tCommandHistory[#tCommandHistory] ~= sLine then\\\\\\\
  1286.            table.insert( tCommandHistory, sLine )\\\\\\\
  1287.        end\\\\\\\
  1288.        shell.run( sLine )\\\\\\\
  1289.    end\\\\\\\
  1290. end\\\"\",\
  1291.  \"F:systeminfo\",\
  1292.  \"\\\"print(os.version())\\\\\\\
  1293. print(\\\\\\\"Path:\\\\\\\" shell.path())\\\\\\\
  1294. print(\\\\\\\"ID \\\\\\\"..os.getComputerID() or \\\\\\\"N/A\\\\\\\")\\\\\\\
  1295. print(\\\\\\\"Computer labeled as \\\\\\\"..os.getComputerLabel() or \\\\\\\"N/A\\\\\\\")\\\"\",\
  1296.  \"F:tree\",\
  1297.  \"\\\"-- Context: http://www.computercraft.info/forums2/index.php?/topic/44-request-windows-tree-command/\\\\\\\
  1298. \\\\\\\
  1299. local tArgs = { ... }\\\\\\\
  1300. local currentPath = shell.resolve(\\\\\\\".\\\\\\\")\\\\\\\
  1301. local lineCounter = 0\\\\\\\
  1302. local pageFlip = false\\\\\\\
  1303. local askingForHelp = false\\\\\\\
  1304. \\\\\\\
  1305. --[[ Process command line arguments ]]\\\\\\\
  1306. if #tArgs > 1 then  -- More than one argument.\\\\\\\
  1307.    if ( tArgs[1] == string.lower( \\\\\\\"-m\\\\\\\" ) ) or ( tArgs[1] == string.lower( \\\\\\\"-more\\\\\\\" ) ) then\\\\\\\
  1308.        pageFlip = true\\\\\\\
  1309.        currentPath = shell.resolve( tArgs[2] )\\\\\\\
  1310.    elseif ( tArgs[2] == string.lower( \\\\\\\"-m\\\\\\\" ) ) or ( tArgs[2] == string.lower( \\\\\\\"-more\\\\\\\" ) ) then\\\\\\\
  1311.        pageFlip = true\\\\\\\
  1312.        currentPath = shell.resolve( tArgs[1] )\\\\\\\
  1313.    else\\\\\\\
  1314.        currentPath = shell.resolve( tArgs[1] )\\\\\\\
  1315.    end\\\\\\\
  1316. else    -- Only one argument.\\\\\\\
  1317.    if ( tArgs[1] == string.lower( \\\\\\\"-h\\\\\\\" ) ) or ( tArgs[1] == string.lower( \\\\\\\"-help\\\\\\\" ) ) then\\\\\\\
  1318.        askingForHelp = true\\\\\\\
  1319.    elseif tArgs[1] ~= nil then\\\\\\\
  1320.        currentPath = shell.resolve( tArgs[1] )\\\\\\\
  1321.    end\\\\\\\
  1322. end\\\\\\\
  1323. \\\\\\\
  1324. function printUsage()\\\\\\\
  1325.    print( \\\\\\\"Usage: tree [-more] [-help] [<DIRECTORY>]\\\\\\\\n\\\\\\\" )\\\\\\\
  1326.    \\\\\\\
  1327.    print( \\\\\\\"-m  or  -more   Enable page flipping.\\\\\\\" )\\\\\\\
  1328.    print( \\\\\\\"-h  or  -help   Show this help.\\\\\\\" )\\\\\\\
  1329.    print( \\\\\\\"<DIRECTORY>     Name of the directory.\\\\\\\" )\\\\\\\
  1330.    print( \\\\\\\"                (Default is current directory)\\\\\\\" )\\\\\\\
  1331. \\\\009print( \\\\\\\"Made by Espen.\\\\\\\")\\\\\\\
  1332. end\\\\\\\
  1333. \\\\\\\
  1334. function listDir( path, prefix )\\\\\\\
  1335.    if path == \\\\\\\"\\\\\\\" then path = \\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\" end  -- Path of execution.\\\\\\\
  1336.    \\\\\\\
  1337.    -- Iterate through every element (file or dir) in the path.\\\\\\\
  1338.    for k, v in pairs( fs.list( path ) ) do\\\\\\\
  1339.        ---[[ PAGE-FLIP\\\\\\\
  1340.        if pageFlip then\\\\\\\
  1341.            lineCounter = lineCounter + 1\\\\\\\
  1342.            if lineCounter >= 17 then\\\\\\\
  1343.                write(\\\\\\\"Press any key to continue\\\\\\\")\\\\\\\
  1344.                read()\\\\\\\
  1345.                term.setCursorPos( 1, 1 )\\\\\\\
  1346.                term.clear()\\\\\\\
  1347.                lineCounter = 0\\\\\\\
  1348.            end\\\\\\\
  1349.        end\\\\\\\
  1350.        --]]\\\\\\\
  1351.        -- Print file/dir name.\\\\\\\
  1352.        print( prefix..\\\\\\\"-- \\\\\\\"..v )\\\\\\\
  1353.        -- Traverse next directory, if any.\\\\\\\
  1354.        local nextDir = path..\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\"..v\\\\\\\
  1355.        if fs.isDir( nextDir ) then listDir( nextDir, prefix..\\\\\\\"   |\\\\\\\" ) end\\\\\\\
  1356.    end\\\\\\\
  1357. end\\\\\\\
  1358. \\\\\\\
  1359. if askingForHelp then\\\\\\\
  1360.    printUsage()\\\\\\\
  1361. else\\\\\\\
  1362.    print( \\\\\\\"Listing directory: \\\\\\\"..currentPath )\\\\\\\
  1363.    listDir( currentPath, \\\\\\\"|\\\\\\\" )\\\\\\\
  1364. end\\\"\",\
  1365.  \"F:tty\",\
  1366.  \"\\\"local x, y = term.getSize()\\\\\\\
  1367. print(\\\\\\\"terminal object size is \\\\\\\"..tostring(x)..\\\\\\\"x\\\\\\\"..tostring(y))\\\\\\\
  1368. \\\"\",\
  1369. }",
  1370.   "D:boot",
  1371.   "{\
  1372.  \"D:esi\",\
  1373.  \"{\\\
  1374.  \\\"F:config.dat\\\",\\\
  1375.  \\\"\\\\\\\"{\\\\\\\\\\\\\\\
  1376.  script = \\\\\\\\\\\\\\\"Orbital\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\
  1377. }\\\\\\\"\\\",\\\
  1378.  \\\"D:drivers\\\",\\\
  1379.  \\\"{\\\\\\\
  1380.  \\\\\\\"F:dmouse.sys\\\\\\\",\\\\\\\
  1381.  \\\\\\\"\\\\\\\\\\\\\\\"local function handleRegionMouseInput(xx, yy, x1, x2, y1, y2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1382. y0 = y2 or y1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1383. if (xx >= x1 and xx <= x2) then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1384.  if (yy >= y1 and yy <= y0) then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1385.   return true\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1386.  elseif yy == y1 or yy == y0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1387.   return true\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1388.  end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1389. end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1390. return false\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1391. end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1392. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1393. __declare_api(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"peripheral\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"handleMouseInput\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", function(...)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1394. local tArgs = {...}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1395. if #tArgs < 1 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1396.  error(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"usage: handleMouseInput(<table describing the minX, maxX, minY and maxY positions of a button>, [more tables like this]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1397. else\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1398.  while true do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1399.   sleep(0.01)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1400.   local a, b, x, y = os.pullEvent(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"mouse_click\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1401.   sleep(0.01)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1402.   for k,v in ipairs(tArgs) do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1403.    local minX = v[1]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1404. \\\\\\\\\\\\\\\\009local maxX = v[2]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1405. \\\\\\\\\\\\\\\\009local minY = v[3]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1406. \\\\\\\\\\\\\\\\009local maxY = v[4] or v[3]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1407.    if handleRegionMouseInput(x, y, minX, maxX, minY, maxY) then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1408.     return k\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1409.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1410.   end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1411.  end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1412. end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1413. end)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1414. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1415. return true\\\\\\\\\\\\\\\"\\\\\\\",\\\\\\\
  1416.  \\\\\\\"F:dvirt.sys\\\\\\\",\\\\\\\
  1417.  \\\\\\\"\\\\\\\\\\\\\\\"-- Guest Virtualization Driver for Orbital.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1418. -- Supports CCEmuX.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1419. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1420. if ccemux then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1421. ccemux.attach(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"top\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"wireless_modem\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1422. if __DEBUG then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1423.  __declare(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"__DEBUG_REMOTE\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", __kstruct({true}))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1424. end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1425. return true\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1426. end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1427. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1428. return false, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"Compatible hypervisor not detected\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\",\\\\\\\
  1429.  \\\\\\\"F:ecc.sys\\\\\\\",\\\\\\\
  1430.  \\\\\\\"\\\\\\\\\\\\\\\"-- Elliptic Curve Cryptography in Computercraft\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1431. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1432. local byteTableMT = {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1433.    __tostring = function(a) return string.char(unpack(a)) end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1434.    __index = {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1435.        toHex = function(self, s) return (\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"%02x\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"):rep(#self):format(unpack(self)) end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1436.        isEqual = function(self, t)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1437.            if type(t) ~= \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" then return false end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1438.            if #self ~= #t then return false end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1439.            local ret = 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1440.            for i = 1, #self do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1441.                ret = bit32.bor(ret, bit32.bxor(self[i], t[i]))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1442.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1443.            return ret == 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1444.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1445.    }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1446. }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1447. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1448. -- SHA-256, HMAC and PBKDF2 functions in ComputerCraft\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1449. -- By Anavrins\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1450. -- For help and details, you can PM me on the CC forums\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1451. -- You may use this code in your projects without asking me, as long as credit is given and this header is kept intact\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1452. -- http://www.computercraft.info/forums2/index.php?/user/12870-anavrins\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1453. -- http://pastebin.com/6UV4qfNF\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1454. -- Last update: October 10, 2017\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1455. local sha256 = (function()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1456.    local mod32 = 2^32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1457.    local band    = bit32 and bit32.band or bit.band\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1458.    local bnot    = bit32 and bit32.bnot or bit.bnot\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1459.    local bxor    = bit32 and bit32.bxor or bit.bxor\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1460.    local blshift = bit32 and bit32.lshift or bit.blshift\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1461.    local upack   = unpack\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1462. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1463.    local function rrotate(n, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1464.        local s = n/(2^b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1465.        local f = s%1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1466.        return (s-f) + f*mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1467.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1468.    local function brshift(int, by) -- Thanks bit32 for bad rshift\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1469.        local s = int / (2^by)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1470.        return s - s%1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1471.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1472. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1473.    local H = {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1474.        0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1475.        0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1476.    }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1477. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1478.    local K = {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1479.        0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1480.        0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1481.        0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1482.        0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1483.        0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1484.        0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1485.        0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1486.        0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1487.    }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1488. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1489.    local function counter(incr)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1490.        local t1, t2 = 0, 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1491.        if 0xFFFFFFFF - t1 < incr then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1492.            t2 = t2 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1493.            t1 = incr - (0xFFFFFFFF - t1) - 1       \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1494.        else t1 = t1 + incr\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1495.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1496.        return t2, t1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1497.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1498. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1499.    local function BE_toInt(bs, i)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1500.        return blshift((bs[i] or 0), 24) + blshift((bs[i+1] or 0), 16) + blshift((bs[i+2] or 0), 8) + (bs[i+3] or 0)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1501.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1502. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1503.    local function preprocess(data)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1504.        local len = #data\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1505.        local proc = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1506.        data[#data+1] = 0x80\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1507.        while #data%64~=56 do data[#data+1] = 0 end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1508.        local blocks = math.ceil(#data/64)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1509.        for i = 1, blocks do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1510.            proc[i] = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1511.            for j = 1, 16 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1512.                proc[i][j] = BE_toInt(data, 1+((i-1)*64)+((j-1)*4))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1513.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1514.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1515.        proc[blocks][15], proc[blocks][16] = counter(len*8)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1516.        return proc\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1517.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1518. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1519.    local function digestblock(w, C)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1520.        for j = 17, 64 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1521.            local v = w[j-15]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1522.            local s0 = bxor(bxor(rrotate(w[j-15], 7), rrotate(w[j-15], 18)), brshift(w[j-15], 3))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1523.            local s1 = bxor(bxor(rrotate(w[j-2], 17), rrotate(w[j-2], 19)), brshift(w[j-2], 10))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1524.            w[j] = (w[j-16] + s0 + w[j-7] + s1)%mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1525.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1526.        local a, b, c, d, e, f, g, h = upack(C)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1527.        for j = 1, 64 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1528.            local S1 = bxor(bxor(rrotate(e, 6), rrotate(e, 11)), rrotate(e, 25))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1529.            local ch = bxor(band(e, f), band(bnot(e), g))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1530.            local temp1 = (h + S1 + ch + K[j] + w[j])%mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1531.            local S0 = bxor(bxor(rrotate(a, 2), rrotate(a, 13)), rrotate(a, 22))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1532.            local maj = bxor(bxor(band(a, b), band(a, c)), band(b, c))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1533.            local temp2 = (S0 + maj)%mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1534.            h, g, f, e, d, c, b, a = g, f, e, (d+temp1)%mod32, c, b, a, (temp1+temp2)%mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1535.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1536.        C[1] = (C[1] + a)%mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1537.        C[2] = (C[2] + b)%mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1538.        C[3] = (C[3] + c)%mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1539.        C[4] = (C[4] + d)%mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1540.        C[5] = (C[5] + e)%mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1541.        C[6] = (C[6] + f)%mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1542.        C[7] = (C[7] + g)%mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1543.        C[8] = (C[8] + h)%mod32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1544.        return C\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1545.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1546. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1547.    local function toBytes(t, n)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1548.        local b = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1549.        for i = 1, n do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1550.            b[(i-1)*4+1] = band(brshift(t[i], 24), 0xFF)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1551.            b[(i-1)*4+2] = band(brshift(t[i], 16), 0xFF)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1552.            b[(i-1)*4+3] = band(brshift(t[i], 8), 0xFF)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1553.            b[(i-1)*4+4] = band(t[i], 0xFF)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1554.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1555.        return setmetatable(b, byteTableMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1556.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1557. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1558.    local function digest(data)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1559.        data = data or \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1560.        data = type(data) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" and {upack(data)} or {tostring(data):byte(1,-1)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1561. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1562.        data = preprocess(data)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1563.        local C = {upack(H)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1564.        for i = 1, #data do C = digestblock(data[i], C) end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1565.        return toBytes(C, 8)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1566.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1567. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1568.    local function hmac(data, key)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1569.        local data = type(data) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" and {upack(data)} or {tostring(data):byte(1,-1)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1570.        local key = type(key) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" and {upack(key)} or {tostring(key):byte(1,-1)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1571. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1572.        local blocksize = 64\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1573. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1574.        key = #key > blocksize and digest(key) or key\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1575. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1576.        local ipad = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1577.        local opad = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1578.        local padded_key = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1579. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1580.        for i = 1, blocksize do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1581.            ipad[i] = bxor(0x36, key[i] or 0)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1582.            opad[i] = bxor(0x5C, key[i] or 0)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1583.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1584. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1585.        for i = 1, #data do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1586.            ipad[blocksize+i] = data[i]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1587.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1588. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1589.        ipad = digest(ipad)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1590. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1591.        for i = 1, blocksize do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1592.            padded_key[i] = opad[i]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1593.            padded_key[blocksize+i] = ipad[i]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1594.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1595. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1596.        return digest(padded_key)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1597.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1598. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1599.    local function pbkdf2(pass, salt, iter, dklen)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1600.        local salt = type(salt) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" and salt or {tostring(salt):byte(1,-1)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1601.        local hashlen = 32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1602.        local dklen = dklen or 32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1603.        local block = 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1604.        local out = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1605. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1606.        while dklen > 0 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1607.            local ikey = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1608.            local isalt = {upack(salt)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1609.            local clen = dklen > hashlen and hashlen or dklen\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1610. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1611.            isalt[#isalt+1] = band(brshift(block, 24), 0xFF)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1612.            isalt[#isalt+1] = band(brshift(block, 16), 0xFF)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1613.            isalt[#isalt+1] = band(brshift(block, 8), 0xFF)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1614.            isalt[#isalt+1] = band(block, 0xFF)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1615. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1616.            for j = 1, iter do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1617.                isalt = hmac(isalt, pass)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1618.                for k = 1, clen do ikey[k] = bxor(isalt[k], ikey[k] or 0) end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1619.                if j % 200 == 0 then os.queueEvent(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"PBKDF2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", j) coroutine.yield(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"PBKDF2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\") end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1620.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1621.            dklen = dklen - clen\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1622.            block = block+1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1623.            for k = 1, clen do out[#out+1] = ikey[k] end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1624.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1625. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1626.        return setmetatable(out, byteTableMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1627.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1628. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1629.    return {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1630.        digest = digest,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1631.        hmac = hmac,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1632.        pbkdf2 = pbkdf2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1633.    }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1634. end)()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1635. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1636. -- Chacha20 cipher in ComputerCraft\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1637. -- By Anavrins\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1638. -- For help and details, you can PM me on the CC forums\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1639. -- You may use this code in your projects without asking me, as long as credit is given and this header is kept intact\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1640. -- http://www.computercraft.info/forums2/index.php?/user/12870-anavrins\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1641. -- http://pastebin.com/GPzf9JSa\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1642. -- Last update: April 17, 2017\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1643. local chacha20 = (function()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1644.    local bxor = bit32.bxor\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1645.    local band = bit32.band\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1646.    local blshift = bit32.lshift\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1647.    local brshift = bit32.arshift\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1648. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1649.    local mod = 2^32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1650.    local tau = {(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"expand 16-byte k\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"):byte(1,-1)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1651.    local sigma = {(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"expand 32-byte k\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"):byte(1,-1)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1652. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1653.    local function rotl(n, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1654.        local s = n/(2^(32-b))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1655.        local f = s%1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1656.        return (s-f) + f*mod\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1657.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1658. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1659.    local function quarterRound(s, a, b, c, d)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1660.        s[a] = (s[a]+s[b])%mod; s[d] = rotl(bxor(s[d], s[a]), 16)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1661.        s[c] = (s[c]+s[d])%mod; s[b] = rotl(bxor(s[b], s[c]), 12)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1662.        s[a] = (s[a]+s[b])%mod; s[d] = rotl(bxor(s[d], s[a]), 8)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1663.        s[c] = (s[c]+s[d])%mod; s[b] = rotl(bxor(s[b], s[c]), 7)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1664.        return s\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1665.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1666. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1667.    local function hashBlock(state, rnd)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1668.        local s = {unpack(state)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1669.        for i = 1, rnd do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1670.            local r = i%2==1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1671.            s = r and quarterRound(s, 1, 5,  9, 13) or quarterRound(s, 1, 6, 11, 16)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1672.            s = r and quarterRound(s, 2, 6, 10, 14) or quarterRound(s, 2, 7, 12, 13)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1673.            s = r and quarterRound(s, 3, 7, 11, 15) or quarterRound(s, 3, 8,  9, 14)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1674.            s = r and quarterRound(s, 4, 8, 12, 16) or quarterRound(s, 4, 5, 10, 15)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1675.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1676.        for i = 1, 16 do s[i] = (s[i]+state[i])%mod end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1677.        return s\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1678.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1679. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1680.    local function LE_toInt(bs, i)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1681.        return (bs[i+1] or 0)+\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1682.        blshift((bs[i+2] or 0), 8)+\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1683.        blshift((bs[i+3] or 0), 16)+\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1684.        blshift((bs[i+4] or 0), 24)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1685.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1686. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1687.    local function initState(key, nonce, counter)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1688.        local isKey256 = #key == 32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1689.        local const = isKey256 and sigma or tau\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1690.        local state = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1691. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1692.        state[ 1] = LE_toInt(const, 0)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1693.        state[ 2] = LE_toInt(const, 4)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1694.        state[ 3] = LE_toInt(const, 8)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1695.        state[ 4] = LE_toInt(const, 12)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1696. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1697.        state[ 5] = LE_toInt(key, 0)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1698.        state[ 6] = LE_toInt(key, 4)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1699.        state[ 7] = LE_toInt(key, 8)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1700.        state[ 8] = LE_toInt(key, 12)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1701.        state[ 9] = LE_toInt(key, isKey256 and 16 or 0)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1702.        state[10] = LE_toInt(key, isKey256 and 20 or 4)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1703.        state[11] = LE_toInt(key, isKey256 and 24 or 8)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1704.        state[12] = LE_toInt(key, isKey256 and 28 or 12)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1705. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1706.        state[13] = counter\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1707.        state[14] = LE_toInt(nonce, 0)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1708.        state[15] = LE_toInt(nonce, 4)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1709.        state[16] = LE_toInt(nonce, 8)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1710. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1711.        return state\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1712.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1713. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1714.    local function serialize(state)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1715.        local r = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1716.        for i = 1, 16 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1717.            r[#r+1] = band(state[i], 0xFF)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1718.            r[#r+1] = band(brshift(state[i], 8), 0xFF)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1719.            r[#r+1] = band(brshift(state[i], 16), 0xFF)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1720.            r[#r+1] = band(brshift(state[i], 24), 0xFF)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1721.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1722.        return r\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1723.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1724. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1725.    function crypt(data, key, nonce, cntr, round)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1726.        assert(type(key) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"ChaCha20: Invalid key format (\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"..type(key)..\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"), must be table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1727.        assert(type(nonce) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"ChaCha20: Invalid nonce format (\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"..type(nonce)..\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"), must be table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1728.        assert(#key == 16 or #key == 32, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"ChaCha20: Invalid key length (\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"..#key..\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"), must be 16 or 32\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1729.        assert(#nonce == 12, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"ChaCha20: Invalid nonce length (\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"..#nonce..\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"), must be 12\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1730. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1731.        local data = type(data) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" and {unpack(data)} or {tostring(data):byte(1,-1)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1732.        cntr = tonumber(cntr) or 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1733.        round = tonumber(round) or 20\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1734. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1735.        local out = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1736.        local state = initState(key, nonce, cntr)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1737.        local blockAmt = math.floor(#data/64)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1738.        for i = 0, blockAmt do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1739.            local ks = serialize(hashBlock(state, round))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1740.            state[13] = (state[13]+1) % mod\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1741. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1742.            local block = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1743.            for j = 1, 64 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1744.                block[j] = data[((i)*64)+j]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1745.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1746.            for j = 1, #block do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1747.                out[#out+1] = bxor(block[j], ks[j])\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1748.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1749. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1750.            if i % 1000 == 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1751.                os.queueEvent(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1752.                os.pullEvent(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1753.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1754.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1755.        return setmetatable(out, byteTableMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1756.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1757. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1758.    return {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1759.        crypt = crypt\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1760.    }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1761. end)()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1762. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1763. -- random.lua - Random Byte Generator\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1764. local random = (function()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1765.    local oldPull = os.pullEvent\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1766.    local entropy = \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1767.    local accumulator = \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1768.    local entropyPath = \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"/.random\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1769.    local running = false\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1770. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1771.    local function feed(data)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1772.        accumulator = accumulator .. (data or \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1773.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1774. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1775.    local function digest()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1776.        local input = accumulator:sub(1, 87)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1777.        accumulator = accumulator:sub(88)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1778. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1779.        entropy = tostring(sha256.digest(entropy .. input))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1780.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1781. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1782.    if fs.exists(entropyPath) then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1783.        local entropyFile = fs.open(entropyPath, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"rb\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1784.        feed(entropyFile.readAll())\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1785.        entropyFile.close()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1786.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1787. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1788.    feed(tostring(math.random(1, 2^31 - 1)))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1789.    feed(tostring(math.random(1, 2^31 - 1)))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1790.    for i = 1, 10000 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1791.        feed(tostring(os.epoch(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"utc\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")):sub(-8))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1792.        feed(tostring({}):sub(-8))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1793.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1794.    digest()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1795. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1796.    local function save()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1797.        feed(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"save\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1798.        feed(tostring(os.epoch(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"utc\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")):sub(-8))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1799.        feed(tostring({}):sub(-8))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1800.        digest()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1801. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1802.        local entropyFile = fs.open(entropyPath, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"wb\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1803.        entropyFile.write(tostring(sha256.hmac(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"save\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", entropy)))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1804.        entropy = tostring(sha256.digest(entropy))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1805.        entropyFile.close()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1806.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1807.    save()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1808. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1809.    local function seed(data)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1810.        feed(data)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1811.        feed(tostring(os.epoch(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"utc\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1812.        feed(tostring({}))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1813.        digest()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1814.        save()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1815.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1816. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1817.    local function random()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1818.        feed(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"random\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1819.        feed(tostring(os.epoch(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"utc\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")):sub(-8))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1820.        feed(tostring({}):sub(-8))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1821.        digest()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1822.        save()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1823. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1824.        local result = sha256.hmac(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"out\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", entropy)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1825.        entropy = tostring(sha256.digest(entropy))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1826.        \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1827.        return result\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1828.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1829. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1830.    return {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1831.        seed = seed,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1832.        save = save,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1833.        random = random\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1834.    }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1835. end)()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1836. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1837. -- Big integer arithmetic for 168-bit (and 336-bit) numbers\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1838. -- Numbers are represented as little-endian tables of 24-bit integers\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1839. local arith = (function()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1840.    local function isEqual(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1841.        return (\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1842.            a[1] == b[1]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1843.            and a[2] == b[2]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1844.            and a[3] == b[3]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1845.            and a[4] == b[4]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1846.            and a[5] == b[5]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1847.            and a[6] == b[6]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1848.            and a[7] == b[7]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1849.        )\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1850.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1851. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1852.    local function compare(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1853.        for i = 7, 1, -1 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1854.            if a[i] > b[i] then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1855.                return 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1856.            elseif a[i] < b[i] then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1857.                return -1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1858.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1859.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1860. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1861.        return 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1862.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1863. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1864.    local function add(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1865.        -- c7 may be greater than 2^24 before reduction\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1866.        local c1 = a[1] + b[1]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1867.        local c2 = a[2] + b[2]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1868.        local c3 = a[3] + b[3]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1869.        local c4 = a[4] + b[4]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1870.        local c5 = a[5] + b[5]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1871.        local c6 = a[6] + b[6]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1872.        local c7 = a[7] + b[7]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1873. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1874.        if c1 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1875.            c2 = c2 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1876.            c1 = c1 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1877.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1878.        if c2 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1879.            c3 = c3 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1880.            c2 = c2 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1881.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1882.        if c3 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1883.            c4 = c4 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1884.            c3 = c3 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1885.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1886.        if c4 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1887.            c5 = c5 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1888.            c4 = c4 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1889.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1890.        if c5 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1891.            c6 = c6 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1892.            c5 = c5 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1893.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1894.        if c6 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1895.            c7 = c7 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1896.            c6 = c6 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1897.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1898.        \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1899.        return {c1, c2, c3, c4, c5, c6, c7}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1900.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1901. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1902.    local function sub(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1903.        -- c7 may be negative before reduction\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1904.        local c1 = a[1] - b[1]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1905.        local c2 = a[2] - b[2]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1906.        local c3 = a[3] - b[3]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1907.        local c4 = a[4] - b[4]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1908.        local c5 = a[5] - b[5]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1909.        local c6 = a[6] - b[6]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1910.        local c7 = a[7] - b[7]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1911. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1912.        if c1 < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1913.            c2 = c2 - 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1914.            c1 = c1 + 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1915.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1916.        if c2 < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1917.            c3 = c3 - 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1918.            c2 = c2 + 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1919.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1920.        if c3 < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1921.            c4 = c4 - 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1922.            c3 = c3 + 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1923.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1924.        if c4 < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1925.            c5 = c5 - 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1926.            c4 = c4 + 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1927.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1928.        if c5 < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1929.            c6 = c6 - 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1930.            c5 = c5 + 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1931.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1932.        if c6 < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1933.            c7 = c7 - 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1934.            c6 = c6 + 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1935.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1936.        \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1937.        return {c1, c2, c3, c4, c5, c6, c7}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1938.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1939. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1940.    local function rShift(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1941.        local c1 = a[1]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1942.        local c2 = a[2]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1943.        local c3 = a[3]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1944.        local c4 = a[4]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1945.        local c5 = a[5]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1946.        local c6 = a[6]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1947.        local c7 = a[7]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1948. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1949.        c1 = c1 / 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1950.        c1 = c1 - c1 % 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1951.        c1 = c1 + (c2 % 2) * 0x800000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1952.        c2 = c2 / 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1953.        c2 = c2 - c2 % 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1954.        c2 = c2 + (c3 % 2) * 0x800000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1955.        c3 = c3 / 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1956.        c3 = c3 - c3 % 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1957.        c3 = c3 + (c4 % 2) * 0x800000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1958.        c4 = c4 / 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1959.        c4 = c4 - c4 % 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1960.        c4 = c4 + (c5 % 2) * 0x800000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1961.        c5 = c5 / 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1962.        c5 = c5 - c5 % 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1963.        c5 = c5 + (c6 % 2) * 0x800000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1964.        c6 = c6 / 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1965.        c6 = c6 - c6 % 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1966.        c6 = c6 + (c7 % 2) * 0x800000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1967.        c7 = c7 / 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1968.        c7 = c7 - c7 % 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1969. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1970.        return {c1, c2, c3, c4, c5, c6, c7}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1971.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1972. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1973.    local function addDouble(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1974.        -- a and b are 336-bit integers (14 words)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1975.        local c1 = a[1] + b[1]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1976.        local c2 = a[2] + b[2]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1977.        local c3 = a[3] + b[3]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1978.        local c4 = a[4] + b[4]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1979.        local c5 = a[5] + b[5]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1980.        local c6 = a[6] + b[6]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1981.        local c7 = a[7] + b[7]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1982.        local c8 = a[8] + b[8]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1983.        local c9 = a[9] + b[9]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1984.        local c10 = a[10] + b[10]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1985.        local c11 = a[11] + b[11]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1986.        local c12 = a[12] + b[12]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1987.        local c13 = a[13] + b[13]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1988.        local c14 = a[14] + b[14]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1989. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1990.        if c1 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1991.            c2 = c2 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1992.            c1 = c1 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1993.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1994.        if c2 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1995.            c3 = c3 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1996.            c2 = c2 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1997.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1998.        if c3 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  1999.            c4 = c4 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2000.            c3 = c3 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2001.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2002.        if c4 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2003.            c5 = c5 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2004.            c4 = c4 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2005.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2006.        if c5 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2007.            c6 = c6 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2008.            c5 = c5 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2009.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2010.        if c6 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2011.            c7 = c7 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2012.            c6 = c6 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2013.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2014.        if c7 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2015.            c8 = c8 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2016.            c7 = c7 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2017.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2018.        if c8 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2019.            c9 = c9 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2020.            c8 = c8 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2021.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2022.        if c9 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2023.            c10 = c10 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2024.            c9 = c9 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2025.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2026.        if c10 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2027.            c11 = c11 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2028.            c10 = c10 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2029.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2030.        if c11 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2031.            c12 = c12 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2032.            c11 = c11 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2033.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2034.        if c12 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2035.            c13 = c13 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2036.            c12 = c12 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2037.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2038.        if c13 > 0xffffff then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2039.            c14 = c14 + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2040.            c13 = c13 - 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2041.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2042. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2043.        return {c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2044.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2045. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2046.    local function mult(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2047.        local a1, a2, a3, a4, a5, a6, a7 = unpack(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2048.        local b1, b2, b3, b4, b5, b6, b7 = unpack(b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2049.        \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2050.        local c1 = a1 * b1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2051.        local c2 = a1 * b2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2052.        c2 = c2 + a2 * b1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2053.        local c3 = a1 * b3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2054.        c3 = c3 + a2 * b2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2055.        c3 = c3 + a3 * b1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2056.        local c4 = a1 * b4\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2057.        c4 = c4 + a2 * b3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2058.        c4 = c4 + a3 * b2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2059.        c4 = c4 + a4 * b1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2060.        local c5 = a1 * b5\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2061.        c5 = c5 + a2 * b4\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2062.        c5 = c5 + a3 * b3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2063.        c5 = c5 + a4 * b2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2064.        c5 = c5 + a5 * b1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2065.        local c6 = a1 * b6\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2066.        c6 = c6 + a2 * b5\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2067.        c6 = c6 + a3 * b4\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2068.        c6 = c6 + a4 * b3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2069.        c6 = c6 + a5 * b2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2070.        c6 = c6 + a6 * b1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2071.        local c7 = a1 * b7\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2072.        c7 = c7 + a2 * b6\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2073.        c7 = c7 + a3 * b5\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2074.        c7 = c7 + a4 * b4\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2075.        c7 = c7 + a5 * b3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2076.        c7 = c7 + a6 * b2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2077.        c7 = c7 + a7 * b1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2078.        local c8 = a2 * b7\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2079.        c8 = c8 + a3 * b6\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2080.        c8 = c8 + a4 * b5\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2081.        c8 = c8 + a5 * b4\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2082.        c8 = c8 + a6 * b3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2083.        c8 = c8 + a7 * b2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2084.        local c9 = a3 * b7\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2085.        c9 = c9 + a4 * b6\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2086.        c9 = c9 + a5 * b5\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2087.        c9 = c9 + a6 * b4\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2088.        c9 = c9 + a7 * b3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2089.        local c10 = a4 * b7\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2090.        c10 = c10 + a5 * b6\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2091.        c10 = c10 + a6 * b5\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2092.        c10 = c10 + a7 * b4\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2093.        local c11 = a5 * b7\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2094.        c11 = c11 + a6 * b6\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2095.        c11 = c11 + a7 * b5\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2096.        local c12 = a6 * b7\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2097.        c12 = c12 + a7 * b6\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2098.        local c13 = a7 * b7\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2099.        local c14 = 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2100. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2101.        local temp\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2102.        temp = c1 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2103.        c2 = c2 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2104.        c1 = c1 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2105.        temp = c2 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2106.        c3 = c3 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2107.        c2 = c2 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2108.        temp = c3 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2109.        c4 = c4 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2110.        c3 = c3 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2111.        temp = c4 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2112.        c5 = c5 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2113.        c4 = c4 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2114.        temp = c5 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2115.        c6 = c6 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2116.        c5 = c5 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2117.        temp = c6 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2118.        c7 = c7 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2119.        c6 = c6 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2120.        temp = c7 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2121.        c8 = c8 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2122.        c7 = c7 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2123.        temp = c8 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2124.        c9 = c9 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2125.        c8 = c8 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2126.        temp = c9 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2127.        c10 = c10 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2128.        c9 = c9 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2129.        temp = c10 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2130.        c11 = c11 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2131.        c10 = c10 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2132.        temp = c11 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2133.        c12 = c12 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2134.        c11 = c11 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2135.        temp = c12 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2136.        c13 = c13 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2137.        c12 = c12 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2138.        temp = c13 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2139.        c14 = c14 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2140.        c13 = c13 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2141. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2142.        return {c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2143.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2144. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2145.    local function square(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2146.        -- returns a 336-bit integer (14 words)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2147.        local a1, a2, a3, a4, a5, a6, a7 = unpack(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2148.        \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2149.        local c1 = a1 * a1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2150.        local c2 = a1 * a2 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2151.        local c3 = a1 * a3 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2152.        c3 = c3 + a2 * a2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2153.        local c4 = a1 * a4 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2154.        c4 = c4 + a2 * a3 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2155.        local c5 = a1 * a5 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2156.        c5 = c5 + a2 * a4 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2157.        c5 = c5 + a3 * a3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2158.        local c6 = a1 * a6 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2159.        c6 = c6 + a2 * a5 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2160.        c6 = c6 + a3 * a4 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2161.        local c7 = a1 * a7 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2162.        c7 = c7 + a2 * a6 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2163.        c7 = c7 + a3 * a5 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2164.        c7 = c7 + a4 * a4\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2165.        local c8 = a2 * a7 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2166.        c8 = c8 + a3 * a6 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2167.        c8 = c8 + a4 * a5 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2168.        local c9 = a3 * a7 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2169.        c9 = c9 + a4 * a6 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2170.        c9 = c9 + a5 * a5\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2171.        local c10 = a4 * a7 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2172.        c10 = c10 + a5 * a6 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2173.        local c11 = a5 * a7 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2174.        c11 = c11 + a6 * a6\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2175.        local c12 = a6 * a7 * 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2176.        local c13 = a7 * a7\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2177.        local c14 = 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2178. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2179.        local temp\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2180.        temp = c1 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2181.        c2 = c2 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2182.        c1 = c1 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2183.        temp = c2 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2184.        c3 = c3 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2185.        c2 = c2 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2186.        temp = c3 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2187.        c4 = c4 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2188.        c3 = c3 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2189.        temp = c4 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2190.        c5 = c5 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2191.        c4 = c4 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2192.        temp = c5 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2193.        c6 = c6 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2194.        c5 = c5 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2195.        temp = c6 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2196.        c7 = c7 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2197.        c6 = c6 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2198.        temp = c7 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2199.        c8 = c8 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2200.        c7 = c7 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2201.        temp = c8 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2202.        c9 = c9 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2203.        c8 = c8 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2204.        temp = c9 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2205.        c10 = c10 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2206.        c9 = c9 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2207.        temp = c10 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2208.        c11 = c11 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2209.        c10 = c10 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2210.        temp = c11 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2211.        c12 = c12 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2212.        c11 = c11 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2213.        temp = c12 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2214.        c13 = c13 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2215.        c12 = c12 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2216.        temp = c13 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2217.        c14 = c14 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2218.        c13 = c13 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2219. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2220.        return {c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2221.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2222. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2223.    -- Converts a number from base 2^startLength to base 2^resultLength\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2224.    local function reword(start, startLength, resultLength)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2225.        local result = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2226.        local buffer = 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2227.        local bufferLength = 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2228.        local startIndex = 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2229.        local totalBits = #start * startLength\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2230. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2231.        while totalBits > 0 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2232.            while bufferLength < resultLength do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2233.                buffer = buffer + (start[startIndex] or 0) * 2^bufferLength\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2234.                startIndex = startIndex + 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2235.                bufferLength = bufferLength + startLength\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2236.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2237.            result[#result + 1] = buffer % 2^resultLength\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2238.            buffer = buffer / 2^resultLength\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2239.            buffer = buffer - buffer % 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2240.            bufferLength = bufferLength - resultLength\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2241.            totalBits = totalBits - resultLength\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2242.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2243. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2244.        return result\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2245.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2246. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2247.    local function mods(d, w)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2248.        local result = d[1] % 2^w\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2249. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2250.        if result >= 2^(w - 1) then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2251.            result = result - 2^w\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2252.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2253. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2254.        return result\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2255.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2256. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2257.    -- Represents a 168-bit number as the (2^w)-ary Non-Adjacent Form\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2258.    local function NAF(d, w)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2259.        local t = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2260.        local d = {unpack(d)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2261. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2262.        for i = 1, 168 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2263.            if d[1] % 2 == 1 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2264.                t[#t + 1] = mods(d, w)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2265.                d = sub(d, {t[#t], 0, 0, 0, 0, 0, 0})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2266.            else\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2267.                t[#t + 1] = 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2268.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2269. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2270.            d = rShift(d)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2271.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2272. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2273.        return t\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2274.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2275. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2276.    return {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2277.        isEqual = isEqual,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2278.        compare = compare,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2279.        add = add,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2280.        sub = sub,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2281.        addDouble = addDouble,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2282.        mult = mult,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2283.        square = square,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2284.        reword = reword,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2285.        NAF = NAF\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2286.    }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2287. end)()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2288. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2289. -- Arithmetic on the finite field of integers modulo p\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2290. -- Where p is the finite field modulus\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2291. local modp = (function()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2292.    local add = arith.add\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2293.    local sub = arith.sub\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2294.    local addDouble = arith.addDouble\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2295.    local mult = arith.mult\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2296.    local square = arith.square\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2297. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2298.    local p = {3, 0, 0, 0, 0, 0, 15761408}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2299. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2300.    -- We're using the Montgomery Reduction for fast modular multiplication.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2301.    -- https://en.wikipedia.org/wiki/Montgomery_modular_multiplication \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2302.    -- r = 2^168\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2303.    -- p * pInverse = -1 (mod r)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2304.    -- r2 = r * r (mod p)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2305.    local pInverse = {5592405, 5592405, 5592405, 5592405, 5592405, 5592405, 14800213}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2306.    local r2 = {13533400, 837116, 6278376, 13533388, 837116, 6278376, 7504076}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2307. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2308.    local function multByP(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2309.        local a1, a2, a3, a4, a5, a6, a7 = unpack(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2310. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2311.        local c1 = a1 * 3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2312.        local c2 = a2 * 3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2313.        local c3 = a3 * 3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2314.        local c4 = a4 * 3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2315.        local c5 = a5 * 3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2316.        local c6 = a6 * 3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2317.        local c7 = a1 * 15761408\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2318.        c7 = c7 + a7 * 3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2319.        local c8 = a2 * 15761408\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2320.        local c9 = a3 * 15761408\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2321.        local c10 = a4 * 15761408\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2322.        local c11 = a5 * 15761408\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2323.        local c12 = a6 * 15761408\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2324.        local c13 = a7 * 15761408\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2325.        local c14 = 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2326. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2327.        local temp\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2328.        temp = c1 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2329.        c2 = c2 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2330.        c1 = c1 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2331.        temp = c2 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2332.        c3 = c3 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2333.        c2 = c2 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2334.        temp = c3 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2335.        c4 = c4 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2336.        c3 = c3 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2337.        temp = c4 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2338.        c5 = c5 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2339.        c4 = c4 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2340.        temp = c5 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2341.        c6 = c6 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2342.        c5 = c5 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2343.        temp = c6 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2344.        c7 = c7 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2345.        c6 = c6 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2346.        temp = c7 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2347.        c8 = c8 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2348.        c7 = c7 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2349.        temp = c8 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2350.        c9 = c9 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2351.        c8 = c8 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2352.        temp = c9 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2353.        c10 = c10 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2354.        c9 = c9 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2355.        temp = c10 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2356.        c11 = c11 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2357.        c10 = c10 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2358.        temp = c11 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2359.        c12 = c12 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2360.        c11 = c11 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2361.        temp = c12 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2362.        c13 = c13 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2363.        c12 = c12 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2364.        temp = c13 / 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2365.        c14 = c14 + (temp - temp % 1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2366.        c13 = c13 % 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2367. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2368.        return {c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2369.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2370. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2371.    -- Reduces a number from [0, 2p - 1] to [0, p - 1]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2372.    local function reduceModP(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2373.        -- a < p\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2374.        if a[7] < 15761408 or a[7] == 15761408 and a[1] < 3 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2375.            return {unpack(a)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2376.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2377. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2378.        -- a > p\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2379.        local c1 = a[1]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2380.        local c2 = a[2]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2381.        local c3 = a[3]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2382.        local c4 = a[4]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2383.        local c5 = a[5]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2384.        local c6 = a[6]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2385.        local c7 = a[7]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2386. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2387.        c1 = c1 - 3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2388.        c7 = c7 - 15761408\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2389. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2390.        if c1 < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2391.            c2 = c2 - 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2392.            c1 = c1 + 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2393.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2394.        if c2 < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2395.            c3 = c3 - 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2396.            c2 = c2 + 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2397.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2398.        if c3 < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2399.            c4 = c4 - 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2400.            c3 = c3 + 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2401.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2402.        if c4 < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2403.            c5 = c5 - 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2404.            c4 = c4 + 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2405.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2406.        if c5 < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2407.            c6 = c6 - 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2408.            c5 = c5 + 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2409.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2410.        if c6 < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2411.            c7 = c7 - 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2412.            c6 = c6 + 0x1000000\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2413.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2414. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2415.        return {c1, c2, c3, c4, c5, c6, c7}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2416.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2417. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2418.    local function addModP(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2419.        return reduceModP(add(a, b))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2420.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2421. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2422.    local function subModP(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2423.        local result = sub(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2424. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2425.        if result[7] < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2426.            result = add(result, p)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2427.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2428.        \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2429.        return result\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2430.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2431. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2432.    -- Montgomery REDC algorithn\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2433.    -- Reduces a number from [0, p^2 - 1] to [0, p - 1]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2434.    local function REDC(T)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2435.        local m = {unpack(mult({unpack(T, 1, 7)}, pInverse), 1, 7)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2436.        local t = {unpack(addDouble(T, multByP(m)), 8, 14)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2437. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2438.        return reduceModP(t)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2439.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2440. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2441.    local function multModP(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2442.        -- Only works with a, b in Montgomery form\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2443.        return REDC(mult(a, b))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2444.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2445. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2446.    local function squareModP(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2447.        -- Only works with a in Montgomery form\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2448.        return REDC(square(a))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2449.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2450. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2451.    local function montgomeryModP(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2452.        return multModP(a, r2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2453.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2454. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2455.    local function inverseMontgomeryModP(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2456.        local a = {unpack(a)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2457. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2458.        for i = 8, 14 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2459.            a[i] = 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2460.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2461. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2462.        return REDC(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2463.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2464. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2465.    local ONE = montgomeryModP({1, 0, 0, 0, 0, 0, 0})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2466. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2467.    local function expModP(base, exponentBinary)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2468.        local base = {unpack(base)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2469.        local result = {unpack(ONE)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2470. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2471.        for i = 1, 168 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2472.            if exponentBinary[i] == 1 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2473.                result = multModP(result, base)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2474.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2475.            base = squareModP(base)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2476.        end \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2477. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2478.        return result\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2479.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2480. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2481.    return {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2482.        addModP = addModP,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2483.        subModP = subModP,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2484.        multModP = multModP,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2485.        squareModP = squareModP,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2486.        montgomeryModP = montgomeryModP,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2487.        inverseMontgomeryModP = inverseMontgomeryModP,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2488.        expModP = expModP\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2489.    }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2490. end)()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2491. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2492. -- Arithmetic on the Finite Field of Integers modulo q\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2493. -- Where q is the generator's subgroup order.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2494. local modq = (function()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2495.    local isEqual = arith.isEqual\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2496.    local compare = arith.compare\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2497.    local add = arith.add\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2498.    local sub = arith.sub\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2499.    local addDouble = arith.addDouble\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2500.    local mult = arith.mult\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2501.    local square = arith.square\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2502.    local reword = arith.reword\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2503. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2504.    local modQMT\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2505. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2506.    local q = {9622359, 6699217, 13940450, 16775734, 16777215, 16777215, 3940351}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2507.    local qMinusTwoBinary = {1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2508.    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2509.    -- We're using the Montgomery Reduction for fast modular multiplication.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2510.    -- https://en.wikipedia.org/wiki/Montgomery_modular_multiplication \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2511.    -- r = 2^168\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2512.    -- q * qInverse = -1 (mod r)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2513.    -- r2 = r * r (mod q)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2514.    local qInverse = {15218585, 5740955, 3271338, 9903997, 9067368, 7173545, 6988392}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2515.    local r2 = {1336213, 11071705, 9716828, 11083885, 9188643, 1494868, 3306114}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2516. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2517.    -- Reduces a number from [0, 2q - 1] to [0, q - 1]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2518.    local function reduceModQ(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2519.        local result = {unpack(a)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2520. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2521.        if compare(result, q) >= 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2522.            result = sub(result, q)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2523.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2524. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2525.        return setmetatable(result, modQMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2526.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2527. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2528.    local function addModQ(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2529.        return reduceModQ(add(a, b))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2530.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2531. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2532.    local function subModQ(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2533.        local result = sub(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2534. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2535.        if result[7] < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2536.            result = add(result, q)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2537.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2538.        \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2539.        return setmetatable(result, modQMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2540.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2541. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2542.    -- Montgomery REDC algorithn\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2543.    -- Reduces a number from [0, q^2 - 1] to [0, q - 1]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2544.    local function REDC(T)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2545.        local m = {unpack(mult({unpack(T, 1, 7)}, qInverse), 1, 7)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2546.        local t = {unpack(addDouble(T, mult(m, q)), 8, 14)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2547. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2548.        return reduceModQ(t)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2549.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2550. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2551.    local function multModQ(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2552.        -- Only works with a, b in Montgomery form\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2553.        return REDC(mult(a, b))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2554.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2555. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2556.    local function squareModQ(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2557.        -- Only works with a in Montgomery form\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2558.        return REDC(square(a))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2559.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2560. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2561.    local function montgomeryModQ(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2562.        return multModQ(a, r2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2563.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2564. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2565.    local function inverseMontgomeryModQ(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2566.        local a = {unpack(a)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2567. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2568.        for i = 8, 14 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2569.            a[i] = 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2570.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2571. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2572.        return REDC(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2573.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2574. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2575.    local ONE = montgomeryModQ({1, 0, 0, 0, 0, 0, 0})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2576. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2577.    local function expModQ(base, exponentBinary)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2578.        local base = {unpack(base)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2579.        local result = {unpack(ONE)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2580. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2581.        for i = 1, 168 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2582.            if exponentBinary[i] == 1 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2583.                result = multModQ(result, base)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2584.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2585.            base = squareModQ(base)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2586.        end \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2587. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2588.        return result\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2589.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2590. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2591.    local function intExpModQ(base, exponent)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2592.        local base = {unpack(base)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2593.        local result = setmetatable({unpack(ONE)}, modQMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2594. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2595.        if exponent < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2596.            base = expModQ(base, qMinusTwoBinary)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2597.            exponent = -exponent\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2598.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2599. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2600.        while exponent > 0 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2601.            if exponent % 2 == 1 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2602.                result = multModQ(result, base)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2603.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2604.            base = squareModQ(base)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2605.            exponent = exponent / 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2606.            exponent = exponent - exponent % 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2607.        end \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2608. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2609.        return result\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2610.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2611. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2612.    local function encodeModQ(a)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2613.        local result = reword(a, 24, 8)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2614. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2615.        return setmetatable(result, byteTableMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2616.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2617. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2618.    local function decodeModQ(s)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2619.        s = type(s) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" and {unpack(s, 1, 21)} or {tostring(s):byte(1, 21)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2620.        local result = reword(s, 8, 24)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2621.        result[8] = nil\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2622.        result[7] = result[7] % q[7]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2623. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2624.        return setmetatable(result, modQMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2625.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2626. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2627.    local function hashModQ(data)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2628.        local result = decodeModQ(sha256.digest(data))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2629. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2630.        return setmetatable(result, modQMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2631.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2632. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2633.    modQMT = {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2634.        __index = {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2635.            encode = function(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2636.                return encodeModQ(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2637.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2638.        },\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2639. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2640.        __tostring = function(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2641.            return self:encode():toHex()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2642.        end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2643. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2644.        __add = function(self, other)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2645.            if type(self) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2646.                return other + self\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2647.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2648. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2649.            if type(other) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2650.                assert(other < 2^24, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number operand too big\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2651.                other = montgomeryModQ({other, 0, 0, 0, 0, 0, 0})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2652.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2653. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2654.            return addModQ(self, other)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2655.        end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2656. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2657.        __sub = function(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2658.            if type(a) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2659.                assert(a < 2^24, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number operand too big\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2660.                a = montgomeryModQ({a, 0, 0, 0, 0, 0, 0})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2661.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2662. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2663.            if type(b) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2664.                assert(b < 2^24, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number operand too big\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2665.                b = montgomeryModQ({b, 0, 0, 0, 0, 0, 0})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2666.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2667. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2668.            return subModQ(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2669.        end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2670. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2671.        __unm = function(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2672.            return subModQ(q, self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2673.        end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2674. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2675.        __eq = function(self, other)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2676.            return isEqual(self, other)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2677.        end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2678. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2679.        __mul = function(self, other)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2680.            if type(self) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2681.                return other * self\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2682.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2683. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2684.            -- EC point\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2685.            -- Use the point's metatable to handle multiplication\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2686.            if type(other) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" and type(other[1]) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2687.                return other * self\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2688.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2689. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2690.            if type(other) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2691.                assert(other < 2^24, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number operand too big\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2692.                other = montgomeryModQ({other, 0, 0, 0, 0, 0, 0})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2693.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2694. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2695.            return multModQ(self, other)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2696.        end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2697. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2698.        __div = function(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2699.            if type(a) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2700.                assert(a < 2^24, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number operand too big\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2701.                a = montgomeryModQ({a, 0, 0, 0, 0, 0, 0})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2702.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2703. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2704.            if type(b) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2705.                assert(b < 2^24, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number operand too big\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2706.                b = montgomeryModQ({b, 0, 0, 0, 0, 0, 0})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2707.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2708. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2709.            bInv = expModQ(b, qMinusTwoBinary)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2710. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2711.            return multModQ(a, bInv)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2712.        end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2713. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2714.        __pow = function(self, other)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2715.            return intExpModQ(self, other)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2716.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2717.    }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2718. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2719.    return {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2720.        hashModQ = hashModQ,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2721.        randomModQ = randomModQ,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2722.        decodeModQ = decodeModQ,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2723.        inverseMontgomeryModQ = inverseMontgomeryModQ\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2724.    }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2725. end)()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2726. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2727. -- Elliptic curve arithmetic\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2728. local curve = (function()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2729.    ---- About the Curve Itself\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2730.    -- Field Size: 168 bits\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2731.    -- Field Modulus (p): 481 * 2^159 + 3\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2732.    -- Equation: x^2 + y^2 = 1 + 122 * x^2 * y^2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2733.    -- Parameters: Edwards Curve with d = 122\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2734.    -- Curve Order (n): 351491143778082151827986174289773107581916088585564\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2735.    -- Cofactor (h): 4\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2736.    -- Generator Order (q): 87872785944520537956996543572443276895479022146391\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2737.    ---- About the Curve's Security\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2738.    -- Current best attack security: 81.777 bits (Small Subgroup + Rho)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2739.    -- Rho Security: log2(0.884 * sqrt(q)) = 82.777 bits\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2740.    -- Transfer Security? Yes: p ~= q; k > 20\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2741.    -- Field Discriminant Security? Yes:\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2742.    --    t = 27978492958645335688000168\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2743.    --    s = 10\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2744.    --    |D| = 6231685068753619775430107799412237267322159383147 > 2^100\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2745.    -- Rigidity? No, not at all.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2746.    -- XZ/YZ Ladder Security? No: Single coordinate ladders are insecure.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2747.    -- Small Subgroup Security? No.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2748.    -- Invalid Curve Security? Yes: Points are checked before every operation.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2749.    -- Invalid Curve Twist Security? No: Don't use single coordinate ladders.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2750.    -- Completeness? Yes: The curve is complete.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2751.    -- Indistinguishability? Yes (Elligator 2), but not implemented.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2752. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2753.    local isEqual = arith.isEqual\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2754.    local NAF = arith.NAF\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2755.    local reword = arith.reword\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2756.    local multModP = modp.multModP\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2757.    local squareModP = modp.squareModP\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2758.    local addModP = modp.addModP\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2759.    local subModP = modp.subModP\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2760.    local montgomeryModP = modp.montgomeryModP\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2761.    local inverseMontgomeryModP = modp.inverseMontgomeryModP\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2762.    local expModP = modp.expModP\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2763.    local inverseMontgomeryModQ = modq.inverseMontgomeryModQ\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2764.    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2765.    local pointMT\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2766.    local ZERO = {0, 0, 0, 0, 0, 0, 0}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2767.    local ONE = montgomeryModP({1, 0, 0, 0, 0, 0, 0})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2768. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2769.    -- Curve Parameters\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2770.    local d = montgomeryModP({122, 0, 0, 0, 0, 0, 0})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2771.    local p = {3, 0, 0, 0, 0, 0, 15761408}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2772.    local pMinusTwoBinary = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2773.    local pMinusThreeOverFourBinary = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2774.    local G = {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2775.        {6636044, 10381432, 15741790, 2914241, 5785600, 264923, 4550291},\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2776.        {13512827, 8449886, 5647959, 1135556, 5489843, 7177356, 8002203},\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2777.        {unpack(ONE)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2778.    }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2779.    local O = {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2780.        {unpack(ZERO)},\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2781.        {unpack(ONE)},\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2782.        {unpack(ONE)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2783.    }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2784. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2785.    -- Projective Coordinates for Edwards curves for point addition/doubling.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2786.    -- Points are represented as: (X:Y:Z) where x = X/Z and y = Y/Z\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2787.    -- The identity element is represented by (0:1:1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2788.    -- Point operation formulas are available on the EFD:\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2789.    -- https://www.hyperelliptic.org/EFD/g1p/auto-edwards-projective.html\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2790.    local function pointDouble(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2791.        -- 3M + 4S\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2792.        local X1, Y1, Z1 = unpack(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2793. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2794.        local b = addModP(X1, Y1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2795.        local B = squareModP(b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2796.        local C = squareModP(X1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2797.        local D = squareModP(Y1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2798.        local E = addModP(C, D)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2799.        local H = squareModP(Z1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2800.        local J = subModP(E, addModP(H, H))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2801.        local X3 = multModP(subModP(B, E), J)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2802.        local Y3 = multModP(E, subModP(C, D))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2803.        local Z3 = multModP(E, J)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2804.        local P3 = {X3, Y3, Z3}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2805. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2806.        return setmetatable(P3, pointMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2807.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2808. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2809.    local function pointAdd(P1, P2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2810.        -- 10M + 1S\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2811.        local X1, Y1, Z1 = unpack(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2812.        local X2, Y2, Z2 = unpack(P2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2813. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2814.        local A = multModP(Z1, Z2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2815.        local B = squareModP(A)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2816.        local C = multModP(X1, X2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2817.        local D = multModP(Y1, Y2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2818.        local E = multModP(d, multModP(C, D))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2819.        local F = subModP(B, E)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2820.        local G = addModP(B, E)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2821.        local X3 = multModP(A, multModP(F, subModP(multModP(addModP(X1, Y1), addModP(X2, Y2)), addModP(C, D))))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2822.        local Y3 = multModP(A, multModP(G, subModP(D, C)))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2823.        local Z3 = multModP(F, G)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2824.        local P3 = {X3, Y3, Z3}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2825. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2826.        return setmetatable(P3, pointMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2827.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2828. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2829.    local function pointNeg(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2830.        local X1, Y1, Z1 = unpack(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2831. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2832.        local X3 = subModP(ZERO, X1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2833.        local Y3 = {unpack(Y1)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2834.        local Z3 = {unpack(Z1)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2835.        local P3 = {X3, Y3, Z3}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2836. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2837.        return setmetatable(P3, pointMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2838.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2839. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2840.    local function pointSub(P1, P2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2841.        return pointAdd(P1, pointNeg(P2))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2842.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2843. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2844.    -- Converts (X:Y:Z) into (X:Y:1) = (x:y:1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2845.    local function pointScale(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2846.        local X1, Y1, Z1 = unpack(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2847. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2848.        local A = expModP(Z1, pMinusTwoBinary)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2849.        local X3 = multModP(X1, A)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2850.        local Y3 = multModP(Y1, A)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2851.        local Z3 = {unpack(ONE)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2852.        local P3 = {X3, Y3, Z3}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2853. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2854.        return setmetatable(P3, pointMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2855.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2856. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2857.    local function pointIsEqual(P1, P2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2858.        local X1, Y1, Z1 = unpack(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2859.        local X2, Y2, Z2 = unpack(P2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2860. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2861.        local A1 = multModP(X1, Z2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2862.        local B1 = multModP(Y1, Z2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2863.        local A2 = multModP(X2, Z1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2864.        local B2 = multModP(Y2, Z1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2865. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2866.        return isEqual(A1, A2) and isEqual(B1, B2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2867.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2868. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2869.    -- Checks if a projective point satisfies the curve equation\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2870.    local function pointIsOnCurve(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2871.        local X1, Y1, Z1 = unpack(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2872. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2873.        local X12 = squareModP(X1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2874.        local Y12 = squareModP(Y1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2875.        local Z12 = squareModP(Z1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2876.        local Z14 = squareModP(Z12)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2877.        local a = addModP(X12, Y12)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2878.        a = multModP(a, Z12)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2879.        local b = multModP(d, multModP(X12, Y12))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2880.        b = addModP(Z14, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2881. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2882.        return isEqual(a, b)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2883.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2884. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2885.    local function pointIsInf(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2886.        return isEqual(P1[1], ZERO)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2887.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2888. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2889.    -- W-ary Non-Adjacent Form (wNAF) method for scalar multiplication:\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2890.    -- https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#w-ary_non-adjacent_form_(wNAF)_method\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2891.    local function scalarMult(multiplier, P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2892.        -- w = 5\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2893.        local naf = NAF(multiplier, 5)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2894.        local PTable = {P1}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2895.        local P2 = pointDouble(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2896.        local Q = {{unpack(ZERO)}, {unpack(ONE)}, {unpack(ONE)}}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2897. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2898.        for i = 3, 31, 2 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2899.            PTable[i] = pointAdd(PTable[i - 2], P2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2900.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2901. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2902.        for i = #naf, 1, -1 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2903.            Q = pointDouble(Q)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2904. \\\\\\\\\\\\\\\\009\\\\\\\\\\\\\\\\009\\\\\\\\\\\\\\\\009local TMP = naf[i]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2905.            if TMP > 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2906.                Q = pointAdd(Q, PTable[TMP])\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2907.            elseif TMP < 0 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2908.                Q = pointSub(Q, PTable[-TMP])\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2909.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2910.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2911. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2912.        return setmetatable(Q, pointMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2913.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2914. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2915.    -- Lookup table 4-ary NAF method for scalar multiplication by G.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2916.    -- Precomputations for the regular NAF method are done before the multiplication.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2917.    local GTable = {G}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2918.    for i = 2, 168 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2919.        GTable[i] = pointDouble(GTable[i - 1])\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2920.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2921. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2922.    local function scalarMultG(multiplier)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2923.        local naf = NAF(multiplier, 2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2924.        local Q = {{unpack(ZERO)}, {unpack(ONE)}, {unpack(ONE)}}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2925. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2926.        for i = 1, 168 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2927.            if naf[i] == 1 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2928.                Q = pointAdd(Q, GTable[i])\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2929.            elseif naf[i] == -1 then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2930.                Q = pointSub(Q, GTable[i])\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2931.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2932.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2933. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2934.        return setmetatable(Q, pointMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2935.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2936. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2937.    -- Point compression and encoding.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2938.    -- Compresses curve points to 22 bytes.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2939.    local function pointEncode(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2940.        P1 = pointScale(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2941.        local result = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2942.        local x, y = unpack(P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2943.        local temp\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2944. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2945.        -- Encode y\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2946.        result = reword(y, 24, 8)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2947.        -- Encode one bit from x\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2948.        result[22] = x[1] % 2\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2949. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2950.        return setmetatable(result, byteTableMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2951.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2952. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2953.    local function pointDecode(enc)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2954.        enc = type(enc) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" and {unpack(enc, 1, 22)} or {tostring(enc):byte(1, 22)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2955.        --Find x's bit\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2956.        local xbit = enc[22]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2957.        -- Decode y\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2958.        local y = reword(enc, 8, 24)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2959.        y[8] = nil\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2960.        y[7] = y[7] % p[7]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2961.        -- Find {x, -x} using curve equation\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2962.        local y2 = squareModP(y)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2963.        local u = subModP(y2, ONE)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2964.        local v = subModP(multModP(d, y2), ONE)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2965.        local u2 = squareModP(u)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2966.        local u3 = multModP(u, u2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2967.        local u5 = multModP(u3, u2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2968.        local v3 = multModP(v, squareModP(v))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2969.        local w = multModP(u5, v3)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2970.        local x = multModP(u3, multModP(v, expModP(w, pMinusThreeOverFourBinary)))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2971.        -- Use x's bit to find x from {x, -x}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2972.        if x[1] % 2 ~= xbit then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2973.            x = subModP(ZERO, x)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2974.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2975.        local P3 = {x, y, {unpack(ONE)}}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2976. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2977.        return setmetatable(P3, pointMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2978.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2979. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2980.    pointMT = {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2981.        __index = {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2982.            isOnCurve = function(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2983.                return pointIsOnCurve(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2984.            end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2985. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2986.            isInf = function(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2987.                return self:isOnCurve() and pointIsInf(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2988.            end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2989. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2990.            encode = function(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2991.                return pointEncode(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2992.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2993.        },\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2994. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2995.        __tostring = function(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2996.            return self:encode():toHex()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2997.        end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2998. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2999.        __add = function(P1, P2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3000.            assert(P1:isOnCurve(), \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"invalid point\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3001.            assert(P2:isOnCurve(), \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"invalid point\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3002.            \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3003.            return pointAdd(P1, P2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3004.        end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3005. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3006.        __sub = function(P1, P2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3007.            assert(P1:isOnCurve(), \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"invalid point\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3008.            assert(P2:isOnCurve(), \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"invalid point\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3009.            \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3010.            return pointSub(P1, P2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3011.        end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3012. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3013.        __unm = function(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3014.            assert(self:isOnCurve(), \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"invalid point\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3015.            \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3016.            return pointNeg(self)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3017.        end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3018. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3019.        __eq = function(P1, P2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3020.            assert(P1:isOnCurve(), \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"invalid point\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3021.            assert(P2:isOnCurve(), \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"invalid point\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3022.            \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3023.            return pointIsEqual(P1, P2)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3024.        end,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3025. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3026.        __mul = function(P1, s)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3027.            if type(P1) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3028.                return s * P1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3029.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3030. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3031.            if type(s) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3032.                assert(s < 2^24, \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"number multiplier too big\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3033.                s = {s, 0, 0, 0, 0, 0, 0}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3034.            else\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3035.                s = inverseMontgomeryModQ(s)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3036.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3037. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3038.            if P1 == G then\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3039.                return scalarMultG(s)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3040.            else\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3041.                return scalarMult(s, P1)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3042.            end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3043.        end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3044.    }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3045. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3046.    G = setmetatable(G, pointMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3047.    O = setmetatable(O, pointMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3048. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3049.    return {\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3050.        G = G,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3051.        O = O,\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3052.        pointDecode = pointDecode\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3053.    }\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3054. end)()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3055. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3056. local function getNonceFromEpoch()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3057.    local nonce = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3058.    local epoch = os.epoch(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"utc\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3059.    for i = 1, 12 do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3060.        nonce[#nonce + 1] = epoch % 256\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3061.        epoch = epoch / 256\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3062.        epoch = epoch - epoch % 1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3063.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3064. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3065.    return nonce\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3066. end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3067. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3068. local function encrypt(data, key)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3069.    local encKey = sha256.hmac(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"encKey\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", key)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3070.    local macKey = sha256.hmac(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"macKey\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", key)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3071.    local nonce = getNonceFromEpoch()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3072.    local ciphertext = chacha20.crypt(data, encKey, nonce)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3073.    local result = nonce\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3074.    for i = 1, #ciphertext do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3075.        result[#result + 1] = ciphertext[i]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3076.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3077.    local mac = sha256.hmac(result, macKey)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3078.    for i = 1, #mac do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3079.        result[#result + 1] = mac[i]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3080.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3081. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3082.    return setmetatable(result, byteTableMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3083. end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3084. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3085. local function decrypt(data, key)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3086.    local encKey = sha256.hmac(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"encKey\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", key)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3087.    local macKey = sha256.hmac(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"macKey\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", key)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3088.    local mac = sha256.hmac({unpack(data, 1, #data - 32)}, macKey)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3089.    local messageMac = {unpack(data, #data - 31)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3090.    assert(mac:isEqual(messageMac), \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"invalid mac\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3091.    local nonce = {unpack(data, 1, 12)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3092.    local ciphertext = {unpack(data, 13, #data - 32)}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3093.    local result = chacha20.crypt(ciphertext, encKey, nonce)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3094. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3095.    return setmetatable(result, byteTableMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3096. end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3097. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3098. local function keypair(seed)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3099.    seed = seed or random.random()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3100.    local x = modq.hashModQ(seed)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3101.    local Y = curve.G * x\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3102. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3103.    local privateKey = x:encode()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3104.    local publicKey = Y:encode()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3105. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3106.    return privateKey, publicKey\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3107. end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3108. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3109. local function exchange(privateKey, publicKey)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3110.    local x = modq.decodeModQ(privateKey)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3111.    local Y = curve.pointDecode(publicKey)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3112. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3113.    local Z = Y * x\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3114. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3115.    local sharedSecret = sha256.digest(Z:encode())\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3116. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3117.    return sharedSecret\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3118. end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3119. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3120. local function sign(privateKey, message)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3121.    local message = type(message) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" and string.char(unpack(message)) or tostring(message)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3122.    local privateKey = type(privateKey) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" and string.char(unpack(privateKey)) or tostring(privateKey)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3123.    local x = modq.decodeModQ(privateKey)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3124.    local k = modq.hashModQ(message .. privateKey)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3125.    local R = curve.G * k\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3126.    local e = modq.hashModQ(message .. tostring(R))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3127.    local s = k - x * e\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3128. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3129.    e = e:encode()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3130.    s = s:encode()\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3131. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3132.    local result = e\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3133.    for i = 1, #s do\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3134.        result[#result + 1] = s[i]\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3135.    end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3136. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3137.    return setmetatable(result, byteTableMT)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3138. end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3139. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3140. local function verify(publicKey, message, signature)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3141.    local message = type(message) == \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"table\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" and string.char(unpack(message)) or tostring(message)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3142.    Y = curve.pointDecode(publicKey)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3143.    e = modq.decodeModQ({unpack(signature, 1, #signature / 2)})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3144.    s = modq.decodeModQ({unpack(signature, #signature / 2 + 1)})\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3145.    Rv = curve.G * s + Y * e\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3146.    ev = modq.hashModQ(message .. tostring(Rv))\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3147. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3148.    return ev == e\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3149. end\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3150. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3151. local API = {}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3152. API.ChaCha20 = chacha20\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3153. API.SHA256 = sha256\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3154. API.random = random\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3155. API.encrypt = encrypt\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3156. API.decrypt = decrypt\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3157. API.keypair = keypair\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3158. API.exchange = exchange\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3159. API.sign = sign\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3160. API.verify = verify\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3161. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3162. __declare(\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"crypt\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\", API)\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3163. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3164. return 1\\\\\\\\\\\\\\\"\\\\\\\",\\\\\\\
  3165. }\\\",\\\
  3166.  \\\"F:esiboot.b\\\",\\\
  3167.  \\\"\\\\\\\"local sr = shell.run\\\\\\\\\\\\\\\
  3168. local args = {...}\\\\\\\\\\\\\\\
  3169. local bootConfigDefaults = {}\\\\\\\\\\\\\\\
  3170. bootConfigDefaults.script = \\\\\\\\\\\\\\\"Orbital\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\
  3171. \\\\\\\\\\\\\\\
  3172. local function boot_handleBootElement(str)\\\\\\\\\\\\\\\
  3173.   local s1 = \\\\\\\\\\\\\\\"                                           \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\
  3174.   local n1 = s1:len()\\\\\\\\\\\\\\\
  3175.   local n2 = str:len()\\\\\\\\\\\\\\\
  3176.   local s2 = string.sub(s1, 1, n1-n2)\\\\\\\\\\\\\\\
  3177.   return \\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\"..str..s2..\\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\
  3178. end\\\\\\\\\\\\\\\
  3179. \\\\\\\\\\\\\\\
  3180. local function boot_mprint(array, this, x, y, h, g)\\\\\\\\\\\\\\\
  3181.   local c1 = term.getBackgroundColor()\\\\\\\\\\\\\\\
  3182.   local c2 = term.getTextColor()\\\\\\\\\\\\\\\
  3183.   term.setTextColor(colors.lightGray)\\\\\\\\\\\\\\\
  3184.   for i = 1, #array do\\\\\\\\\\\\\\\
  3185.      term.setCursorPos(x, y)\\\\\\\\\\\\\\\
  3186.      --Check if option selected\\\\\\\\\\\\\\\
  3187.      if i == this then \\\\\\\\\\\\\\\
  3188.      --Option selected   \\\\\\\\\\\\\\\
  3189.         term.setBackgroundColor(h)\\\\\\\\\\\\\\\
  3190.         term.setTextColor(g)\\\\\\\\\\\\\\\
  3191.      else \\\\\\\\\\\\\\\
  3192.      --Option NOT selected \\\\\\\\\\\\\\\
  3193.         term.setBackgroundColor(g)\\\\\\\\\\\\\\\
  3194.         term.setTextColor(h)\\\\\\\\\\\\\\\
  3195.      end\\\\\\\\\\\\\\\
  3196.      --Print the string\\\\\\\\\\\\\\\
  3197.      term.write(boot_handleBootElement(array[i]))\\\\\\\\\\\\\\\
  3198.      y = y + 1 \\\\\\\\\\\\\\\
  3199.   end\\\\\\\\\\\\\\\
  3200.   term.setBackgroundColor(c1)\\\\\\\\\\\\\\\
  3201.   term.setTextColor(c2)\\\\\\\\\\\\\\\
  3202. end\\\\\\\\\\\\\\\
  3203. \\\\\\\\\\\\\\\
  3204. local function boot_drawBootMenu(array, pos_x, pos_y, highlight, generic)\\\\\\\\\\\\\\\
  3205.   local select = 1\\\\\\\\\\\\\\\
  3206.   local x, y = term.getCursorPos()\\\\\\\\\\\\\\\
  3207.   \\\\\\\\\\\\\\\
  3208.   while true do\\\\\\\\\\\\\\\
  3209.      term.setCursorPos(x, y)\\\\\\\\\\\\\\\
  3210.      boot_mprint(array, select, pos_x, pos_y, highlight, generic)\\\\\\\\\\\\\\\
  3211.      event, key = os.pullEvent(\\\\\\\\\\\\\\\"key\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3212.      --Enter\\\\\\\\\\\\\\\
  3213.      if key == 28 then \\\\\\\\\\\\\\\
  3214.         return select \\\\\\\\\\\\\\\
  3215.      end\\\\\\\\\\\\\\\
  3216.      \\\\\\\\\\\\\\\
  3217.      if #array > 1 then\\\\\\\\\\\\\\\
  3218.         --Arrow UP or W key\\\\\\\\\\\\\\\
  3219.         if key == 200 or key == 17 then \\\\\\\\\\\\\\\
  3220.      \\\\\\\\009\\\\\\\\009    select = select - 1 \\\\\\\\\\\\\\\
  3221. \\\\\\\\009\\\\\\\\009\\\\\\\\009\\\\\\\\\\\\\\\
  3222.            if select < 1 then \\\\\\\\\\\\\\\
  3223.               select = #array \\\\\\\\\\\\\\\
  3224.            end\\\\\\\\\\\\\\\
  3225.         --Arrow Down or S key\\\\\\\\\\\\\\\
  3226.         elseif key == 208 or key == 31 then \\\\\\\\\\\\\\\
  3227.      \\\\\\\\009\\\\\\\\009    select = select + 1     \\\\\\\\\\\\\\\
  3228.        \\\\\\\\009\\\\\\\\009\\\\\\\\009 if select > #array then select = 1 end\\\\\\\\\\\\\\\
  3229.  \\\\\\\\009      end\\\\\\\\\\\\\\\
  3230.      end   \\\\\\\\\\\\\\\
  3231.   end\\\\\\\\\\\\\\\
  3232. end\\\\\\\\\\\\\\\
  3233. \\\\\\\\\\\\\\\
  3234. local function boot_printColoredTextLine(y, txt, bg, fg)\\\\\\\\\\\\\\\
  3235. term.setCursorPos(1, y)\\\\\\\\\\\\\\\
  3236. term.setBackgroundColor(bg or colors.lightGray)\\\\\\\\\\\\\\\
  3237. term.write(\\\\\\\\\\\\\\\"                                                   \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3238. term.setCursorPos(1, y)\\\\\\\\\\\\\\\
  3239. term.setTextColor(fg or colors.black)\\\\\\\\\\\\\\\
  3240. print(txt)\\\\\\\\\\\\\\\
  3241. term.setBackgroundColor(colors.black)\\\\\\\\\\\\\\\
  3242. term.setTextColor(colors.white)\\\\\\\\\\\\\\\
  3243. end\\\\\\\\\\\\\\\
  3244. \\\\\\\\\\\\\\\
  3245. __declare(\\\\\\\\\\\\\\\"drawBootManager\\\\\\\\\\\\\\\", nil)\\\\\\\\\\\\\\\
  3246. \\\\\\\\\\\\\\\
  3247. local function drawBootManager(opt)\\\\\\\\\\\\\\\
  3248.    term.setBackgroundColor(colors.black)\\\\\\\\\\\\\\\
  3249.    term.clear()\\\\\\\\\\\\\\\
  3250.    term.setCursorPos(1,1)\\\\\\\\\\\\\\\
  3251. \\\\\\\\009if not opt then\\\\\\\\\\\\\\\
  3252.        boot_printColoredTextLine(2, \\\\\\\\\\\\\\\"             Orbital Boot Manager v3.1             \\\\\\\\\\\\\\\", colors.lightGray, colors.black)\\\\\\\\\\\\\\\
  3253.        boot_printColoredTextLine(18, \\\\\\\\\\\\\\\" F2=ESI Setup                        F10=Boot Menu \\\\\\\\\\\\\\\", colors.lightGray, colors.black)\\\\\\\\\\\\\\\
  3254. \\\\\\\\009else\\\\\\\\\\\\\\\
  3255.        boot_printColoredTextLine(2, \\\\\\\\\\\\\\\"             Orbital Boot Manager v3.1             \\\\\\\\\\\\\\\", colors.red, colors.black)\\\\\\\\\\\\\\\
  3256.        boot_printColoredTextLine(18, \\\\\\\\\\\\\\\" CTRL+R=Reboot                                     \\\\\\\\\\\\\\\", colors.red, colors.black)\\\\\\\\\\\\\\\
  3257. \\\\\\\\009end\\\\\\\\\\\\\\\
  3258. end\\\\\\\\\\\\\\\
  3259. \\\\\\\\\\\\\\\
  3260. local esiTable = {}\\\\\\\\\\\\\\\
  3261. esiTable.UIBootMenu = boot_drawBootMenu\\\\\\\\\\\\\\\
  3262. esiTable.UIHandleElement = boot_handleBootElement\\\\\\\\\\\\\\\
  3263. esiTable.UIColoredLine = boot_printColoredTextLine\\\\\\\\\\\\\\\
  3264. esiTable.UIInit = drawBootManager\\\\\\\\\\\\\\\
  3265. esiTable.LoadBootConfig = function()\\\\\\\\\\\\\\\
  3266. if not fs.exists(\\\\\\\\\\\\\\\"/boot/esi/config.dat\\\\\\\\\\\\\\\") then\\\\\\\\\\\\\\\
  3267.  return nil\\\\\\\\\\\\\\\
  3268. end\\\\\\\\\\\\\\\
  3269. local lf = fs.open(\\\\\\\\\\\\\\\"/boot/esi/config.dat\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3270. local contents = lf.readAll()\\\\\\\\\\\\\\\
  3271. lf.close()\\\\\\\\\\\\\\\
  3272. return textutils.unserialize(contents) \\\\\\\\\\\\\\\
  3273. end\\\\\\\\\\\\\\\
  3274. esiTable.SaveBootConfig = function(cTable)\\\\\\\\\\\\\\\
  3275. local sf = fs.open(\\\\\\\\\\\\\\\"/boot/esi/config.dat\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3276. sf.write(textutils.serialize(cTable))\\\\\\\\\\\\\\\
  3277. sf.close()\\\\\\\\\\\\\\\
  3278. return true\\\\\\\\\\\\\\\
  3279. end\\\\\\\\\\\\\\\
  3280. esiTable.Finalize = function()\\\\\\\\\\\\\\\
  3281. __declare(\\\\\\\\\\\\\\\"RunInternal\\\\\\\\\\\\\\\", nil)\\\\\\\\\\\\\\\
  3282. __declare(\\\\\\\\\\\\\\\"RunMap\\\\\\\\\\\\\\\", nil)\\\\\\\\\\\\\\\
  3283. __declare(\\\\\\\\\\\\\\\"UserMode\\\\\\\\\\\\\\\", nil)\\\\\\\\\\\\\\\
  3284. __declare(\\\\\\\\\\\\\\\"Boot\\\\\\\\\\\\\\\", nil)\\\\\\\\\\\\\\\
  3285. __declare(\\\\\\\\\\\\\\\"RunExternal\\\\\\\\\\\\\\\", nil)\\\\\\\\\\\\\\\
  3286. __declare_api(\\\\\\\\\\\\\\\"ESI\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"Finalize\\\\\\\\\\\\\\\", nil)\\\\\\\\\\\\\\\
  3287. __declare_api(\\\\\\\\\\\\\\\"ESI\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"RunScript\\\\\\\\\\\\\\\", nil)\\\\\\\\\\\\\\\
  3288. end\\\\\\\\\\\\\\\
  3289. esiTable.RunScript = function(s)\\\\\\\\\\\\\\\
  3290. __declare(\\\\\\\\\\\\\\\"RunInternal\\\\\\\\\\\\\\\", function(m)\\\\\\\\\\\\\\\
  3291. dofile(\\\\\\\\\\\\\\\"/boot/esi/\\\\\\\\\\\\\\\"..m..\\\\\\\\\\\\\\\".b\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3292. end)\\\\\\\\\\\\\\\
  3293. __declare(\\\\\\\\\\\\\\\"RunMap\\\\\\\\\\\\\\\", function(m)\\\\\\\\\\\\\\\
  3294. sr(\\\\\\\\\\\\\\\"/boot/\\\\\\\\\\\\\\\"..m..\\\\\\\\\\\\\\\".map\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3295. end)\\\\\\\\\\\\\\\
  3296. __declare(\\\\\\\\\\\\\\\"UserMode\\\\\\\\\\\\\\\", function(null)\\\\\\\\\\\\\\\
  3297. sr(\\\\\\\\\\\\\\\"/bin/sh\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3298. end)\\\\\\\\\\\\\\\
  3299. __declare(\\\\\\\\\\\\\\\"Boot\\\\\\\\\\\\\\\", function(k)\\\\\\\\\\\\\\\
  3300. dofile(\\\\\\\\\\\\\\\"/boot/kernel/\\\\\\\\\\\\\\\"..k)\\\\\\\\\\\\\\\
  3301. end)\\\\\\\\\\\\\\\
  3302. __declare(\\\\\\\\\\\\\\\"RunExternal\\\\\\\\\\\\\\\", function(f)\\\\\\\\\\\\\\\
  3303. dofile(\\\\\\\\\\\\\\\"/boot/\\\\\\\\\\\\\\\"..f)\\\\\\\\\\\\\\\
  3304. end)\\\\\\\\\\\\\\\
  3305. sr(\\\\\\\\\\\\\\\"/boot/esi/scripts/\\\\\\\\\\\\\\\"..s..\\\\\\\\\\\\\\\".script\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3306. end\\\\\\\\\\\\\\\
  3307. \\\\\\\\\\\\\\\
  3308. __declare(\\\\\\\\\\\\\\\"ESI\\\\\\\\\\\\\\\", esiTable)\\\\\\\\\\\\\\\
  3309. \\\\\\\\\\\\\\\
  3310. local conf = ESI.LoadBootConfig()\\\\\\\\\\\\\\\
  3311. \\\\\\\\\\\\\\\
  3312. if not conf then\\\\\\\\\\\\\\\
  3313.    ESI.SaveBootConfig(bootConfigDefaults)\\\\\\\\\\\\\\\
  3314.    drawBootManager(true)\\\\\\\\\\\\\\\
  3315.    term.setBackgroundColor(colors.black)\\\\\\\\\\\\\\\
  3316.    term.setTextColor(colors.red)\\\\\\\\009\\\\\\\\\\\\\\\
  3317. \\\\\\\\009term.setCursorPos(2,4)\\\\\\\\\\\\\\\
  3318. \\\\\\\\009print(\\\\\\\\\\\\\\\"The Orbital Boot Manager was unable to continue\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3319. \\\\\\\\009term.setCursorPos(2,5)\\\\\\\\\\\\\\\
  3320. \\\\\\\\009print(\\\\\\\\\\\\\\\"the booting process.\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3321. \\\\\\\\009term.setCursorPos(2,7)\\\\\\\\\\\\\\\
  3322. \\\\\\\\009print(\\\\\\\\\\\\\\\"Status:\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3323. \\\\\\\\009term.setCursorPos(2,8)\\\\\\\\\\\\\\\
  3324. \\\\\\\\009print(\\\\\\\\\\\\\\\"ESI_CONFIGURATION_MISSING (0x00000001)\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3325. \\\\\\\\009term.setCursorPos(2,10)\\\\\\\\\\\\\\\
  3326. \\\\\\\\009print(\\\\\\\\\\\\\\\"Information:\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3327. \\\\\\\\009term.setCursorPos(2,11)\\\\\\\\\\\\\\\
  3328. \\\\\\\\009print(\\\\\\\\\\\\\\\"The /boot/esi/config.dat file is missing.\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3329. \\\\\\\\009term.setCursorPos(2,12)\\\\\\\\\\\\\\\
  3330. \\\\\\\\009print(\\\\\\\\\\\\\\\"A default file will be generated after rebooting.\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3331.    while true do\\\\\\\\\\\\\\\
  3332. \\\\\\\\009    sleep(1)\\\\\\\\\\\\\\\
  3333. \\\\\\\\009end\\\\\\\\\\\\\\\
  3334. end\\\\\\\\\\\\\\\
  3335. \\\\\\\\\\\\\\\
  3336. local secondsPast = 0\\\\\\\\\\\\\\\
  3337. local timerID = os.startTimer( 1 )\\\\\\\\\\\\\\\
  3338. \\\\\\\\\\\\\\\
  3339. ESI.UIInit(false)\\\\\\\\\\\\\\\
  3340. term.setBackgroundColor(colors.black)\\\\\\\\\\\\\\\
  3341. term.setTextColor(colors.lightGray)\\\\\\\\009\\\\\\\\\\\\\\\
  3342. term.setCursorPos(2,4)\\\\\\\\\\\\\\\
  3343. print(\\\\\\\\\\\\\\\"Extensible System Interface (ESI)\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3344. term.setCursorPos(2,6)\\\\\\\\\\\\\\\
  3345. print(\\\\\\\\\\\\\\\"Computer ID: \\\\\\\\\\\\\\\"..tostring(os.getComputerID()))\\\\\\\\\\\\\\\
  3346. term.setCursorPos(2,7)\\\\\\\\\\\\\\\
  3347. print(\\\\\\\\\\\\\\\"Hostname: \\\\\\\\\\\\\\\"..tostring(os.getComputerLabel() or \\\\\\\\\\\\\\\"N/A\\\\\\\\\\\\\\\"))\\\\\\\\\\\\\\\
  3348. \\\\\\\\\\\\\\\
  3349. sleep(0.25)\\\\\\\\\\\\\\\
  3350. \\\\\\\\\\\\\\\
  3351. for k, file in pairs(fs.list(\\\\\\\\\\\\\\\"/boot/esi/drivers\\\\\\\\\\\\\\\")) do\\\\\\\\\\\\\\\
  3352. if not dofile(\\\\\\\\\\\\\\\"/boot/esi/drivers/\\\\\\\\\\\\\\\"..file) then\\\\\\\\\\\\\\\
  3353.    drawBootManager(true)\\\\\\\\\\\\\\\
  3354.    term.setBackgroundColor(colors.black)\\\\\\\\\\\\\\\
  3355.    term.setTextColor(colors.red)\\\\\\\\009\\\\\\\\\\\\\\\
  3356. \\\\\\\\009term.setCursorPos(2,4)\\\\\\\\\\\\\\\
  3357. \\\\\\\\009print(\\\\\\\\\\\\\\\"The Orbital Boot Manager was unable to continue\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3358. \\\\\\\\009term.setCursorPos(2,5)\\\\\\\\\\\\\\\
  3359. \\\\\\\\009print(\\\\\\\\\\\\\\\"the booting process.\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3360. \\\\\\\\009term.setCursorPos(2,7)\\\\\\\\\\\\\\\
  3361. \\\\\\\\009print(\\\\\\\\\\\\\\\"Status:\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3362. \\\\\\\\009term.setCursorPos(2,8)\\\\\\\\\\\\\\\
  3363. \\\\\\\\009print(\\\\\\\\\\\\\\\"DRIVER_LOAD_FAILURE (0x00000003)\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3364. \\\\\\\\009term.setCursorPos(2,10)\\\\\\\\\\\\\\\
  3365. \\\\\\\\009print(\\\\\\\\\\\\\\\"Information:\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3366. \\\\\\\\009term.setCursorPos(2,11)\\\\\\\\\\\\\\\
  3367. \\\\\\\\009print(\\\\\\\\\\\\\\\"The following driver failed to load:\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3368. \\\\\\\\009term.setCursorPos(2,12)\\\\\\\\\\\\\\\
  3369. \\\\\\\\009print(\\\\\\\\\\\\\\\"/boot/esi/drivers/\\\\\\\\\\\\\\\"..file)\\\\\\\\\\\\\\\
  3370.    while true do\\\\\\\\\\\\\\\
  3371. \\\\\\\\009    sleep(1)\\\\\\\\\\\\\\\
  3372. \\\\\\\\009end\\\\\\\\\\\\\\\
  3373. else\\\\\\\\\\\\\\\
  3374.  term.setCursorPos(2,8+k) \\\\\\\\\\\\\\\
  3375.  print(\\\\\\\\\\\\\\\"Loaded driver: \\\\\\\\\\\\\\\"..file)\\\\\\\\\\\\\\\
  3376. end\\\\\\\\\\\\\\\
  3377. end\\\\\\\\\\\\\\\
  3378. \\\\\\\\\\\\\\\
  3379. sleep(0.25)\\\\\\\\\\\\\\\
  3380. \\\\\\\\\\\\\\\
  3381. term.setCursorPos(2,16)\\\\\\\\\\\\\\\
  3382. print(\\\\\\\\\\\\\\\"Booting active kernel...\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3383. \\\\\\\\\\\\\\\
  3384. while true do\\\\\\\\\\\\\\\
  3385. local event, value = os.pullEvent()\\\\\\\\\\\\\\\
  3386. --sleep(0.1)\\\\\\\\\\\\\\\
  3387. if event == \\\\\\\\\\\\\\\"timer\\\\\\\\\\\\\\\" and value == timerID then\\\\\\\\\\\\\\\
  3388.  secondsPast = secondsPast + 1 -- Increment secondsPast by one, a second has passed\\\\\\\\\\\\\\\
  3389.  if secondsPast == 3 then\\\\\\\\\\\\\\\
  3390.   --sleep(0.1)\\\\\\\\\\\\\\\
  3391.   ESI.UIColoredLine(18, \\\\\\\\\\\\\\\"                                                   \\\\\\\\\\\\\\\", colors.lightGray, colors.black)\\\\\\\\\\\\\\\
  3392.   break\\\\\\\\\\\\\\\
  3393.  else\\\\\\\\\\\\\\\
  3394.   timerID = os.startTimer( 1 )\\\\\\\\\\\\\\\
  3395.  end\\\\\\\\\\\\\\\
  3396. elseif event == \\\\\\\\\\\\\\\"key\\\\\\\\\\\\\\\" and value == 60 then\\\\\\\\\\\\\\\
  3397.  break\\\\\\\\\\\\\\\
  3398. end\\\\\\\\\\\\\\\
  3399. end\\\\\\\\\\\\\\\
  3400. \\\\\\\\\\\\\\\
  3401. if secondsPast == 3 then\\\\\\\\\\\\\\\
  3402. ESI.RunScript(conf.script)\\\\\\\\\\\\\\\
  3403. else\\\\\\\\\\\\\\\
  3404. --sr(\\\\\\\\\\\\\\\"esiconfig\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3405. end\\\\\\\"\\\",\\\
  3406.  \\\"F:esiconfig.b\\\",\\\
  3407.  \\\"\\\\\\\"local function boot_handleBootElement(str)\\\\\\\\\\\\\\\
  3408.   local s1 = \\\\\\\\\\\\\\\"                     \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\
  3409.   local n1 = s1:len()\\\\\\\\\\\\\\\
  3410.   local n2 = str:len()\\\\\\\\\\\\\\\
  3411.   local s2 = string.sub(s1, 1, n1-n2)\\\\\\\\\\\\\\\
  3412.   return \\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\"..str..s2..\\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\
  3413. end\\\\\\\\\\\\\\\
  3414. \\\\\\\\\\\\\\\
  3415. local function boot_mprint(array, this, x, y, h, g)\\\\\\\\\\\\\\\
  3416.   local c1 = term.getBackgroundColor()\\\\\\\\\\\\\\\
  3417.   local c2 = term.getTextColor()\\\\\\\\\\\\\\\
  3418.   term.setTextColor(colors.lightGray)\\\\\\\\\\\\\\\
  3419.   for i = 1, #array do\\\\\\\\\\\\\\\
  3420.      term.setCursorPos(x, y)\\\\\\\\\\\\\\\
  3421.      --Check if option selected\\\\\\\\\\\\\\\
  3422.      if i == this then \\\\\\\\\\\\\\\
  3423.      --Option selected   \\\\\\\\\\\\\\\
  3424.         term.setBackgroundColor(h)\\\\\\\\\\\\\\\
  3425.         term.setTextColor(g)\\\\\\\\\\\\\\\
  3426.      else \\\\\\\\\\\\\\\
  3427.      --Option NOT selected \\\\\\\\\\\\\\\
  3428.         term.setBackgroundColor(g)\\\\\\\\\\\\\\\
  3429.         term.setTextColor(h)\\\\\\\\\\\\\\\
  3430.      end\\\\\\\\\\\\\\\
  3431.      --Print the string\\\\\\\\\\\\\\\
  3432.      term.write(boot_handleBootElement(array[i]))\\\\\\\\\\\\\\\
  3433.      y = y + 1 \\\\\\\\\\\\\\\
  3434.   end\\\\\\\\\\\\\\\
  3435.   term.setBackgroundColor(c1)\\\\\\\\\\\\\\\
  3436.   term.setTextColor(c2)\\\\\\\\\\\\\\\
  3437. end\\\\\\\\\\\\\\\
  3438. \\\\\\\\\\\\\\\
  3439. local function boot_drawBootMenu(array, pos_x, pos_y, highlight, generic)\\\\\\\\\\\\\\\
  3440.   local select = 1\\\\\\\\\\\\\\\
  3441.   local x, y = term.getCursorPos()\\\\\\\\\\\\\\\
  3442.   \\\\\\\\\\\\\\\
  3443.   while true do\\\\\\\\\\\\\\\
  3444.      term.setCursorPos(x, y)\\\\\\\\\\\\\\\
  3445.      boot_mprint(array, select, pos_x, pos_y, highlight, generic)\\\\\\\\\\\\\\\
  3446.      event, key = os.pullEvent(\\\\\\\\\\\\\\\"key\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3447.      --Enter\\\\\\\\\\\\\\\
  3448.      if key == 28 then \\\\\\\\\\\\\\\
  3449.         return select \\\\\\\\\\\\\\\
  3450.      end\\\\\\\\\\\\\\\
  3451.      \\\\\\\\\\\\\\\
  3452.      if #array > 1 then\\\\\\\\\\\\\\\
  3453.         --Arrow UP or W key\\\\\\\\\\\\\\\
  3454.         if key == 200 or key == 17 then \\\\\\\\\\\\\\\
  3455.      \\\\\\\\009\\\\\\\\009    select = select - 1 \\\\\\\\\\\\\\\
  3456. \\\\\\\\009\\\\\\\\009\\\\\\\\009\\\\\\\\\\\\\\\
  3457.            if select < 1 then \\\\\\\\\\\\\\\
  3458.               select = #array \\\\\\\\\\\\\\\
  3459.            end\\\\\\\\\\\\\\\
  3460.         --Arrow Down or S key\\\\\\\\\\\\\\\
  3461.         elseif key == 208 or key == 31 then \\\\\\\\\\\\\\\
  3462.      \\\\\\\\009\\\\\\\\009    select = select + 1     \\\\\\\\\\\\\\\
  3463.        \\\\\\\\009\\\\\\\\009\\\\\\\\009 if select > #array then select = 1 end\\\\\\\\\\\\\\\
  3464.  \\\\\\\\009      end\\\\\\\\\\\\\\\
  3465.      end   \\\\\\\\\\\\\\\
  3466.   end\\\\\\\\\\\\\\\
  3467. end\\\\\\\\\\\\\\\
  3468. \\\\\\\\\\\\\\\
  3469. term.clear()\\\\\\\\\\\\\\\
  3470. boot_drawBootMenu({boot_handleBootElement(\\\\\\\\\\\\\\\"Darwin Developer Preview 0.1.0.7\\\\\\\\\\\\\\\"), boot_handleBootElement(\\\\\\\\\\\\\\\"Tesseract Bootstrap 1.0.0.0\\\\\\\\\\\\\\\"), boot_handleBootElement(\\\\\\\\\\\\\\\"aaaaaaaaaa\\\\\\\\\\\\\\\")}, 2, 2, colors.lightGray, colors.black)\\\\\\\"\\\",\\\
  3471.  \\\"D:scripts\\\",\\\
  3472.  \\\"{\\\\\\\
  3473.  \\\\\\\"F:Orbital.script\\\\\\\",\\\\\\\
  3474.  \\\\\\\"\\\\\\\\\\\\\\\"-- Example ESI boot script.\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3475. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3476. RunMap \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"kernel\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" -- run kernel.map\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3477. RunMap \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"security\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" -- run security.map\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3478. Boot \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"darwin-rolling-0.1.0.7\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" -- boot the kernel\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  3479. UserMode \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"Default\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" -- go user mode\\\\\\\\\\\\\\\"\\\\\\\",\\\\\\\
  3480. }\\\",\\\
  3481. }\",\
  3482.  \"D:kernel\",\
  3483.  \"{\\\
  3484.  \\\"F:darwin-rolling-0.1.0.7\\\",\\\
  3485.  \\\"\\\\\\\"-- @PRODUCTNAME Darwin\\\\\\\\\\\\\\\
  3486. -- @VERSION 0.0.4.6\\\\\\\\\\\\\\\
  3487. -- @RELEASETYPE rolling\\\\\\\\\\\\\\\
  3488. -- @SKU Developer Preview\\\\\\\\\\\\\\\
  3489. \\\\\\\\\\\\\\\
  3490. --term.clear()\\\\\\\\\\\\\\\
  3491. \\\\\\\\\\\\\\\
  3492. os.version = function()\\\\\\\\\\\\\\\
  3493. return \\\\\\\\\\\\\\\"Orbital 0.1.0.7 Developer Preview\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\
  3494. end\\\\\\\\\\\\\\\
  3495. \\\\\\\\\\\\\\\
  3496. if not dofile(\\\\\\\\\\\\\\\"/boot/kernel.map\\\\\\\\\\\\\\\") then\\\\\\\\\\\\\\\
  3497. printError(\\\\\\\\\\\\\\\"[ X ] Failed to initialize kernel library\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3498. while true do\\\\\\\\\\\\\\\
  3499.  coroutine.yield()\\\\\\\\\\\\\\\
  3500. end\\\\\\\\\\\\\\\
  3501. end\\\\\\\\\\\\\\\
  3502. \\\\\\\\\\\\\\\
  3503. __declare(\\\\\\\\\\\\\\\"__DEBUG\\\\\\\\\\\\\\\", __kstruct({true}))\\\\\\\\\\\\\\\
  3504. \\\\\\\\\\\\\\\
  3505. n = 1\\\\\\\\\\\\\\\
  3506. for k, file in pairs(fs.list(\\\\\\\\\\\\\\\"/lib\\\\\\\\\\\\\\\")) do\\\\\\\\\\\\\\\
  3507. if string.sub(file, -3) == \\\\\\\\\\\\\\\".so\\\\\\\\\\\\\\\" and file ~= \\\\\\\\\\\\\\\"libstdlua.2.so\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\
  3508.  term.setCursorPos(2,3 + n)\\\\\\\\\\\\\\\
  3509.  __kload(\\\\\\\\\\\\\\\"/lib/\\\\\\\\\\\\\\\"..file) -- attempting to hook the file\\\\\\\\\\\\\\\
  3510.  n = k\\\\\\\\\\\\\\\
  3511. else\\\\\\\\\\\\\\\
  3512.  n = k - 1\\\\\\\\\\\\\\\
  3513. end\\\\\\\\\\\\\\\
  3514. end\\\\\\\\\\\\\\\
  3515. \\\\\\\\\\\\\\\
  3516. -- finalize kernel-mode init\\\\\\\\\\\\\\\
  3517. __kfinalize()\\\\\\\\\\\\\\\
  3518. \\\\\\\\\\\\\\\
  3519. sleep(0.5)\\\\\\\\\\\\\\\
  3520. \\\\\\\\\\\\\\\
  3521. -- output\\\\\\\\\\\\\\\
  3522. --term.setCursorPos(2,8)\\\\\\\\\\\\\\\
  3523. --printk(1, \\\\\\\\\\\\\\\"Darwin kernel loaded\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3524. \\\\\\\\\\\\\\\
  3525. sleep(2)\\\\\\\\\\\\\\\
  3526. \\\\\\\\\\\\\\\
  3527. term.clear()\\\\\\\\\\\\\\\
  3528. term.setCursorPos(1,1)\\\\\\\"\\\",\\\
  3529.  \\\"F:tesseract-bootstrap-1.0\\\",\\\
  3530.  \\\"\\\\\\\"-- @PRODUCTNAME Tesseract\\\\\\\\\\\\\\\
  3531. -- @VERSION 1.0.0.0\\\\\\\\\\\\\\\
  3532. -- @RELEASETYPE release\\\\\\\\\\\\\\\
  3533. -- @SKU Bootstrap\\\\\\\\\\\\\\\
  3534. \\\\\\\\\\\\\\\
  3535. local temp_kernel = [[\\\\\\\\\\\\\\\
  3536. -- Halt the system completely, yield all coroutines\\\\\\\\\\\\\\\
  3537. local function halt()\\\\\\\\\\\\\\\
  3538. while true do\\\\\\\\\\\\\\\
  3539.  coroutine.create(function() while true do coroutine.yield() end end)\\\\\\\\\\\\\\\
  3540.  coroutine.yield()\\\\\\\\\\\\\\\
  3541. end\\\\\\\\\\\\\\\
  3542. end\\\\\\\\\\\\\\\
  3543. \\\\\\\\\\\\\\\
  3544. -- Low-level routines\\\\\\\\\\\\\\\
  3545. function traverseKey(array, text)\\\\\\\\\\\\\\\
  3546. for k,v in pairs(array) do\\\\\\\\\\\\\\\
  3547.  if v == text then\\\\\\\\\\\\\\\
  3548.   return true, k\\\\\\\\\\\\\\\
  3549.  end\\\\\\\\\\\\\\\
  3550. end\\\\\\\\\\\\\\\
  3551. return false, nil\\\\\\\\\\\\\\\
  3552. end\\\\\\\\\\\\\\\
  3553. \\\\\\\\\\\\\\\
  3554. function traverseValue(array, text)\\\\\\\\\\\\\\\
  3555. for k,v in pairs(array) do\\\\\\\\\\\\\\\
  3556.  if k == text then\\\\\\\\\\\\\\\
  3557.   return true, v\\\\\\\\\\\\\\\
  3558.  end\\\\\\\\\\\\\\\
  3559. end\\\\\\\\\\\\\\\
  3560. return false, nil\\\\\\\\\\\\\\\
  3561. end\\\\\\\\\\\\\\\
  3562. \\\\\\\\\\\\\\\
  3563. function findKey(array, text)\\\\\\\\\\\\\\\
  3564. for k,v in pairs(array) do\\\\\\\\\\\\\\\
  3565.  if k == text then\\\\\\\\\\\\\\\
  3566.   return true, k\\\\\\\\\\\\\\\
  3567.  end\\\\\\\\\\\\\\\
  3568. end\\\\\\\\\\\\\\\
  3569. return false, nil\\\\\\\\\\\\\\\
  3570. end\\\\\\\\\\\\\\\
  3571. \\\\\\\\\\\\\\\
  3572. function findValue(array, text)\\\\\\\\\\\\\\\
  3573. for k,v in pairs(array) do\\\\\\\\\\\\\\\
  3574.  if v == text then\\\\\\\\\\\\\\\
  3575.   return true, v\\\\\\\\\\\\\\\
  3576.  end\\\\\\\\\\\\\\\
  3577. end\\\\\\\\\\\\\\\
  3578. return false, nil\\\\\\\\\\\\\\\
  3579. end\\\\\\\\\\\\\\\
  3580. \\\\\\\\\\\\\\\
  3581. function queryForKey(array, text)\\\\\\\\\\\\\\\
  3582. for k,v in pairs(array) do\\\\\\\\\\\\\\\
  3583.  if string.find(k, text) then\\\\\\\\\\\\\\\
  3584.   return true, k\\\\\\\\\\\\\\\
  3585.  end\\\\\\\\\\\\\\\
  3586. end\\\\\\\\\\\\\\\
  3587. return false, nil\\\\\\\\\\\\\\\
  3588. end\\\\\\\\\\\\\\\
  3589. \\\\\\\\\\\\\\\
  3590. function queryForValue(array, text)\\\\\\\\\\\\\\\
  3591. for k,v in pairs(array) do\\\\\\\\\\\\\\\
  3592.  if string.find(v, text) then\\\\\\\\\\\\\\\
  3593.   return true, v\\\\\\\\\\\\\\\
  3594.  end\\\\\\\\\\\\\\\
  3595. end\\\\\\\\\\\\\\\
  3596. return false, nil\\\\\\\\\\\\\\\
  3597. end\\\\\\\\\\\\\\\
  3598. \\\\\\\\\\\\\\\
  3599. function stringToBytes(str)\\\\\\\\\\\\\\\
  3600. return string.byte(str, 1, str:len())\\\\\\\\\\\\\\\
  3601. end\\\\\\\\\\\\\\\
  3602. \\\\\\\\\\\\\\\
  3603. function bytesToString(...)\\\\\\\\\\\\\\\
  3604. return string.char(...)\\\\\\\\\\\\\\\
  3605. end\\\\\\\\\\\\\\\
  3606. \\\\\\\\\\\\\\\
  3607. function iterateFileLines(path)\\\\\\\\\\\\\\\
  3608. local handle = fs.open(path, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3609. local commands = {}\\\\\\\\\\\\\\\
  3610. local line = handle.readLine()\\\\\\\\\\\\\\\
  3611. while line do\\\\\\\\\\\\\\\
  3612.  commands[#commands + 1] = line\\\\\\\\\\\\\\\
  3613.  line = handle.readLine()\\\\\\\\\\\\\\\
  3614. end\\\\\\\\\\\\\\\
  3615. handle.close()\\\\\\\\\\\\\\\
  3616. return commands\\\\\\\\\\\\\\\
  3617. end\\\\\\\\\\\\\\\
  3618. \\\\\\\\\\\\\\\
  3619. -- Clear the screen\\\\\\\\\\\\\\\
  3620. function clear()\\\\\\\\\\\\\\\
  3621. term.clear()\\\\\\\\\\\\\\\
  3622. term.setCursorPos(1,1)\\\\\\\\\\\\\\\
  3623. end\\\\\\\\\\\\\\\
  3624. \\\\\\\\\\\\\\\
  3625. -- Shut the system down safely.\\\\\\\\\\\\\\\
  3626. function shutdown()\\\\\\\\\\\\\\\
  3627. gui.printBootSuccess(\\\\\\\\\\\\\\\"System is ready for shutdown\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3628. sleep(1.5)\\\\\\\\\\\\\\\
  3629. os.shutdown()\\\\\\\\\\\\\\\
  3630. halt()\\\\\\\\\\\\\\\
  3631. end\\\\\\\\\\\\\\\
  3632. \\\\\\\\\\\\\\\
  3633. function reboot()\\\\\\\\\\\\\\\
  3634. gui.printBootSuccess(\\\\\\\\\\\\\\\"System is rebooting\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3635. sleep(1.5)\\\\\\\\\\\\\\\
  3636. os.reboot()\\\\\\\\\\\\\\\
  3637. halt()\\\\\\\\\\\\\\\
  3638. end\\\\\\\\\\\\\\\
  3639. \\\\\\\\\\\\\\\
  3640. -- Crash the system\\\\\\\\\\\\\\\
  3641. function crashReport(text)\\\\\\\\\\\\\\\
  3642. printError(\\\\\\\\\\\\\\\"[ ! ] Fatal error (\\\\\\\\\\\\\\\"..text..\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3643. printError(\\\\\\\\\\\\\\\"[ ! ] HALTING EXECUTION!\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3644. halt()\\\\\\\\\\\\\\\
  3645. end\\\\\\\\\\\\\\\
  3646. \\\\\\\\\\\\\\\
  3647. -- Import a file\\\\\\\\\\\\\\\
  3648. function import(file)\\\\\\\\\\\\\\\
  3649. if fs.exists(file) and not fs.isDir(file) then\\\\\\\\\\\\\\\
  3650.  return os.loadAPI(file)\\\\\\\\\\\\\\\
  3651. else\\\\\\\\\\\\\\\
  3652.  log.write(\\\\\\\\\\\\\\\"Failed to load \\\\\\\\\\\\\\\"..file..\\\\\\\\\\\\\\\" as an API\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3653.  return false\\\\\\\\\\\\\\\
  3654. end\\\\\\\\\\\\\\\
  3655. end\\\\\\\\\\\\\\\
  3656. \\\\\\\\\\\\\\\
  3657. -- Require a file as a Lua module\\\\\\\\\\\\\\\
  3658. function require(file) -- A primitive require\\\\\\\\\\\\\\\
  3659. if fs.exists(file) and not fs.isDir(file) then\\\\\\\\\\\\\\\
  3660.  return dofile(file)\\\\\\\\\\\\\\\
  3661. else\\\\\\\\\\\\\\\
  3662.  log.write(\\\\\\\\\\\\\\\"Failed to load \\\\\\\\\\\\\\\"..file..\\\\\\\\\\\\\\\" as an module\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3663.  return nil\\\\\\\\\\\\\\\
  3664. end\\\\\\\\\\\\\\\
  3665. end\\\\\\\\\\\\\\\
  3666. \\\\\\\\\\\\\\\
  3667. -- API hook\\\\\\\\\\\\\\\
  3668. function APIHook(t)\\\\\\\\\\\\\\\
  3669. if t then\\\\\\\\\\\\\\\
  3670.  return true\\\\\\\\\\\\\\\
  3671. else\\\\\\\\\\\\\\\
  3672.  -- Not loaded\\\\\\\\\\\\\\\
  3673.  if import(\\\\\\\\\\\\\\\"/system/api/\\\\\\\\\\\\\\\"..t) then\\\\\\\\\\\\\\\
  3674.   return true\\\\\\\\\\\\\\\
  3675.  end\\\\\\\\\\\\\\\
  3676. end\\\\\\\\\\\\\\\
  3677. return false\\\\\\\\\\\\\\\
  3678. end\\\\\\\\\\\\\\\
  3679. \\\\\\\\\\\\\\\
  3680. -- Load system libraries\\\\\\\\\\\\\\\
  3681. function loadAssemblies(dir)\\\\\\\\\\\\\\\
  3682. local flist = fs.list(dir)\\\\\\\\\\\\\\\
  3683. for _, file in ipairs(flist) do\\\\\\\\\\\\\\\
  3684.  sleep(0.25)\\\\\\\\\\\\\\\
  3685.  kernel.import(dir..\\\\\\\\\\\\\\\"/\\\\\\\\\\\\\\\"..file) -- attempting to hook the file\\\\\\\\\\\\\\\
  3686.  gui.printBootSuccess(\\\\\\\\\\\\\\\"Assembly \\\\\\\\\\\\\\\"..file..\\\\\\\\\\\\\\\" hooked into RAM!\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3687. end\\\\\\\\\\\\\\\
  3688. end\\\\\\\\\\\\\\\
  3689. \\\\\\\\\\\\\\\
  3690. function printFile(file)\\\\\\\\\\\\\\\
  3691. if fs.exists(file) and not fs.isDir(file) then\\\\\\\\\\\\\\\
  3692.  local handle = fs.open(file, \\\\\\\\\\\\\\\"r\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3693.  local contents = handle.readAll()\\\\\\\\\\\\\\\
  3694.  handle.close()\\\\\\\\\\\\\\\
  3695.  return contents\\\\\\\\\\\\\\\
  3696. end\\\\\\\\\\\\\\\
  3697. end\\\\\\\\\\\\\\\
  3698. \\\\\\\\\\\\\\\
  3699. function getURLContents(url)\\\\\\\\\\\\\\\
  3700. local handlex = http.get(url)\\\\\\\\\\\\\\\
  3701. local contents = handlex.readAll()\\\\\\\\\\\\\\\
  3702. handlex.close()\\\\\\\\\\\\\\\
  3703. return contents\\\\\\\\\\\\\\\
  3704. end\\\\\\\\\\\\\\\
  3705. \\\\\\\\\\\\\\\
  3706. function getFile(file, url, overwrite)\\\\\\\\\\\\\\\
  3707. if not fs.exists(file) then\\\\\\\\\\\\\\\
  3708.  local handle = fs.open(file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3709.  handle.writeLine(getURLContents(url))\\\\\\\\\\\\\\\
  3710.  handle.close()\\\\\\\\\\\\\\\
  3711.  return true\\\\\\\\\\\\\\\
  3712. elseif overwrite and not fs.isDir(file) then\\\\\\\\\\\\\\\
  3713.  local handle = fs.open(file, \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3714.  handle.writeLine(getURLContents(url))\\\\\\\\\\\\\\\
  3715.  handle.close()\\\\\\\\\\\\\\\
  3716.  return true\\\\\\\\\\\\\\\
  3717. end\\\\\\\\\\\\\\\
  3718. return false\\\\\\\\\\\\\\\
  3719. end\\\\\\\\\\\\\\\
  3720. \\\\\\\\\\\\\\\
  3721. function secureInput(invite, definition)\\\\\\\\\\\\\\\
  3722. write(invite..\\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3723. local input = read(\\\\\\\\\\\\\\\"*\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3724. if input == definition then\\\\\\\\\\\\\\\
  3725.  return true\\\\\\\\\\\\\\\
  3726. else\\\\\\\\\\\\\\\
  3727.  return false\\\\\\\\\\\\\\\
  3728. end\\\\\\\\\\\\\\\
  3729. end\\\\\\\\\\\\\\\
  3730. ]]\\\\\\\\\\\\\\\
  3731. \\\\\\\\\\\\\\\
  3732. local temp_gui = [[\\\\\\\\\\\\\\\
  3733. function clearScreen(color)\\\\\\\\\\\\\\\
  3734. term.setBackgroundColor(color or colors.black)\\\\\\\\\\\\\\\
  3735. kernel.clear()\\\\\\\\\\\\\\\
  3736. end\\\\\\\\\\\\\\\
  3737. \\\\\\\\\\\\\\\
  3738. function button(text, x1, x2, y)\\\\\\\\\\\\\\\
  3739. term.setCursorPos(x1, y)\\\\\\\\\\\\\\\
  3740. print(text)\\\\\\\\\\\\\\\
  3741. local a, b, xx, yy = os.pullEvent(\\\\\\\\\\\\\\\"mouse_click\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3742. if (xx >= x1 and xx <= x2 and yy == y) then\\\\\\\\\\\\\\\
  3743.  return true\\\\\\\\\\\\\\\
  3744. else\\\\\\\\\\\\\\\
  3745.  return false\\\\\\\\\\\\\\\
  3746. end\\\\\\\\\\\\\\\
  3747. end\\\\\\\\\\\\\\\
  3748. \\\\\\\\\\\\\\\
  3749. function counter(text, y)\\\\\\\\\\\\\\\
  3750. for i=1,100 do\\\\\\\\\\\\\\\
  3751.  sleep(0.1)\\\\\\\\\\\\\\\
  3752.  term.setCursorPos(1, y)\\\\\\\\\\\\\\\
  3753.  print(text..\\\\\\\\\\\\\\\" [\\\\\\\\\\\\\\\"..tostring(i)..\\\\\\\\\\\\\\\"%]\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3754. end\\\\\\\\\\\\\\\
  3755. end\\\\\\\\\\\\\\\
  3756. \\\\\\\\\\\\\\\
  3757. function drawProgress(txt, y)\\\\\\\\\\\\\\\
  3758. term.setCursorPos(4, 4)\\\\\\\\\\\\\\\
  3759. print(txt)\\\\\\\\\\\\\\\
  3760. term.setCursorPos(1, y)\\\\\\\\\\\\\\\
  3761. print(\\\\\\\\\\\\\\\"[                             ]\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3762. term.setCursorPos(2, y)\\\\\\\\\\\\\\\
  3763. textutils.slowPrint(\\\\\\\\\\\\\\\"==============================]\\\\\\\\\\\\\\\", 10)\\\\\\\\\\\\\\\
  3764. end\\\\\\\\\\\\\\\
  3765. \\\\\\\\\\\\\\\
  3766. function drawProgressAlt(color)\\\\\\\\\\\\\\\
  3767. term.setCursorPos(4, 10)\\\\\\\\\\\\\\\
  3768. print(\\\\\\\\\\\\\\\"#-------------------------------------------#\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3769. term.setCursorPos(4, 11)\\\\\\\\\\\\\\\
  3770. print(\\\\\\\\\\\\\\\"|                                           |\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3771. term.setCursorPos(4, 12)\\\\\\\\\\\\\\\
  3772. print(\\\\\\\\\\\\\\\"#-------------------------------------------#\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3773. term.setBackgroundColor(color or colors.yellow)\\\\\\\\\\\\\\\
  3774. term.setCursorPos(5, 11)\\\\\\\\\\\\\\\
  3775. textutils.slowWrite(\\\\\\\\\\\\\\\"                                           \\\\\\\\\\\\\\\", 10)\\\\\\\\\\\\\\\
  3776. term.setBackgroundColor(colors.black)\\\\\\\\\\\\\\\
  3777. end\\\\\\\\\\\\\\\
  3778. \\\\\\\\\\\\\\\
  3779. function printColoredTextLine(y, txt, bg, fg)\\\\\\\\\\\\\\\
  3780. term.setCursorPos(1, y)\\\\\\\\\\\\\\\
  3781. term.setBackgroundColor(bg or colors.lightGray)\\\\\\\\\\\\\\\
  3782. term.write(\\\\\\\\\\\\\\\"                                                   \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3783. term.setCursorPos(1, y)\\\\\\\\\\\\\\\
  3784. term.setTextColor(fg or colors.black)\\\\\\\\\\\\\\\
  3785. print(txt)\\\\\\\\\\\\\\\
  3786. term.setBackgroundColor(colors.black)\\\\\\\\\\\\\\\
  3787. term.setTextColor(colors.white)\\\\\\\\\\\\\\\
  3788. end\\\\\\\\\\\\\\\
  3789. \\\\\\\\\\\\\\\
  3790. function printBootInfo(i)\\\\\\\\\\\\\\\
  3791. term.setBackgroundColor(colors.black)\\\\\\\\\\\\\\\
  3792. term.setTextColor(colors.lightGray)\\\\\\\\\\\\\\\
  3793. write(\\\\\\\\\\\\\\\"[ \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3794. term.setTextColor(colors.cyan)\\\\\\\\\\\\\\\
  3795. write(\\\\\\\\\\\\\\\"* \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3796. term.setTextColor(colors.lightGray)\\\\\\\\\\\\\\\
  3797. write(\\\\\\\\\\\\\\\"] \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3798. print(\\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\"..i)\\\\\\\\\\\\\\\
  3799. term.setTextColor(colors.white)\\\\\\\\\\\\\\\
  3800. end\\\\\\\\\\\\\\\
  3801. \\\\\\\\\\\\\\\
  3802. function printBootWarning(w)\\\\\\\\\\\\\\\
  3803. term.setBackgroundColor(colors.black)\\\\\\\\\\\\\\\
  3804. term.setTextColor(colors.lightGray)\\\\\\\\\\\\\\\
  3805. write(\\\\\\\\\\\\\\\"[ \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3806. term.setTextColor(colors.orange)\\\\\\\\\\\\\\\
  3807. write(\\\\\\\\\\\\\\\"! \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3808. term.setTextColor(colors.lightGray)\\\\\\\\\\\\\\\
  3809. write(\\\\\\\\\\\\\\\"] \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3810. print(\\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\"..w)\\\\\\\\\\\\\\\
  3811. term.setTextColor(colors.white)\\\\\\\\\\\\\\\
  3812. end\\\\\\\\\\\\\\\
  3813. \\\\\\\\\\\\\\\
  3814. function printBootSuccess(wa)\\\\\\\\\\\\\\\
  3815. term.setBackgroundColor(colors.black)\\\\\\\\\\\\\\\
  3816. term.setTextColor(colors.lightGray)\\\\\\\\\\\\\\\
  3817. write(\\\\\\\\\\\\\\\"[ \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3818. term.setTextColor(colors.lime)\\\\\\\\\\\\\\\
  3819. write(\\\\\\\\\\\\\\\"v \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3820. term.setTextColor(colors.lightGray)\\\\\\\\\\\\\\\
  3821. write(\\\\\\\\\\\\\\\"] \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3822. print(\\\\\\\\\\\\\\\" \\\\\\\\\\\\\\\"..wa)\\\\\\\\\\\\\\\
  3823. term.setTextColor(colors.white)\\\\\\\\\\\\\\\
  3824. end\\\\\\\\\\\\\\\
  3825. \\\\\\\\\\\\\\\
  3826. function printAppInfo(header, msg)\\\\\\\\\\\\\\\
  3827. term.setTextColor(colors.cyan)\\\\\\\\\\\\\\\
  3828. write(header..\\\\\\\\\\\\\\\": \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3829. term.setTextColor(colors.lightGray)\\\\\\\\\\\\\\\
  3830. print(msg)\\\\\\\\\\\\\\\
  3831. term.setTextColor(colors.white)\\\\\\\\\\\\\\\
  3832. end\\\\\\\\\\\\\\\
  3833. \\\\\\\\\\\\\\\
  3834. function printAppWarning(header, msg)\\\\\\\\\\\\\\\
  3835. term.setTextColor(colors.red)\\\\\\\\\\\\\\\
  3836. write(header..\\\\\\\\\\\\\\\": \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3837. term.setTextColor(colors.orange)\\\\\\\\\\\\\\\
  3838. print(msg)\\\\\\\\\\\\\\\
  3839. term.setTextColor(colors.white)\\\\\\\\\\\\\\\
  3840. end\\\\\\\\\\\\\\\
  3841. \\\\\\\\\\\\\\\
  3842. function printAppSuccess(header, msg)\\\\\\\\\\\\\\\
  3843. term.setTextColor(colors.lime)\\\\\\\\\\\\\\\
  3844. write(header..\\\\\\\\\\\\\\\": \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3845. term.setTextColor(colors.green)\\\\\\\\\\\\\\\
  3846. print(msg)\\\\\\\\\\\\\\\
  3847. term.setTextColor(colors.white)\\\\\\\\\\\\\\\
  3848. end\\\\\\\\\\\\\\\
  3849. \\\\\\\\\\\\\\\
  3850. function request(req)\\\\\\\\\\\\\\\
  3851. while true do\\\\\\\\\\\\\\\
  3852.  term.setTextColor(colors.cyan)\\\\\\\\\\\\\\\
  3853.  write(req .. \\\\\\\\\\\\\\\"? \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3854.  term.setTextColor(colors.lightGray)\\\\\\\\\\\\\\\
  3855.  write(\\\\\\\\\\\\\\\"(\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3856.  term.setTextColor(colors.lime)\\\\\\\\\\\\\\\
  3857.  write(\\\\\\\\\\\\\\\"Y\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3858.  term.setTextColor(colors.lightGray)\\\\\\\\\\\\\\\
  3859.  write(\\\\\\\\\\\\\\\"/\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3860.  term.setTextColor(colors.red)\\\\\\\\\\\\\\\
  3861.  write(\\\\\\\\\\\\\\\"N\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3862.  term.setTextColor(colors.lightGray)\\\\\\\\\\\\\\\
  3863.  write(\\\\\\\\\\\\\\\") \\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3864.  local presel=read()\\\\\\\\\\\\\\\
  3865.  if presel==\\\\\\\\\\\\\\\"Y\\\\\\\\\\\\\\\" or presel==\\\\\\\\\\\\\\\"y\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\
  3866.   return true\\\\\\\\\\\\\\\
  3867.  elseif presel==\\\\\\\\\\\\\\\"N\\\\\\\\\\\\\\\" or presel==\\\\\\\\\\\\\\\"n\\\\\\\\\\\\\\\" then\\\\\\\\\\\\\\\
  3868.   return false\\\\\\\\\\\\\\\
  3869.  end\\\\\\\\\\\\\\\
  3870. end\\\\\\\\\\\\\\\
  3871. end\\\\\\\\\\\\\\\
  3872. \\\\\\\\\\\\\\\
  3873. function drawImg(path, x, y)\\\\\\\\\\\\\\\
  3874. if fs.exists(path) and not fs.isDir(path) then\\\\\\\\\\\\\\\
  3875.  local img = paintutils.loadImage(path)\\\\\\\\\\\\\\\
  3876.  paintutils.drawImage(img, x, y)\\\\\\\\\\\\\\\
  3877. else\\\\\\\\\\\\\\\
  3878.  gui.printAppWarning(\\\\\\\\\\\\\\\"gui\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"image not found\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3879. end\\\\\\\\\\\\\\\
  3880. end\\\\\\\\\\\\\\\
  3881. \\\\\\\\\\\\\\\
  3882. function printColored(text, color)\\\\\\\\\\\\\\\
  3883. local tmp = term.getTextColor()\\\\\\\\\\\\\\\
  3884. term.setTextColor(color)\\\\\\\\\\\\\\\
  3885. print(text)\\\\\\\\\\\\\\\
  3886. term.setTextColor(tmp)\\\\\\\\\\\\\\\
  3887. end\\\\\\\\\\\\\\\
  3888. ]]\\\\\\\\\\\\\\\
  3889. \\\\\\\\\\\\\\\
  3890. if not fs.exists(\\\\\\\\\\\\\\\"/.tmp\\\\\\\\\\\\\\\") then\\\\\\\\\\\\\\\
  3891. fs.makeDir(\\\\\\\\\\\\\\\"/.tmp\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3892. end\\\\\\\\\\\\\\\
  3893. \\\\\\\\\\\\\\\
  3894. local h_kernel = fs.open(\\\\\\\\\\\\\\\"/.tmp/kernel\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3895. local h_gui = fs.open(\\\\\\\\\\\\\\\"/.tmp/gui\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"w\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3896. h_kernel.writeLine(temp_kernel)\\\\\\\\\\\\\\\
  3897. h_kernel.close()\\\\\\\\\\\\\\\
  3898. h_gui.writeLine(temp_gui)\\\\\\\\\\\\\\\
  3899. h_gui.close()\\\\\\\\\\\\\\\
  3900. \\\\\\\\\\\\\\\
  3901. os.version = function()\\\\\\\\\\\\\\\
  3902. return \\\\\\\\\\\\\\\"Tesseract Bootstrap 1.0\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\
  3903. end\\\\\\\\\\\\\\\
  3904. \\\\\\\\\\\\\\\
  3905. os.loadAPI(\\\\\\\\\\\\\\\"/.tmp/kernel\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3906. os.loadAPI(\\\\\\\\\\\\\\\"/.tmp/gui\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3907. \\\\\\\\\\\\\\\
  3908. fs.delete(\\\\\\\\\\\\\\\"/.tmp/kernel\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3909. fs.delete(\\\\\\\\\\\\\\\"/.tmp/gui\\\\\\\\\\\\\\\")\\\\\\\\\\\\\\\
  3910. \\\\\\\\\\\\\\\
  3911. gui.printAppSuccess(\\\\\\\\\\\\\\\"tesseract\\\\\\\\\\\\\\\", \\\\\\\\\\\\\\\"bootstrap kernel loaded\\\\\\\\\\\\\\\")\\\\\\\"\\\",\\\
  3912. }\",\
  3913.  \"F:kernel.map\",\
  3914.  \"\\\"-- Darwin native API\\\\\\\
  3915. \\\\\\\
  3916. -- LOCALS\\\\\\\
  3917. \\\\\\\
  3918. -- declare bug check codes\\\\\\\
  3919. local tmp_kc = {}\\\\\\\
  3920. tmp_kc[0x0000] = \\\\\\\"UNDEFINED_EXCEPTION\\\\\\\"\\\\\\\
  3921. tmp_kc[0x0001] = \\\\\\\"KERNEL_INTEGRITY_VIOLATION\\\\\\\"\\\\\\\
  3922. tmp_kc[0x0002] = \\\\\\\"KERNEL_ASSEMBLY_NOT_ACCESSIBLE\\\\\\\"\\\\\\\
  3923. tmp_kc[0x0003] = \\\\\\\"FIRMWARE_VERSION_INCOMPATIBLE\\\\\\\"\\\\\\\
  3924. tmp_kc[0x0004] = \\\\\\\"ATTEMPTED_KERNEL_ENVIRONMENT_BYPASS\\\\\\\"\\\\\\\
  3925. tmp_kc[0x0005] = \\\\\\\"ATTEMPTED_KERNEL_STRUCT_MODIFICATION\\\\\\\"\\\\\\\
  3926. tmp_kc[0xFFFE] = \\\\\\\"DELIBERATELY_THROWN_EXCEPTION\\\\\\\"\\\\\\\
  3927. tmp_kc[0xFFFF] = \\\\\\\"UNHANDLED_USER_MODE_EXCEPTION\\\\\\\"\\\\\\\
  3928. \\\\\\\
  3929. -- handle the bug check codes\\\\\\\
  3930. local function handleBugCheckCode(code)\\\\\\\
  3931. if code > 0xFFFFFFFF then\\\\\\\
  3932.  return \\\\\\\"0xFFFFFFFF\\\\\\\"\\\\\\\
  3933. end\\\\\\\
  3934. local h = \\\\\\\"0x00000000\\\\\\\"\\\\\\\
  3935. local code_s = string.format(\\\\\\\"%X\\\\\\\", code)\\\\\\\
  3936. return string.format(\\\\\\\"%s%s\\\\\\\", string.sub(h, 1, h:len() - code_s:len()), code_s)\\\\\\\
  3937. end\\\\\\\
  3938. \\\\\\\
  3939. local function getCodeID(c)\\\\\\\
  3940. if code > 0xFFFFFFFF then\\\\\\\
  3941.  return tmp_kc[0x00000000]\\\\\\\
  3942. end\\\\\\\
  3943. return tmp_kc[c] or tmp_kc[0x00000000]\\\\\\\
  3944. end\\\\\\\
  3945. \\\\\\\
  3946. local function handleBootMessage(str)\\\\\\\
  3947.   local s1 = \\\\\\\"                                                 \\\\\\\"\\\\\\\
  3948.   local n1 = s1:len()\\\\\\\
  3949.   local n2 = str:len()\\\\\\\
  3950.   local s2 = string.sub(s1, 1, n1-n2)\\\\\\\
  3951.   return \\\\\\\" \\\\\\\"..str..s2..\\\\\\\" \\\\\\\"\\\\\\\
  3952. end\\\\\\\
  3953. \\\\\\\
  3954. -- GLOBALS\\\\\\\
  3955. \\\\\\\
  3956. -- declare log function\\\\\\\
  3957. __declare(\\\\\\\"log\\\\\\\", function(l)\\\\\\\
  3958. if not fs.exists(\\\\\\\"/etc/darwin.log\\\\\\\") then\\\\\\\
  3959.  x = fs.open(\\\\\\\"/etc/darwin.log\\\\\\\", \\\\\\\"w\\\\\\\")\\\\\\\
  3960. else\\\\\\\
  3961.  x = fs.open(\\\\\\\"/etc/darwin.log\\\\\\\", \\\\\\\"a\\\\\\\")\\\\\\\
  3962. end\\\\\\\
  3963. x.writeLine(tostring(os.day())..\\\\\\\"d:\\\\\\\"..textutils.formatTime(os.time(), true)..\\\\\\\" | \\\\\\\"..l)\\\\\\\
  3964. x.close()\\\\\\\
  3965. end)\\\\\\\
  3966. \\\\\\\
  3967. -- declare bug check stub\\\\\\\
  3968. __declare(\\\\\\\"__kstop\\\\\\\", function(code, p1, p2, p3, p4)\\\\\\\
  3969. os.pullEvent = os.pullEventRaw\\\\\\\
  3970. local code_a = 0x00000000\\\\\\\
  3971. if tmp_kc[code] ~= nil then\\\\\\\
  3972.  code_a = code\\\\\\\
  3973. end\\\\\\\
  3974. \\\\\\\
  3975. t = string.format(\\\\\\\"KSTOP CALLED! %s %s %s %s %s %s\\\\\\\", handleBugCheckCode(code_a), tmp_kc[code_a], tostring(p1), tostring(p2), tostring(p3), tostring(p4))\\\\\\\
  3976. log(t)\\\\\\\
  3977. \\\\\\\
  3978. if not  __DEBUG then\\\\\\\
  3979.  os.reboot()\\\\\\\
  3980. end\\\\\\\
  3981. \\\\\\\
  3982. term.setBackgroundColor(colors.blue)\\\\\\\
  3983. term.setTextColor(colors.white)\\\\\\\
  3984. term.clear()\\\\\\\
  3985. term.setCursorPos(1,1)\\\\\\\
  3986. \\\\\\\
  3987. x = string.format([[\\\\\\\
  3988. The system has encountered an unrecoverable error.\\\\\\\
  3989. Your computer needs to be restarted.\\\\\\\
  3990. \\\\\\\
  3991. Please write down the following parameters\\\\\\\
  3992. and send them to the Darwin development team:\\\\\\\
  3993. \\\\\\\
  3994. [%s] %s\\\\\\\
  3995. \\\\\\\
  3996. [1] %s\\\\\\\
  3997. [2] %s\\\\\\\
  3998. [3] %s\\\\\\\
  3999. [4] %s\\\\\\\
  4000. \\\\\\\
  4001. 15 seconds until reboot.\\\\\\\
  4002. ]], handleBugCheckCode(code_a), tmp_kc[code_a], tostring(p1), tostring(p2), tostring(p3), tostring(p4))\\\\\\\
  4003. stdout(x..\\\\\\\"\\\\\\\\n\\\\\\\")\\\\\\\
  4004. sleep(15)\\\\\\\
  4005. os.reboot()\\\\\\\
  4006. end)\\\\\\\
  4007. \\\\\\\
  4008. -- declare executive\\\\\\\
  4009. __declare(\\\\\\\"run\\\\\\\", function(ap)\\\\\\\
  4010. return os.run(getfenv(1), ap)\\\\\\\
  4011. end)\\\\\\\
  4012. \\\\\\\
  4013. -- declare device IDs\\\\\\\
  4014. local d = {}\\\\\\\
  4015. d.MONITOR = \\\\\\\"monitor\\\\\\\"\\\\\\\
  4016. d.FLOPPY = \\\\\\\"drive\\\\\\\"\\\\\\\
  4017. d.MODEM = \\\\\\\"modem\\\\\\\"\\\\\\\
  4018. d.PRINTER = \\\\\\\"printer\\\\\\\"\\\\\\\
  4019. __declare(\\\\\\\"DEVICE_ID\\\\\\\", __kstruct(d))\\\\\\\
  4020. \\\\\\\
  4021. -- declare FS access flags\\\\\\\
  4022. __declare_api(\\\\\\\"fs\\\\\\\", \\\\\\\"AF_READ\\\\\\\", \\\\\\\"r\\\\\\\")\\\\\\\
  4023. __declare_api(\\\\\\\"fs\\\\\\\", \\\\\\\"AF_WRITE\\\\\\\", \\\\\\\"w\\\\\\\")\\\\\\\
  4024. __declare_api(\\\\\\\"fs\\\\\\\", \\\\\\\"AF_APPEND\\\\\\\", \\\\\\\"a\\\\\\\")\\\\\\\
  4025. __declare_api(\\\\\\\"fs\\\\\\\", \\\\\\\"AF_READBINARY\\\\\\\", \\\\\\\"rb\\\\\\\")\\\\\\\
  4026. __declare_api(\\\\\\\"fs\\\\\\\", \\\\\\\"AF_WRITEBINARY\\\\\\\", \\\\\\\"wb\\\\\\\")\\\\\\\
  4027. __declare_api(\\\\\\\"fs\\\\\\\", \\\\\\\"AF_APPENDBINARY\\\\\\\", \\\\\\\"ab\\\\\\\")\\\\\\\
  4028. \\\\\\\
  4029. -- declare stream descriptors\\\\\\\
  4030. __declare(\\\\\\\"stdin\\\\\\\", read)\\\\\\\
  4031. __declare(\\\\\\\"stdout\\\\\\\", write)\\\\\\\
  4032. __declare(\\\\\\\"stderr\\\\\\\", printError)\\\\\\\
  4033. \\\\\\\
  4034. -- declare format descriptor\\\\\\\
  4035. __declare(\\\\\\\"printf\\\\\\\", function(...)\\\\\\\
  4036. stdout(string.format(...))\\\\\\\
  4037. end)\\\\\\\
  4038. \\\\\\\
  4039. -- declare kernel descriptor\\\\\\\
  4040. __declare(\\\\\\\"printk\\\\\\\", function(n, i)\\\\\\\
  4041. local LOG_TYPES = {}\\\\\\\
  4042. LOG_TYPES[0] = {colors.lightGray, \\\\\\\" i \\\\\\\"}\\\\\\\
  4043. LOG_TYPES[1] = {colors.lime, \\\\\\\" v \\\\\\\"}\\\\\\\
  4044. LOG_TYPES[2] = {colors.cyan, \\\\\\\" * \\\\\\\"}\\\\\\\
  4045. LOG_TYPES[3] = {colors.orange, \\\\\\\" ! \\\\\\\"}\\\\\\\
  4046. LOG_TYPES[4] = {colors.red, \\\\\\\"!!!\\\\\\\"}\\\\\\\
  4047. if n > 4 then\\\\\\\
  4048.  n = 4\\\\\\\
  4049. end\\\\\\\
  4050. if __DEBUG then\\\\\\\
  4051.  term.setBackgroundColor(colors.black)\\\\\\\
  4052.  term.setTextColor(colors.gray)\\\\\\\
  4053.  stdout(\\\\\\\"[\\\\\\\")\\\\\\\
  4054.  term.setTextColor(LOG_TYPES[n][1])\\\\\\\
  4055.  stdout(LOG_TYPES[n][2])\\\\\\\
  4056.  term.setTextColor(colors.gray)\\\\\\\
  4057.  stdout(\\\\\\\"]\\\\\\\")\\\\\\\
  4058.  if n == 4 then\\\\\\\
  4059.   term.setTextColor(colors.red)\\\\\\\
  4060.  else\\\\\\\
  4061.   term.setTextColor(colors.lightGray)   \\\\\\\
  4062.  end\\\\\\\
  4063.  stdout(\\\\\\\" \\\\\\\"..i..\\\\\\\"\\\\\\\\n\\\\\\\")\\\\\\\
  4064.  term.setTextColor(colors.white)\\\\\\\
  4065. end\\\\\\\
  4066. log(i)\\\\\\\
  4067. end)\\\\\\\
  4068. \\\\\\\
  4069. -- declare kernel reader\\\\\\\
  4070. __declare(\\\\\\\"kreadfile\\\\\\\", function(path)\\\\\\\
  4071. local handle = fs.open(path, \\\\\\\"r\\\\\\\")\\\\\\\
  4072. local content = handle.readAll()\\\\\\\
  4073. handle.close()\\\\\\\
  4074. return content\\\\\\\
  4075. end)\\\\\\\
  4076. \\\\\\\
  4077. -- declare temporary kernel-mode loader\\\\\\\
  4078. local function loadAssembly(path)\\\\\\\
  4079. sleep(0.2)\\\\\\\
  4080. if not fs.exists(path) or fs.isDir(path) then\\\\\\\
  4081.  printk(4, \\\\\\\"LOAD FAILED: \\\\\\\"..path)\\\\\\\
  4082.  return false\\\\\\\
  4083. else\\\\\\\
  4084.  if dofile(path) then\\\\\\\
  4085.   ESI.UIColoredLine(18, handleBootMessage(\\\\\\\"Loaded: \\\\\\\"..path), colors.lightGray, colors.black)\\\\\\\
  4086.   return true\\\\\\\
  4087.  else\\\\\\\
  4088.   printk(4, \\\\\\\"LOAD FAILED: \\\\\\\"..path)\\\\\\\
  4089.   return false\\\\\\\
  4090.  end\\\\\\\
  4091. end\\\\\\\
  4092. end\\\\\\\
  4093. \\\\\\\
  4094. __declare(\\\\\\\"__kload\\\\\\\", function(path)\\\\\\\
  4095. if not loadAssembly(path) then\\\\\\\
  4096. return false, __kstop(0x00000002, path)\\\\\\\
  4097. else\\\\\\\
  4098. return true, nil\\\\\\\
  4099. end\\\\\\\
  4100. end)\\\\\\\
  4101. \\\\\\\
  4102. -- declare finalizer\\\\\\\
  4103. __declare(\\\\\\\"__kfinalize\\\\\\\", function()\\\\\\\
  4104. __declare(\\\\\\\"__kload\\\\\\\", nil)\\\\\\\
  4105. __declare(\\\\\\\"__kread\\\\\\\", nil)\\\\\\\
  4106. __declare(\\\\\\\"__kfinalize\\\\\\\", nil)\\\\\\\
  4107. if __DEBUG then\\\\\\\
  4108. __declare(\\\\\\\"__khandlecode\\\\\\\", handleBugCheckCode)\\\\\\\
  4109. return\\\\\\\
  4110. end\\\\\\\
  4111. ESI.Finalize()\\\\\\\
  4112. __declare(\\\\\\\"__declare\\\\\\\", nil)\\\\\\\
  4113. __declare(\\\\\\\"__declare_api\\\\\\\", nil)\\\\\\\
  4114. end)\\\\\\\
  4115. \\\\\\\
  4116. -- return\\\\\\\
  4117. return 1\\\"\",\
  4118.  \"F:security.map\",\
  4119.  \"\\\"local oldReadOnly = _G[\\\\\\\"fs\\\\\\\"][\\\\\\\"isReadOnly\\\\\\\"]\\\\\\\
  4120. local oldMove = _G[\\\\\\\"fs\\\\\\\"][\\\\\\\"move\\\\\\\"]\\\\\\\
  4121. local oldDelete = _G[\\\\\\\"fs\\\\\\\"][\\\\\\\"delete\\\\\\\"]\\\\\\\
  4122. local oldHttpGet = _G[\\\\\\\"http\\\\\\\"][\\\\\\\"get\\\\\\\"]\\\\\\\
  4123. local oldError = _G[\\\\\\\"error\\\\\\\"]\\\\\\\
  4124. _G[\\\\\\\"fs\\\\\\\"][\\\\\\\"isReadOnly\\\\\\\"] = function(path)\\\\\\\
  4125. local find1 = shell.resolve(path) or path\\\\\\\
  4126. if string.find(find1, \\\\\\\"boot\\\\\\\") or string.find(find1, \\\\\\\"bin\\\\\\\") or string.find(find1, \\\\\\\"lib\\\\\\\") then\\\\\\\
  4127.  log(\\\\\\\"Attempt to access system files!\\\\\\\")\\\\\\\
  4128.  if  __DEBUG then\\\\\\\
  4129.   log(\\\\\\\"Superuser access verified.\\\\\\\")\\\\\\\
  4130.   return false\\\\\\\
  4131.  else\\\\\\\
  4132.   log(\\\\\\\"Attempt blocked.\\\\\\\")\\\\\\\
  4133.   return true\\\\\\\
  4134.  end\\\\\\\
  4135. elseif find1 == \\\\\\\"startup\\\\\\\" or find1 == \\\\\\\"/startup\\\\\\\" then\\\\\\\
  4136.  log(\\\\\\\"Attempt to access bootloader!\\\\\\\")\\\\\\\
  4137.  log(\\\\\\\"Attempt blocked.\\\\\\\")\\\\\\\
  4138.  return true\\\\\\\
  4139. end \\\\\\\
  4140. return oldReadOnly(path)\\\\\\\
  4141. end\\\\\\\
  4142. _G[\\\\\\\"fs\\\\\\\"][\\\\\\\"move\\\\\\\"] = function(path1, path2)\\\\\\\
  4143. local find2 = shell.resolve(path1)\\\\\\\
  4144. if string.find(find2, \\\\\\\"boot\\\\\\\") or string.find(find2, \\\\\\\"bin\\\\\\\") or string.find(find2, \\\\\\\"lib\\\\\\\") then\\\\\\\
  4145.  log(\\\\\\\"Attempt to access system files!\\\\\\\")\\\\\\\
  4146.  if  __DEBUG then\\\\\\\
  4147.   log(\\\\\\\"Superuser access verified.\\\\\\\")\\\\\\\
  4148.  else\\\\\\\
  4149.   log(\\\\\\\"Attempt blocked.\\\\\\\")\\\\\\\
  4150.   return nil\\\\\\\
  4151.  end\\\\\\\
  4152. elseif find2 == \\\\\\\"startup\\\\\\\" or find2 == \\\\\\\"/startup\\\\\\\" then\\\\\\\
  4153.  log(\\\\\\\"Attempt to access boot loader!\\\\\\\")\\\\\\\
  4154.  log(\\\\\\\"Attempt blocked.\\\\\\\")\\\\\\\
  4155.  return nil\\\\\\\
  4156. end \\\\\\\
  4157. return oldMove(path1, path2)\\\\\\\
  4158. end\\\\\\\
  4159. _G[\\\\\\\"fs\\\\\\\"][\\\\\\\"delete\\\\\\\"] = function(path)\\\\\\\
  4160. local find3 = shell.resolve(path) or path\\\\\\\
  4161. if string.find(find3, \\\\\\\"boot\\\\\\\") or string.find(find3, \\\\\\\"bin\\\\\\\") or string.find(find3, \\\\\\\"lib\\\\\\\") then\\\\\\\
  4162.  log(\\\\\\\"Attempt to access system files!\\\\\\\")\\\\\\\
  4163.  if  __DEBUG then\\\\\\\
  4164.   log(\\\\\\\"Superuser access verified.\\\\\\\")\\\\\\\
  4165.  else\\\\\\\
  4166.   log(\\\\\\\"Attempt blocked.\\\\\\\")\\\\\\\
  4167.   return nil\\\\\\\
  4168.  end\\\\\\\
  4169. elseif find3 == \\\\\\\"startup\\\\\\\" or find3 == \\\\\\\"/startup\\\\\\\" then\\\\\\\
  4170.  log(\\\\\\\"Attempt to access bootloader!\\\\\\\")\\\\\\\
  4171.  log(\\\\\\\"Attempt blocked.\\\\\\\")\\\\\\\
  4172.  return nil\\\\\\\
  4173. end \\\\\\\
  4174. return oldDelete(path)\\\\\\\
  4175. end\\\\\\\
  4176. _G[\\\\\\\"http\\\\\\\"][\\\\\\\"get\\\\\\\"] = function(url, headers)\\\\\\\
  4177. log(\\\\\\\"Downloaded contents of \\\\\\\"..url)\\\\\\\
  4178. return oldHttpGet(url, headers)\\\\\\\
  4179. end\\\"\",\
  4180. }",
  4181.   "D:etc",
  4182.   "{\
  4183.  \"F:darwin.log\",\
  4184.  \"\\\"3d:3:06 | Loaded system file: /lib/libstdlua.2.so\\\\\\\
  4185. 3d:3:07 | Loaded system file: /lib/libuser.2.so\\\\\\\
  4186. 3d:3:07 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
  4187. 3d:3:07 | Darwin kernel loaded\\\\\\\
  4188. 3d:3:45 | Loaded system file: /lib/libstdlua.2.so\\\\\\\
  4189. 3d:3:45 | Loaded system file: /lib/libuser.2.so\\\\\\\
  4190. 3d:3:45 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
  4191. 3d:3:45 | Darwin kernel loaded\\\\\\\
  4192. 3d:4:45 | Loaded system file: /lib/libstdlua.2.so\\\\\\\
  4193. 3d:4:45 | Loaded system file: /lib/libuser.2.so\\\\\\\
  4194. 3d:4:46 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
  4195. 3d:4:46 | Darwin kernel loaded\\\\\\\
  4196. 3d:5:10 | Loaded system file: /lib/libstdlua.2.so\\\\\\\
  4197. 3d:5:10 | Loaded system file: /lib/libuser.2.so\\\\\\\
  4198. 3d:5:11 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
  4199. 3d:5:11 | Darwin kernel loaded\\\\\\\
  4200. 3d:5:46 | Loaded system file: /lib/libstdlua.2.so\\\\\\\
  4201. 3d:5:47 | Loaded system file: /lib/libuser.2.so\\\\\\\
  4202. 3d:5:47 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
  4203. 3d:5:48 | Darwin kernel loaded\\\\\\\
  4204. 3d:9:37 | Loaded system file: /lib/libstdlua.2.so\\\\\\\
  4205. 3d:9:37 | Loaded system file: /lib/libuser.2.so\\\\\\\
  4206. 3d:9:37 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
  4207. 3d:9:38 | Darwin kernel loaded\\\\\\\
  4208. 3d:10:21 | Loaded system file: /lib/libstdlua.2.so\\\\\\\
  4209. 3d:10:21 | Loaded system file: /lib/libuser.2.so\\\\\\\
  4210. 3d:10:21 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
  4211. 3d:10:22 | Darwin kernel loaded\\\\\\\
  4212. 3d:11:06 | Downloaded contents of https://pastebin.com/raw/wFgCiYkY\\\\\\\
  4213. 5d:12:33 | Attempt to access system files!\\\\\\\
  4214. 5d:12:33 | Superuser access verified.\\\\\\\
  4215. 5d:12:33 | Loaded system file: /lib/libstdlua.2.so\\\\\\\
  4216. 5d:12:33 | Loaded system file: /lib/libuser.2.so\\\\\\\
  4217. 5d:12:34 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
  4218. 5d:12:34 | Darwin kernel loaded\\\\\\\
  4219. 5d:15:25 | Attempt to access system files!\\\\\\\
  4220. 5d:15:25 | Superuser access verified.\\\\\\\
  4221. 5d:15:25 | Loaded system file: /lib/libstdlua.2.so\\\\\\\
  4222. 5d:15:25 | Loaded system file: /lib/libuser.2.so\\\\\\\
  4223. 5d:15:26 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
  4224. 5d:15:26 | Darwin kernel loaded\\\\\\\
  4225. 1d:6:04 | Attempt to access system files!\\\\\\\
  4226. 1d:6:04 | Superuser access verified.\\\\\\\
  4227. 1d:6:04 | Loaded system file: /lib/libstdlua.2.so\\\\\\\
  4228. 1d:6:05 | Loaded system file: /lib/libuser.2.so\\\\\\\
  4229. 1d:6:05 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
  4230. 1d:6:06 | Darwin kernel loaded\\\\\\\
  4231. 2d:3:52 | Attempt to access system files!\\\\\\\
  4232. 2d:3:52 | Superuser access verified.\\\\\\\
  4233. 2d:3:52 | Loaded system file: /lib/libstdlua.2.so\\\\\\\
  4234. 2d:3:52 | Loaded system file: /lib/libuser.2.so\\\\\\\
  4235. 2d:3:53 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
  4236. 2d:3:53 | Darwin kernel loaded\\\\\\\
  4237. 2d:4:27 | Attempt to access system files!\\\\\\\
  4238. 2d:4:27 | Superuser access verified.\\\\\\\
  4239. 2d:4:27 | Loaded system file: /lib/libstdlua.2.so\\\\\\\
  4240. 2d:4:27 | Loaded system file: /lib/libuser.2.so\\\\\\\
  4241. 2d:4:27 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
  4242. 2d:4:28 | Darwin kernel loaded\\\\\\\
  4243. 2d:12:34 | Darwin kernel loaded\\\\\\\
  4244. 2d:13:01 | Darwin kernel loaded\\\\\\\
  4245. 2d:13:25 | Darwin kernel loaded\\\\\\\
  4246. 2d:14:01 | Darwin kernel loaded\\\\\\\
  4247. 2d:15:32 | Darwin kernel loaded\\\\\\\
  4248. 2d:16:36 | Darwin kernel loaded\\\\\\\
  4249. 2d:19:15 | Attempt to access system files!\\\\\\\
  4250. 2d:19:15 | Superuser access verified.\\\\\\\
  4251. 2d:21:52 | Loaded system file: /lib/libdaemon.1.so\\\\\\\
  4252. 2d:21:53 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
  4253. 2d:21:53 | Loaded system file: /lib/libsha256_anavrins.1.so\\\\\\\
  4254. 2d:21:53 | Loaded system file: /lib/libuser.2.so\\\\\\\
  4255. 2d:21:54 | Darwin kernel loaded\\\\\\\
  4256. 2d:23:04 | Loaded system file: /lib/libdaemon.1.so\\\\\\\
  4257. 2d:23:04 | Loaded system file: /lib/libgui_txui.1.so\\\\\\\
  4258. 2d:23:05 | Loaded system file: /lib/libsha256_anavrins.1.so\\\\\\\
  4259. 2d:23:05 | Loaded system file: /lib/libuser.2.so\\\\\\\
  4260. 3d:0:06 | Assembly loaded: /lib/libdaemon.1.so\\\\\\\
  4261. 3d:0:07 | Assembly loaded: /lib/libgui_txui.1.so\\\\\\\
  4262. 3d:0:07 | Assembly loaded: /lib/libsha256_anavrins.1.so\\\\\\\
  4263. 3d:0:07 | Assembly loaded: /lib/libuser.2.so\\\\\\\
  4264. 3d:0:48 | Loaded: /lib/libdaemon.1.so\\\\\\\
  4265. 3d:0:48 | Loaded: /lib/libgui_txui.1.so\\\\\\\
  4266. 3d:0:49 | Loaded: /lib/libsha256_anavrins.1.so\\\\\\\
  4267. 3d:0:49 | Loaded: /lib/libuser.2.so\\\\\\\
  4268. 3d:5:39 | Loaded: /lib/libdaemon.1.so\\\\\\\
  4269. 3d:5:39 | Loaded: /lib/libgui_txui.1.so\\\\\\\
  4270. 3d:5:40 | Loaded: /lib/libsha256_anavrins.1.so\\\\\\\
  4271. 3d:5:40 | Loaded: /lib/libuser.2.so\\\\\\\
  4272. 3d:6:01 | Loaded: /lib/libdaemon.1.so\\\\\\\
  4273. 3d:6:02 | Loaded: /lib/libgui_txui.1.so\\\\\\\
  4274. 3d:6:02 | Loaded: /lib/libsha256_anavrins.1.so\\\\\\\
  4275. 3d:6:02 | Loaded: /lib/libuser.2.so\\\\\\\
  4276. 4d:18:12 | Downloaded contents of https://pastebin.com/raw/bggiSgmc\\\\\\\
  4277. 5d:3:14 | Downloaded contents of https://pastebin.com/raw/ZGJGBJdg\\\\\\\
  4278. 5d:20:19 | Attempt to access system files!\\\\\\\
  4279. 5d:20:19 | Superuser access verified.\\\\\\\
  4280. 6d:11:06 | Attempt to access system files!\\\\\\\
  4281. 6d:11:06 | Superuser access verified.\\\\\\\
  4282. 6d:11:11 | Attempt to access system files!\\\\\\\
  4283. 6d:11:11 | Superuser access verified.\\\\\\\
  4284. 6d:11:27 | Attempt to access system files!\\\\\\\
  4285. 6d:11:27 | Superuser access verified.\\\\\\\
  4286. 6d:11:46 | Attempt to access system files!\\\\\\\
  4287. 6d:11:46 | Superuser access verified.\\\\\\\
  4288. 6d:12:21 | Attempt to access system files!\\\\\\\
  4289. 6d:12:21 | Superuser access verified.\\\\\\\
  4290. 6d:19:51 | Attempt to access system files!\\\\\\\
  4291. 6d:19:51 | Superuser access verified.\\\\\\\
  4292. 6d:19:56 | Attempt to access system files!\\\\\\\
  4293. 6d:19:56 | Superuser access verified.\\\"\",\
  4294.  \"F:process\",\
  4295.  \"\\\"\\\\\\\
  4296. -- Setup process switching\\\\\\\
  4297. local parentTerm = term.current()\\\\\\\
  4298. local w,h = parentTerm.getSize()\\\\\\\
  4299. \\\\\\\
  4300. local tProcesses = {}\\\\\\\
  4301. local nCurrentProcess = nil\\\\\\\
  4302. local nRunningProcess = nil\\\\\\\
  4303. local bShowMenu = false\\\\\\\
  4304. local bWindowsResized = false\\\\\\\
  4305. \\\\\\\
  4306. local function selectProcess( n )\\\\\\\
  4307.    if nCurrentProcess ~= n then\\\\\\\
  4308.        if nCurrentProcess then\\\\\\\
  4309.            local tOldProcess = tProcesses[ nCurrentProcess ]\\\\\\\
  4310.            tOldProcess.window.setVisible( false )\\\\\\\
  4311.        end\\\\\\\
  4312.        nCurrentProcess = n\\\\\\\
  4313.        if nCurrentProcess then\\\\\\\
  4314.            local tNewProcess = tProcesses[ nCurrentProcess ]\\\\\\\
  4315.            tNewProcess.window.setVisible( true )\\\\\\\
  4316.            tNewProcess.bInteracted = true\\\\\\\
  4317.        end\\\\\\\
  4318.    end\\\\\\\
  4319. end\\\\\\\
  4320. \\\\\\\
  4321. local function setProcessTitle( n, sTitle )\\\\\\\
  4322.    tProcesses[ n ].sTitle = sTitle\\\\\\\
  4323. end\\\\\\\
  4324. \\\\\\\
  4325. local function resumeProcess( nProcess, sEvent, ... )\\\\\\\
  4326.    local tProcess = tProcesses[ nProcess ]\\\\\\\
  4327.    local sFilter = tProcess.sFilter\\\\\\\
  4328.    if sFilter == nil or sFilter == sEvent or sEvent == \\\\\\\"terminate\\\\\\\" then\\\\\\\
  4329.        local nPreviousProcess = nRunningProcess\\\\\\\
  4330.        nRunningProcess = nProcess\\\\\\\
  4331.        term.redirect( tProcess.terminal )\\\\\\\
  4332.        local ok, result = coroutine.resume( tProcess.co, sEvent, ... )\\\\\\\
  4333.        tProcess.terminal = term.current()\\\\\\\
  4334.        if ok then\\\\\\\
  4335.            tProcess.sFilter = result\\\\\\\
  4336.        else\\\\\\\
  4337.            printError( result )\\\\\\\
  4338.        end\\\\\\\
  4339.        nRunningProcess = nPreviousProcess\\\\\\\
  4340.    end\\\\\\\
  4341. end\\\\\\\
  4342. \\\\\\\
  4343. local function launchProcess( tProgramEnv, sProgramPath, ... )\\\\\\\
  4344.    local tProgramArgs = table.pack( ... )\\\\\\\
  4345.    local nProcess = #tProcesses + 1\\\\\\\
  4346.    local tProcess = {}\\\\\\\
  4347.    tProcess.sTitle = fs.getName( sProgramPath )\\\\\\\
  4348.    if bShowMenu then\\\\\\\
  4349.        tProcess.window = window.create( parentTerm, 1, 2, w, h-1, false )\\\\\\\
  4350.    else\\\\\\\
  4351.        tProcess.window = window.create( parentTerm, 1, 1, w, h, false )\\\\\\\
  4352.    end\\\\\\\
  4353.    tProcess.co = coroutine.create( function()\\\\\\\
  4354.        os.run( tProgramEnv, sProgramPath, table.unpack( tProgramArgs, 1, tProgramArgs.n ) )\\\\\\\
  4355.        if not tProcess.bInteracted then\\\\\\\
  4356.            term.setCursorBlink( false )\\\\\\\
  4357.            print( \\\\\\\"Press any key to continue\\\\\\\" )\\\\\\\
  4358.            os.pullEvent( \\\\\\\"char\\\\\\\" )\\\\\\\
  4359.        end\\\\\\\
  4360.    end )\\\\\\\
  4361.    tProcess.sFilter = nil\\\\\\\
  4362.    tProcess.terminal = tProcess.window\\\\\\\
  4363.    tProcess.bInteracted = false\\\\\\\
  4364.    tProcesses[ nProcess ] = tProcess\\\\\\\
  4365.    resumeProcess( nProcess )\\\\\\\
  4366.    return nProcess\\\\\\\
  4367. end\\\\\\\
  4368. \\\\\\\
  4369. local function cullProcess( nProcess )\\\\\\\
  4370.    local tProcess = tProcesses[ nProcess ]\\\\\\\
  4371.    if coroutine.status( tProcess.co ) == \\\\\\\"dead\\\\\\\" then\\\\\\\
  4372.        if nCurrentProcess == nProcess then\\\\\\\
  4373.            selectProcess( nil )\\\\\\\
  4374.        end\\\\\\\
  4375.        table.remove( tProcesses, nProcess )\\\\\\\
  4376.        if nCurrentProcess == nil then\\\\\\\
  4377.            if nProcess > 1 then\\\\\\\
  4378.                selectProcess( nProcess - 1 )\\\\\\\
  4379.            elseif #tProcesses > 0 then\\\\\\\
  4380.                selectProcess( 1 )\\\\\\\
  4381.            end\\\\\\\
  4382.        end\\\\\\\
  4383.        return true\\\\\\\
  4384.    end\\\\\\\
  4385.    return false\\\\\\\
  4386. end\\\\\\\
  4387. \\\\\\\
  4388. local function cullProcesses()\\\\\\\
  4389.    local culled = false\\\\\\\
  4390.    for n=#tProcesses,1,-1 do\\\\\\\
  4391.        culled = culled or cullProcess( n )\\\\\\\
  4392.    end\\\\\\\
  4393.    return culled\\\\\\\
  4394. end\\\\\\\
  4395. \\\\\\\
  4396. -- Setup the main menu\\\\\\\
  4397. local menuMainTextColor, menuMainBgColor, menuOtherTextColor, menuOtherBgColor\\\\\\\
  4398. if parentTerm.isColor() then\\\\\\\
  4399.    menuMainTextColor, menuMainBgColor = colors.yellow, colors.black\\\\\\\
  4400.    menuOtherTextColor, menuOtherBgColor = colors.black, colors.gray\\\\\\\
  4401. else\\\\\\\
  4402.    menuMainTextColor, menuMainBgColor = colors.white, colors.black\\\\\\\
  4403.    menuOtherTextColor, menuOtherBgColor = colors.black, colors.gray\\\\\\\
  4404. end\\\\\\\
  4405. \\\\\\\
  4406. local function redrawMenu()\\\\\\\
  4407.    if bShowMenu then\\\\\\\
  4408.        -- Draw menu\\\\\\\
  4409.        parentTerm.setCursorPos( 1, 1 )\\\\\\\
  4410.        parentTerm.setBackgroundColor( menuOtherBgColor )\\\\\\\
  4411.        parentTerm.clearLine()\\\\\\\
  4412.        for n=1,#tProcesses do\\\\\\\
  4413.            if n == nCurrentProcess then\\\\\\\
  4414.                parentTerm.setTextColor( menuMainTextColor )\\\\\\\
  4415.                parentTerm.setBackgroundColor( menuMainBgColor )\\\\\\\
  4416.            else\\\\\\\
  4417.                parentTerm.setTextColor( menuOtherTextColor )\\\\\\\
  4418.                parentTerm.setBackgroundColor( menuOtherBgColor )\\\\\\\
  4419.            end\\\\\\\
  4420.            parentTerm.write( \\\\\\\" \\\\\\\" .. tProcesses[n].sTitle .. \\\\\\\" \\\\\\\" )\\\\\\\
  4421.        end\\\\\\\
  4422. \\\\\\\
  4423.        -- Put the cursor back where it should be\\\\\\\
  4424.        local tProcess = tProcesses[ nCurrentProcess ]\\\\\\\
  4425.        if tProcess then\\\\\\\
  4426.            tProcess.window.restoreCursor()\\\\\\\
  4427.        end\\\\\\\
  4428.    end\\\\\\\
  4429. end\\\\\\\
  4430. \\\\\\\
  4431. local function resizeWindows()\\\\\\\
  4432.    local windowY, windowHeight\\\\\\\
  4433.    if bShowMenu then\\\\\\\
  4434.        windowY = 2\\\\\\\
  4435.        windowHeight = h-1\\\\\\\
  4436.    else\\\\\\\
  4437.        windowY = 1\\\\\\\
  4438.        windowHeight = h\\\\\\\
  4439.    end\\\\\\\
  4440.    for n=1,#tProcesses do\\\\\\\
  4441.        local tProcess = tProcesses[n]\\\\\\\
  4442.        local window = tProcess.window\\\\\\\
  4443.        local x,y = tProcess.window.getCursorPos()\\\\\\\
  4444.        if y > windowHeight then\\\\\\\
  4445.            tProcess.window.scroll( y - windowHeight )\\\\\\\
  4446.            tProcess.window.setCursorPos( x, windowHeight )\\\\\\\
  4447.        end\\\\\\\
  4448.        tProcess.window.reposition( 1, windowY, w, windowHeight )\\\\\\\
  4449.    end\\\\\\\
  4450.    bWindowsResized = true\\\\\\\
  4451. end\\\\\\\
  4452. \\\\\\\
  4453. local function setMenuVisible( bVis )\\\\\\\
  4454.    if bShowMenu ~= bVis then\\\\\\\
  4455.        bShowMenu = bVis\\\\\\\
  4456.        resizeWindows()\\\\\\\
  4457.        redrawMenu()\\\\\\\
  4458.    end\\\\\\\
  4459. end\\\\\\\
  4460. \\\\\\\
  4461. local process = {}\\\\\\\
  4462. \\\\\\\
  4463. function process.getFocus()\\\\\\\
  4464.    return nCurrentProcess\\\\\\\
  4465. end\\\\\\\
  4466. \\\\\\\
  4467. function process.setFocus( n )\\\\\\\
  4468.    if type( n ) ~= \\\\\\\"number\\\\\\\" then\\\\\\\
  4469.        error( \\\\\\\"bad argument #1 (expected number, got \\\\\\\" .. type( n ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  4470.    end\\\\\\\
  4471.    if n >= 1 and n <= #tProcesses then\\\\\\\
  4472.        selectProcess( n )\\\\\\\
  4473.        redrawMenu()\\\\\\\
  4474.        return true\\\\\\\
  4475.    end\\\\\\\
  4476.    return false\\\\\\\
  4477. end\\\\\\\
  4478. \\\\\\\
  4479. function process.getTitle( n )\\\\\\\
  4480.    if type( n ) ~= \\\\\\\"number\\\\\\\" then\\\\\\\
  4481.        error( \\\\\\\"bad argument #1 (expected number, got \\\\\\\" .. type( n ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  4482.    end\\\\\\\
  4483.    if n >= 1 and n <= #tProcesses then\\\\\\\
  4484.        return tProcesses[n].sTitle\\\\\\\
  4485.    end\\\\\\\
  4486.    return nil\\\\\\\
  4487. end\\\\\\\
  4488. \\\\\\\
  4489. function process.setTitle( n, sTitle )\\\\\\\
  4490.    if type( n ) ~= \\\\\\\"number\\\\\\\" then\\\\\\\
  4491.        error( \\\\\\\"bad argument #1 (expected number, got \\\\\\\" .. type( n ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  4492.    end\\\\\\\
  4493.    if type( sTitle ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
  4494.        error( \\\\\\\"bad argument #2 (expected string, got \\\\\\\" .. type( sTitle ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  4495.    end\\\\\\\
  4496.    if n >= 1 and n <= #tProcesses then\\\\\\\
  4497.        setProcessTitle( n, sTitle )\\\\\\\
  4498.        redrawMenu()\\\\\\\
  4499.    end\\\\\\\
  4500. end\\\\\\\
  4501. \\\\\\\
  4502. function process.getCurrent()\\\\\\\
  4503.    return nRunningProcess\\\\\\\
  4504. end\\\\\\\
  4505. \\\\\\\
  4506. function process.launch( tProgramEnv, sProgramPath, ... )\\\\\\\
  4507.    if type( tProgramEnv ) ~= \\\\\\\"table\\\\\\\" then\\\\\\\
  4508.        error( \\\\\\\"bad argument #1 (expected table, got \\\\\\\" .. type( tProgramEnv ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  4509.    end\\\\\\\
  4510.    if type( sProgramPath ) ~= \\\\\\\"string\\\\\\\" then\\\\\\\
  4511.        error( \\\\\\\"bad argument #2 (expected string, got \\\\\\\" .. type( sProgramPath ) .. \\\\\\\")\\\\\\\", 2 )\\\\\\\
  4512.    end\\\\\\\
  4513.    local previousTerm = term.current()\\\\\\\
  4514.    setMenuVisible( (#tProcesses + 1) >= 2 )\\\\\\\
  4515.    local nResult = launchProcess( tProgramEnv, sProgramPath, ... )\\\\\\\
  4516.    redrawMenu()\\\\\\\
  4517.    term.redirect( previousTerm )\\\\\\\
  4518.    return nResult\\\\\\\
  4519. end\\\\\\\
  4520. \\\\\\\
  4521. function process.getCount()\\\\\\\
  4522.    return #tProcesses\\\\\\\
  4523. end\\\\\\\
  4524. \\\\\\\
  4525. -- Begin\\\\\\\
  4526. parentTerm.clear()\\\\\\\
  4527. setMenuVisible( false )\\\\\\\
  4528. selectProcess( launchProcess( {\\\\\\\
  4529.    [\\\\\\\"shell\\\\\\\"] = shell,\\\\\\\
  4530.    [\\\\\\\"process\\\\\\\"] = process,\\\\\\\
  4531. }, \\\\\\\"/bin/msh\\\\\\\" ) )\\\\\\\
  4532. redrawMenu()\\\\\\\
  4533. \\\\\\\
  4534. -- Run processes\\\\\\\
  4535. while #tProcesses > 0 do\\\\\\\
  4536.    -- Get the event\\\\\\\
  4537.    local tEventData = table.pack( os.pullEventRaw() )\\\\\\\
  4538.    local sEvent = tEventData[1]\\\\\\\
  4539.    if sEvent == \\\\\\\"term_resize\\\\\\\" then\\\\\\\
  4540.        -- Resize event\\\\\\\
  4541.        w,h = parentTerm.getSize()\\\\\\\
  4542.        resizeWindows()\\\\\\\
  4543.        redrawMenu()\\\\\\\
  4544. \\\\\\\
  4545.    elseif sEvent == \\\\\\\"char\\\\\\\" or sEvent == \\\\\\\"key\\\\\\\" or sEvent == \\\\\\\"key_up\\\\\\\" or sEvent == \\\\\\\"paste\\\\\\\" or sEvent == \\\\\\\"terminate\\\\\\\" then\\\\\\\
  4546.        -- Keyboard event\\\\\\\
  4547.        -- Passthrough to current process\\\\\\\
  4548.        resumeProcess( nCurrentProcess, table.unpack( tEventData, 1, tEventData.n ) )\\\\\\\
  4549.        if cullProcess( nCurrentProcess ) then\\\\\\\
  4550.            setMenuVisible( #tProcesses >= 2 )\\\\\\\
  4551.            redrawMenu()\\\\\\\
  4552.        end\\\\\\\
  4553. \\\\\\\
  4554.    elseif sEvent == \\\\\\\"mouse_click\\\\\\\" then\\\\\\\
  4555.        -- Click event\\\\\\\
  4556.        local button, x, y = tEventData[2], tEventData[3], tEventData[4]\\\\\\\
  4557.        if bShowMenu and y == 1 then\\\\\\\
  4558.            -- Switch process\\\\\\\
  4559.            local tabStart = 1\\\\\\\
  4560.            for n=1,#tProcesses do\\\\\\\
  4561.                local tabEnd = tabStart + string.len( tProcesses[n].sTitle ) + 1\\\\\\\
  4562.                if x >= tabStart and x <= tabEnd then\\\\\\\
  4563.                    selectProcess( n )\\\\\\\
  4564.                    redrawMenu()\\\\\\\
  4565.                    break\\\\\\\
  4566.                end\\\\\\\
  4567.                tabStart = tabEnd + 1\\\\\\\
  4568.            end\\\\\\\
  4569.        else\\\\\\\
  4570.            -- Passthrough to current process\\\\\\\
  4571.            resumeProcess( nCurrentProcess, sEvent, button, x, (bShowMenu and y-1) or y )\\\\\\\
  4572.            if cullProcess( nCurrentProcess ) then\\\\\\\
  4573.                setMenuVisible( #tProcesses >= 2 )\\\\\\\
  4574.                redrawMenu()\\\\\\\
  4575.            end\\\\\\\
  4576.        end\\\\\\\
  4577. \\\\\\\
  4578.    elseif sEvent == \\\\\\\"mouse_drag\\\\\\\" or sEvent == \\\\\\\"mouse_up\\\\\\\" or sEvent == \\\\\\\"mouse_scroll\\\\\\\" then\\\\\\\
  4579.        -- Other mouse event\\\\\\\
  4580.        local p1, x, y = tEventData[2], tEventData[3], tEventData[4]\\\\\\\
  4581.        if not (bShowMenu and y == 1) then\\\\\\\
  4582.            -- Passthrough to current process\\\\\\\
  4583.            resumeProcess( nCurrentProcess, sEvent, p1, x, (bShowMenu and y-1) or y )\\\\\\\
  4584.            if cullProcess( nCurrentProcess ) then\\\\\\\
  4585.                setMenuVisible( #tProcesses >= 2 )\\\\\\\
  4586.                redrawMenu()\\\\\\\
  4587.            end\\\\\\\
  4588.        end\\\\\\\
  4589. \\\\\\\
  4590.    else\\\\\\\
  4591.        -- Other event\\\\\\\
  4592.        -- Passthrough to all processes\\\\\\\
  4593.        local nLimit = #tProcesses -- Storing this ensures any new things spawned don't get the event\\\\\\\
  4594.        for n=1,nLimit do\\\\\\\
  4595.            resumeProcess( n, table.unpack( tEventData, 1, tEventData.n ) )\\\\\\\
  4596.        end\\\\\\\
  4597.        if cullProcesses() then\\\\\\\
  4598.            setMenuVisible( #tProcesses >= 2 )\\\\\\\
  4599.            redrawMenu()\\\\\\\
  4600.        end\\\\\\\
  4601.    end\\\\\\\
  4602. \\\\\\\
  4603.    if bWindowsResized then\\\\\\\
  4604.        -- Pass term_resize to all processes\\\\\\\
  4605.        local nLimit = #tProcesses -- Storing this ensures any new things spawned don't get the event\\\\\\\
  4606.        for n=1,nLimit do\\\\\\\
  4607.            resumeProcess( n, \\\\\\\"term_resize\\\\\\\" )\\\\\\\
  4608.        end\\\\\\\
  4609.        bWindowsResized = false\\\\\\\
  4610.        if cullProcesses() then\\\\\\\
  4611.            setMenuVisible( #tProcesses >= 2 )\\\\\\\
  4612.            redrawMenu()\\\\\\\
  4613.        end\\\\\\\
  4614.    end\\\\\\\
  4615. end\\\\\\\
  4616. \\\\\\\
  4617. -- Shutdown\\\\\\\
  4618. term.redirect( parentTerm )\\\"\",\
  4619.  \"D:resources\",\
  4620.  \"{\\\
  4621.  \\\"F:dialog_box.img\\\",\\\
  4622.  \\\"\\\\\\\"\\\\\\\\\\\\\\\
  4623. \\\\\\\\\\\\\\\
  4624. \\\\\\\\\\\\\\\
  4625. \\\\\\\\\\\\\\\
  4626. \\\\\\\\\\\\\\\
  4627.   000000000000000000000000000000000000000000000\\\\\\\\\\\\\\\
  4628.   0000000000000000000000000000000000000000000007\\\\\\\\\\\\\\\
  4629.   0000000000000000000000000000000000000000000007\\\\\\\\\\\\\\\
  4630.   0000000000000000000000000000000000000000000007\\\\\\\\\\\\\\\
  4631.   0777777777777777777777777777777777777777777707\\\\\\\\\\\\\\\
  4632.   0777777777777777777777777777777777777777777707\\\\\\\\\\\\\\\
  4633.   0777777777777777777777777777777777777777777707\\\\\\\\\\\\\\\
  4634.   0000000000000000000000000000000000000000000007\\\\\\\\\\\\\\\
  4635.    777777777777777777777777777777777777777777777\\\\\\\"\\\",\\\
  4636. }\",\
  4637. }",
  4638.   "D:lib",
  4639.   "{\
  4640.  \"F:libdaemon.1.so\",\
  4641.  \"\\\"local libcode = [[\\\\\\\
  4642. --a stateless iterator for use in for loops.\\\\\\\
  4643. local function fIter (t, i)\\\\\\\
  4644.    i = not i and #t or (i - 1)\\\\\\\
  4645.    if i>0 then\\\\\\\
  4646.        return i, t[i]\\\\\\\
  4647.    end\\\\\\\
  4648. end\\\\\\\
  4649. \\\\\\\
  4650. --a table that stores all running daemons when we add a new value we first create a coroutine using the fFunc passed\\\\\\\
  4651. local tBackground = setmetatable({},{\\\\\\\
  4652.    __newindex = function(t, k, v)\\\\\\\
  4653.        v.cRoutine=coroutine.create(v[1])\\\\\\\
  4654.        rawset(t, k, v)\\\\\\\
  4655.    end;\\\\\\\
  4656. })\\\\\\\
  4657. \\\\\\\
  4658. --starts a new daemon\\\\\\\
  4659. \\\\\\\
  4660. --fFunc = function that runs in background\\\\\\\
  4661. --fError = function ran if fFunc ever ends for any reason\\\\\\\
  4662. \\\\\\\
  4663. --returns identifier for new daemon\\\\\\\
  4664. \\\\\\\
  4665. function add(fFunc, fError)\\\\\\\
  4666.    tBackground[#tBackground + 1] = {fFunc, fError=fError}\\\\\\\
  4667.    return tBackground[#tBackground]\\\\\\\
  4668. end\\\\\\\
  4669. \\\\\\\
  4670. --removes a running daemon\\\\\\\
  4671. --internally this sets a flag telling the system to remove this daemon next time it loops through\\\\\\\
  4672. --cRoutine = daemon to remove\\\\\\\
  4673. \\\\\\\
  4674. function rem(cRoutine)\\\\\\\
  4675.    cRoutine.sFilter=\\\\\\\"Daemon_internal_remove\\\\\\\"\\\\\\\
  4676. end\\\\\\\
  4677. \\\\\\\
  4678. --returns identifiers for all running daemons\\\\\\\
  4679. function getBackground()\\\\\\\
  4680.    return tBackground\\\\\\\
  4681. end\\\\\\\
  4682. \\\\\\\
  4683. --internal variable, determines what level of depth we are in the daemon\\\\\\\
  4684. local bPullMeta = false\\\\\\\
  4685. \\\\\\\
  4686. \\\\\\\
  4687. --replacing the native os.pullEventRaw to function\\\\\\\
  4688. __declare_api(\\\\\\\"os\\\\\\\", \\\\\\\"pullEventRaw\\\\\\\", function(sEvent)\\\\\\\
  4689.    local tData\\\\\\\
  4690. \\\\\\\
  4691.    if bPullMeta then\\\\\\\
  4692.        return coroutine.yield(sEvent)\\\\\\\
  4693.    else\\\\\\\
  4694.        repeat\\\\\\\
  4695.            bPullMeta = true\\\\\\\
  4696.            tData = {coroutine.yield()}\\\\\\\
  4697. \\\\\\\
  4698.            for iIndex, cRoutine in fIter, tBackground do --\\\\\\\
  4699.                if cRoutine.sFilter==tData[1] or not cRoutine.sFilter then\\\\\\\
  4700.                    local bOk, sInnerEvent = coroutine.resume(cRoutine.cRoutine, unpack(tData))\\\\\\\
  4701.                    if bOk then\\\\\\\
  4702.                        cRoutine.sFilter = sInnerEvent\\\\\\\
  4703.                    else\\\\\\\
  4704.                        table.remove(tBackground, iIndex)\\\\\\\
  4705.                        if cRoutine.fError then\\\\\\\
  4706.                            cRoutine.fError(sInnerEvent, cRoutine)\\\\\\\
  4707.                        end\\\\\\\
  4708.                    end\\\\\\\
  4709.                elseif cRoutine.sFilter==\\\\\\\"Daemon_internal_remove\\\\\\\" then\\\\\\\
  4710.                    table.remove(tBackground, iIndex)\\\\\\\
  4711.                end\\\\\\\
  4712.            end\\\\\\\
  4713.            bPullMeta = false\\\\\\\
  4714.        until tData[1] == sEvent or not sEvent\\\\\\\
  4715.        return unpack(tData)\\\\\\\
  4716.    end\\\\\\\
  4717. end)\\\\\\\
  4718. ]]\\\\\\\
  4719. \\\\\\\
  4720. persist(\\\\\\\"daemon\\\\\\\", libcode)\\\\\\\
  4721. \\\\\\\
  4722. return 1\\\"\",\
  4723.  \"F:libgui_txui.1.so\",\
  4724.  \"\\\"local libcode = [[\\\\\\\
  4725. -- --\\\\\\\
  4726. -- txUI - ComputerCraft User Interface Library\\\\\\\
  4727. -- rel\\\\\\\
  4728. -- tuogex\\\\\\\
  4729. -- --\\\\\\\
  4730. \\\\\\\
  4731. -- --\\\\\\\
  4732. -- Controller @static\\\\\\\
  4733. -- Holds the windows of the program and handles events\\\\\\\
  4734. -- --\\\\\\\
  4735. Controller = {}\\\\\\\
  4736. Controller.prototype = {\\\\\\\
  4737. \\\\009--vars\\\\\\\
  4738. \\\\009components = {};\\\\\\\
  4739. \\\\009windows = {};\\\\\\\
  4740. \\\\009termSize = {};\\\\\\\
  4741. \\\\009spaceColor = colors.white;\\\\\\\
  4742. \\\\009style = {};\\\\\\\
  4743. \\\\009useNative = true;\\\\\\\
  4744. \\\\009multiWindow = false;\\\\\\\
  4745. \\\\009oldTerm = {};\\\\\\\
  4746. \\\\009--functions\\\\\\\
  4747. \\\\009drawAll = function(self)\\\\\\\
  4748. \\\\009\\\\009local w, h = term.getSize()\\\\\\\
  4749. \\\\009\\\\009Utils:drawRect(1, 1, w, h, self.spaceColor)\\\\\\\
  4750. \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  4751. \\\\009\\\\009\\\\009if (val.visible) then\\\\\\\
  4752. \\\\009\\\\009\\\\009\\\\009val:draw()\\\\\\\
  4753. \\\\009\\\\009\\\\009end\\\\\\\
  4754. \\\\009\\\\009end\\\\\\\
  4755. \\\\009\\\\009local drawQueue = {}\\\\\\\
  4756. \\\\009\\\\009for key, val in pairs(self.windows) do\\\\\\\
  4757. \\\\009\\\\009\\\\009if (val.visible) then\\\\\\\
  4758. \\\\009\\\\009\\\\009\\\\009table.insert(drawQueue, 1, val)\\\\\\\
  4759. \\\\009\\\\009\\\\009end\\\\\\\
  4760. \\\\009\\\\009end\\\\\\\
  4761. \\\\009\\\\009for key, val in pairs(drawQueue) do\\\\\\\
  4762. \\\\009\\\\009\\\\009val:draw()\\\\\\\
  4763. \\\\009\\\\009end\\\\\\\
  4764. \\\\009end;\\\\\\\
  4765. \\\\009appUpdate = function(self, eventTbl) end;\\\\\\\
  4766. \\\\009startUpdateCycle = function(self)\\\\\\\
  4767. \\\\009\\\\009Controller.termSize = term.getSize()\\\\\\\
  4768. \\\\009\\\\009if (self.useNative) then\\\\\\\
  4769. \\\\009\\\\009\\\\009Controller.oldTerm = term.current()\\\\\\\
  4770. \\\\009\\\\009\\\\009term.redirect(term.native())\\\\\\\
  4771. \\\\009\\\\009end\\\\\\\
  4772. \\\\009\\\\009local handleEvent = function()\\\\\\\
  4773. \\\\009\\\\009\\\\009local event\\\\\\\
  4774. \\\\009\\\\009\\\\009repeat\\\\\\\
  4775. \\\\009\\\\009\\\\009\\\\009event = {os.pullEventRaw()}\\\\\\\
  4776. \\\\009\\\\009\\\\009until(event[1] ~= \\\\\\\"timer\\\\\\\")\\\\\\\
  4777. \\\\009\\\\009\\\\009if (event[1] == \\\\\\\"terminate\\\\\\\") then\\\\\\\
  4778. \\\\009\\\\009\\\\009\\\\009self:terminate()\\\\\\\
  4779. \\\\009\\\\009\\\\009elseif (event[1] == \\\\\\\"mouse_click\\\\\\\" or event[1] == \\\\\\\"monitor_touch\\\\\\\") then\\\\\\\
  4780. \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  4781. \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and val:click(event[3], event[4], event[2])) then\\\\\\\
  4782. \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
  4783. \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4784. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4785. \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.windows) do\\\\\\\
  4786. \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and Utils:inBounds(val.x, val.y, val.w, val.h, event[3], event[4]) and tostring(self.windows[1]) ~= tostring(val)) then\\\\\\\
  4787. \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009table.remove(self.windows, key)\\\\\\\
  4788. \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009table.insert(self.windows, 1, val)\\\\\\\
  4789. \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
  4790. \\\\009\\\\009\\\\009\\\\009\\\\009elseif (val.visible and Utils:inBounds(val.x, val.y, val.w, val.h, event[3], event[4]) and tostring(self.windows[1]) == tostring(val)) then\\\\\\\
  4791. \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
  4792. \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4793. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4794. \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.windows) do\\\\\\\
  4795. \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and Utils:inBounds(val.x, val.y, val.w, val.h, event[3], event[4]) and tostring(self.windows[1]) == tostring(val) and val:click(event[3], event[4], event[2])) then\\\\\\\
  4796. \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
  4797. \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4798. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4799. \\\\009\\\\009\\\\009elseif (event[1] == \\\\\\\"mouse_scroll\\\\\\\") then\\\\\\\
  4800. \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  4801. \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and val:scroll(event[2])) then\\\\\\\
  4802. \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
  4803. \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4804. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4805. \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.windows) do\\\\\\\
  4806. \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and val:scroll(event[2])) then\\\\\\\
  4807. \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
  4808. \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4809. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4810. \\\\009\\\\009\\\\009elseif (event[1] == \\\\\\\"mouse_drag\\\\\\\") then\\\\\\\
  4811. \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  4812. \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and val:drag(event[3], event[4], event[2])) then\\\\\\\
  4813. \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
  4814. \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4815. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4816. \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.windows) do\\\\\\\
  4817. \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and val:drag(event[3], event[4], event[2])) then\\\\\\\
  4818. \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
  4819. \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4820. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4821. \\\\009\\\\009\\\\009elseif (event[1] == \\\\\\\"char\\\\\\\") then\\\\\\\
  4822. \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  4823. \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and val:char(event[2])) then\\\\\\\
  4824. \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
  4825. \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4826. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4827. \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.windows) do\\\\\\\
  4828. \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and val:char(event[2])) then\\\\\\\
  4829. \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
  4830. \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4831. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4832. \\\\009\\\\009\\\\009elseif (event[1] == \\\\\\\"key\\\\\\\") then\\\\\\\
  4833. \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  4834. \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and val:key(event[2])) then\\\\\\\
  4835. \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
  4836. \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4837. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4838. \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.windows) do\\\\\\\
  4839. \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and val:key(event[2])) then\\\\\\\
  4840. \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
  4841. \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4842. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4843. \\\\009\\\\009\\\\009else\\\\\\\
  4844. \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  4845. \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and val:event(event)) then\\\\\\\
  4846. \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
  4847. \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4848. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4849. \\\\009\\\\009\\\\009\\\\009for key, val in pairs(self.windows) do\\\\\\\
  4850. \\\\009\\\\009\\\\009\\\\009\\\\009if (val.visible and val:event(event)) then\\\\\\\
  4851. \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009break\\\\\\\
  4852. \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4853. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4854. \\\\009\\\\009\\\\009end\\\\\\\
  4855. \\\\009\\\\009\\\\009return event\\\\\\\
  4856. \\\\009\\\\009end\\\\\\\
  4857. \\\\009\\\\009while (true) do\\\\\\\
  4858. \\\\009\\\\009\\\\009if (#self.windows == 0 and #self.components == 0) then\\\\\\\
  4859. \\\\009\\\\009\\\\009\\\\009self:exit()\\\\\\\
  4860. \\\\009\\\\009\\\\009end\\\\\\\
  4861. \\\\009\\\\009\\\\009self:drawAll()\\\\\\\
  4862. \\\\009\\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  4863. \\\\009\\\\009\\\\009\\\\009if (val.visible) then\\\\\\\
  4864. \\\\009\\\\009\\\\009\\\\009\\\\009val:update()\\\\\\\
  4865. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4866. \\\\009\\\\009\\\\009end\\\\\\\
  4867. \\\\009\\\\009\\\\009for key, val in pairs(self.windows) do\\\\\\\
  4868. \\\\009\\\\009\\\\009\\\\009if (val.visible) then\\\\\\\
  4869. \\\\009\\\\009\\\\009\\\\009\\\\009val:update()\\\\\\\
  4870. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4871. \\\\009\\\\009\\\\009end\\\\\\\
  4872. \\\\009\\\\009\\\\009local eventTbl = handleEvent()\\\\\\\
  4873. \\\\009\\\\009\\\\009self:appUpdate(eventTbl);\\\\\\\
  4874. \\\\009\\\\009\\\\009--remove components marked for removal\\\\\\\
  4875. \\\\009\\\\009\\\\009local removed = {}\\\\\\\
  4876. \\\\009\\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  4877. \\\\009\\\\009\\\\009\\\\009if (val.removed) then\\\\\\\
  4878. \\\\009\\\\009\\\\009\\\\009\\\\009table.insert(removed, key)\\\\\\\
  4879. \\\\009\\\\009\\\\009\\\\009else\\\\\\\
  4880. \\\\009\\\\009\\\\009\\\\009\\\\009val:update()\\\\\\\
  4881. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4882. \\\\009\\\\009\\\\009end\\\\\\\
  4883. \\\\009\\\\009\\\\009for key, val in pairs(removed) do\\\\\\\
  4884. \\\\009\\\\009\\\\009\\\\009self.components[val] = nil\\\\\\\
  4885. \\\\009\\\\009\\\\009end\\\\\\\
  4886. \\\\009\\\\009\\\\009--close windows marked for close\\\\\\\
  4887. \\\\009\\\\009\\\\009local closed = {}\\\\\\\
  4888. \\\\009\\\\009\\\\009for key, val in pairs(self.windows) do\\\\\\\
  4889. \\\\009\\\\009\\\\009\\\\009if (val.closed) then\\\\\\\
  4890. \\\\009\\\\009\\\\009\\\\009\\\\009table.insert(closed, key)\\\\\\\
  4891. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  4892. \\\\009\\\\009\\\\009end\\\\\\\
  4893. \\\\009\\\\009\\\\009for key, val in pairs(closed) do\\\\\\\
  4894. \\\\009\\\\009\\\\009\\\\009self.windows[val] = nil\\\\\\\
  4895. \\\\009\\\\009\\\\009end\\\\\\\
  4896. \\\\009\\\\009end\\\\\\\
  4897. \\\\009end;\\\\\\\
  4898. \\\\009setVisibleWindow = function(self, windowTbl)\\\\\\\
  4899. \\\\009\\\\009for key, val in pairs(self.windows) do\\\\\\\
  4900. \\\\009\\\\009\\\\009local wasVisible = val.visible\\\\\\\
  4901. \\\\009\\\\009\\\\009val.visible = (tostring(val) == tostring(windowTbl) or self.multiWindow)\\\\\\\
  4902. \\\\009\\\\009\\\\009if (not wasVisible and val.visible) then\\\\\\\
  4903. \\\\009\\\\009\\\\009\\\\009val:onView()\\\\\\\
  4904. \\\\009\\\\009\\\\009end\\\\\\\
  4905. \\\\009\\\\009\\\\009if (wasVisible and not val.visible) then\\\\\\\
  4906. \\\\009\\\\009\\\\009\\\\009val:onHide()\\\\\\\
  4907. \\\\009\\\\009\\\\009end\\\\\\\
  4908. \\\\009\\\\009end\\\\\\\
  4909. \\\\009end;\\\\\\\
  4910. \\\\009addWindow = function(self, windowTbl)\\\\\\\
  4911. \\\\009\\\\009windowTbl.closed = false\\\\\\\
  4912. \\\\009\\\\009windowTbl.visible = self.multiWindow\\\\\\\
  4913. \\\\009\\\\009table.insert(self.windows, windowTbl)\\\\\\\
  4914. \\\\009\\\\009if (#self.windows == 1) then\\\\\\\
  4915. \\\\009\\\\009\\\\009self:setVisibleWindow(windowTbl)\\\\\\\
  4916. \\\\009\\\\009end\\\\\\\
  4917. \\\\009end;\\\\\\\
  4918. \\\\009closeWindow = function(self, windowTbl)\\\\\\\
  4919. \\\\009\\\\009for key, val in pairs(self.windows) do\\\\\\\
  4920. \\\\009\\\\009\\\\009if (val == windowTbl) then\\\\\\\
  4921. \\\\009\\\\009\\\\009\\\\009val.closed = true\\\\\\\
  4922. \\\\009\\\\009\\\\009end\\\\\\\
  4923. \\\\009\\\\009end\\\\\\\
  4924. \\\\009end;\\\\\\\
  4925. \\\\009addComponent = function(self, componentTbl)\\\\\\\
  4926. \\\\009\\\\009componentTbl.parent = self\\\\\\\
  4927. \\\\009\\\\009componentTbl.parent.x = 1\\\\\\\
  4928. \\\\009\\\\009componentTbl.parent.y = 1\\\\\\\
  4929. \\\\009\\\\009componentTbl.parent.w = self.termSize[1]\\\\\\\
  4930. \\\\009\\\\009componentTbl.parent.h = self.termSize[2]\\\\\\\
  4931. \\\\009\\\\009componentTbl.removed = false\\\\\\\
  4932. \\\\009\\\\009table.insert(self.components, componentTbl)\\\\\\\
  4933. \\\\009end;\\\\\\\
  4934. \\\\009removeComponent = function(self, componentTbl)\\\\\\\
  4935. \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  4936. \\\\009\\\\009\\\\009if (val == componentTbl) then\\\\\\\
  4937. \\\\009\\\\009\\\\009\\\\009val.removed = true\\\\\\\
  4938. \\\\009\\\\009\\\\009end\\\\\\\
  4939. \\\\009\\\\009end\\\\\\\
  4940. \\\\009end;\\\\\\\
  4941. \\\\009terminate = function(self)\\\\\\\
  4942. \\\\009\\\\009self:exit()\\\\\\\
  4943. \\\\009end;\\\\\\\
  4944. \\\\009exit = function(self)\\\\\\\
  4945. \\\\009\\\\009if (self.useNative) then\\\\\\\
  4946. \\\\009\\\\009\\\\009term.redirect(self.oldTerm)\\\\\\\
  4947. \\\\009\\\\009end\\\\\\\
  4948. \\\\009\\\\009term.setBackgroundColor(colors.black)\\\\\\\
  4949. \\\\009\\\\009term.clear()\\\\\\\
  4950. \\\\009\\\\009term.setCursorPos(1, 1)\\\\\\\
  4951. \\\\009\\\\009error()\\\\\\\
  4952. \\\\009end;\\\\\\\
  4953. \\\\009cloneComponent = function(self, obj, copied)\\\\\\\
  4954. \\\\009\\\\009if type(obj) ~= 'table' then\\\\\\\
  4955. \\\\009\\\\009\\\\009return obj\\\\\\\
  4956. \\\\009\\\\009end\\\\\\\
  4957. \\\\009\\\\009if copied and copied[obj] then\\\\\\\
  4958. \\\\009\\\\009\\\\009return copied[obj]\\\\\\\
  4959. \\\\009\\\\009end\\\\\\\
  4960. \\\\009\\\\009local c = copied or {}\\\\\\\
  4961. \\\\009\\\\009local res = setmetatable({}, getmetatable(obj))\\\\\\\
  4962. \\\\009\\\\009c[obj] = res\\\\\\\
  4963. \\\\009\\\\009for k, v in pairs(obj) do\\\\\\\
  4964. \\\\009\\\\009\\\\009res[self:cloneComponent(k, c)] = self:cloneComponent(v, c)\\\\\\\
  4965. \\\\009\\\\009end\\\\\\\
  4966. \\\\009\\\\009return res\\\\\\\
  4967. \\\\009end;\\\\\\\
  4968. \\\\009inheritComponent = function(self, obj, newTbl)\\\\\\\
  4969. \\\\009\\\\009local oldComponent = self:cloneComponent(obj)\\\\\\\
  4970. \\\\009\\\\009for k, v in pairs(newTbl) do\\\\\\\
  4971. \\\\009\\\\009\\\\009oldComponent[k] = v\\\\\\\
  4972. \\\\009\\\\009end \\\\\\\
  4973. \\\\009\\\\009return oldComponent\\\\\\\
  4974. \\\\009end;\\\\\\\
  4975. \\\\009setDefaultStyle = function(self, styleTbl)\\\\\\\
  4976. \\\\009\\\\009self.style = styleTbl\\\\\\\
  4977. \\\\009end;\\\\\\\
  4978. }\\\\\\\
  4979. Controller.mt = {\\\\\\\
  4980. \\\\009__index = function (table, key)\\\\\\\
  4981. \\\\009\\\\009return Controller.prototype[key]\\\\\\\
  4982. \\\\009end;\\\\\\\
  4983. }\\\\\\\
  4984. setmetatable(Controller, Controller.mt)\\\\\\\
  4985. \\\\\\\
  4986. -- --\\\\\\\
  4987. -- Utils @static\\\\\\\
  4988. -- Utilities to aid in UI design\\\\\\\
  4989. -- --\\\\\\\
  4990. Utils = {}\\\\\\\
  4991. Utils.prototype = {\\\\\\\
  4992. \\\\009drawRect = function(self, x, y, w, h, color)\\\\\\\
  4993. \\\\009\\\\009term.setBackgroundColor(color)\\\\\\\
  4994. \\\\009\\\\009for pY = y, h - 1 + y, 1 do\\\\\\\
  4995. \\\\009\\\\009\\\\009term.setCursorPos(x, pY)\\\\\\\
  4996. \\\\009\\\\009\\\\009for pX = x, w - 1 + x, 1 do\\\\\\\
  4997. \\\\009\\\\009\\\\009\\\\009term.write(\\\\\\\" \\\\\\\")\\\\\\\
  4998. \\\\009\\\\009\\\\009end\\\\\\\
  4999. \\\\009\\\\009end\\\\\\\
  5000. \\\\009end;\\\\\\\
  5001. \\\\009alignText = function(self, alignment, textLength, x, w)\\\\\\\
  5002. \\\\009\\\\009if (alignment == \\\\\\\"left\\\\\\\") then\\\\\\\
  5003. \\\\009\\\\009\\\\009return x\\\\\\\
  5004. \\\\009\\\\009elseif (alignment == \\\\\\\"center\\\\\\\") then\\\\\\\
  5005. \\\\009\\\\009\\\\009return x + ((w - textLength) / 2)\\\\\\\
  5006. \\\\009\\\\009elseif (alignment == \\\\\\\"right\\\\\\\") then\\\\\\\
  5007. \\\\009\\\\009\\\\009return x + (w - textLength)\\\\\\\
  5008. \\\\009\\\\009end\\\\\\\
  5009. \\\\009end;\\\\\\\
  5010. \\\\009limitText = function(self, text, limit, tail)\\\\\\\
  5011. \\\\009\\\\009if (string.len(text) > limit) then\\\\\\\
  5012. \\\\009\\\\009\\\\009return string.sub(text, 0, limit - string.len(tail)) .. tail\\\\\\\
  5013. \\\\009\\\\009else\\\\\\\
  5014. \\\\009\\\\009\\\\009return text\\\\\\\
  5015. \\\\009\\\\009end\\\\\\\
  5016. \\\\009end;\\\\\\\
  5017. \\\\009wrapText = function(self, text, limit)\\\\\\\
  5018. \\\\009\\\\009local index = 0\\\\\\\
  5019. \\\\009\\\\009return text:gsub(\\\\\\\"(%C?)\\\\\\\", function (w)\\\\\\\
  5020. \\\\009\\\\009\\\\009index = index + 1\\\\\\\
  5021. \\\\009\\\\009\\\\009return w .. (index % limit == 0 and \\\\\\\"\\\\\\\\n\\\\\\\" or \\\\\\\"\\\\\\\")\\\\\\\
  5022. \\\\009\\\\009end)\\\\\\\
  5023. \\\\009end;\\\\\\\
  5024. \\\\009splitText = function(self, str, pat)\\\\\\\
  5025. \\\\009\\\\009local t = {}\\\\\\\
  5026. \\\\009\\\\009local fpat = \\\\\\\"(.-)\\\\\\\" .. pat\\\\\\\
  5027. \\\\009\\\\009local last_end = 1\\\\\\\
  5028. \\\\009\\\\009local s, e, cap = str:find(fpat, 1)\\\\\\\
  5029. \\\\009\\\\009while s do\\\\\\\
  5030. \\\\009\\\\009\\\\009if (s ~= 1 or cap ~= \\\\\\\"\\\\\\\") then\\\\\\\
  5031. \\\\009\\\\009\\\\009\\\\009table.insert(t,cap)\\\\\\\
  5032. \\\\009\\\\009\\\\009end\\\\\\\
  5033. \\\\009\\\\009\\\\009last_end = e + 1\\\\\\\
  5034. \\\\009\\\\009\\\\009s, e, cap = str:find(fpat, last_end)\\\\\\\
  5035. \\\\009\\\\009end\\\\\\\
  5036. \\\\009\\\\009if (last_end <= #str) then\\\\\\\
  5037. \\\\009\\\\009\\\\009cap = str:sub(last_end)\\\\\\\
  5038. \\\\009\\\\009\\\\009table.insert(t, cap)\\\\\\\
  5039. \\\\009\\\\009end\\\\\\\
  5040. \\\\009\\\\009return t\\\\\\\
  5041. \\\\009end;\\\\\\\
  5042. \\\\009inBounds = function(self, boundX, boundY, boundW, boundH, checkX, checkY)\\\\\\\
  5043. \\\\009\\\\009local xInBound = (checkX >= boundX) and (checkX <= boundX + boundW - 1)\\\\\\\
  5044. \\\\009\\\\009local yInBound = (checkY >= boundY) and (checkY <= boundY + boundH - 1)\\\\\\\
  5045. \\\\009\\\\009return xInBound and yInBound\\\\\\\
  5046. \\\\009end;\\\\\\\
  5047. }\\\\\\\
  5048. Utils.mt = {\\\\\\\
  5049. \\\\009__index = function(table, key)\\\\\\\
  5050. \\\\009\\\\009return Utils.prototype[key]\\\\\\\
  5051. \\\\009end;\\\\\\\
  5052. }\\\\\\\
  5053. setmetatable(Utils, Utils.mt)\\\\\\\
  5054. \\\\\\\
  5055. -- --\\\\\\\
  5056. -- Style\\\\\\\
  5057. -- Contains default styles for components and windows\\\\\\\
  5058. -- --\\\\\\\
  5059. Style = {}\\\\\\\
  5060. Style.prototype = {\\\\\\\
  5061. \\\\009Window = {};\\\\\\\
  5062. \\\\009Component = {};\\\\\\\
  5063. \\\\009Panel = {};\\\\\\\
  5064. \\\\009Button = {};\\\\\\\
  5065. \\\\009Label = {};\\\\\\\
  5066. \\\\009TextField = {};\\\\\\\
  5067. \\\\009List = {};\\\\\\\
  5068. \\\\009CheckBox = {};\\\\\\\
  5069. \\\\009ProgressBar = {};\\\\\\\
  5070. }\\\\\\\
  5071. Style.mt = {\\\\\\\
  5072. \\\\009__index = function (table, key)\\\\\\\
  5073. \\\\009\\\\009return Style.prototype[key]\\\\\\\
  5074. \\\\009end;\\\\\\\
  5075. }\\\\\\\
  5076. function Style:new(styleTbl)\\\\\\\
  5077. \\\\009setmetatable(styleTbl, Style.mt)\\\\\\\
  5078. \\\\009return styleTbl\\\\\\\
  5079. end\\\\\\\
  5080. \\\\\\\
  5081. -- --\\\\\\\
  5082. -- Window\\\\\\\
  5083. -- Pretty self explainatory\\\\\\\
  5084. -- --\\\\\\\
  5085. Window = {}\\\\\\\
  5086. Window.prototype = {\\\\\\\
  5087. \\\\009-- vars\\\\\\\
  5088. \\\\009bgColor = colors.lightGray;\\\\\\\
  5089. \\\\009tlColor = colors.gray;\\\\\\\
  5090. \\\\009activeTlColor = colors.blue;\\\\\\\
  5091. \\\\009components = {};\\\\\\\
  5092. \\\\009titleLabel = {};\\\\\\\
  5093. \\\\009z = 0;\\\\\\\
  5094. \\\\009x = 1;\\\\\\\
  5095. \\\\009y = 1;\\\\\\\
  5096. \\\\009h = 1;\\\\\\\
  5097. \\\\009w = 1;\\\\\\\
  5098. \\\\009draggable = false;\\\\\\\
  5099. \\\\009lastClick = {};\\\\\\\
  5100. \\\\009hasShadow = false;\\\\\\\
  5101. \\\\009shadowColor = colors.black;\\\\\\\
  5102. \\\\009visible = false;\\\\\\\
  5103. \\\\009closed = false;\\\\\\\
  5104. \\\\009--functions\\\\\\\
  5105. \\\\009draw = function(self)\\\\\\\
  5106. \\\\009\\\\009--draw shadow\\\\\\\
  5107. \\\\009\\\\009if (self.hasShadow) then\\\\\\\
  5108. \\\\009\\\\009\\\\009Utils:drawRect(self.x + 1, self.y + 1, self.w, self.h, self.shadowColor)\\\\\\\
  5109. \\\\009\\\\009end\\\\\\\
  5110. \\\\009\\\\009--drawPane\\\\\\\
  5111. \\\\009\\\\009Utils:drawRect(self.x, self.y, self.w, self.h, self.bgColor)\\\\\\\
  5112. \\\\009\\\\009--drawTitle\\\\\\\
  5113. \\\\009\\\\009term.setBackgroundColor((self:isActive() and Controller.multiWindow) and self.activeTlColor or self.tlColor)\\\\\\\
  5114. \\\\009\\\\009term.setCursorPos(self.x, self.y)\\\\\\\
  5115. \\\\009\\\\009for pX = self.x, self.w + self.x - 1, 1 do\\\\\\\
  5116. \\\\009\\\\009\\\\009term.write(\\\\\\\" \\\\\\\")\\\\\\\
  5117. \\\\009\\\\009end\\\\\\\
  5118. \\\\009\\\\009if (self.titleLabel.draw ~= nil) then\\\\\\\
  5119. \\\\009\\\\009\\\\009self.titleLabel:draw()\\\\\\\
  5120. \\\\009\\\\009end\\\\\\\
  5121. \\\\009\\\\009--draw components\\\\\\\
  5122. \\\\009\\\\009self:drawComponents()\\\\\\\
  5123. \\\\009end;\\\\\\\
  5124. \\\\009drawComponents = function(self)\\\\\\\
  5125. \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  5126. \\\\009\\\\009\\\\009if (val.visible) then\\\\\\\
  5127. \\\\009\\\\009\\\\009\\\\009val:draw()\\\\\\\
  5128. \\\\009\\\\009\\\\009end\\\\\\\
  5129. \\\\009\\\\009end\\\\\\\
  5130. \\\\009end;\\\\\\\
  5131. \\\\009setTitleLabel = function(self, newLabel)\\\\\\\
  5132. \\\\009\\\\009newLabel.parent = self\\\\\\\
  5133. \\\\009\\\\009setmetatable(newLabel, Label.tlmt)\\\\\\\
  5134. \\\\009\\\\009self.titleLabel = newLabel\\\\\\\
  5135. \\\\009end;\\\\\\\
  5136. \\\\009addComponent = function(self, componentTbl)\\\\\\\
  5137. \\\\009\\\\009componentTbl.parent = self\\\\\\\
  5138. \\\\009\\\\009componentTbl.removed = false\\\\\\\
  5139. \\\\009\\\\009table.insert(self.components, componentTbl)\\\\\\\
  5140. \\\\009end;\\\\\\\
  5141. \\\\009removeComponent = function(self, componentTbl)\\\\\\\
  5142. \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  5143. \\\\009\\\\009\\\\009if (val == componentTbl) then\\\\\\\
  5144. \\\\009\\\\009\\\\009\\\\009val.removed = true\\\\\\\
  5145. \\\\009\\\\009\\\\009end\\\\\\\
  5146. \\\\009\\\\009end\\\\\\\
  5147. \\\\009end;\\\\\\\
  5148. \\\\009close = function(self)\\\\\\\
  5149. \\\\009\\\\009Controller:closeWindow(self)\\\\\\\
  5150. \\\\009end;\\\\\\\
  5151. \\\\009click = function(self, x, y)\\\\\\\
  5152. \\\\009\\\\009if (self.draggable and ((x >= self.x) and (x <= (self.x + self.w - 1)) and (y >= self.y) and (y <= self.y))) then\\\\\\\
  5153. \\\\009\\\\009\\\\009self.lastClick.x = x\\\\\\\
  5154. \\\\009\\\\009\\\\009self.lastClick.y = y\\\\\\\
  5155. \\\\009\\\\009else\\\\\\\
  5156. \\\\009\\\\009\\\\009self.lastClick.x = nil\\\\\\\
  5157. \\\\009\\\\009\\\\009self.lastClick.y = nil\\\\\\\
  5158. \\\\009\\\\009end\\\\\\\
  5159. \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  5160. \\\\009\\\\009\\\\009val:click(x, y)\\\\\\\
  5161. \\\\009\\\\009end\\\\\\\
  5162. \\\\009\\\\009return (self.draggable and ((x >= self.x) and (x <= (self.x + self.w - 1)) and (y >= self.y) and (y <= self.y)))\\\\\\\
  5163. \\\\009end;\\\\\\\
  5164. \\\\009key = function(self, keyCode)\\\\\\\
  5165. \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  5166. \\\\009\\\\009\\\\009val:key(keyCode)\\\\\\\
  5167. \\\\009\\\\009end\\\\\\\
  5168. \\\\009end;\\\\\\\
  5169. \\\\009char = function(self, char)\\\\\\\
  5170. \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  5171. \\\\009\\\\009\\\\009val:char(char)\\\\\\\
  5172. \\\\009\\\\009end\\\\\\\
  5173. \\\\009end;\\\\\\\
  5174. \\\\009scroll = function(self, direction)\\\\\\\
  5175. \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  5176. \\\\009\\\\009\\\\009val:scroll(direction)\\\\\\\
  5177. \\\\009\\\\009end\\\\\\\
  5178. \\\\009end;\\\\\\\
  5179. \\\\009drag = function(self, x, y)\\\\\\\
  5180. \\\\009\\\\009if (self.draggable and self.lastClick.x ~= nil) then\\\\\\\
  5181. \\\\009\\\\009\\\\009self.x = self.x + x - self.lastClick.x\\\\\\\
  5182. \\\\009\\\\009\\\\009self.y = self.y + y - self.lastClick.y\\\\\\\
  5183. \\\\009\\\\009\\\\009self.lastClick.x = x\\\\\\\
  5184. \\\\009\\\\009\\\\009self.lastClick.y = y\\\\\\\
  5185. \\\\009\\\\009end\\\\\\\
  5186. \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  5187. \\\\009\\\\009\\\\009val:drag(x, y)\\\\\\\
  5188. \\\\009\\\\009end\\\\\\\
  5189. \\\\009end;\\\\\\\
  5190. \\\\009event = function(self, eventTbl)\\\\\\\
  5191. \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  5192. \\\\009\\\\009\\\\009val:event(eventTbl)\\\\\\\
  5193. \\\\009\\\\009end\\\\\\\
  5194. \\\\009end;\\\\\\\
  5195. \\\\009onView = function(self)\\\\\\\
  5196. \\\\009end;\\\\\\\
  5197. \\\\009onHide = function(self)\\\\\\\
  5198. \\\\009end;\\\\\\\
  5199. \\\\009update = function(self)\\\\\\\
  5200. \\\\009\\\\009local removed = {}\\\\\\\
  5201. \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  5202. \\\\009\\\\009\\\\009if (val.removed) then\\\\\\\
  5203. \\\\009\\\\009\\\\009\\\\009table.insert(removed, key)\\\\\\\
  5204. \\\\009\\\\009\\\\009else\\\\\\\
  5205. \\\\009\\\\009\\\\009\\\\009val:update()\\\\\\\
  5206. \\\\009\\\\009\\\\009end\\\\\\\
  5207. \\\\009\\\\009end\\\\\\\
  5208. \\\\009\\\\009for key, val in pairs(removed) do\\\\\\\
  5209. \\\\009\\\\009\\\\009self.components[val] = nil\\\\\\\
  5210. \\\\009\\\\009end\\\\\\\
  5211. \\\\009end;\\\\\\\
  5212. \\\\009isActive = function(self)\\\\\\\
  5213. \\\\009\\\\009return Controller.windows[1] == self\\\\\\\
  5214. \\\\009end;\\\\\\\
  5215. }\\\\\\\
  5216. Window.mt = {\\\\\\\
  5217. \\\\009__index = function (table, key)\\\\\\\
  5218. \\\\009\\\\009if (Controller.style.Window[key] ~= nil) then\\\\\\\
  5219. \\\\009\\\\009\\\\009return Controller.style.Window[key]\\\\\\\
  5220. \\\\009\\\\009else\\\\\\\
  5221. \\\\009\\\\009\\\\009return Window.prototype[key]\\\\\\\
  5222. \\\\009\\\\009end\\\\\\\
  5223. \\\\009end;\\\\\\\
  5224. }\\\\\\\
  5225. function Window:new(windowTbl)\\\\\\\
  5226. \\\\009setmetatable(windowTbl, Window.mt)\\\\\\\
  5227. \\\\009windowTbl.components = {}\\\\\\\
  5228. \\\\009return windowTbl\\\\\\\
  5229. end\\\\\\\
  5230. \\\\\\\
  5231. -- --\\\\\\\
  5232. -- Component @abstract\\\\\\\
  5233. -- Abstract class used to represent components in a window\\\\\\\
  5234. -- --\\\\\\\
  5235. Component = {}\\\\\\\
  5236. Component.prototype = {\\\\\\\
  5237. \\\\009--vars\\\\\\\
  5238. \\\\009x = 1;\\\\\\\
  5239. \\\\009y = 1;\\\\\\\
  5240. \\\\009h = 1;\\\\\\\
  5241. \\\\009w = 1;\\\\\\\
  5242. \\\\009z = 0;\\\\\\\
  5243. \\\\009parent = {};\\\\\\\
  5244. \\\\009removed = false;\\\\\\\
  5245. \\\\009visible = true;\\\\\\\
  5246. \\\\009--functions\\\\\\\
  5247. \\\\009draw = function(self) end;\\\\\\\
  5248. \\\\009click = function(self, x, y, button) return false end;\\\\\\\
  5249. \\\\009key = function(self, keyCode) return false end;\\\\\\\
  5250. \\\\009char = function(self, char) return false end;\\\\\\\
  5251. \\\\009scroll = function(self, direction) return false end;\\\\\\\
  5252. \\\\009drag = function(self, x, y, button) return false end;\\\\\\\
  5253. \\\\009event = function(self, eventTbl) return false end;\\\\\\\
  5254. \\\\009update = function(self) return false end;\\\\\\\
  5255. \\\\009termX = function(self) return self.x + self.parent.x - 1 end;\\\\\\\
  5256. \\\\009termY = function(self) return self.y + self.parent.y - 1 end;\\\\\\\
  5257. \\\\009setPos = function(self, x, y)\\\\\\\
  5258. \\\\009\\\\009self.x = x;\\\\\\\
  5259. \\\\009\\\\009self.y = y;\\\\\\\
  5260. \\\\009end;\\\\\\\
  5261. \\\\009setSize = function(self, w, h)\\\\\\\
  5262. \\\\009\\\\009self.w = w;\\\\\\\
  5263. \\\\009\\\\009self.h = h;\\\\\\\
  5264. \\\\009end;\\\\\\\
  5265. }\\\\\\\
  5266. \\\\\\\
  5267. -- --\\\\\\\
  5268. -- Panel\\\\\\\
  5269. -- Pretty self explainatory\\\\\\\
  5270. -- --\\\\\\\
  5271. Panel = {}\\\\\\\
  5272. Panel.prototype = {\\\\\\\
  5273. \\\\009-- vars\\\\\\\
  5274. \\\\009bgColor = colors.lightGray;\\\\\\\
  5275. \\\\009components = {};\\\\\\\
  5276. \\\\009z = 0;\\\\\\\
  5277. \\\\009x = 1;\\\\\\\
  5278. \\\\009y = 1;\\\\\\\
  5279. \\\\009h = 1;\\\\\\\
  5280. \\\\009w = 1;\\\\\\\
  5281. \\\\009--functions\\\\\\\
  5282. \\\\009draw = function(self)\\\\\\\
  5283. \\\\009\\\\009--drawPane\\\\\\\
  5284. \\\\009\\\\009Utils:drawRect(self.x, self.y, self.w, self.h, self.bgColor)\\\\\\\
  5285. \\\\009\\\\009--draw components\\\\\\\
  5286. \\\\009\\\\009self:drawComponents()\\\\\\\
  5287. \\\\009end;\\\\\\\
  5288. \\\\009drawComponents = function(self)\\\\\\\
  5289. \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  5290. \\\\009\\\\009\\\\009val:draw()\\\\\\\
  5291. \\\\009\\\\009end\\\\\\\
  5292. \\\\009end;\\\\\\\
  5293. \\\\009addComponent = function(self, componentTbl)\\\\\\\
  5294. \\\\009\\\\009componentTbl.parent = self\\\\\\\
  5295. \\\\009\\\\009componentTbl.removed = false\\\\\\\
  5296. \\\\009\\\\009table.insert(self.components, componentTbl)\\\\\\\
  5297. \\\\009end;\\\\\\\
  5298. \\\\009removeComponent = function(self, componentTbl)\\\\\\\
  5299. \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  5300. \\\\009\\\\009\\\\009if (val == componentTbl) then\\\\\\\
  5301. \\\\009\\\\009\\\\009\\\\009val.removed = true\\\\\\\
  5302. \\\\009\\\\009\\\\009end\\\\\\\
  5303. \\\\009\\\\009end\\\\\\\
  5304. \\\\009end;\\\\\\\
  5305. \\\\009close = function(self)\\\\\\\
  5306. \\\\009\\\\009Controller:closeWindow(self)\\\\\\\
  5307. \\\\009end;\\\\\\\
  5308. \\\\009click = function(self, x, y)\\\\\\\
  5309. \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  5310. \\\\009\\\\009\\\\009val:click(x, y)\\\\\\\
  5311. \\\\009\\\\009end\\\\\\\
  5312. \\\\009end;\\\\\\\
  5313. \\\\009key = function(self, keyCode)\\\\\\\
  5314. \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  5315. \\\\009\\\\009\\\\009val:key(keyCode)\\\\\\\
  5316. \\\\009\\\\009end\\\\\\\
  5317. \\\\009end;\\\\\\\
  5318. \\\\009char = function(self, char)\\\\\\\
  5319. \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  5320. \\\\009\\\\009\\\\009val:char(char)\\\\\\\
  5321. \\\\009\\\\009end\\\\\\\
  5322. \\\\009end;\\\\\\\
  5323. \\\\009scroll = function(self, direction)\\\\\\\
  5324. \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  5325. \\\\009\\\\009\\\\009val:scroll(direction)\\\\\\\
  5326. \\\\009\\\\009end\\\\\\\
  5327. \\\\009end;\\\\\\\
  5328. \\\\009drag = function(self, x, y)\\\\\\\
  5329. \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  5330. \\\\009\\\\009\\\\009val:drag(x, y)\\\\\\\
  5331. \\\\009\\\\009end\\\\\\\
  5332. \\\\009end;\\\\\\\
  5333. \\\\009event = function(self, eventTbl)\\\\\\\
  5334. \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  5335. \\\\009\\\\009\\\\009val:event(eventTbl)\\\\\\\
  5336. \\\\009\\\\009end\\\\\\\
  5337. \\\\009end;\\\\\\\
  5338. \\\\009update = function(self)\\\\\\\
  5339. \\\\009\\\\009local removed = {}\\\\\\\
  5340. \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  5341. \\\\009\\\\009\\\\009if (val.removed) then\\\\\\\
  5342. \\\\009\\\\009\\\\009\\\\009table.insert(removed, key)\\\\\\\
  5343. \\\\009\\\\009\\\\009else\\\\\\\
  5344. \\\\009\\\\009\\\\009\\\\009val:update()\\\\\\\
  5345. \\\\009\\\\009\\\\009end\\\\\\\
  5346. \\\\009\\\\009end\\\\\\\
  5347. \\\\009\\\\009for key, val in pairs(removed) do\\\\\\\
  5348. \\\\009\\\\009\\\\009self.components[val] = nil\\\\\\\
  5349. \\\\009\\\\009end\\\\\\\
  5350. \\\\009end;\\\\\\\
  5351. }\\\\\\\
  5352. Panel.mt = {\\\\\\\
  5353. \\\\009__index = function (table, key)\\\\\\\
  5354. \\\\009\\\\009if (Controller.style.Panel[key] ~= nil) then\\\\\\\
  5355. \\\\009\\\\009\\\\009return Controller.style.Panel[key]\\\\\\\
  5356. \\\\009\\\\009elseif (Panel.prototype[key] ~= nil) then\\\\\\\
  5357. \\\\009\\\\009\\\\009return Panel.prototype[key]\\\\\\\
  5358. \\\\009\\\\009else\\\\\\\
  5359. \\\\009\\\\009\\\\009return Component.prototype[key]\\\\\\\
  5360. \\\\009\\\\009end\\\\\\\
  5361. \\\\009end;\\\\\\\
  5362. }\\\\\\\
  5363. function Panel:new(panelTbl)\\\\\\\
  5364. \\\\009setmetatable(panelTbl, Panel.mt)\\\\\\\
  5365. \\\\009panelTbl.components = {}\\\\\\\
  5366. \\\\009return panelTbl\\\\\\\
  5367. end\\\\\\\
  5368. \\\\\\\
  5369. -- --\\\\\\\
  5370. -- Button extends Component\\\\\\\
  5371. -- A component that you can click\\\\\\\
  5372. -- --\\\\\\\
  5373. Button = {}\\\\\\\
  5374. Button.prototype = {\\\\\\\
  5375. \\\\009--vars\\\\\\\
  5376. \\\\009h = 3;\\\\\\\
  5377. \\\\009w = 16;\\\\\\\
  5378. \\\\009bgColor = colors.lightBlue;\\\\\\\
  5379. \\\\009textColor = colors.white;\\\\\\\
  5380. \\\\009activeColor = colors.blue;\\\\\\\
  5381. \\\\009activeTextColor = colors.white;\\\\\\\
  5382. \\\\009active = false;\\\\\\\
  5383. \\\\009text = \\\\\\\"txUI Button\\\\\\\";\\\\\\\
  5384. \\\\009textAlign = \\\\\\\"center\\\\\\\";\\\\\\\
  5385. \\\\009vertCenter = true;\\\\\\\
  5386. \\\\009--functions\\\\\\\
  5387. \\\\009action = function(self) end;\\\\\\\
  5388. \\\\009draw = function(self)\\\\\\\
  5389. \\\\009\\\\009Utils:drawRect(self:termX(), self:termY(), self.w, self.h, (function(self) if (self.active) then return self.activeColor else return self.bgColor end end)(self))\\\\\\\
  5390. \\\\009\\\\009term.setTextColor((function(self) if (self.active) then return self.activeTextColor else return self.textColor end end)(self))\\\\\\\
  5391. \\\\009\\\\009local lines = #Utils:splitText(self.text, \\\\\\\"\\\\\\\\n\\\\\\\")\\\\\\\
  5392. \\\\009\\\\009for k, v in ipairs(Utils:splitText(self.text, \\\\\\\"\\\\\\\\n\\\\\\\")) do\\\\\\\
  5393. \\\\009\\\\009\\\\009term.setCursorPos(Utils:alignText(self.textAlign, string.len(v), self:termX(), self.w), self:termY() + k - 1 + (self.vertCenter and ((self.h - lines) / 2) or 0))\\\\\\\
  5394. \\\\009\\\\009\\\\009term.write(v)\\\\\\\
  5395. \\\\009\\\\009end\\\\\\\
  5396. \\\\009end;\\\\\\\
  5397. \\\\009click = function (self, x, y)\\\\\\\
  5398. \\\\009\\\\009if ((x >= self:termX()) and (x <= (self:termX() + self.w - 1)) and (y >= self:termY()) and (y <= (self:termY() + self.h - 1))) then\\\\\\\
  5399. \\\\009\\\\009\\\\009self.active = true\\\\\\\
  5400. \\\\009\\\\009\\\\009self:action()\\\\\\\
  5401. \\\\009\\\\009else\\\\\\\
  5402. \\\\009\\\\009\\\\009self.active = false\\\\\\\
  5403. \\\\009\\\\009end\\\\\\\
  5404. \\\\009end;\\\\\\\
  5405. \\\\009update = function(self) return false end;\\\\\\\
  5406. }\\\\\\\
  5407. Button.mt = {\\\\\\\
  5408. \\\\009__index = function (table, key)\\\\\\\
  5409. \\\\009\\\\009if (Controller.style.Button[key] ~= nil) then\\\\\\\
  5410. \\\\009\\\\009\\\\009return Controller.style.Button[key]\\\\\\\
  5411. \\\\009\\\\009elseif (Button.prototype[key] ~= nil) then\\\\\\\
  5412. \\\\009\\\\009\\\\009return Button.prototype[key]\\\\\\\
  5413. \\\\009\\\\009else\\\\\\\
  5414. \\\\009\\\\009\\\\009return Component.prototype[key]\\\\\\\
  5415. \\\\009\\\\009end\\\\\\\
  5416. \\\\009end;\\\\\\\
  5417. }\\\\\\\
  5418. function Button:new(buttonTbl)\\\\\\\
  5419. \\\\009if (buttonTbl == nil) then\\\\\\\
  5420. \\\\009\\\\009buttonTbl = self\\\\\\\
  5421. \\\\009end\\\\\\\
  5422. \\\\009setmetatable(buttonTbl, Button.mt)\\\\\\\
  5423. \\\\009return buttonTbl\\\\\\\
  5424. end\\\\\\\
  5425. \\\\\\\
  5426. -- --\\\\\\\
  5427. -- Label extends Component\\\\\\\
  5428. -- A component that displays text\\\\\\\
  5429. -- --\\\\\\\
  5430. Label = {}\\\\\\\
  5431. Label.prototype = {\\\\\\\
  5432. \\\\009--vars\\\\\\\
  5433. \\\\009h = 1;\\\\\\\
  5434. \\\\009w = 16;\\\\\\\
  5435. \\\\009bgColor = colors.white;\\\\\\\
  5436. \\\\009textColor = colors.black;\\\\\\\
  5437. \\\\009text = \\\\\\\"txUI Label\\\\\\\";\\\\\\\
  5438. \\\\009textAlign = \\\\\\\"center\\\\\\\";\\\\\\\
  5439. \\\\009vertCenter = true;\\\\\\\
  5440. \\\\009--functions\\\\\\\
  5441. \\\\009draw = function(self)\\\\\\\
  5442. \\\\009\\\\009Utils:drawRect(self:termX(), self:termY(), self.w, self.h, self.bgColor)\\\\\\\
  5443. \\\\009\\\\009term.setBackgroundColor(self.bgColor)\\\\\\\
  5444. \\\\009\\\\009term.setTextColor(self.textColor)\\\\\\\
  5445. \\\\009\\\\009local lines = #Utils:splitText(self.text, \\\\\\\"\\\\\\\\n\\\\\\\")\\\\\\\
  5446. \\\\009\\\\009for k, v in ipairs(Utils:splitText(self.text, \\\\\\\"\\\\\\\\n\\\\\\\")) do\\\\\\\
  5447. \\\\009\\\\009\\\\009term.setCursorPos(Utils:alignText(self.textAlign, string.len(v), self:termX(), self.w), self:termY() + k - 1 + (self.vertCenter and ((self.h - lines) / 2) or 0))\\\\\\\
  5448. \\\\009\\\\009\\\\009term.write(v)\\\\\\\
  5449. \\\\009\\\\009end\\\\\\\
  5450. \\\\009end;\\\\\\\
  5451. \\\\009update = function(self) return false end;\\\\\\\
  5452. }\\\\\\\
  5453. Label.mt = {\\\\\\\
  5454. \\\\009__index = function (table, key)\\\\\\\
  5455. \\\\009\\\\009if (Label.prototype[key] ~= nil) then\\\\\\\
  5456. \\\\009\\\\009\\\\009return Label.prototype[key]\\\\\\\
  5457. \\\\009\\\\009else\\\\\\\
  5458. \\\\009\\\\009\\\\009return Component.prototype[key]\\\\\\\
  5459. \\\\009\\\\009end\\\\\\\
  5460. \\\\009end;\\\\\\\
  5461. }\\\\\\\
  5462. Label.tlmt = {\\\\\\\
  5463. \\\\009__index = function (table, key)\\\\\\\
  5464. \\\\009\\\\009if (key == \\\\\\\"w\\\\\\\") then\\\\\\\
  5465. \\\\009\\\\009\\\\009return table.parent.w\\\\\\\
  5466. \\\\009\\\\009elseif (key == \\\\\\\"bgColor\\\\\\\") then\\\\\\\
  5467. \\\\009\\\\009\\\\009return table.parent.tlColor\\\\\\\
  5468. \\\\009\\\\009elseif (Label.prototype[key] ~= nil) then\\\\\\\
  5469. \\\\009\\\\009\\\\009return Label.prototype[key]\\\\\\\
  5470. \\\\009\\\\009else\\\\\\\
  5471. \\\\009\\\\009\\\\009return Component.prototype[key]\\\\\\\
  5472. \\\\009\\\\009end\\\\\\\
  5473. \\\\009end;\\\\\\\
  5474. }\\\\\\\
  5475. function Label:new(labelTbl)\\\\\\\
  5476. \\\\009if (labelTbl == nil) then\\\\\\\
  5477. \\\\009\\\\009labelTbl = self\\\\\\\
  5478. \\\\009end\\\\\\\
  5479. \\\\009setmetatable(labelTbl, Label.mt)\\\\\\\
  5480. \\\\009return labelTbl\\\\\\\
  5481. end\\\\\\\
  5482. \\\\\\\
  5483. -- --\\\\\\\
  5484. -- TextField extends Component\\\\\\\
  5485. -- A component that allows for text input\\\\\\\
  5486. -- --\\\\\\\
  5487. TextField = {}\\\\\\\
  5488. TextField.prototype = {\\\\\\\
  5489. \\\\009--vars\\\\\\\
  5490. \\\\009h = 1;\\\\\\\
  5491. \\\\009w = 16;\\\\\\\
  5492. \\\\009bgColor = colors.white;\\\\\\\
  5493. \\\\009textColor = colors.black;\\\\\\\
  5494. \\\\009placeholderColor = colors.lightGray;\\\\\\\
  5495. \\\\009placeholder = \\\\\\\"txUI TextField\\\\\\\";\\\\\\\
  5496. \\\\009text = \\\\\\\"\\\\\\\";\\\\\\\
  5497. \\\\009textAlign = \\\\\\\"left\\\\\\\";\\\\\\\
  5498. \\\\009textMask = \\\\\\\"\\\\\\\";\\\\\\\
  5499. \\\\009active = false;\\\\\\\
  5500. \\\\009cursorPos = 0;\\\\\\\
  5501. \\\\009displayOffset = 0;\\\\\\\
  5502. \\\\009--functions\\\\\\\
  5503. \\\\009draw = function(self)\\\\\\\
  5504. \\\\009\\\\009Utils:drawRect(self:termX(), self:termY(), self.w, self.h, self.bgColor)\\\\\\\
  5505. \\\\009\\\\009term.setBackgroundColor(self.bgColor)\\\\\\\
  5506. \\\\009\\\\009if (self.active or string.len(self.text) ~= 0) then\\\\\\\
  5507. \\\\009\\\\009\\\\009local toWrite = string.sub(self.text, self.displayOffset + 1, self.displayOffset + self.w)\\\\\\\
  5508. \\\\009\\\\009\\\\009if (string.len(self.textMask) ~= 0) then\\\\\\\
  5509. \\\\009\\\\009\\\\009\\\\009toWrite = string.gsub(toWrite, \\\\\\\"%C\\\\\\\", self.textMask)\\\\\\\
  5510. \\\\009\\\\009\\\\009end\\\\\\\
  5511. \\\\009\\\\009\\\\009term.setCursorPos(Utils:alignText(self.textAlign, string.len(toWrite), self:termX(), self.w), self:termY() + (self.h / 2))\\\\\\\
  5512. \\\\009\\\\009\\\\009term.setTextColor(self.textColor)\\\\\\\
  5513. \\\\009\\\\009\\\\009term.write(toWrite)\\\\\\\
  5514. \\\\009\\\\009else\\\\\\\
  5515. \\\\009\\\\009\\\\009local toWrite = string.sub(self.placeholder, self.displayOffset + 1)\\\\\\\
  5516. \\\\009\\\\009\\\\009term.setCursorPos(Utils:alignText(self.textAlign, string.len(toWrite), self:termX(), self.w), self:termY() + (self.h / 2))\\\\\\\
  5517. \\\\009\\\\009\\\\009term.setTextColor(self.placeholderColor)\\\\\\\
  5518. \\\\009\\\\009\\\\009term.write(toWrite)\\\\\\\
  5519. \\\\009\\\\009end\\\\\\\
  5520. \\\\009\\\\009term.setCursorBlink(self.active)\\\\\\\
  5521. \\\\009\\\\009if (self.active) then\\\\\\\
  5522. \\\\009\\\\009\\\\009term.setCursorPos(self:termX() + self.cursorPos - self.displayOffset, self:termY() + (self.h / 2))\\\\\\\
  5523. \\\\009\\\\009end\\\\\\\
  5524. \\\\009end;\\\\\\\
  5525. \\\\009click = function (self, x, y)\\\\\\\
  5526. \\\\009\\\\009if ((x >= self:termX()) and (x <= (self:termX() + self.w - 1)) and (y >= self:termY()) and (y <= (self:termY() + self.h - 1))) then\\\\\\\
  5527. \\\\009\\\\009\\\\009self.active = true\\\\\\\
  5528. \\\\009\\\\009else\\\\\\\
  5529. \\\\009\\\\009\\\\009self.active = false\\\\\\\
  5530. \\\\009\\\\009end\\\\\\\
  5531. \\\\009end;\\\\\\\
  5532. \\\\009action = function(self)\\\\\\\
  5533. \\\\009end;\\\\\\\
  5534. \\\\009key = function(self, keyCode)\\\\\\\
  5535. \\\\009\\\\009if (self.active == false) then\\\\\\\
  5536. \\\\009\\\\009\\\\009return\\\\\\\
  5537. \\\\009\\\\009end\\\\\\\
  5538. \\\\009\\\\009if (keyCode == keys.backspace) then\\\\\\\
  5539. \\\\009\\\\009\\\\009if (self.cursorPos > 0) then\\\\\\\
  5540. \\\\009\\\\009\\\\009\\\\009self.text = string.sub(self.text, 1, self.cursorPos - 1) .. string.sub(self.text, self.cursorPos + 1)\\\\\\\
  5541. \\\\009\\\\009\\\\009\\\\009self.cursorPos = self.cursorPos - 1\\\\\\\
  5542. \\\\009\\\\009\\\\009\\\\009if (self.cursorPos - self.displayOffset < 0) then\\\\\\\
  5543. \\\\009\\\\009\\\\009\\\\009\\\\009self.displayOffset = self.displayOffset - 1\\\\\\\
  5544. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  5545. \\\\009\\\\009\\\\009\\\\009self:draw()\\\\\\\
  5546. \\\\009\\\\009\\\\009end\\\\\\\
  5547. \\\\009\\\\009elseif (keyCode == keys.left) then\\\\\\\
  5548. \\\\009\\\\009\\\\009if (self.cursorPos > 0) then\\\\\\\
  5549. \\\\009\\\\009\\\\009\\\\009self.cursorPos = self.cursorPos - 1\\\\\\\
  5550. \\\\009\\\\009\\\\009\\\\009if (self.cursorPos - self.displayOffset < 0) then\\\\\\\
  5551. \\\\009\\\\009\\\\009\\\\009\\\\009self.displayOffset = self.displayOffset - 1\\\\\\\
  5552. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  5553. \\\\009\\\\009\\\\009\\\\009self:draw()\\\\\\\
  5554. \\\\009\\\\009\\\\009end\\\\\\\
  5555. \\\\009\\\\009elseif (keyCode == keys.right) then\\\\\\\
  5556. \\\\009\\\\009\\\\009if (self.cursorPos < string.len(self.text)) then\\\\\\\
  5557. \\\\009\\\\009\\\\009\\\\009self.cursorPos = self.cursorPos + 1\\\\\\\
  5558. \\\\009\\\\009\\\\009\\\\009if (self.cursorPos - self.displayOffset > self.w - 1) then\\\\\\\
  5559. \\\\009\\\\009\\\\009\\\\009\\\\009self.displayOffset = self.displayOffset + 1\\\\\\\
  5560. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  5561. \\\\009\\\\009\\\\009\\\\009self:draw()\\\\\\\
  5562. \\\\009\\\\009\\\\009end\\\\\\\
  5563. \\\\009\\\\009elseif (keyCode == keys.enter) then\\\\\\\
  5564. \\\\009\\\\009\\\\009self:action()\\\\\\\
  5565. \\\\009\\\\009end\\\\\\\
  5566. \\\\009end;\\\\\\\
  5567. \\\\009char = function(self, char)\\\\\\\
  5568. \\\\009\\\\009if (self.active == false) then\\\\\\\
  5569. \\\\009\\\\009\\\\009return\\\\\\\
  5570. \\\\009\\\\009end\\\\\\\
  5571. \\\\009\\\\009self.text = string.sub(self.text, 1, self.cursorPos) .. char .. string.sub(self.text, self.cursorPos + 1)\\\\\\\
  5572. \\\\009\\\\009if (self.cursorPos - self.displayOffset > self.w - 2) then\\\\\\\
  5573. \\\\009\\\\009\\\\009self.displayOffset = self.displayOffset + 1\\\\\\\
  5574. \\\\009\\\\009end\\\\\\\
  5575. \\\\009\\\\009self.cursorPos = self.cursorPos + 1\\\\\\\
  5576. \\\\009end;\\\\\\\
  5577. \\\\009update = function(self)\\\\\\\
  5578. \\\\009\\\\009if (self.active) then\\\\\\\
  5579. \\\\009\\\\009\\\\009self:draw()\\\\\\\
  5580. \\\\009\\\\009end\\\\\\\
  5581. \\\\009end;\\\\\\\
  5582. }\\\\\\\
  5583. TextField.mt = {\\\\\\\
  5584. \\\\009__index = function (table, key)\\\\\\\
  5585. \\\\009\\\\009if (TextField.prototype[key] ~= nil) then\\\\\\\
  5586. \\\\009\\\\009\\\\009return TextField.prototype[key]\\\\\\\
  5587. \\\\009\\\\009else\\\\\\\
  5588. \\\\009\\\\009\\\\009return Component.prototype[key]\\\\\\\
  5589. \\\\009\\\\009end\\\\\\\
  5590. \\\\009end;\\\\\\\
  5591. }\\\\\\\
  5592. function TextField:new(textFieldTbl)\\\\\\\
  5593. \\\\009if (textFieldTbl == nil) then\\\\\\\
  5594. \\\\009\\\\009textFieldTbl = self\\\\\\\
  5595. \\\\009end\\\\\\\
  5596. \\\\009setmetatable(textFieldTbl, TextField.mt)\\\\\\\
  5597. \\\\009return textFieldTbl\\\\\\\
  5598. end\\\\\\\
  5599. \\\\\\\
  5600. -- --\\\\\\\
  5601. -- List extends Component\\\\\\\
  5602. -- A component that lets you hold lists of other components\\\\\\\
  5603. -- --\\\\\\\
  5604. List = {}\\\\\\\
  5605. List.prototype = {\\\\\\\
  5606. \\\\009--vars\\\\\\\
  5607. \\\\009h = 5;\\\\\\\
  5608. \\\\009w = 16;\\\\\\\
  5609. \\\\009bgColor = colors.white;\\\\\\\
  5610. \\\\009bgColorStripe = colors.lightGray;\\\\\\\
  5611. \\\\009textColor = colors.black;\\\\\\\
  5612. \\\\009textColorStripe = colors.black;\\\\\\\
  5613. \\\\009activeColor = colors.gray;\\\\\\\
  5614. \\\\009activeTextColor = colors.white;\\\\\\\
  5615. \\\\009textAlign = \\\\\\\"left\\\\\\\";\\\\\\\
  5616. \\\\009scrollBarColor = colors.gray;\\\\\\\
  5617. \\\\009scrollBarTextColor = colors.white;\\\\\\\
  5618. \\\\009scrollBar = true;\\\\\\\
  5619. \\\\009wrapText = false;\\\\\\\
  5620. \\\\009displayOffset = 0;\\\\\\\
  5621. \\\\009components = {};\\\\\\\
  5622. \\\\009active = false;\\\\\\\
  5623. \\\\009--functions\\\\\\\
  5624. \\\\009draw = function(self)\\\\\\\
  5625. \\\\009\\\\009Utils:drawRect(self:termX(), self:termY(), self.w, self.h, self.bgColor)\\\\\\\
  5626. \\\\009\\\\009term.setBackgroundColor(self.bgColor)\\\\\\\
  5627. \\\\009\\\\009-- draw the components\\\\\\\
  5628. \\\\009\\\\009local index = 1\\\\\\\
  5629. \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  5630. \\\\009\\\\009\\\\009val.w = self.w - (self.scrollBar and 1 or 0)\\\\\\\
  5631. \\\\009\\\\009\\\\009val.y = self.displayOffset + index\\\\\\\
  5632. \\\\009\\\\009\\\\009index = index + val.h\\\\\\\
  5633. \\\\009\\\\009\\\\009if ((val.y > 0) and (val.y <= self.h)) then\\\\\\\
  5634. \\\\009\\\\009\\\\009\\\\009val:draw()\\\\\\\
  5635. \\\\009\\\\009\\\\009end\\\\\\\
  5636. \\\\009\\\\009\\\\009self.components[key] = val\\\\\\\
  5637. \\\\009\\\\009end\\\\\\\
  5638. \\\\009\\\\009-- draw the scroll bar\\\\\\\
  5639. \\\\009\\\\009if (self.scrollBar) then\\\\\\\
  5640. \\\\009\\\\009\\\\009Utils:drawRect(self:termX() + self.w - 1, self:termY(), 1, self.h, self.scrollBarColor)\\\\\\\
  5641. \\\\009\\\\009\\\\009term.setBackgroundColor(self.scrollBarColor)\\\\\\\
  5642. \\\\009\\\\009\\\\009term.setTextColor(self.scrollBarTextColor)\\\\\\\
  5643. \\\\009\\\\009\\\\009term.setCursorPos(self:termX() + self.w - 1, self:termY())\\\\\\\
  5644. \\\\009\\\\009\\\\009term.write(\\\\\\\"^\\\\\\\")\\\\\\\
  5645. \\\\009\\\\009\\\\009term.setCursorPos(self:termX() + self.w - 1, self:termY() + self.h - 1)\\\\\\\
  5646. \\\\009\\\\009\\\\009term.write(\\\\\\\"v\\\\\\\")\\\\\\\
  5647. \\\\009\\\\009end\\\\\\\
  5648. \\\\009end;\\\\\\\
  5649. \\\\009click = function (self, x, y)\\\\\\\
  5650. \\\\009\\\\009for key, val in pairs(self.components) do\\\\\\\
  5651. \\\\009\\\\009\\\\009if ((val.y > 0) and (val.y <= self.h)) then\\\\\\\
  5652. \\\\009\\\\009\\\\009\\\\009val:click(x, y)\\\\\\\
  5653. \\\\009\\\\009\\\\009end\\\\\\\
  5654. \\\\009\\\\009end\\\\\\\
  5655. \\\\009\\\\009if ((x >= self:termX()) and (x <= (self:termX() + self.w - 1)) and (y >= self:termY()) and (y <= (self:termY() + self.h - 1))) then\\\\\\\
  5656. \\\\009\\\\009\\\\009self.active = true\\\\\\\
  5657. \\\\009\\\\009else\\\\\\\
  5658. \\\\009\\\\009\\\\009self.active = false\\\\\\\
  5659. \\\\009\\\\009end\\\\\\\
  5660. \\\\009\\\\009if (self.scrollBar) then\\\\\\\
  5661. \\\\009\\\\009\\\\009if ((x == self:termX() + self.w - 1) and (y == self:termY())) then\\\\\\\
  5662. \\\\009\\\\009\\\\009\\\\009if (self.displayOffset < 0) then\\\\\\\
  5663. \\\\009\\\\009\\\\009\\\\009\\\\009self.displayOffset = self.displayOffset + 1\\\\\\\
  5664. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  5665. \\\\009\\\\009\\\\009end\\\\\\\
  5666. \\\\009\\\\009\\\\009if ((x == self:termX() + self.w - 1) and (y == self:termY() + self.h - 1)) then\\\\\\\
  5667. \\\\009\\\\009\\\\009\\\\009if (self.displayOffset > -#self.components + 1) then\\\\\\\
  5668. \\\\009\\\\009\\\\009\\\\009\\\\009self.displayOffset = self.displayOffset - 1\\\\\\\
  5669. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  5670. \\\\009\\\\009\\\\009end\\\\\\\
  5671. \\\\009\\\\009end\\\\\\\
  5672. \\\\009end;\\\\\\\
  5673. \\\\009scroll = function (self, direction)\\\\\\\
  5674. \\\\009\\\\009if (self.active) then\\\\\\\
  5675. \\\\009\\\\009\\\\009if (direction == -1) then\\\\\\\
  5676. \\\\009\\\\009\\\\009\\\\009if (self.displayOffset < 0) then\\\\\\\
  5677. \\\\009\\\\009\\\\009\\\\009\\\\009self.displayOffset = self.displayOffset + 1\\\\\\\
  5678. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  5679. \\\\009\\\\009\\\\009end\\\\\\\
  5680. \\\\009\\\\009\\\\009if (direction == 1) then\\\\\\\
  5681. \\\\009\\\\009\\\\009\\\\009if (self.displayOffset > -#self.components + 1) then\\\\\\\
  5682. \\\\009\\\\009\\\\009\\\\009\\\\009self.displayOffset = self.displayOffset - 1\\\\\\\
  5683. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  5684. \\\\009\\\\009\\\\009end\\\\\\\
  5685. \\\\009\\\\009end\\\\\\\
  5686. \\\\009end;\\\\\\\
  5687. \\\\009addComponent = function(self, componentTbl)\\\\\\\
  5688. \\\\009\\\\009componentTbl.h = 1\\\\\\\
  5689. \\\\009\\\\009componentTbl.w = self.w - (self.scrollBar and 1 or 0)\\\\\\\
  5690. \\\\009\\\\009if (not self.wrapText) then\\\\\\\
  5691. \\\\009\\\\009\\\\009componentTbl.text = Utils:limitText(componentTbl.text, componentTbl.w, \\\\\\\"...\\\\\\\")\\\\\\\
  5692. \\\\009\\\\009else\\\\\\\
  5693. \\\\009\\\\009\\\\009if (string.len(componentTbl.text) > componentTbl.w) then\\\\\\\
  5694. \\\\009\\\\009\\\\009\\\\009componentTbl.h = math.ceil(string.len(componentTbl.text) / componentTbl.w)\\\\\\\
  5695. \\\\009\\\\009\\\\009\\\\009componentTbl.text = Utils:wrapText(componentTbl.text, componentTbl.w)\\\\\\\
  5696. \\\\009\\\\009\\\\009end\\\\\\\
  5697. \\\\009\\\\009end\\\\\\\
  5698. \\\\009\\\\009componentTbl.bgColor = (#self.components % 2 == 0 and self.bgColor or self.bgColorStripe)\\\\\\\
  5699. \\\\009\\\\009componentTbl.textColor = (#self.components % 2 == 0 and self.textColor or self.textColorStripe)\\\\\\\
  5700. \\\\009\\\\009componentTbl.textAlign = self.textAlign\\\\\\\
  5701. \\\\009\\\\009componentTbl.activeColor = self.activeColor\\\\\\\
  5702. \\\\009\\\\009componentTbl.activeTextColor = self.activeTextColor\\\\\\\
  5703. \\\\009\\\\009componentTbl.parent = self\\\\\\\
  5704. \\\\009\\\\009componentTbl.removed = false\\\\\\\
  5705. \\\\009\\\\009table.insert(self.components, componentTbl)\\\\\\\
  5706. \\\\009end;\\\\\\\
  5707. \\\\009update = function(self) return false end;\\\\\\\
  5708. }\\\\\\\
  5709. List.mt = {\\\\\\\
  5710. \\\\009__index = function (table, key)\\\\\\\
  5711. \\\\009\\\\009if (List.prototype[key] ~= nil) then\\\\\\\
  5712. \\\\009\\\\009\\\\009return List.prototype[key]\\\\\\\
  5713. \\\\009\\\\009else\\\\\\\
  5714. \\\\009\\\\009\\\\009return Component.prototype[key]\\\\\\\
  5715. \\\\009\\\\009end\\\\\\\
  5716. \\\\009end;\\\\\\\
  5717. }\\\\\\\
  5718. function List:new(listTbl)\\\\\\\
  5719. \\\\009if (listTbl == nil) then\\\\\\\
  5720. \\\\009\\\\009listTbl = self\\\\\\\
  5721. \\\\009end\\\\\\\
  5722. \\\\009setmetatable(listTbl, List.mt)\\\\\\\
  5723. \\\\009listTbl.components = {}\\\\\\\
  5724. \\\\009return listTbl\\\\\\\
  5725. end\\\\\\\
  5726. \\\\\\\
  5727. -- --\\\\\\\
  5728. -- Checkbox extends Component\\\\\\\
  5729. -- A component that lets users make a boolean choice\\\\\\\
  5730. -- --\\\\\\\
  5731. Checkbox = {}\\\\\\\
  5732. Checkbox.prototype = {\\\\\\\
  5733. \\\\009--vars\\\\\\\
  5734. \\\\009h = 1;\\\\\\\
  5735. \\\\009w = 16;\\\\\\\
  5736. \\\\009bgColor = colors.lightGray;\\\\\\\
  5737. \\\\009boxColor = colors.white;\\\\\\\
  5738. \\\\009textColor = colors.black;\\\\\\\
  5739. \\\\009checkedChar = \\\\\\\"X\\\\\\\";\\\\\\\
  5740. \\\\009checked = false;\\\\\\\
  5741. \\\\009text = \\\\\\\"txUI Checkbox\\\\\\\";\\\\\\\
  5742. \\\\009textPosition = \\\\\\\"right\\\\\\\";\\\\\\\
  5743. \\\\009--functions\\\\\\\
  5744. \\\\009draw = function(self)\\\\\\\
  5745. \\\\009\\\\009Utils:drawRect(self:termX(), self:termY(), self.w, self.h, self.bgColor)\\\\\\\
  5746. \\\\009\\\\009-- draw box and set label position\\\\\\\
  5747. \\\\009\\\\009term.setBackgroundColor(self.boxColor)\\\\\\\
  5748. \\\\009\\\\009term.setTextColor(self.textColor)\\\\\\\
  5749. \\\\009\\\\009if (self.textPosition == \\\\\\\"right\\\\\\\") then\\\\\\\
  5750. \\\\009\\\\009\\\\009Utils:drawRect(self:termX(), self:termY(), 1, 1, self.boxColor)\\\\\\\
  5751. \\\\009\\\\009\\\\009term.setCursorPos(self:termX(), self:termY())\\\\\\\
  5752. \\\\009\\\\009\\\\009term.write(self.checked and self.checkedChar or \\\\\\\" \\\\\\\")\\\\\\\
  5753. \\\\009\\\\009\\\\009term.setCursorPos(self:termX() + 2, self:termY())\\\\\\\
  5754. \\\\009\\\\009elseif (self.textPosition == \\\\\\\"left\\\\\\\") then\\\\\\\
  5755. \\\\009\\\\009\\\\009Utils:drawRect(self:termX() + self.w - 1, self:termY(), 1, 1, self.boxColor)\\\\\\\
  5756. \\\\009\\\\009\\\\009term.setCursorPos(self:termX() + self.w - 1, self:termY())\\\\\\\
  5757. \\\\009\\\\009\\\\009term.write(self.checked and self.checkedChar or \\\\\\\" \\\\\\\")\\\\\\\
  5758. \\\\009\\\\009\\\\009term.setCursorPos(self:termX() + self.w - string.len(self.text) - 2, self:termY())\\\\\\\
  5759. \\\\009\\\\009end\\\\\\\
  5760. \\\\009\\\\009-- draw label\\\\\\\
  5761. \\\\009\\\\009term.setBackgroundColor(self.bgColor)\\\\\\\
  5762. \\\\009\\\\009term.write(self.text)\\\\\\\
  5763. \\\\009end;\\\\\\\
  5764. \\\\009click = function (self, x, y)\\\\\\\
  5765. \\\\009\\\\009if ((x >= self:termX()) and (x <= (self:termX() + self.w - 1)) and (y >= self:termY()) and (y <= (self:termY() + self.h - 1))) then\\\\\\\
  5766. \\\\009\\\\009\\\\009self.checked = not self.checked\\\\\\\
  5767. \\\\009\\\\009end\\\\\\\
  5768. \\\\009end;\\\\\\\
  5769. \\\\009update = function(self) return false end;\\\\\\\
  5770. }\\\\\\\
  5771. Checkbox.mt = {\\\\\\\
  5772. \\\\009__index = function (table, key)\\\\\\\
  5773. \\\\009\\\\009if (Checkbox.prototype[key] ~= nil) then\\\\\\\
  5774. \\\\009\\\\009\\\\009return Checkbox.prototype[key]\\\\\\\
  5775. \\\\009\\\\009else\\\\\\\
  5776. \\\\009\\\\009\\\\009return Component.prototype[key]\\\\\\\
  5777. \\\\009\\\\009end\\\\\\\
  5778. \\\\009end;\\\\\\\
  5779. }\\\\\\\
  5780. function Checkbox:new(checkboxTbl)\\\\\\\
  5781. \\\\009if (checkboxTbl == nil) then\\\\\\\
  5782. \\\\009\\\\009checkboxTbl = self\\\\\\\
  5783. \\\\009end\\\\\\\
  5784. \\\\009setmetatable(checkboxTbl, Checkbox.mt)\\\\\\\
  5785. \\\\009return checkboxTbl\\\\\\\
  5786. end\\\\\\\
  5787. \\\\\\\
  5788. -- --\\\\\\\
  5789. -- ProgressBar extends Component\\\\\\\
  5790. -- A component that shows progress\\\\\\\
  5791. -- --\\\\\\\
  5792. ProgressBar = {}\\\\\\\
  5793. ProgressBar.prototype = {\\\\\\\
  5794. \\\\009--vars\\\\\\\
  5795. \\\\009h = 1;\\\\\\\
  5796. \\\\009w = 16;\\\\\\\
  5797. \\\\009val = 0;\\\\\\\
  5798. \\\\009bgColor = colors.white;\\\\\\\
  5799. \\\\009barColor = colors.lime;\\\\\\\
  5800. \\\\009textColor = colors.black;\\\\\\\
  5801. \\\\009barTextColor = colors.white;\\\\\\\
  5802. \\\\009textAlign = \\\\\\\"center\\\\\\\";\\\\\\\
  5803. \\\\009textMask = \\\\\\\"{val}%\\\\\\\";\\\\\\\
  5804. \\\\009showText = true;\\\\\\\
  5805. \\\\009vertCenter = true;\\\\\\\
  5806. \\\\009--functions\\\\\\\
  5807. \\\\009draw = function(self)\\\\\\\
  5808. \\\\009\\\\009if (self.val > 100) then\\\\\\\
  5809. \\\\009\\\\009\\\\009self.val = 100\\\\\\\
  5810. \\\\009\\\\009end\\\\\\\
  5811. \\\\009\\\\009local barWidth = self.w * (self.val / 100)\\\\\\\
  5812. \\\\009\\\\009Utils:drawRect(self:termX(), self:termY(), self.w, self.h, self.bgColor)\\\\\\\
  5813. \\\\009\\\\009Utils:drawRect(self:termX(), self:termY(), barWidth, self.h, self.barColor)\\\\\\\
  5814. \\\\009\\\\009if (self.showText) then\\\\\\\
  5815. \\\\009\\\\009\\\\009local text = string.gsub(self.textMask, \\\\\\\"{val}\\\\\\\", tostring(self.val))\\\\\\\
  5816. \\\\009\\\\009\\\\009term.setBackgroundColor(self.bgColor)\\\\\\\
  5817. \\\\009\\\\009\\\\009term.setTextColor(self.textColor)\\\\\\\
  5818. \\\\009\\\\009\\\\009local lines = #Utils:splitText(text, \\\\\\\"\\\\\\\\n\\\\\\\")\\\\\\\
  5819. \\\\009\\\\009\\\\009for k, v in ipairs(Utils:splitText(text, \\\\\\\"\\\\\\\\n\\\\\\\")) do\\\\\\\
  5820. \\\\009\\\\009\\\\009\\\\009term.setCursorPos(Utils:alignText(self.textAlign, string.len(v), self:termX(), self.w), self:termY() + k - 1 + (self.vertCenter and ((self.h - lines) / 2) or 0))\\\\\\\
  5821. \\\\009\\\\009\\\\009\\\\009local x, y = term.getCursorPos()\\\\\\\
  5822. \\\\009\\\\009\\\\009\\\\009if (x - self:termX() < barWidth) then\\\\\\\
  5823. \\\\009\\\\009\\\\009\\\\009\\\\009term.setBackgroundColor(self.barColor)\\\\\\\
  5824. \\\\009\\\\009\\\\009\\\\009\\\\009term.setTextColor(self.barTextColor)\\\\\\\
  5825. \\\\009\\\\009\\\\009\\\\009\\\\009term.write(v)\\\\\\\
  5826. \\\\009\\\\009\\\\009\\\\009\\\\009if (x - self:termX() + string.len(v) > barWidth) then\\\\\\\
  5827. \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009term.setBackgroundColor(self.bgColor)\\\\\\\
  5828. \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009term.setTextColor(self.textColor)\\\\\\\
  5829. \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009local overflow = x - self:termX() + string.len(v) - barWidth\\\\\\\
  5830. \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009local ax, ay = term.getCursorPos()\\\\\\\
  5831. \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009term.setCursorPos(ax - overflow, ay)\\\\\\\
  5832. \\\\009\\\\009\\\\009\\\\009\\\\009\\\\009term.write(string.sub(v, math.abs(string.len(v) - overflow) + 1))\\\\\\\
  5833. \\\\009\\\\009\\\\009\\\\009\\\\009end\\\\\\\
  5834. \\\\009\\\\009\\\\009\\\\009else\\\\\\\
  5835. \\\\009\\\\009\\\\009\\\\009\\\\009term.write(v)\\\\\\\
  5836. \\\\009\\\\009\\\\009\\\\009end\\\\\\\
  5837. \\\\009\\\\009\\\\009end\\\\\\\
  5838. \\\\009\\\\009end\\\\\\\
  5839. \\\\009end;\\\\\\\
  5840. \\\\009update = function(self) return false end;\\\\\\\
  5841. }\\\\\\\
  5842. ProgressBar.mt = {\\\\\\\
  5843. \\\\009__index = function (table, key)\\\\\\\
  5844. \\\\009\\\\009if (ProgressBar.prototype[key] ~= nil) then\\\\\\\
  5845. \\\\009\\\\009\\\\009return ProgressBar.prototype[key]\\\\\\\
  5846. \\\\009\\\\009else\\\\\\\
  5847. \\\\009\\\\009\\\\009return Component.prototype[key]\\\\\\\
  5848. \\\\009\\\\009end\\\\\\\
  5849. \\\\009end;\\\\\\\
  5850. }\\\\\\\
  5851. function ProgressBar:new(progressBarTbl)\\\\\\\
  5852. \\\\009if (progressBarTbl == nil) then\\\\\\\
  5853. \\\\009\\\\009progressBarTbl = self\\\\\\\
  5854. \\\\009end\\\\\\\
  5855. \\\\009setmetatable(progressBarTbl, ProgressBar.mt)\\\\\\\
  5856. \\\\009return progressBarTbl\\\\\\\
  5857. end\\\\\\\
  5858. \\\\\\\
  5859. Controller:setDefaultStyle(Style:new({}))\\\\\\\
  5860. ]]\\\\\\\
  5861. \\\\\\\
  5862. persist(\\\\\\\"GUI\\\\\\\", libcode)\\\\\\\
  5863. \\\\\\\
  5864. return 1\\\"\",\
  5865.  \"F:libstdlua.2.so\",\
  5866.  \"\\\"local libcode = [[\\\\\\\
  5867. --\\\\\\\
  5868. --Copyright (C) 2012 Thomas Farr a.k.a tomass1996 [[email protected]]\\\\\\\
  5869. --Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\\\\\\\
  5870. --associated documentation files (the \\\\\\\"Software\\\\\\\"), to deal in the Software without restriction,\\\\\\\
  5871. --including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,\\\\\\\
  5872. --copies of the Software, and to permit persons to whom the Software is furnished to do so,\\\\\\\
  5873. --subject to the following conditions:\\\\\\\
  5874. ---The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\\\\\\\
  5875. ---Visible credit is given to the original author.\\\\\\\
  5876. ---The software is distributed in a non-profit way.\\\\\\\
  5877. --THE SOFTWARE IS PROVIDED \\\\\\\"AS IS\\\\\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\\\\\\\
  5878. --WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\\\\\\\
  5879. --COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\\\\\\\
  5880. --ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\\\\\\\
  5881. --\\\\\\\
  5882. \\\\\\\
  5883. local floor,modf, insert = math.floor,math.modf, table.insert\\\\\\\
  5884. local char,format,rep = string.char,string.format,string.rep\\\\\\\
  5885. \\\\\\\
  5886. local function basen(n,b)\\\\\\\
  5887. \\\\009if n < 0 then\\\\\\\
  5888. \\\\009\\\\009n = -n\\\\\\\
  5889. \\\\009end\\\\\\\
  5890.       local t = \\\\\\\"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\\\\\]^_abcdefghijklmnopqrstuvwxyz{|}~\\\\\\\"\\\\\\\
  5891.   if n < b then\\\\\\\
  5892. \\\\009local ret = \\\\\\\"\\\\\\\"\\\\\\\
  5893. \\\\009ret = ret..string.sub(t, (n%b)+1,(n%b)+1)\\\\\\\
  5894. \\\\009return ret\\\\\\\
  5895.   else\\\\\\\
  5896. \\\\009local tob = tostring(basen(math.floor(n/b), b))\\\\\\\
  5897. \\\\009local ret = tob..t:sub((n%b)+1,(n%b)+1)\\\\\\\
  5898. \\\\009return ret\\\\\\\
  5899.   end\\\\\\\
  5900. end\\\\\\\
  5901. \\\\\\\
  5902. local Base64 = {}\\\\\\\
  5903. Base64[\\\\\\\"lsh\\\\\\\"] = function(value,shift)\\\\\\\
  5904.    return (value*(2^shift)) % 256\\\\\\\
  5905. end\\\\\\\
  5906. Base64[\\\\\\\"rsh\\\\\\\"] = function(value,shift)\\\\\\\
  5907.    return math.floor(value/2^shift) % 256\\\\\\\
  5908. end\\\\\\\
  5909. Base64[\\\\\\\"bit\\\\\\\"] = function(x,b)\\\\\\\
  5910.    return (x % 2^b - x % 2^(b-1) > 0)\\\\\\\
  5911. end\\\\\\\
  5912. Base64[\\\\\\\"lor\\\\\\\"] = function(x,y)\\\\\\\
  5913.    local result = 0\\\\\\\
  5914.    for p=1,8 do result = result + (((Base64.bit(x,p) or Base64.bit(y,p)) == true) and 2^(p-1) or 0) end\\\\\\\
  5915.    return result\\\\\\\
  5916. end\\\\\\\
  5917. Base64[\\\\\\\"base64chars\\\\\\\"] = {\\\\\\\
  5918.    [0]='A',[1]='B',[2]='C',[3]='D',[4]='E',[5]='F',[6]='G',[7]='H',[8]='I',[9]='J',[10]='K',\\\\\\\
  5919.    [11]='L',[12]='M',[13]='N',[14]='O',[15]='P',[16]='Q',[17]='R',[18]='S',[19]='T',[20]='U',\\\\\\\
  5920.    [21]='V',[22]='W',[23]='X',[24]='Y',[25]='Z',[26]='a',[27]='b',[28]='c',[29]='d',[30]='e',\\\\\\\
  5921.    [31]='f',[32]='g',[33]='h',[34]='i',[35]='j',[36]='k',[37]='l',[38]='m',[39]='n',[40]='o',\\\\\\\
  5922.    [41]='p',[42]='q',[43]='r',[44]='s',[45]='t',[46]='u',[47]='v',[48]='w',[49]='x',[50]='y',\\\\\\\
  5923.    [51]='z',[52]='0',[53]='1',[54]='2',[55]='3',[56]='4',[57]='5',[58]='6',[59]='7',[60]='8',\\\\\\\
  5924.    [61]='9',[62]='-',[63]='_'}\\\\\\\
  5925. Base64[\\\\\\\"base64bytes\\\\\\\"] = {\\\\\\\
  5926.    ['A']=0,['B']=1,['C']=2,['D']=3,['E']=4,['F']=5,['G']=6,['H']=7,['I']=8,['J']=9,['K']=10,\\\\\\\
  5927.    ['L']=11,['M']=12,['N']=13,['O']=14,['P']=15,['Q']=16,['R']=17,['S']=18,['T']=19,['U']=20,\\\\\\\
  5928.    ['V']=21,['W']=22,['X']=23,['Y']=24,['Z']=25,['a']=26,['b']=27,['c']=28,['d']=29,['e']=30,\\\\\\\
  5929.    ['f']=31,['g']=32,['h']=33,['i']=34,['j']=35,['k']=36,['l']=37,['m']=38,['n']=39,['o']=40,\\\\\\\
  5930.    ['p']=41,['q']=42,['r']=43,['s']=44,['t']=45,['u']=46,['v']=47,['w']=48,['x']=49,['y']=50,\\\\\\\
  5931.    ['z']=51,['0']=52,['1']=53,['2']=54,['3']=55,['4']=56,['5']=57,['6']=58,['7']=59,['8']=60,\\\\\\\
  5932.    ['9']=61,['-']=62,['_']=63,['=']=nil}\\\\\\\
  5933. \\\\\\\
  5934. local base32 = \\\\\\\"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567\\\\\\\"\\\\\\\
  5935. \\\\\\\
  5936. local tSHA1 = {}\\\\\\\
  5937. tSHA1[\\\\\\\"bytes_to_w32\\\\\\\"] = function(a,b,c,d) return a*0x1000000+b*0x10000+c*0x100+d end\\\\\\\
  5938. tSHA1[\\\\\\\"w32_to_bytes\\\\\\\"] = function(i) return floor(i/0x1000000)%0x100,floor(i/0x10000)%0x100,floor(i/0x100)%0x100,i%0x100 end\\\\\\\
  5939. tSHA1[\\\\\\\"w32_rot\\\\\\\"] = function(bits,a)\\\\\\\
  5940.    local b2 = 2^(32-bits)\\\\\\\
  5941.    local a,b = modf(a/b2)\\\\\\\
  5942.    return a+b*b2*(2^(bits))\\\\\\\
  5943. end\\\\\\\
  5944. tSHA1[\\\\\\\"byte_to_bits\\\\\\\"] = function(b)\\\\\\\
  5945.    local b = function (n)\\\\\\\
  5946.        local b = floor(b/n)\\\\\\\
  5947.        return b%2==1\\\\\\\
  5948.    end\\\\\\\
  5949.    return b(1),b(2),b(4),b(8),b(16),b(32),b(64),b(128)\\\\\\\
  5950. end\\\\\\\
  5951. tSHA1[\\\\\\\"bits_to_byte\\\\\\\"] = function(a,b,c,d,e,f,g,h)\\\\\\\
  5952.    local function n(b,x) return b and x or 0 end\\\\\\\
  5953.    return n(a,1)+n(b,2)+n(c,4)+n(d,8)+n(e,16)+n(f,32)+n(g,64)+n(h,128)\\\\\\\
  5954. end\\\\\\\
  5955. tSHA1[\\\\\\\"bits_to_string\\\\\\\"] = function(a,b,c,d,e,f,g,h)\\\\\\\
  5956.    local function x(b) return b and \\\\\\\"1\\\\\\\" or \\\\\\\"0\\\\\\\" end\\\\\\\
  5957.    return (\\\\\\\"%s%s%s%s %s%s%s%s\\\\\\\"):format(x(a),x(b),x(c),x(d),x(e),x(f),x(g),x(h))\\\\\\\
  5958. end\\\\\\\
  5959. tSHA1[\\\\\\\"byte_to_bit_string\\\\\\\"] = function(b) return tSHA1.bits_to_string(byte_to_bits(b)) end\\\\\\\
  5960. tSHA1[\\\\\\\"w32_to_bit_string\\\\\\\"] = function(a)\\\\\\\
  5961.    if type(a) == \\\\\\\"string\\\\\\\" then return a end\\\\\\\
  5962.    local aa,ab,ac,ad = tSHA1.w32_to_bytes(a)\\\\\\\
  5963.    local s = tSHA1.byte_to_bit_string\\\\\\\
  5964.    return (\\\\\\\"%s %s %s %s\\\\\\\"):format(s(aa):reverse(),s(ab):reverse(),s(ac):reverse(),s(ad):reverse()):reverse()\\\\\\\
  5965. end\\\\\\\
  5966. tSHA1[\\\\\\\"band\\\\\\\"] = function(a,b)\\\\\\\
  5967.    local A,B,C,D,E,F,G,H = tSHA1.byte_to_bits(b)\\\\\\\
  5968.    local a,b,c,d,e,f,g,h = tSHA1.byte_to_bits(a)\\\\\\\
  5969.    return tSHA1.bits_to_byte(\\\\\\\
  5970.        A and a, B and b, C and c, D and d,\\\\\\\
  5971.        E and e, F and f, G and g, H and h)\\\\\\\
  5972. end\\\\\\\
  5973. tSHA1[\\\\\\\"bor\\\\\\\"] = function(a,b)\\\\\\\
  5974.    local A,B,C,D,E,F,G,H = tSHA1.byte_to_bits(b)\\\\\\\
  5975.    local a,b,c,d,e,f,g,h = tSHA1.byte_to_bits(a)\\\\\\\
  5976.    return tSHA1.bits_to_byte(\\\\\\\
  5977.        A or a, B or b, C or c, D or d,\\\\\\\
  5978.        E or e, F or f, G or g, H or h)\\\\\\\
  5979. end\\\\\\\
  5980. tSHA1[\\\\\\\"bxor\\\\\\\"] = function(a,b)\\\\\\\
  5981.    local A,B,C,D,E,F,G,H = tSHA1.byte_to_bits(b)\\\\\\\
  5982.    local a,b,c,d,e,f,g,h = tSHA1.byte_to_bits(a)\\\\\\\
  5983.    return tSHA1.bits_to_byte(\\\\\\\
  5984.        A ~= a, B ~= b, C ~= c, D ~= d,\\\\\\\
  5985.        E ~= e, F ~= f, G ~= g, H ~= h)\\\\\\\
  5986. end\\\\\\\
  5987. tSHA1[\\\\\\\"bnot\\\\\\\"] = function(x) return 255-(x % 256) end\\\\\\\
  5988. tSHA1[\\\\\\\"w32_comb\\\\\\\"] = function(fn)\\\\\\\
  5989.    return function (a,b)\\\\\\\
  5990.        local aa,ab,ac,ad = tSHA1.w32_to_bytes(a)\\\\\\\
  5991.        local ba,bb,bc,bd = tSHA1.w32_to_bytes(b)\\\\\\\
  5992.        return tSHA1.bytes_to_w32(fn(aa,ba),fn(ab,bb),fn(ac,bc),fn(ad,bd))\\\\\\\
  5993.    end\\\\\\\
  5994. end\\\\\\\
  5995. tSHA1[\\\\\\\"w32_xor_n\\\\\\\"] = function(a,...)\\\\\\\
  5996.    local aa,ab,ac,ad = tSHA1.w32_to_bytes(a)\\\\\\\
  5997.    for i=1,select('#',...) do\\\\\\\
  5998.        local ba,bb,bc,bd = tSHA1.w32_to_bytes(select(i,...))\\\\\\\
  5999.        aa,ab,ac,ad = tSHA1.bxor(aa,ba),tSHA1.bxor(ab,bb),tSHA1.bxor(ac,bc),tSHA1.bxor(ad,bd)\\\\\\\
  6000.    end\\\\\\\
  6001.    return tSHA1.bytes_to_w32(aa,ab,ac,ad)\\\\\\\
  6002. end\\\\\\\
  6003. tSHA1[\\\\\\\"w32_or3\\\\\\\"] = function(a,b,c)\\\\\\\
  6004.    local aa,ab,ac,ad = tSHA1.w32_to_bytes(a)\\\\\\\
  6005.    local ba,bb,bc,bd = tSHA1.w32_to_bytes(b)\\\\\\\
  6006.    local ca,cb,cc,cd = tSHA1.w32_to_bytes(c)\\\\\\\
  6007.    return tSHA1.bytes_to_w32(\\\\\\\
  6008.        tSHA1.bor(aa,tSHA1.bor(ba,ca)), tSHA1.bor(ab,tSHA1.bor(bb,cb)), tSHA1.bor(ac,tSHA1.bor(bc,cc)), tSHA1.bor(ad,tSHA1.bor(bd,cd))\\\\\\\
  6009.    )\\\\\\\
  6010. end\\\\\\\
  6011. tSHA1[\\\\\\\"w32_not\\\\\\\"] = function(a) return 4294967295-(a % 4294967296) end\\\\\\\
  6012. tSHA1[\\\\\\\"w32_add\\\\\\\"] = function(a,b) return (a+b) % 4294967296 end\\\\\\\
  6013. tSHA1[\\\\\\\"w32_add_n\\\\\\\"] = function(a,...)\\\\\\\
  6014.    for i=1,select('#',...) do\\\\\\\
  6015.        a = (a+select(i,...)) % 4294967296\\\\\\\
  6016.    end\\\\\\\
  6017.    return a\\\\\\\
  6018. end\\\\\\\
  6019. tSHA1[\\\\\\\"w32_to_hexstring\\\\\\\"] = function(w) return format(\\\\\\\"%08x\\\\\\\",w) end\\\\\\\
  6020. tSHA1[\\\\\\\"w32_and\\\\\\\"] = tSHA1.w32_comb(tSHA1.band)\\\\\\\
  6021. tSHA1[\\\\\\\"w32_xor\\\\\\\"] = tSHA1.w32_comb(tSHA1.bxor)\\\\\\\
  6022. tSHA1[\\\\\\\"w32_or\\\\\\\"] = tSHA1.w32_comb(tSHA1.bor)\\\\\\\
  6023. \\\\\\\
  6024. local CRC = {}\\\\\\\
  6025. CRC.crc32 = {\\\\\\\
  6026.    0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,\\\\\\\
  6027.    0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,\\\\\\\
  6028.    0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,\\\\\\\
  6029.    0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,\\\\\\\
  6030.    0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,\\\\\\\
  6031.    0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,\\\\\\\
  6032.    0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,\\\\\\\
  6033.    0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,\\\\\\\
  6034.    0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,\\\\\\\
  6035.    0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,\\\\\\\
  6036.    0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,\\\\\\\
  6037.    0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,\\\\\\\
  6038.    0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,\\\\\\\
  6039.    0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,\\\\\\\
  6040.    0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,\\\\\\\
  6041.    0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,\\\\\\\
  6042.    0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,\\\\\\\
  6043.    0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,\\\\\\\
  6044.    0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,\\\\\\\
  6045.    0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,\\\\\\\
  6046.    0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,\\\\\\\
  6047.    0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,\\\\\\\
  6048.    0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,\\\\\\\
  6049.    0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,\\\\\\\
  6050.    0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,\\\\\\\
  6051.    0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,\\\\\\\
  6052.    0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,\\\\\\\
  6053.    0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,\\\\\\\
  6054.    0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,\\\\\\\
  6055.    0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,\\\\\\\
  6056.    0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,\\\\\\\
  6057.    0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,\\\\\\\
  6058.    0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,\\\\\\\
  6059.    0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,\\\\\\\
  6060.    0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,\\\\\\\
  6061.    0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,\\\\\\\
  6062.    0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,\\\\\\\
  6063.    0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,\\\\\\\
  6064.    0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,\\\\\\\
  6065.    0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,\\\\\\\
  6066.    0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,\\\\\\\
  6067.    0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,\\\\\\\
  6068.    0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D }\\\\\\\
  6069. \\\\\\\
  6070. local bit = {}\\\\\\\
  6071. bit[\\\\\\\"bnot\\\\\\\"] = function(n)\\\\\\\
  6072.    local tbl = bit.tobits(n)\\\\\\\
  6073.    local size = math.max(table.getn(tbl), 32)\\\\\\\
  6074.    for i = 1, size do\\\\\\\
  6075.        if(tbl[i] == 1) then\\\\\\\
  6076.            tbl[i] = 0\\\\\\\
  6077.        else\\\\\\\
  6078.            tbl[i] = 1\\\\\\\
  6079.        end\\\\\\\
  6080.    end\\\\\\\
  6081.    return bit.tonumb(tbl)\\\\\\\
  6082. end\\\\\\\
  6083. bit[\\\\\\\"band\\\\\\\"] = function(m, n)\\\\\\\
  6084.    local tbl_m = bit.tobits(m)\\\\\\\
  6085.    local tbl_n = bit.tobits(n)\\\\\\\
  6086.    bit.expand(tbl_m, tbl_n)\\\\\\\
  6087.    local tbl = {}\\\\\\\
  6088.    local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n))\\\\\\\
  6089.    for i = 1, rslt do\\\\\\\
  6090.        if(tbl_m[i]== 0 or tbl_n[i] == 0) then\\\\\\\
  6091.            tbl[i] = 0\\\\\\\
  6092.        else\\\\\\\
  6093.            tbl[i] = 1\\\\\\\
  6094.        end\\\\\\\
  6095.    end\\\\\\\
  6096.    return bit.tonumb(tbl)\\\\\\\
  6097. end\\\\\\\
  6098. bit[\\\\\\\"bor\\\\\\\"] = function(m, n)\\\\\\\
  6099.    local tbl_m = bit.tobits(m)\\\\\\\
  6100.    local tbl_n = bit.tobits(n)\\\\\\\
  6101.    bit.expand(tbl_m, tbl_n)\\\\\\\
  6102.    local tbl = {}\\\\\\\
  6103.    local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n))\\\\\\\
  6104.    for i = 1, rslt do\\\\\\\
  6105.        if(tbl_m[i]== 0 and tbl_n[i] == 0) then\\\\\\\
  6106.            tbl[i] = 0\\\\\\\
  6107.        else\\\\\\\
  6108.            tbl[i] = 1\\\\\\\
  6109.        end\\\\\\\
  6110.    end\\\\\\\
  6111.    return bit.tonumb(tbl)\\\\\\\
  6112. end\\\\\\\
  6113. bit[\\\\\\\"bxor\\\\\\\"] = function(m, n)\\\\\\\
  6114.    local tbl_m = bit.tobits(m)\\\\\\\
  6115.    local tbl_n = bit.tobits(n)\\\\\\\
  6116.    bit.expand(tbl_m, tbl_n)\\\\\\\
  6117.    local tbl = {}\\\\\\\
  6118.    local rslt = math.max(table.getn(tbl_m), table.getn(tbl_n))\\\\\\\
  6119.    for i = 1, rslt do\\\\\\\
  6120.        if(tbl_m[i] ~= tbl_n[i]) then\\\\\\\
  6121.            tbl[i] = 1\\\\\\\
  6122.        else\\\\\\\
  6123.            tbl[i] = 0\\\\\\\
  6124.        end\\\\\\\
  6125.    end\\\\\\\
  6126.    return bit.tonumb(tbl)\\\\\\\
  6127. end\\\\\\\
  6128. bit[\\\\\\\"brshift\\\\\\\"] = function(n, bits)\\\\\\\
  6129.    bit.checkint(n)\\\\\\\
  6130.    local high_bit = 0\\\\\\\
  6131.    if(n < 0) then\\\\\\\
  6132.        n = bit.bnot(math.abs(n)) + 1\\\\\\\
  6133.        high_bit = 2147483648\\\\\\\
  6134.    end\\\\\\\
  6135.    for i=1, bits do\\\\\\\
  6136.        n = n/2\\\\\\\
  6137.        n = bit.bor(math.floor(n), high_bit)\\\\\\\
  6138.    end\\\\\\\
  6139.    return math.floor(n)\\\\\\\
  6140. end\\\\\\\
  6141. bit[\\\\\\\"blshift\\\\\\\"] = function(n, bits)\\\\\\\
  6142.    bit.checkint(n)\\\\\\\
  6143.    if(n < 0) then\\\\\\\
  6144.        n = bit.bnot(math.abs(n)) + 1\\\\\\\
  6145.    end\\\\\\\
  6146.    for i=1, bits do\\\\\\\
  6147.        n = n*2\\\\\\\
  6148.    end\\\\\\\
  6149.    return bit.band(n, 4294967295)\\\\\\\
  6150. end\\\\\\\
  6151. bit[\\\\\\\"bxor2\\\\\\\"] = function(m, n)\\\\\\\
  6152.    local rhs = bit.bor(bit.bnot(m), bit.bnot(n))\\\\\\\
  6153.    local lhs = bit.bor(m, n)\\\\\\\
  6154.    local rslt = bit.band(lhs, rhs)\\\\\\\
  6155.    return rslt\\\\\\\
  6156. end\\\\\\\
  6157. bit[\\\\\\\"blogic_rshift\\\\\\\"] = function(n, bits)\\\\\\\
  6158.    bit.checkint(n)\\\\\\\
  6159.    if(n < 0) then\\\\\\\
  6160.        n = bit.bnot(math.abs(n)) + 1\\\\\\\
  6161.    end\\\\\\\
  6162.    for i=1, bits do\\\\\\\
  6163.        n = n/2\\\\\\\
  6164.    end\\\\\\\
  6165.    return math.floor(n)\\\\\\\
  6166. end\\\\\\\
  6167. bit[\\\\\\\"tobits\\\\\\\"] = function(n)\\\\\\\
  6168.    bit.checkint(n)\\\\\\\
  6169.    if(n < 0) then\\\\\\\
  6170.        return bit.tobits(bit.bnot(math.abs(n)) + 1)\\\\\\\
  6171.    end\\\\\\\
  6172.    local tbl = {}\\\\\\\
  6173.    local cnt = 1\\\\\\\
  6174.    while (n > 0) do\\\\\\\
  6175.        local last = math.fmod(n,2)\\\\\\\
  6176.        if(last == 1) then\\\\\\\
  6177.            tbl[cnt] = 1\\\\\\\
  6178.        else\\\\\\\
  6179.            tbl[cnt] = 0\\\\\\\
  6180.        end\\\\\\\
  6181.        n = (n-last)/2\\\\\\\
  6182.        cnt = cnt + 1\\\\\\\
  6183.    end\\\\\\\
  6184.    return tbl\\\\\\\
  6185. end\\\\\\\
  6186. bit[\\\\\\\"tonumb\\\\\\\"] = function(tbl)\\\\\\\
  6187.    local n = table.getn(tbl)\\\\\\\
  6188.    local rslt = 0\\\\\\\
  6189.    local power = 1\\\\\\\
  6190.    for i = 1, n do\\\\\\\
  6191.        rslt = rslt + tbl[i]*power\\\\\\\
  6192.        power = power*2\\\\\\\
  6193.    end\\\\\\\
  6194.    return rslt\\\\\\\
  6195. end\\\\\\\
  6196. bit[\\\\\\\"checkint\\\\\\\"] = function(n)\\\\\\\
  6197.    if(n - math.floor(n) > 0) then\\\\\\\
  6198.        error(\\\\\\\"trying to use bitwise operation on non-integer!\\\\\\\")\\\\\\\
  6199.    end\\\\\\\
  6200. end\\\\\\\
  6201. bit[\\\\\\\"expand\\\\\\\"] = function(tbl_m, tbl_n)\\\\\\\
  6202.    local big = {}\\\\\\\
  6203.    local small = {}\\\\\\\
  6204.    if(table.getn(tbl_m) > table.getn(tbl_n)) then\\\\\\\
  6205.        big = tbl_m\\\\\\\
  6206.        small = tbl_n\\\\\\\
  6207.    else\\\\\\\
  6208.        big = tbl_n\\\\\\\
  6209.        small = tbl_m\\\\\\\
  6210.    end\\\\\\\
  6211.    for i = table.getn(small) + 1, table.getn(big) do\\\\\\\
  6212.        small[i] = 0\\\\\\\
  6213.    end\\\\\\\
  6214. end\\\\\\\
  6215. \\\\\\\
  6216. local FCS = {}\\\\\\\
  6217. FCS[\\\\\\\"16\\\\\\\"] = {\\\\\\\
  6218.    [0]=0, 4489, 8978, 12955, 17956, 22445, 25910, 29887,\\\\\\\
  6219.    35912, 40385, 44890, 48851, 51820, 56293, 59774, 63735,\\\\\\\
  6220.    4225, 264, 13203, 8730, 22181, 18220, 30135, 25662,\\\\\\\
  6221.    40137, 36160, 49115, 44626, 56045, 52068, 63999, 59510,\\\\\\\
  6222.    8450, 12427, 528, 5017, 26406, 30383, 17460, 21949,\\\\\\\
  6223.    44362, 48323, 36440, 40913, 60270, 64231, 51324, 55797,\\\\\\\
  6224.    12675, 8202, 4753, 792, 30631, 26158, 21685, 17724,\\\\\\\
  6225.    48587, 44098, 40665, 36688, 64495, 60006, 55549, 51572,\\\\\\\
  6226.    16900, 21389, 24854, 28831, 1056, 5545, 10034, 14011,\\\\\\\
  6227.    52812, 57285, 60766, 64727, 34920, 39393, 43898, 47859,\\\\\\\
  6228.    21125, 17164, 29079, 24606, 5281, 1320, 14259, 9786,\\\\\\\
  6229.    57037, 53060, 64991, 60502, 39145, 35168, 48123, 43634,\\\\\\\
  6230.    25350, 29327, 16404, 20893, 9506, 13483, 1584, 6073,\\\\\\\
  6231.    61262, 65223, 52316, 56789, 43370, 47331, 35448, 39921,\\\\\\\
  6232.    29575, 25102, 20629, 16668, 13731, 9258, 5809, 1848,\\\\\\\
  6233.    65487, 60998, 56541, 52564, 47595, 43106, 39673, 35696,\\\\\\\
  6234.    33800, 38273, 42778, 46739, 49708, 54181, 57662, 61623,\\\\\\\
  6235.    2112, 6601, 11090, 15067, 20068, 24557, 28022, 31999,\\\\\\\
  6236.    38025, 34048, 47003, 42514, 53933, 49956, 61887, 57398,\\\\\\\
  6237.    6337, 2376, 15315, 10842, 24293, 20332, 32247, 27774,\\\\\\\
  6238.    42250, 46211, 34328, 38801, 58158, 62119, 49212, 53685,\\\\\\\
  6239.    10562, 14539, 2640, 7129, 28518, 32495, 19572, 24061,\\\\\\\
  6240.    46475, 41986, 38553, 34576, 62383, 57894, 53437, 49460,\\\\\\\
  6241.    14787, 10314, 6865, 2904, 32743, 28270, 23797, 19836,\\\\\\\
  6242.    50700, 55173, 58654, 62615, 32808, 37281, 41786, 45747,\\\\\\\
  6243.    19012, 23501, 26966, 30943, 3168, 7657, 12146, 16123,\\\\\\\
  6244.    54925, 50948, 62879, 58390, 37033, 33056, 46011, 41522,\\\\\\\
  6245.    23237, 19276, 31191, 26718, 7393, 3432, 16371, 11898,\\\\\\\
  6246.    59150, 63111, 50204, 54677, 41258, 45219, 33336, 37809,\\\\\\\
  6247.    27462, 31439, 18516, 23005, 11618, 15595, 3696, 8185,\\\\\\\
  6248.    63375, 58886, 54429, 50452, 45483, 40994, 37561, 33584,\\\\\\\
  6249.    31687, 27214, 22741, 18780, 15843, 11370, 7921, 3960 }\\\\\\\
  6250. FCS[\\\\\\\"32\\\\\\\"] = {\\\\\\\
  6251.    [0]=0, 1996959894, -301047508, -1727442502, 124634137, 1886057615, -379345611, -1637575261,\\\\\\\
  6252.    249268274, 2044508324, -522852066, -1747789432, 162941995, 2125561021, -407360249, -1866523247,\\\\\\\
  6253.    498536548, 1789927666, -205950648, -2067906082, 450548861, 1843258603, -187386543, -2083289657,\\\\\\\
  6254.    325883990, 1684777152, -43845254, -1973040660, 335633487, 1661365465, -99664541, -1928851979,\\\\\\\
  6255.    997073096, 1281953886, -715111964, -1570279054, 1006888145, 1258607687, -770865667, -1526024853,\\\\\\\
  6256.    901097722, 1119000684, -608450090, -1396901568, 853044451, 1172266101, -589951537, -1412350631,\\\\\\\
  6257.    651767980, 1373503546, -925412992, -1076862698, 565507253, 1454621731, -809855591, -1195530993,\\\\\\\
  6258.    671266974, 1594198024, -972236366, -1324619484, 795835527, 1483230225, -1050600021, -1234817731,\\\\\\\
  6259.    1994146192, 31158534, -1731059524, -271249366, 1907459465, 112637215, -1614814043, -390540237,\\\\\\\
  6260.    2013776290, 251722036, -1777751922, -519137256, 2137656763, 141376813, -1855689577, -429695999,\\\\\\\
  6261.    1802195444, 476864866, -2056965928, -228458418, 1812370925, 453092731, -2113342271, -183516073,\\\\\\\
  6262.    1706088902, 314042704, -1950435094, -54949764, 1658658271, 366619977, -1932296973, -69972891,\\\\\\\
  6263.    1303535960, 984961486, -1547960204, -725929758, 1256170817, 1037604311, -1529756563, -740887301,\\\\\\\
  6264.    1131014506, 879679996, -1385723834, -631195440, 1141124467, 855842277, -1442165665, -586318647,\\\\\\\
  6265.    1342533948, 654459306, -1106571248, -921952122, 1466479909, 544179635, -1184443383, -832445281,\\\\\\\
  6266.    1591671054, 702138776, -1328506846, -942167884, 1504918807, 783551873, -1212326853, -1061524307,\\\\\\\
  6267.    -306674912, -1698712650, 62317068, 1957810842, -355121351, -1647151185, 81470997, 1943803523,\\\\\\\
  6268.    -480048366, -1805370492, 225274430, 2053790376, -468791541, -1828061283, 167816743, 2097651377,\\\\\\\
  6269.    -267414716, -2029476910, 503444072, 1762050814, -144550051, -2140837941, 426522225, 1852507879,\\\\\\\
  6270.    -19653770, -1982649376, 282753626, 1742555852, -105259153, -1900089351, 397917763, 1622183637,\\\\\\\
  6271.    -690576408, -1580100738, 953729732, 1340076626, -776247311, -1497606297, 1068828381, 1219638859,\\\\\\\
  6272.    -670225446, -1358292148, 906185462, 1090812512, -547295293, -1469587627, 829329135, 1181335161,\\\\\\\
  6273.    -882789492, -1134132454, 628085408, 1382605366, -871598187, -1156888829, 570562233, 1426400815,\\\\\\\
  6274.    -977650754, -1296233688, 733239954, 1555261956, -1026031705, -1244606671, 752459403, 1541320221,\\\\\\\
  6275.    -1687895376, -328994266, 1969922972, 40735498, -1677130071, -351390145, 1913087877, 83908371,\\\\\\\
  6276.    -1782625662, -491226604, 2075208622, 213261112, -1831694693, -438977011, 2094854071, 198958881,\\\\\\\
  6277.    -2032938284, -237706686, 1759359992, 534414190, -2118248755, -155638181, 1873836001, 414664567,\\\\\\\
  6278.    -2012718362, -15766928, 1711684554, 285281116, -1889165569, -127750551, 1634467795, 376229701,\\\\\\\
  6279.    -1609899400, -686959890, 1308918612, 956543938, -1486412191, -799009033, 1231636301, 1047427035,\\\\\\\
  6280.    -1362007478, -640263460, 1088359270, 936918000, -1447252397, -558129467, 1202900863, 817233897,\\\\\\\
  6281.    -1111625188, -893730166, 1404277552, 615818150, -1160759803, -841546093, 1423857449, 601450431,\\\\\\\
  6282.    -1285129682, -1000256840, 1567103746, 711928724, -1274298825, -1022587231, 1510334235, 755167117 }\\\\\\\
  6283. \\\\\\\
  6284. --String Utils :\\\\\\\
  6285. \\\\\\\
  6286. function toCharTable(str)  --Returns table of @str's chars\\\\\\\
  6287.    if not str then return nil end\\\\\\\
  6288.    str = tostring(str)\\\\\\\
  6289. \\\\009local chars = {}\\\\\\\
  6290. \\\\009for n=1,#str do\\\\\\\
  6291. \\\\009\\\\009chars[n] = str:sub(n,n)\\\\\\\
  6292. \\\\009end\\\\\\\
  6293. \\\\009return chars\\\\\\\
  6294. end\\\\\\\
  6295. \\\\\\\
  6296. function toByteTable(str)  --Returns table of @str's bytes\\\\\\\
  6297.    if not str then return nil end\\\\\\\
  6298.    str = tostring(str)\\\\\\\
  6299. \\\\009local bytes = {}\\\\\\\
  6300. \\\\009for n=1,#str do\\\\\\\
  6301. \\\\009\\\\009bytes[n] = str:byte(n)\\\\\\\
  6302. \\\\009end\\\\\\\
  6303. \\\\009return bytes\\\\\\\
  6304. end\\\\\\\
  6305. \\\\\\\
  6306. function fromCharTable(chars)  --Returns string made of chracters in @chars\\\\\\\
  6307.    if not chars or type(chars)~=\\\\\\\"table\\\\\\\" then return nil end\\\\\\\
  6308. \\\\009return table.concat(chars)\\\\\\\
  6309. end\\\\\\\
  6310. \\\\\\\
  6311. function fromByteTable(bytes)  --Returns string made of bytes in @bytes\\\\\\\
  6312.    if not bytes or type(bytes)~=\\\\\\\"table\\\\\\\" then return nil end\\\\\\\
  6313. \\\\009local str = \\\\\\\"\\\\\\\"\\\\\\\
  6314. \\\\009for n=1,#bytes do\\\\\\\
  6315. \\\\009\\\\009str = str..string.char(bytes[n])\\\\\\\
  6316. \\\\009end\\\\\\\
  6317. \\\\009return str\\\\\\\
  6318. end\\\\\\\
  6319. \\\\\\\
  6320. function contains(str,find)  --Returns true if @str contains @find\\\\\\\
  6321.    if not str then return nil end\\\\\\\
  6322.    str = tostring(str)\\\\\\\
  6323. \\\\009for n=1, #str-#find+1 do\\\\\\\
  6324. \\\\009\\\\009if str:sub(n,n+#find-1) == find then return true end\\\\\\\
  6325. \\\\009end\\\\\\\
  6326. \\\\009return false\\\\\\\
  6327. end\\\\\\\
  6328. \\\\\\\
  6329. function startsWith(str,Start) --Check if @str starts with @Start\\\\\\\
  6330.    if not str then return nil end\\\\\\\
  6331.    str = tostring(str)\\\\\\\
  6332.    return str:sub(1,Start:len())==Start\\\\\\\
  6333. end\\\\\\\
  6334. \\\\\\\
  6335. function endsWith(str,End)  --Check if @str ends with @End\\\\\\\
  6336.    if not str then return nil end\\\\\\\
  6337.    str = tostring(str)\\\\\\\
  6338.    return End=='' or str:sub(#str-#End+1)==End\\\\\\\
  6339. end\\\\\\\
  6340. \\\\\\\
  6341. function trim(str)  --Trim @str of initial/trailing whitespace\\\\\\\
  6342.    if not str then return nil end\\\\\\\
  6343.    str = tostring(str)\\\\\\\
  6344.    return (str:gsub(\\\\\\\"^%s*(.-)%s*$\\\\\\\", \\\\\\\"%1\\\\\\\"))\\\\\\\
  6345. end\\\\\\\
  6346. \\\\\\\
  6347. function firstLetterUpper(str)  --Capitilizes first letter of @str\\\\\\\
  6348.    if not str then return nil end\\\\\\\
  6349.    str = tostring(str)\\\\\\\
  6350. \\\\009str = str:gsub(\\\\\\\"%a\\\\\\\", string.upper, 1)\\\\\\\
  6351.    return str\\\\\\\
  6352. end\\\\\\\
  6353. \\\\\\\
  6354. function titleCase(str)  --Changes @str to title case\\\\\\\
  6355. \\\\009if not str then return nil end\\\\\\\
  6356. \\\\009str = tostring(str)\\\\\\\
  6357.    local function tchelper(first, rest)\\\\\\\
  6358. \\\\009\\\\009return first:upper()..rest:lower()\\\\\\\
  6359.    end\\\\\\\
  6360.    str = str:gsub(\\\\\\\"(%a)([%w_']*)\\\\\\\", tchelper)\\\\\\\
  6361. \\\\009return str\\\\\\\
  6362. end\\\\\\\
  6363. \\\\\\\
  6364. function isRepetition(str, pat)  --Checks if @str is a repetition of @pat\\\\\\\
  6365.    if not str then return nil end\\\\\\\
  6366.    str = tostring(str)\\\\\\\
  6367. \\\\009return \\\\\\\"\\\\\\\" == str:gsub(pat, \\\\\\\"\\\\\\\")\\\\\\\
  6368. end\\\\\\\
  6369. \\\\\\\
  6370. function isRepetitionWS(str, pat)  --Checks if @str is a repetition of @pat seperated by whitespaces\\\\\\\
  6371.    if not str then return nil end\\\\\\\
  6372.    str = tostring(str)\\\\\\\
  6373. \\\\009return not str:gsub(pat, \\\\\\\"\\\\\\\"):find\\\\\\\"%S\\\\\\\"\\\\\\\
  6374. end\\\\\\\
  6375. \\\\\\\
  6376. function urlDecode(str)  --Url decodes @str\\\\\\\
  6377.    if not str then return nil end\\\\\\\
  6378.    str = tostring(str)\\\\\\\
  6379. \\\\009str = string.gsub (str, \\\\\\\"+\\\\\\\", \\\\\\\" \\\\\\\")\\\\\\\
  6380. \\\\009str = string.gsub (str, \\\\\\\"%%(%x%x)\\\\\\\", function(h) return string.char(tonumber(h,16)) end)\\\\\\\
  6381. \\\\009str = string.gsub (str, \\\\\\\"\\\\\\\\r\\\\\\\\n\\\\\\\", \\\\\\\"\\\\\\\\n\\\\\\\")\\\\\\\
  6382. \\\\009return str\\\\\\\
  6383. end\\\\\\\
  6384. \\\\\\\
  6385. function urlEncode(str)  --Url encodes @str\\\\\\\
  6386.    if not str then return nil end\\\\\\\
  6387.    str = tostring(str)\\\\\\\
  6388. \\\\009if (str) then\\\\\\\
  6389. \\\\009\\\\009str = string.gsub (str, \\\\\\\"\\\\\\\\n\\\\\\\", \\\\\\\"\\\\\\\\r\\\\\\\\n\\\\\\\")\\\\\\\
  6390. \\\\009\\\\009str = string.gsub (str, \\\\\\\"([^%w ])\\\\\\\", function (c) return string.format (\\\\\\\"%%%02X\\\\\\\", string.byte(c)) end)\\\\\\\
  6391. \\\\009\\\\009str = string.gsub (str, \\\\\\\" \\\\\\\", \\\\\\\"+\\\\\\\")\\\\\\\
  6392. \\\\009end\\\\\\\
  6393. \\\\009return str\\\\\\\
  6394. end\\\\\\\
  6395. \\\\\\\
  6396. function isEmailAddress(str)  --Checks if @str is a valid email address\\\\\\\
  6397.    if not str then return nil end\\\\\\\
  6398.    str = tostring(str)\\\\\\\
  6399. \\\\009if (str:match(\\\\\\\"[A-Za-z0-9%.%%%+%-]+@[A-Za-z0-9%.%%%+%-]+%.%w%w%w?%w?\\\\\\\")) then\\\\\\\
  6400. \\\\009\\\\009return true\\\\\\\
  6401. \\\\009else\\\\\\\
  6402. \\\\009\\\\009return false\\\\\\\
  6403. \\\\009end\\\\\\\
  6404. end\\\\\\\
  6405. \\\\\\\
  6406. function chunk(str, size)  --Splits @str into chunks of length @size\\\\\\\
  6407. \\\\009if not size then return nil end\\\\\\\
  6408. \\\\009str = tostring(str)\\\\\\\
  6409. \\\\009local num2App = size - (#str%size)\\\\\\\
  6410. \\\\009str = str..(rep(char(0), num2App) or \\\\\\\"\\\\\\\")\\\\\\\
  6411. \\\\009assert(#str%size==0)\\\\\\\
  6412. \\\\009local chunks = {}\\\\\\\
  6413. \\\\009local numChunks = #str / size\\\\\\\
  6414. \\\\009local chunk = 0\\\\\\\
  6415. \\\\009while chunk < numChunks do\\\\\\\
  6416. \\\\009\\\\009local start = chunk * size + 1\\\\\\\
  6417.        chunk = chunk+1\\\\\\\
  6418. \\\\009\\\\009if start+size-1 > #str-num2App then\\\\\\\
  6419.            if str:sub(start, #str-num2App) ~= (nil or \\\\\\\"\\\\\\\") then\\\\\\\
  6420. \\\\009\\\\009\\\\009    chunks[chunk] = str:sub(start, #str-num2App)\\\\\\\
  6421.            end\\\\\\\
  6422. \\\\009\\\\009else\\\\\\\
  6423. \\\\009\\\\009\\\\009chunks[chunk] = str:sub(start, start+size-1)\\\\\\\
  6424. \\\\009\\\\009end\\\\\\\
  6425. \\\\009end\\\\\\\
  6426. \\\\009return chunks\\\\\\\
  6427. end\\\\\\\
  6428. \\\\\\\
  6429. function find(str, match, startIndex)  --Finds @match in @str optionally after @startIndex\\\\\\\
  6430. \\\\009if not match then return nil end\\\\\\\
  6431. \\\\009str = tostring(str)\\\\\\\
  6432. \\\\009local _ = startIndex or 1\\\\\\\
  6433. \\\\009local _s = nil\\\\\\\
  6434. \\\\009local _e = nil\\\\\\\
  6435. \\\\009local _len = match:len()\\\\\\\
  6436. \\\\009while true do\\\\\\\
  6437. \\\\009\\\\009local _t = str:sub( _ , _len + _ - 1)\\\\\\\
  6438. \\\\009\\\\009if _t == match then\\\\\\\
  6439. \\\\009\\\\009\\\\009_s = _\\\\\\\
  6440. \\\\009\\\\009\\\\009_e = _ + _len - 1\\\\\\\
  6441. \\\\009\\\\009\\\\009break\\\\\\\
  6442. \\\\009\\\\009end\\\\\\\
  6443. \\\\009\\\\009_ = _ + 1\\\\\\\
  6444. \\\\009\\\\009if _ > str:len() then break end\\\\\\\
  6445. \\\\009end\\\\\\\
  6446. \\\\009if _s == nil then return nil else return _s, _e end\\\\\\\
  6447. end\\\\\\\
  6448. \\\\\\\
  6449. function separate(str, divider)  --Separates @str on @divider\\\\\\\
  6450. \\\\009if not divider then return nil end\\\\\\\
  6451. \\\\009str = tostring(str)\\\\\\\
  6452. \\\\009local start = {}\\\\\\\
  6453. \\\\009local endS = {}\\\\\\\
  6454. \\\\009local n=1\\\\\\\
  6455. \\\\009repeat\\\\\\\
  6456. \\\\009\\\\009if n==1 then\\\\\\\
  6457. \\\\009\\\\009\\\\009start[n], endS[n] = find(str, divider)\\\\\\\
  6458. \\\\009\\\\009else\\\\\\\
  6459. \\\\009\\\\009\\\\009start[n], endS[n] = find(str, divider, endS[n-1]+1)\\\\\\\
  6460.        end\\\\\\\
  6461. \\\\009\\\\009n=n+1\\\\\\\
  6462. \\\\009until start[n-1]==nil\\\\\\\
  6463. \\\\009local subs = {}\\\\\\\
  6464. \\\\009for n=1, #start+1 do\\\\\\\
  6465. \\\\009\\\\009if n==1 then\\\\\\\
  6466. \\\\009\\\\009\\\\009subs[n] = str:sub(1, start[n]-1)\\\\\\\
  6467. \\\\009\\\\009elseif n==#start+1 then\\\\\\\
  6468. \\\\009\\\\009\\\\009subs[n] = str:sub(endS[n-1]+1)\\\\\\\
  6469. \\\\009\\\\009else\\\\\\\
  6470. \\\\009\\\\009\\\\009subs[n] = str:sub(endS[n-1]+1, start[n]-1)\\\\\\\
  6471.        end\\\\\\\
  6472. \\\\009end\\\\\\\
  6473. \\\\009return subs\\\\\\\
  6474. end\\\\\\\
  6475. \\\\\\\
  6476. function replace(str, from, to)  --Replaces @from to @to in @str\\\\\\\
  6477. \\\\009if not from then return nil end\\\\\\\
  6478. \\\\009str = tostring(str)\\\\\\\
  6479. \\\\009local pcs = seperate(str, from)\\\\\\\
  6480. \\\\009str = pcs[1]\\\\\\\
  6481. \\\\009for n=2,#pcs do\\\\\\\
  6482. \\\\009\\\\009str = str..to..pcs[n]\\\\\\\
  6483. \\\\009end\\\\\\\
  6484. \\\\009return str\\\\\\\
  6485. end\\\\\\\
  6486. \\\\\\\
  6487. function jumble(str)  --Jumbles @str\\\\\\\
  6488. \\\\009if not str then return nil end\\\\\\\
  6489. \\\\009str = tostring(str)\\\\\\\
  6490. \\\\009local chars = {}\\\\\\\
  6491. \\\\009for i = 1, #str do\\\\\\\
  6492. \\\\009\\\\009chars[i] = str:sub(i, i)\\\\\\\
  6493. \\\\009end\\\\\\\
  6494. \\\\009local usedNums = \\\\\\\":\\\\\\\"\\\\\\\
  6495. \\\\009local res = \\\\\\\"\\\\\\\"\\\\\\\
  6496. \\\\009local rand = 0\\\\\\\
  6497. \\\\009for i=1, #chars do\\\\\\\
  6498. \\\\009\\\\009while true do\\\\\\\
  6499. \\\\009\\\\009\\\\009rand = math.random(#chars)\\\\\\\
  6500. \\\\009\\\\009\\\\009if find(usedNums, \\\\\\\":\\\\\\\"..rand..\\\\\\\":\\\\\\\") == nil then break end\\\\\\\
  6501. \\\\009\\\\009end\\\\\\\
  6502. \\\\009\\\\009res = res..chars[rand]\\\\\\\
  6503. \\\\009\\\\009usedNums = usedNums..rand..\\\\\\\":\\\\\\\"\\\\\\\
  6504. \\\\009end\\\\\\\
  6505. \\\\009return res\\\\\\\
  6506. end\\\\\\\
  6507. \\\\\\\
  6508. function toBase(str, base)  --Encodes @str in @base\\\\\\\
  6509. \\\\009if not base then return nil end\\\\\\\
  6510. \\\\009str = tostring(str)\\\\\\\
  6511. \\\\009local res = \\\\\\\"\\\\\\\"\\\\\\\
  6512. \\\\009for i = 1, str:len() do\\\\\\\
  6513. \\\\009\\\\009if i == 1 then\\\\\\\
  6514. \\\\009\\\\009\\\\009res = basen(str:byte(i), base)\\\\\\\
  6515. \\\\009\\\\009else\\\\\\\
  6516. \\\\009\\\\009\\\\009res = res..\\\\\\\":\\\\\\\"..basen(str:byte(i), base)\\\\\\\
  6517. \\\\009\\\\009end\\\\\\\
  6518. \\\\009end\\\\\\\
  6519. \\\\009return res\\\\\\\
  6520. end\\\\\\\
  6521. \\\\\\\
  6522. function fromBase(str, base)  --Decodes @str from @base\\\\\\\
  6523. \\\\009if not base then return nil end\\\\\\\
  6524. \\\\009str = tostring(str)\\\\\\\
  6525. \\\\009local bytes = seperate(str, \\\\\\\":\\\\\\\")\\\\\\\
  6526. \\\\009local res = \\\\\\\"\\\\\\\"\\\\\\\
  6527. \\\\009for i = 1, #bytes do\\\\\\\
  6528. \\\\009\\\\009res = res..(string.char(basen(tonumber(bytes[i], base), 10)))\\\\\\\
  6529. \\\\009end\\\\\\\
  6530. \\\\009return res\\\\\\\
  6531. end\\\\\\\
  6532. \\\\\\\
  6533. function toBinary(str)  --Encodes @str in binary\\\\\\\
  6534. \\\\009if not str then return nil end\\\\\\\
  6535. \\\\009str = tostring(str)\\\\\\\
  6536. \\\\009return toBase(str, 2)\\\\\\\
  6537. end\\\\\\\
  6538. \\\\\\\
  6539. function fromBinary(str)  --Decodes @str from binary\\\\\\\
  6540. \\\\009if not str then return nil end\\\\\\\
  6541. \\\\009str = tostring(str)\\\\\\\
  6542. \\\\009return fromBase(str, 2)\\\\\\\
  6543. end\\\\\\\
  6544. \\\\\\\
  6545. function toOctal(str)  --Encodes @str in octal\\\\\\\
  6546. \\\\009if not str then return nil end\\\\\\\
  6547. \\\\009str = tostring(str)\\\\\\\
  6548. \\\\009return toBase(str, 8)\\\\\\\
  6549. end\\\\\\\
  6550. \\\\\\\
  6551. function fromOctal(str)  --Decodes @str from octal\\\\\\\
  6552. \\\\009if not str then return nil end\\\\\\\
  6553. \\\\009str = tostring(str)\\\\\\\
  6554. \\\\009return fromBase(str, 8)\\\\\\\
  6555. end\\\\\\\
  6556. \\\\\\\
  6557. function toHex(str)  --Encodes @str in hex\\\\\\\
  6558. \\\\009if not str then return nil end\\\\\\\
  6559. \\\\009str = tostring(str)\\\\\\\
  6560. \\\\009return toBase(str, 16)\\\\\\\
  6561. end\\\\\\\
  6562. \\\\\\\
  6563. function fromHex(str)  --Decodes @str from hex\\\\\\\
  6564. \\\\009if not str then return nil end\\\\\\\
  6565. \\\\009str = tostring(str)\\\\\\\
  6566. \\\\009return fromBase(str, 16)\\\\\\\
  6567. end\\\\\\\
  6568. \\\\\\\
  6569. function toBase36(str)  --Encodes @str in Base36\\\\\\\
  6570. \\\\009if not str then return nil end\\\\\\\
  6571. \\\\009str = tostring(str)\\\\\\\
  6572. \\\\009return toBase(str, 36)\\\\\\\
  6573. end\\\\\\\
  6574. \\\\\\\
  6575. function fromBase36(str)  --Decodes @str from Base36\\\\\\\
  6576. \\\\009if not str then return nil end\\\\\\\
  6577. \\\\009str = tostring(str)\\\\\\\
  6578. \\\\009return fromBase(str, 36)\\\\\\\
  6579. end\\\\\\\
  6580. \\\\\\\
  6581. function toBase32(str)  --Encodes @str in Base32\\\\\\\
  6582. \\\\009if not str then return nil end\\\\\\\
  6583. \\\\009str = tostring(str)\\\\\\\
  6584. \\\\009local byte=0\\\\\\\
  6585. \\\\009local bits=0\\\\\\\
  6586. \\\\009local rez=\\\\\\\"\\\\\\\"\\\\\\\
  6587. \\\\009local i=0\\\\\\\
  6588. \\\\009for i = 1, str:len() do\\\\\\\
  6589. \\\\009\\\\009byte=byte*256+str:byte(i)\\\\\\\
  6590. \\\\009\\\\009bits=bits+8\\\\\\\
  6591. \\\\009\\\\009repeat\\\\\\\
  6592. \\\\009\\\\009\\\\009bits=bits-5\\\\\\\
  6593. \\\\009\\\\009\\\\009local mul=(2^(bits))\\\\\\\
  6594. \\\\009\\\\009\\\\009local b32n=math.floor(byte/mul)\\\\\\\
  6595. \\\\009\\\\009\\\\009byte=byte-(b32n*mul)\\\\\\\
  6596. \\\\009\\\\009\\\\009b32n=b32n+1\\\\\\\
  6597. \\\\009\\\\009\\\\009rez=rez..string.sub(base32,b32n,b32n)\\\\\\\
  6598. \\\\009\\\\009until bits<5\\\\\\\
  6599. \\\\009end\\\\\\\
  6600. \\\\009if bits>0 then\\\\\\\
  6601. \\\\009\\\\009local b32n= math.fmod(byte*(2^(5-bits)),32)\\\\\\\
  6602. \\\\009\\\\009b32n=b32n+1\\\\\\\
  6603. \\\\009\\\\009rez=rez..string.sub(base32,b32n,b32n)\\\\\\\
  6604. \\\\009end\\\\\\\
  6605. \\\\009return rez\\\\\\\
  6606. end\\\\\\\
  6607. \\\\\\\
  6608. function fromBase32(str)  --Decodes @str from Base32\\\\\\\
  6609. \\\\009if not str then return nil end\\\\\\\
  6610. \\\\009str = tostring(str)\\\\\\\
  6611. \\\\009local b32n=0\\\\\\\
  6612. \\\\009local bits=0\\\\\\\
  6613. \\\\009local rez=\\\\\\\"\\\\\\\"\\\\\\\
  6614. \\\\009local i=0\\\\\\\
  6615. \\\\009string.gsub(str:upper(), \\\\\\\"[\\\\\\\"..base32..\\\\\\\"]\\\\\\\", function (char)\\\\\\\
  6616. \\\\009\\\\009local num = string.find(base32, char, 1, true)\\\\\\\
  6617. \\\\009\\\\009b32n=b32n*32+(num - 1)\\\\\\\
  6618. \\\\009\\\\009bits=bits+5\\\\\\\
  6619. \\\\009\\\\009while  bits>=8 do\\\\\\\
  6620. \\\\009\\\\009\\\\009bits=bits-8\\\\\\\
  6621. \\\\009\\\\009\\\\009local mul=(2^(bits))\\\\\\\
  6622. \\\\009\\\\009\\\\009local byte = math.floor(b32n/mul)\\\\\\\
  6623. \\\\009\\\\009\\\\009b32n=b32n-(byte*mul)\\\\\\\
  6624. \\\\009\\\\009\\\\009rez=rez..string.char(byte)\\\\\\\
  6625. \\\\009\\\\009end\\\\\\\
  6626. \\\\009end)\\\\\\\
  6627. \\\\009return rez\\\\\\\
  6628. end\\\\\\\
  6629. \\\\\\\
  6630. function toBase64(str)  --Encodes @str in Base64\\\\\\\
  6631. \\\\009if not str then return nil end\\\\\\\
  6632. \\\\009str = tostring(str)\\\\\\\
  6633. \\\\009local bytes = {}\\\\\\\
  6634. \\\\009local result = \\\\\\\"\\\\\\\"\\\\\\\
  6635. \\\\009for spos=0,str:len()-1,3 do\\\\\\\
  6636. \\\\009\\\\009for byte=1,3 do bytes[byte] = str:byte(spos+byte) or 0 end\\\\\\\
  6637. \\\\009\\\\009result = string.format('%s%s%s%s%s',result,Base64.base64chars[Base64.rsh(bytes[1],2)],Base64.base64chars[Base64.lor(Base64.lsh((bytes[1] % 4),4), Base64.rsh(bytes[2],4))] or \\\\\\\"=\\\\\\\",((str:len()-spos) > 1) and Base64.base64chars[Base64.lor(Base64.lsh(bytes[2] % 16,2), Base64.rsh(bytes[3],6))] or \\\\\\\"=\\\\\\\",((str:len()-spos) > 2) and Base64.base64chars[(bytes[3] % 64)] or \\\\\\\"=\\\\\\\")\\\\\\\
  6638. \\\\009end\\\\\\\
  6639. \\\\009return result\\\\\\\
  6640. end\\\\\\\
  6641. \\\\\\\
  6642. function fromBase64(str)  --Decodes @str from Base64\\\\\\\
  6643. \\\\009if not str then return nil end\\\\\\\
  6644. \\\\009str = tostring(str)\\\\\\\
  6645. \\\\009local chars = {}\\\\\\\
  6646. \\\\009local result=\\\\\\\"\\\\\\\"\\\\\\\
  6647. \\\\009for dpos=0,str:len()-1,4 do\\\\\\\
  6648. \\\\009\\\\009for char=1,4 do chars[char] = Base64.base64bytes[(str:sub((dpos+char),(dpos+char)) or \\\\\\\"=\\\\\\\")] end\\\\\\\
  6649. \\\\009\\\\009result = string.format('%s%s%s%s',result,string.char(Base64.lor(Base64.lsh(chars[1],2), Base64.rsh(chars[2],4))),(chars[3] ~= nil) and string.char(Base64.lor(Base64.lsh(chars[2],4), Base64.rsh(chars[3],2))) or \\\\\\\"\\\\\\\",(chars[4] ~= nil) and string.char(Base64.lor(Base64.lsh(chars[3],6) % 192, (chars[4]))) or \\\\\\\"\\\\\\\")\\\\\\\
  6650. \\\\009end\\\\\\\
  6651. \\\\009return result\\\\\\\
  6652. end\\\\\\\
  6653. \\\\\\\
  6654. function rot13(str)  --Rot13s @str\\\\\\\
  6655. \\\\009if not str then return nil end\\\\\\\
  6656. \\\\009str = tostring(str)\\\\\\\
  6657. \\\\009local rot = \\\\\\\"\\\\\\\"\\\\\\\
  6658. \\\\009local len = str:len()\\\\\\\
  6659. \\\\009for i = 1, len do\\\\\\\
  6660. \\\\009\\\\009local k = str:byte(i)\\\\\\\
  6661. \\\\009\\\\009if (k >= 65 and k <= 77) or (k >= 97 and k <=109) then\\\\\\\
  6662. \\\\009\\\\009\\\\009rot = rot..string.char(k+13)\\\\\\\
  6663. \\\\009\\\\009elseif (k >= 78 and k <= 90) or (k >= 110 and k <= 122) then\\\\\\\
  6664. \\\\009\\\\009\\\\009rot = rot..string.char(k-13)\\\\\\\
  6665. \\\\009\\\\009else\\\\\\\
  6666. \\\\009\\\\009\\\\009rot = rot..string.char(k)\\\\\\\
  6667. \\\\009\\\\009end\\\\\\\
  6668. \\\\009end\\\\\\\
  6669. \\\\009return rot\\\\\\\
  6670. end\\\\\\\
  6671. \\\\\\\
  6672. function rot47(str)  --Rot47s @str\\\\\\\
  6673. \\\\009if not str then return nil end\\\\\\\
  6674. \\\\009str = tostring(str)\\\\\\\
  6675. \\\\009local rot = \\\\\\\"\\\\\\\"\\\\\\\
  6676. \\\\009for i = 1, str:len() do\\\\\\\
  6677. \\\\009\\\\009local p = str:byte(i)\\\\\\\
  6678. \\\\009\\\\009if p >= string.byte('!') and p <= string.byte('O') then\\\\\\\
  6679. \\\\009\\\\009\\\\009p = ((p + 47) % 127)\\\\\\\
  6680. \\\\009\\\\009elseif p >= string.byte('P') and p <= string.byte('~') then\\\\\\\
  6681. \\\\009\\\\009\\\\009p = ((p - 47) % 127)\\\\\\\
  6682. \\\\009\\\\009end\\\\\\\
  6683. \\\\009\\\\009rot = rot..string.char(p)\\\\\\\
  6684. \\\\009end\\\\\\\
  6685. \\\\009return rot\\\\\\\
  6686. end\\\\\\\
  6687. \\\\\\\
  6688. function SHA1(str) --Returns SHA1 Hash of @str\\\\\\\
  6689.    if not str then return nil end\\\\\\\
  6690.    str = tostring(str)\\\\\\\
  6691.    local H0,H1,H2,H3,H4 = 0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476,0xC3D2E1F0\\\\\\\
  6692.    local msg_len_in_bits = #str * 8\\\\\\\
  6693.    local first_append = char(0x80)\\\\\\\
  6694.    local non_zero_message_bytes = #str +1 +8\\\\\\\
  6695.    local current_mod = non_zero_message_bytes % 64\\\\\\\
  6696.    local second_append = current_mod>0 and rep(char(0), 64 - current_mod) or \\\\\\\"\\\\\\\"\\\\\\\
  6697.    local B1, R1 = modf(msg_len_in_bits  / 0x01000000)\\\\\\\
  6698.    local B2, R2 = modf( 0x01000000 * R1 / 0x00010000)\\\\\\\
  6699.    local B3, R3 = modf( 0x00010000 * R2 / 0x00000100)\\\\\\\
  6700.    local B4\\\\009  =\\\\0090x00000100 * R3\\\\\\\
  6701.    local L64 = char( 0) .. char( 0) .. char( 0) .. char( 0)\\\\\\\
  6702.            .. char(B1) .. char(B2) .. char(B3) .. char(B4)\\\\\\\
  6703.    str = str .. first_append .. second_append .. L64\\\\\\\
  6704.    assert(#str % 64 == 0)\\\\\\\
  6705.    local chunks = #str / 64\\\\\\\
  6706.    local W = { }\\\\\\\
  6707.    local start, A, B, C, D, E, f, K, TEMP\\\\\\\
  6708.    local chunk = 0\\\\\\\
  6709.    while chunk < chunks do\\\\\\\
  6710.        start,chunk = chunk * 64 + 1,chunk + 1\\\\\\\
  6711.        for t = 0, 15 do\\\\\\\
  6712.            W[t] = tSHA1.bytes_to_w32(str:byte(start, start + 3))\\\\\\\
  6713.            start = start + 4\\\\\\\
  6714.        end\\\\\\\
  6715.        for t = 16, 79 do\\\\\\\
  6716.            W[t] = tSHA1.w32_rot(1, tSHA1.w32_xor_n(W[t-3], W[t-8], W[t-14], W[t-16]))\\\\\\\
  6717.        end\\\\\\\
  6718.        A,B,C,D,E = H0,H1,H2,H3,H4\\\\\\\
  6719.        for t = 0, 79 do\\\\\\\
  6720.            if t <= 19 then\\\\\\\
  6721.                f = tSHA1.w32_or(tSHA1.w32_and(B, C), tSHA1.w32_and(tSHA1.w32_not(B), D))\\\\\\\
  6722.                K = 0x5A827999\\\\\\\
  6723.            elseif t <= 39 then\\\\\\\
  6724.                f = tSHA1.w32_xor_n(B, C, D)\\\\\\\
  6725.                K = 0x6ED9EBA1\\\\\\\
  6726.            elseif t <= 59 then\\\\\\\
  6727.                f = tSHA1.w32_or3(tSHA1.w32_and(B, C), tSHA1.w32_and(B, D), tSHA1.w32_and(C, D))\\\\\\\
  6728.                K = 0x8F1BBCDC\\\\\\\
  6729.            else\\\\\\\
  6730.                f = tSHA1.w32_xor_n(B, C, D)\\\\\\\
  6731.                K = 0xCA62C1D6\\\\\\\
  6732.            end\\\\\\\
  6733.            A,B,C,D,E = tSHA1.w32_add_n(tSHA1.w32_rot(5, A), f, E, W[t], K),\\\\\\\
  6734.            A, tSHA1.w32_rot(30, B), C, D\\\\\\\
  6735.        end\\\\\\\
  6736.        H0,H1,H2,H3,H4 = tSHA1.w32_add(H0, A),tSHA1.w32_add(H1, B),tSHA1.w32_add(H2, C),tSHA1.w32_add(H3, D),tSHA1.w32_add(H4, E)\\\\\\\
  6737.    end\\\\\\\
  6738.    local f = tSHA1.w32_to_hexstring\\\\\\\
  6739.    return f(H0) .. f(H1) .. f(H2) .. f(H3) .. f(H4)\\\\\\\
  6740. end\\\\\\\
  6741. \\\\\\\
  6742. function CRC32(str) --Returns CRC32 Hash of @str\\\\\\\
  6743.    local crc, l, i = 0xFFFFFFFF, string.len(str)\\\\\\\
  6744.    for i = 1, l, 1 do\\\\\\\
  6745.        crc = bit.bxor(bit.brshift(crc, 8), CRC.crc32[bit.band(bit.bxor(crc, string.byte(str, i)), 0xFF) + 1])\\\\\\\
  6746.    end\\\\\\\
  6747.    return bit.bxor(crc, -1)\\\\\\\
  6748. end\\\\\\\
  6749. \\\\\\\
  6750. function FCS16(str) --Returns FCS16 Hash of @str\\\\\\\
  6751.    local i\\\\\\\
  6752.    local l=string.len(str)\\\\\\\
  6753.    local uFcs16 = 65535\\\\\\\
  6754.    for i = 1,l do\\\\\\\
  6755.        uFcs16 = bit.bxor(bit.brshift(uFcs16,8), FCS[\\\\\\\"16\\\\\\\"][bit.band(bit.bxor(uFcs16, string.byte(str,i)), 255)])\\\\\\\
  6756.    end\\\\\\\
  6757.    return  bit.bxor(uFcs16, 65535)\\\\\\\
  6758. end\\\\\\\
  6759. \\\\\\\
  6760. function FCS32(str) --Returns FCS32 Hash of @str\\\\\\\
  6761.    local i\\\\\\\
  6762.    local l = string.len(str)\\\\\\\
  6763.    local uFcs32 = -1\\\\\\\
  6764.    for i=1,l do\\\\\\\
  6765.        uFcs32 = bit.bxor(bit.brshift(uFcs32,8), FCS[\\\\\\\"32\\\\\\\"][bit.band(bit.bxor(uFcs32, string.byte(str,i)), 255)])\\\\\\\
  6766.    end\\\\\\\
  6767.    return bit.bnot(uFcs32)\\\\\\\
  6768. end\\\\\\\
  6769. \\\\\\\
  6770. function encrypt(str, key)  --Encrypts @str with @key\\\\\\\
  6771. \\\\009if not key then return nil end\\\\\\\
  6772. \\\\009str = tostring(str)\\\\\\\
  6773. \\\\009local alphabet = \\\\\\\"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\\\\\]^_abcdefghijklmnopqrstuvwxyz{|}~\\\\\\\"\\\\\\\
  6774. \\\\009local _rand = math.random(#alphabet-10)\\\\\\\
  6775. \\\\009local iv = string.sub(jumble(alphabet), _rand, _rand  + 9)\\\\\\\
  6776. \\\\009iv = jumble(iv)\\\\\\\
  6777. \\\\009str = iv..str\\\\\\\
  6778. \\\\009local key = SHA1(key)\\\\\\\
  6779. \\\\009local strLen = str:len()\\\\\\\
  6780. \\\\009local keyLen = key:len()\\\\\\\
  6781. \\\\009local j=1\\\\\\\
  6782. \\\\009local result = \\\\\\\"\\\\\\\"\\\\\\\
  6783. \\\\009for i=1, strLen do\\\\\\\
  6784. \\\\009\\\\009local ordStr = string.byte(str:sub(i,i))\\\\\\\
  6785. \\\\009\\\\009if j == keyLen then j=1 end\\\\\\\
  6786. \\\\009\\\\009local ordKey = string.byte(key:sub(j,j))\\\\\\\
  6787. \\\\009\\\\009result = result..string.reverse(basen(ordStr+ordKey, 36))\\\\\\\
  6788. \\\\009\\\\009j = j+1\\\\\\\
  6789. \\\\009end\\\\\\\
  6790. \\\\009return result\\\\\\\
  6791. end\\\\\\\
  6792. \\\\\\\
  6793. function decrypt(str, key)  --Decrypts @str with @key\\\\\\\
  6794. \\\\009if not key then return nil end\\\\\\\
  6795. \\\\009str = tostring(str)\\\\\\\
  6796. \\\\009local key = SHA1(key)\\\\\\\
  6797. \\\\009local strLen = str:len()\\\\\\\
  6798. \\\\009local keyLen = key:len()\\\\\\\
  6799. \\\\009local j=1\\\\\\\
  6800. \\\\009local result = \\\\\\\"\\\\\\\"\\\\\\\
  6801. \\\\009for i=1, strLen, 2 do\\\\\\\
  6802. \\\\009\\\\009local ordStr = basen(tonumber(string.reverse(str:sub(i, i+1)),36),10)\\\\\\\
  6803. \\\\009\\\\009if j==keyLen then j=1 end\\\\\\\
  6804. \\\\009\\\\009local ordKey = string.byte(key:sub(j,j))\\\\\\\
  6805. \\\\009\\\\009result = result..string.char(ordStr-ordKey)\\\\\\\
  6806. \\\\009\\\\009j = j+1\\\\\\\
  6807. \\\\009end\\\\\\\
  6808. \\\\009return result:sub(11)\\\\\\\
  6809. end\\\\\\\
  6810. \\\\\\\
  6811. function setRandSeed(seed)  --Sets random seed to @seed\\\\\\\
  6812. \\\\009math.randomseed(seed)\\\\\\\
  6813. end\\\\\\\
  6814. \\\\\\\
  6815. \\\\\\\
  6816. --\\\\\\\
  6817. -- MODIFIED CODE FROM TESSERACT LIES BELOW. \\\\\\\
  6818. --\\\\\\\
  6819. \\\\\\\
  6820. \\\\\\\
  6821. function traverseKey(array, text)\\\\\\\
  6822. for k,v in pairs(array) do\\\\\\\
  6823.  if v == text then\\\\\\\
  6824.   return true, k\\\\\\\
  6825.  end\\\\\\\
  6826. end\\\\\\\
  6827. return false, nil\\\\\\\
  6828. end\\\\\\\
  6829. \\\\\\\
  6830. function traverseValue(array, text)\\\\\\\
  6831. for k,v in pairs(array) do\\\\\\\
  6832.  if k == text then\\\\\\\
  6833.   return true, v\\\\\\\
  6834.  end\\\\\\\
  6835. end\\\\\\\
  6836. return false, nil\\\\\\\
  6837. end\\\\\\\
  6838. \\\\\\\
  6839. function findKey(array, text)\\\\\\\
  6840. for k,v in pairs(array) do\\\\\\\
  6841.  if k == text then\\\\\\\
  6842.   return true, k\\\\\\\
  6843.  end\\\\\\\
  6844. end\\\\\\\
  6845. return false, nil\\\\\\\
  6846. end\\\\\\\
  6847. \\\\\\\
  6848. function findValue(array, text)\\\\\\\
  6849. for k,v in pairs(array) do\\\\\\\
  6850.  if v == text then\\\\\\\
  6851.   return true, v\\\\\\\
  6852.  end\\\\\\\
  6853. end\\\\\\\
  6854. return false, nil\\\\\\\
  6855. end\\\\\\\
  6856. \\\\\\\
  6857. function queryKey(array, text)\\\\\\\
  6858. for k,v in pairs(array) do\\\\\\\
  6859.  if string.find(k, text) then\\\\\\\
  6860.   return true, k\\\\\\\
  6861.  end\\\\\\\
  6862. end\\\\\\\
  6863. return false, nil\\\\\\\
  6864. end\\\\\\\
  6865. \\\\\\\
  6866. function queryValue(array, text)\\\\\\\
  6867. for k,v in pairs(array) do\\\\\\\
  6868.  if string.find(v, text) then\\\\\\\
  6869.   return true, v\\\\\\\
  6870.  end\\\\\\\
  6871. end\\\\\\\
  6872. return false, nil\\\\\\\
  6873. end\\\\\\\
  6874. \\\\\\\
  6875. function iterateFileLines(path)\\\\\\\
  6876. if not fs.exists(path) then return nil end\\\\\\\
  6877. local handle = fs.open(path, fs.AF_READ)\\\\\\\
  6878. local commands = {}\\\\\\\
  6879. local line = handle.readLine()\\\\\\\
  6880. while line do\\\\\\\
  6881.  commands[#commands + 1] = line\\\\\\\
  6882.  line = handle.readLine()\\\\\\\
  6883. end\\\\\\\
  6884. handle.close()\\\\\\\
  6885. return commands\\\\\\\
  6886. end\\\\\\\
  6887. \\\\\\\
  6888. function readFile(path)\\\\\\\
  6889. if not fs.exists(path) then return nil end\\\\\\\
  6890. local handle = fs.open(path, fs.AF_READ)\\\\\\\
  6891. local content = handle.readAll()\\\\\\\
  6892. handle.close()\\\\\\\
  6893. return content\\\\\\\
  6894. end\\\\\\\
  6895. \\\\\\\
  6896. function cload(path)\\\\\\\
  6897. if fs.exists(path) and not fs.isDir(path) then\\\\\\\
  6898.  local lf = fs.open(path, \\\\\\\"r\\\\\\\")\\\\\\\
  6899.  local contents = lf.readAll()\\\\\\\
  6900.  lf.close()\\\\\\\
  6901.  return textutils.unserialize(contents)\\\\\\\
  6902. else\\\\\\\
  6903.  return nil\\\\\\\
  6904. end\\\\\\\
  6905. end\\\\\\\
  6906. \\\\\\\
  6907. function csave(cTable, path)\\\\\\\
  6908. if fs.exists(path) then\\\\\\\
  6909.  if fs.isDir(path) then\\\\\\\
  6910.   return false\\\\\\\
  6911.  end\\\\\\\
  6912. end\\\\\\\
  6913. local sf = fs.open(path, \\\\\\\"w\\\\\\\")\\\\\\\
  6914. sf.write(textutils.serialize(cTable))\\\\\\\
  6915. sf.close()\\\\\\\
  6916. return true\\\\\\\
  6917. end\\\\\\\
  6918. ]]\\\\\\\
  6919. persist(\\\\\\\"stdlib\\\\\\\", libcode)\\\\\\\
  6920. \\\\\\\
  6921. return 1\\\"\",\
  6922.  \"F:libuser.2.so\",\
  6923.  \"\\\"local libcode = [[\\\\\\\
  6924. CONSTANT_LINE = \\\\\\\"---------------------------------------------------\\\\\\\"\\\\\\\
  6925. \\\\\\\
  6926. --MenuAPI functions (mprint, drawBootMenu) by 1Ridav and MelnikovSM\\\\\\\
  6927. --Context menu provided generously by MasonCipher\\\\\\\
  6928. local function mprint(array, this, s1, s2, x, y)\\\\\\\
  6929.   local c = term.getTextColor()\\\\\\\
  6930.   term.setTextColor(colors.lightGray)\\\\\\\
  6931.   for i = 1, #array do\\\\\\\
  6932.      term.setCursorPos(x, y)\\\\\\\
  6933.      --Check if option selected\\\\\\\
  6934.      if i == this then \\\\\\\
  6935.      --Option selected   \\\\\\\
  6936.         write(s1)\\\\\\\
  6937.      else \\\\\\\
  6938.      --Option NOT selected\\\\\\\
  6939.         write(s2)\\\\\\\
  6940.      end\\\\\\\
  6941.      --Print the string\\\\\\\
  6942.      print(array[i])\\\\\\\
  6943.      y = y + 1 \\\\\\\
  6944.   end\\\\\\\
  6945.   term.setTextColor(c)\\\\\\\
  6946. end\\\\\\\
  6947. \\\\\\\
  6948. local function stdoutg(text, bg, fg)\\\\\\\
  6949. local a = term.getBackgroundColor()\\\\\\\
  6950. local b = term.getTextColor()\\\\\\\
  6951. term.setBackgroundColor(bg or colors.black)\\\\\\\
  6952. term.setTextColor(fg or colors.white)\\\\\\\
  6953. write(text)\\\\\\\
  6954. term.setBackgroundColor(a)\\\\\\\
  6955. term.setTextColor(b)\\\\\\\
  6956. end\\\\\\\
  6957. \\\\\\\
  6958. function clearScreen(color)\\\\\\\
  6959. term.setBackgroundColor(color or colors.black)\\\\\\\
  6960. term.clear()\\\\\\\
  6961. term.setCursorPos(1,1)\\\\\\\
  6962. end\\\\\\\
  6963. \\\\\\\
  6964. function button(text, x1, x2, y)\\\\\\\
  6965. term.setCursorPos(x1, y)\\\\\\\
  6966. print(text)\\\\\\\
  6967. local a, b, xx, yy = os.pullEvent(\\\\\\\"mouse_click\\\\\\\")\\\\\\\
  6968. if (xx >= x1 and xx <= x2 and yy == y) then\\\\\\\
  6969.  return true\\\\\\\
  6970. else\\\\\\\
  6971.  return false\\\\\\\
  6972. end\\\\\\\
  6973. end\\\\\\\
  6974. \\\\\\\
  6975. function counter(text, y)\\\\\\\
  6976. for i=1,100 do\\\\\\\
  6977.  sleep(0.1)\\\\\\\
  6978.  term.setCursorPos(1, y)\\\\\\\
  6979.  print(text..\\\\\\\" [\\\\\\\"..tostring(i)..\\\\\\\"%]\\\\\\\")\\\\\\\
  6980. end\\\\\\\
  6981. end\\\\\\\
  6982. \\\\\\\
  6983. function drawProgress(txt, y)\\\\\\\
  6984. term.setCursorPos(4, 4)\\\\\\\
  6985. print(txt)\\\\\\\
  6986. term.setCursorPos(1, y)\\\\\\\
  6987. print(\\\\\\\"[                             ]\\\\\\\")\\\\\\\
  6988. term.setCursorPos(2, y)\\\\\\\
  6989. textutils.slowPrint(\\\\\\\"==============================]\\\\\\\", 10)\\\\\\\
  6990. end\\\\\\\
  6991. \\\\\\\
  6992. function drawProgressBig(color)\\\\\\\
  6993. term.setCursorPos(4, 10)\\\\\\\
  6994. print(\\\\\\\"\\\\\\\\#-------------------------------------------\\\\\\\\#\\\\\\\")\\\\\\\
  6995. term.setCursorPos(4, 11)\\\\\\\
  6996. print(\\\\\\\"|                                           |\\\\\\\")\\\\\\\
  6997. term.setCursorPos(4, 12)\\\\\\\
  6998. print(\\\\\\\"\\\\\\\\#-------------------------------------------\\\\\\\\#\\\\\\\")\\\\\\\
  6999. term.setBackgroundColor(color or colors.yellow)\\\\\\\
  7000. term.setCursorPos(5, 11)\\\\\\\
  7001. textutils.slowWrite(\\\\\\\"                                           \\\\\\\", 10)\\\\\\\
  7002. term.setBackgroundColor(colors.black)\\\\\\\
  7003. end\\\\\\\
  7004. \\\\\\\
  7005. function printColoredTextLine(y, txt, bg, fg)\\\\\\\
  7006. term.setCursorPos(1, y)\\\\\\\
  7007. term.setBackgroundColor(bg or colors.lightGray)\\\\\\\
  7008. term.write(\\\\\\\"                                                   \\\\\\\")\\\\\\\
  7009. term.setCursorPos(1, y)\\\\\\\
  7010. term.setTextColor(fg or colors.black)\\\\\\\
  7011. print(txt)\\\\\\\
  7012. term.setBackgroundColor(colors.black)\\\\\\\
  7013. term.setTextColor(colors.white)\\\\\\\
  7014. end\\\\\\\
  7015. \\\\\\\
  7016. function outputInfo(header, msg)\\\\\\\
  7017. term.setTextColor(colors.cyan)\\\\\\\
  7018. write(header..\\\\\\\": \\\\\\\")\\\\\\\
  7019. term.setTextColor(colors.lightGray)\\\\\\\
  7020. print(msg)\\\\\\\
  7021. term.setTextColor(colors.white)\\\\\\\
  7022. end\\\\\\\
  7023. \\\\\\\
  7024. function outputWarning(header, msg)\\\\\\\
  7025. term.setTextColor(colors.red)\\\\\\\
  7026. write(header..\\\\\\\": \\\\\\\")\\\\\\\
  7027. term.setTextColor(colors.orange)\\\\\\\
  7028. print(msg)\\\\\\\
  7029. term.setTextColor(colors.white)\\\\\\\
  7030. end\\\\\\\
  7031. \\\\\\\
  7032. function outputSuccess(header, msg)\\\\\\\
  7033. term.setTextColor(colors.lime)\\\\\\\
  7034. write(header..\\\\\\\": \\\\\\\")\\\\\\\
  7035. term.setTextColor(colors.green)\\\\\\\
  7036. print(msg)\\\\\\\
  7037. term.setTextColor(colors.white)\\\\\\\
  7038. end\\\\\\\
  7039. \\\\\\\
  7040. function request(req)\\\\\\\
  7041. while true do\\\\\\\
  7042.  term.setTextColor(colors.cyan)\\\\\\\
  7043.  write(req .. \\\\\\\"? \\\\\\\")\\\\\\\
  7044.  term.setTextColor(colors.lightGray)\\\\\\\
  7045.  write(\\\\\\\"(\\\\\\\")\\\\\\\
  7046.  term.setTextColor(colors.lime)\\\\\\\
  7047.  write(\\\\\\\"Y\\\\\\\")\\\\\\\
  7048.  term.setTextColor(colors.lightGray)\\\\\\\
  7049.  write(\\\\\\\"/\\\\\\\")\\\\\\\
  7050.  term.setTextColor(colors.red)\\\\\\\
  7051.  write(\\\\\\\"N\\\\\\\")\\\\\\\
  7052.  term.setTextColor(colors.lightGray)\\\\\\\
  7053.  write(\\\\\\\") \\\\\\\")\\\\\\\
  7054.  local presel=read()\\\\\\\
  7055.  if presel==\\\\\\\"Y\\\\\\\" or presel==\\\\\\\"y\\\\\\\" then\\\\\\\
  7056.   return true\\\\\\\
  7057.  elseif presel==\\\\\\\"N\\\\\\\" or presel==\\\\\\\"n\\\\\\\" then\\\\\\\
  7058.   return false\\\\\\\
  7059.  end\\\\\\\
  7060. end\\\\\\\
  7061. end\\\\\\\
  7062. \\\\\\\
  7063. function drawImg(path, x, y)\\\\\\\
  7064. if fs.exists(path) and not fs.isDir(path) then\\\\\\\
  7065.  local img = paintutils.loadImage(path)\\\\\\\
  7066.  paintutils.drawImage(img, x, y)\\\\\\\
  7067. else\\\\\\\
  7068.  gui.outputWarning(\\\\\\\"gui\\\\\\\", \\\\\\\"image not found\\\\\\\")\\\\\\\
  7069. end\\\\\\\
  7070. end\\\\\\\
  7071. \\\\\\\
  7072. function drawDialogBox(prompt)\\\\\\\
  7073. drawImg(\\\\\\\"/etc/resources/dialog_box.img\\\\\\\", 1, 1)\\\\\\\
  7074. term.setCursorPos(6,7)\\\\\\\
  7075. term.setBackgroundColor(colors.white)\\\\\\\
  7076. term.setTextColor(colors.black)\\\\\\\
  7077. print(prompt)\\\\\\\
  7078. end\\\\\\\
  7079. \\\\\\\
  7080. function drawDialogButton(text, newline)\\\\\\\
  7081. stdoutg(text, colors.gray, colors.white)\\\\\\\
  7082. if newline then\\\\\\\
  7083.  stdoutg(\\\\\\\"\\\\\\\\n\\\\\\\", colors.gray, colors.white)\\\\\\\
  7084. else\\\\\\\
  7085.  stdoutg(\\\\\\\" \\\\\\\", colors.gray, colors.white)\\\\\\\
  7086. end\\\\\\\
  7087. end\\\\\\\
  7088. \\\\\\\
  7089. function printColored(text, color)\\\\\\\
  7090. local tmp = term.getTextColor()\\\\\\\
  7091. term.setTextColor(color)\\\\\\\
  7092. print(text)\\\\\\\
  7093. term.setTextColor(tmp)\\\\\\\
  7094. end\\\\\\\
  7095. \\\\\\\
  7096. function drawBootMenu(array, state1, state2, pos_x, pos_y)\\\\\\\
  7097.   local select = 1\\\\\\\
  7098.   local x, y = term.getCursorPos()\\\\\\\
  7099.   \\\\\\\
  7100.   while true do\\\\\\\
  7101.      term.setCursorPos(x, y)\\\\\\\
  7102.      mprint(array, select, state1, state2, pos_x, pos_y)\\\\\\\
  7103.      event, key = os.pullEvent(\\\\\\\"key\\\\\\\")\\\\\\\
  7104.      --Enter\\\\\\\
  7105.      if key == 28 then \\\\\\\
  7106.         return select \\\\\\\
  7107.      end\\\\\\\
  7108.      \\\\\\\
  7109.      if #array > 1 then\\\\\\\
  7110.         --Arrow UP or W key\\\\\\\
  7111.         if key == 200 or key == 17 then \\\\\\\
  7112.      \\\\009\\\\009    select = select - 1 \\\\\\\
  7113. \\\\009\\\\009\\\\009\\\\\\\
  7114.            if select < 1 then \\\\\\\
  7115.               select = #array \\\\\\\
  7116.            end\\\\\\\
  7117.         --Arrow Down or S key\\\\\\\
  7118.         elseif key == 208 or key == 31 then \\\\\\\
  7119.      \\\\009\\\\009    select = select + 1     \\\\\\\
  7120.        \\\\009\\\\009\\\\009 if select > #array then select = 1 end\\\\\\\
  7121.  \\\\009      end\\\\\\\
  7122.      end   \\\\\\\
  7123.   end\\\\\\\
  7124. end\\\\\\\
  7125. \\\\\\\
  7126. function drawContextMenu(...)\\\\\\\
  7127.  if #arg < 3 or type(arg[3]) ~= \\\\\\\"table\\\\\\\" then error(\\\\\\\"Usage: UI.drawContextMenu(number x, number y, table Element1, table Element2, table Element3...) \\\\\\\\nReturns: string Action \\\\\\\\n<Element> structure: {string Name[, boolean isElementHidden][,number colorOfText]}\\\\\\\") end\\\\\\\
  7128.  local xSize, ySize = term.getSize()\\\\\\\
  7129.   \\\\\\\
  7130.  local function text(x,y,text1,color)\\\\\\\
  7131.    term.setTextColor(color)\\\\\\\
  7132.    term.setCursorPos(x,y)\\\\\\\
  7133.    term.write(text1)\\\\\\\
  7134.  end\\\\\\\
  7135.   \\\\\\\
  7136.  local Objects = {}\\\\\\\
  7137.  local function newObj(name,isHidden,xStart,xEnd,y)\\\\\\\
  7138.    Objects[name]={}\\\\\\\
  7139.    Objects[name][\\\\\\\"isHidden\\\\\\\"] = isHidden\\\\\\\
  7140.    Objects[name][\\\\\\\"xStart\\\\\\\"] = xStart\\\\\\\
  7141.    Objects[name][\\\\\\\"xEnd\\\\\\\"] = xEnd\\\\\\\
  7142.    Objects[name][\\\\\\\"y\\\\\\\"] = y\\\\\\\
  7143.  end\\\\\\\
  7144.       \\\\\\\
  7145.  local theLongestElement = #arg[3][1]\\\\\\\
  7146.  for i=3,#arg do\\\\\\\
  7147.    if arg[i] ~= \\\\\\\"-\\\\\\\" and theLongestElement < #arg[i][1] then\\\\\\\
  7148.      theLongestElement = #arg[i][1]\\\\\\\
  7149.    end\\\\\\\
  7150.  end\\\\\\\
  7151.   \\\\\\\
  7152.  local xSizeOfMenu = theLongestElement + 4\\\\\\\
  7153.  local ySizeOfMenu = #arg-2\\\\\\\
  7154. \\\\\\\
  7155.  local xStartToDisplay = nil\\\\\\\
  7156.  local yStartToDisplay = nil\\\\\\\
  7157.     \\\\\\\
  7158.  local function square(x1,y1,width,height,color)\\\\\\\
  7159.    local string = string.rep(\\\\\\\" \\\\\\\",width)\\\\\\\
  7160.    term.setBackgroundColor(color)\\\\\\\
  7161.    for y=y1,(y1+height-1) do\\\\\\\
  7162.      term.setCursorPos(x1,y)\\\\\\\
  7163.      term.write(string)\\\\\\\
  7164.    end\\\\\\\
  7165.  end\\\\\\\
  7166.  \\\\\\\
  7167.  local function drawSeparator(x,y,size)\\\\\\\
  7168.    term.setTextColor(colors.lightGray)\\\\\\\
  7169.    term.setCursorPos(x,y)\\\\\\\
  7170.    term.write(string.rep(\\\\\\\"-\\\\\\\",size))\\\\\\\
  7171.  end\\\\\\\
  7172.  \\\\\\\
  7173.  local function drawMenu(xMenu,yMenu)\\\\\\\
  7174.    if yMenu+ySizeOfMenu - 1  >= ySize then yMenu = yMenu - (yMenu+ySizeOfMenu - 1 - ySize) - 1 end\\\\\\\
  7175.    if xMenu+xSizeOfMenu - 1  >= xSize then xMenu = xMenu - (xMenu+xSizeOfMenu - 1 - xSize) - 1 end\\\\\\\
  7176.    xStartToDisplay = xMenu + 2\\\\\\\
  7177.    yStartToDisplay = yMenu\\\\\\\
  7178.    square(xMenu+1,yMenu+1,xSizeOfMenu,ySizeOfMenu,colors.gray)\\\\\\\
  7179.    square(xMenu,yMenu,xSizeOfMenu,ySizeOfMenu,colors.white)\\\\\\\
  7180.    for i=3,#arg do\\\\\\\
  7181.      if arg[i] ~= \\\\\\\"-\\\\\\\" then\\\\\\\
  7182.        local contextColor = colors.black\\\\\\\
  7183.        if arg[i][2] == nil and arg[i][3] == nil then\\\\\\\
  7184.          contextColor = colors.black\\\\\\\
  7185.        elseif arg[i][2] == false and arg[i][3] == nil then\\\\\\\
  7186.          contextColor = colors.black\\\\\\\
  7187.        elseif arg[i][2] == false and arg[i][3] ~= nil then\\\\\\\
  7188.          contextColor = arg[i][3]\\\\\\\
  7189.        elseif arg[i][2] == true then\\\\\\\
  7190.          contextColor = colors.lightGray\\\\\\\
  7191.        end\\\\\\\
  7192.        text(xStartToDisplay,yStartToDisplay+i-3,arg[i][1],contextColor)\\\\\\\
  7193.        newObj(arg[i][1],arg[i][2],xMenu,xMenu+xSizeOfMenu-1,yStartToDisplay+i-3)\\\\\\\
  7194.      else\\\\\\\
  7195.        drawSeparator(xMenu,yStartToDisplay+i-3,xSizeOfMenu)\\\\\\\
  7196.      end\\\\\\\
  7197.    end\\\\\\\
  7198.  end\\\\\\\
  7199.  drawMenu(arg[1],arg[2])\\\\\\\
  7200.  local event,side,xClick,yClick = os.pullEvent()\\\\\\\
  7201.  if event == \\\\\\\"monitor_touch\\\\\\\" then side = 1 end\\\\\\\
  7202.  if event == \\\\\\\"mouse_click\\\\\\\" or event == \\\\\\\"monitor_touch\\\\\\\" then\\\\\\\
  7203.    for key,val in pairs(Objects) do\\\\\\\
  7204.      if xClick >= Objects[key][\\\\\\\"xStart\\\\\\\"] and xClick <= Objects[key][\\\\\\\"xEnd\\\\\\\"] and yClick == Objects[key][\\\\\\\"y\\\\\\\"] and Objects[key][\\\\\\\"isHidden\\\\\\\"] == false or xClick >= Objects[key][\\\\\\\"xStart\\\\\\\"] and xClick <= Objects[key][\\\\\\\"xEnd\\\\\\\"] and yClick == Objects[key][\\\\\\\"y\\\\\\\"] and Objects[key][\\\\\\\"isHidden\\\\\\\"] == nil then\\\\\\\
  7205.        for i=Objects[key][\\\\\\\"xStart\\\\\\\"],Objects[key][\\\\\\\"xEnd\\\\\\\"] do\\\\\\\
  7206.          paintutils.drawPixel(i,Objects[key][\\\\\\\"y\\\\\\\"],colors.blue)\\\\\\\
  7207.        end\\\\\\\
  7208.        text(xStartToDisplay,Objects[key][\\\\\\\"y\\\\\\\"],key,colors.white)\\\\\\\
  7209.        sleep(0.3)\\\\\\\
  7210.        return key\\\\\\\
  7211.      end\\\\\\\
  7212.    end\\\\\\\
  7213.  end\\\\\\\
  7214. end\\\\\\\
  7215. ]]\\\\\\\
  7216. persist(\\\\\\\"UI\\\\\\\", libcode)\\\\\\\
  7217. \\\\\\\
  7218. return 1\\\"\",\
  7219. }",
  7220.   "D:lib",
  7221.   [ 13 ] = "F:startup",
  7222.   [ 14 ] = "\"if not term.isColor() then\\\
  7223. error(\\\"LEFI cannot run on non-advanced computers.\\\")\\\
  7224. end\\\
  7225. \\\
  7226. -- Declare extended Lua attributes\\\
  7227. \\\
  7228. rawset(_G, \\\"__declare\\\", function(g, v)\\\
  7229. return rawset(_G, g, v)\\\
  7230. end)\\\
  7231. \\\
  7232. __declare(\\\"__declare_api\\\", function(a, g, v)\\\
  7233. return rawset(_G[a], g, v)\\\
  7234. end)\\\
  7235. \\\
  7236. __declare(\\\"__try\\\", function(f, e)\\\
  7237. local r = {pcall(f)}\\\
  7238. if table.remove(r, 1) == true then\\\
  7239. return unpack(r)\\\
  7240. else\\\
  7241. if e ~= nil then\\\
  7242.  e(unpack(r))\\\
  7243. else\\\
  7244.  return __kstop(0x0000FFFF, unpack(r))\\\
  7245. end\\\
  7246. end\\\
  7247. end)\\\
  7248. \\\
  7249. __declare(\\\"__kstruct\\\", function(t)\\\
  7250. if t == _G then\\\
  7251.  return setmetatable({}, {\\\
  7252.   __index = t,\\\
  7253.   __newindex = function(table, key, value)\\\
  7254.    __kstop(0x00000004, table, key, value)\\\
  7255.   end,\\\
  7256.   __metatable = {}\\\
  7257.  })\\\
  7258. else\\\
  7259.  return setmetatable({}, {\\\
  7260.   __index = t,\\\
  7261.   __newindex = function(table, key, value)\\\
  7262.    __kstop(0x00000005, table, key, value)\\\
  7263.   end,\\\
  7264.   __metatable = {}\\\
  7265.  })\\\
  7266. end\\\
  7267. end)\\\
  7268. \\\
  7269. -- declare library persistence loader\\\
  7270. __declare(\\\"persist\\\", function(n, c)\\\
  7271. local h = fs.open(\\\"/tmp/\\\"..n, \\\"w\\\")\\\
  7272. h.writeLine(c)\\\
  7273. h.close()\\\
  7274. os.loadAPI(\\\"/tmp/\\\"..n)\\\
  7275. fs.delete(\\\"/tmp/\\\"..n)\\\
  7276. end)\\\
  7277. \\\
  7278. __declare(\\\"drawBootManager\\\", function(opt)\\\
  7279.    term.setBackgroundColor(colors.black)\\\
  7280.    term.clear()\\\
  7281.    term.setCursorPos(1,1)\\\
  7282. \\009if not opt then\\\
  7283.        boot_printColoredTextLine(2, \\\"             Orbital Boot Manager v1.0             \\\", colors.lightGray, colors.black)\\\
  7284.        boot_printColoredTextLine(18, \\\" F2=ESI Setup                        F10=Boot Menu \\\", colors.lightGray, colors.black)\\\
  7285. \\009else\\\
  7286.        boot_printColoredTextLine(2, \\\"             Orbital Boot Manager v2.1             \\\", colors.red, colors.black)\\\
  7287.        boot_printColoredTextLine(18, \\\" CTRL+R=Reboot                                     \\\", colors.red, colors.black)\\\
  7288. \\009end\\\
  7289. end)\\\
  7290. \\\
  7291. local sr = shell.run\\\
  7292. \\\
  7293. if not fs.isDir(\\\"/boot\\\") or not loadfile(\\\"/boot/esi/esiboot.b\\\") then\\\
  7294.    drawBootManager(true)\\\
  7295.    term.setBackgroundColor(colors.black)\\\
  7296.    term.setTextColor(colors.red)\\009\\\
  7297. \\009term.setCursorPos(2,4)\\\
  7298. \\009print(\\\"The Orbital Boot Manager was unable to boot the\\\")\\\
  7299. \\009term.setCursorPos(2,5)\\\
  7300. \\009print(\\\"operating system.\\\")\\\
  7301. \\009term.setCursorPos(2,7)\\\
  7302. \\009print(\\\"Status:\\\")\\\
  7303. \\009term.setCursorPos(2,8)\\\
  7304. \\009print(\\\"ESI_BINARIES_INVALID (0x00000002)\\\")\\\
  7305. \\009term.setCursorPos(2,10)\\\
  7306. \\009print(\\\"Information:\\\")\\\
  7307. \\009term.setCursorPos(2,11)\\\
  7308. \\009print(\\\"One or more ESI files are missing.\\\")\\\
  7309. \\009term.setCursorPos(2,12)\\\
  7310. \\009print(\\\"Please re-install the operating system.\\\")\\\
  7311.    while true do\\\
  7312. \\009    sleep(1)\\\
  7313. \\009end\\\
  7314. end\\\
  7315. \\\
  7316. sr(\\\"/boot/esi/esiboot.b\\\")\"",
  7317.   [ 15 ] = "F:startup",
  7318. }
Add Comment
Please, Sign In to add comment