awsumben13

NightFall

Jan 17th, 2015
1,041
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --PACKAGE_MODE=EXTRACTING
  2. local path=...or".nightfall"
  3. local files={["bundles"]={["Process.lua"]="local e={}local t={}local a={}local o local i local n=\"process\"\
  4. e[1]={name=\"main\",mode='api',content=\"local e={}local t={}local a={}\\\
  5. function a.create(o)local i={}i.name=tostring(o)\\\
  6. i.environment=setmetatable({},{__index=getfenv(2)})i.threads={}\\\
  7. function i:newThread(n)\\\
  8. local s=a.newThread(n,setmetatable({},{__index=function(h,r)return self.environment[r]end,__newindex=function(h,r,d)\\\
  9. self.environment[r]=d end}))table.insert(self.threads,s)return s end function i:stop()\\\
  10. for i=1,#self.threads do self.threads[i]:stop()end\\\
  11. for i=1,#e do if e[i]==self then table.remove(e,i)break end end end\\\
  12. table.insert(e,i)return i end\\\
  13. function a.newThread(o,i)i=i or getfenv(2)local n={}setfenv(o,i)\\\
  14. n.co=coroutine.create(o)\\\
  15. function n:resume(...)local s,h=coroutine.resume(self.co,...)\\\
  16. if not s then\\\
  17. if\\\
  18. type(self.onException)==\\\"function\\\"then self:onException(h)end self:stop()elseif coroutine.status(self.co)==\\\"dead\\\"then if\\\
  19. type(self.onFinish)==\\\"function\\\"then self:onFinish(h)end\\\
  20. self:stop()end end function n:stop()\\\
  21. for i=#t,1,-1 do if t[i]==self then table.remove(t,i)break end end end table.insert(t,n)return n end function a.resume(...)local o={}for i=1,#t do o[i]=t[i]end\\\
  22. for i=1,#o do if not o[i]then print(\\\"oh noes\\\")end o[i]:resume(...)\\\
  23. end end function a.list()local o={}for i=1,#e do\\\
  24. o[#o+1]=e[i]end return o end\\\
  25. setmetatable(a,{__call=function(o,i)\\\
  26. if\\\
  27. type(i)==\\\"function\\\"then return o.newThread(i)else return o.create(i)end end})return a\"}i=1 local s=setmetatable({},{__index=getfenv()})\
  28. s.global=s s.args={...}local h={}local r=_G[\"_bundleLoaded\"]if type(r)~=\"table\"then r={}\
  29. _G[\"_bundleLoaded\"]=r end if r[n]and not o then return r[n]end\
  30. for i=1,#t do\
  31. if r and\
  32. r[t[i]:gsub(\"%.lua$\",\"\",1)]then\
  33. s[t[i]:gsub(\"%.lua$\",\"\",1)]=r[t[i]:gsub(\"%.lua$\",\"\",1)]else\
  34. local d=(_G[\"_bundleDependencyPath\"]or\"\")..\"/\"..t[i]local l,u=loadfile(d)if l then setfenv(l,getfenv())\
  35. s[t[i]:gsub(\"%.lua$\",\"\",1)]=l()else\
  36. error(n..\" requires bundle '\"..t[i]..\"'\",0)end end end\
  37. for i=1,#a do\
  38. if r and r[a[i]:gsub(\"%.lua$\",\"\",1)]then\
  39. s[a[i]:gsub(\"%.lua$\",\"\",1)]=r[a[i]:gsub(\"%.lua$\",\"\",1)]else\
  40. local d=(_G[\"_bundleDependencyPath\"]or\"\")..\"/\"..a[i]local l,u=loadfile(d)if l then setfenv(l,getfenv())\
  41. s[a[i]:gsub(\"%.lua$\",\"\",1)]=l()end end end\
  42. for i=1,#e do\
  43. local d,l=loadstring(e[i].content,\"[\"..n..\"] \"..e[i].name)\
  44. if d then local u=setmetatable({},{__index=s})setfenv(d,u)\
  45. local c,m=pcall(d,...)if not c then printError(m)break end if m==nil then m={}\
  46. for f,w in pairs(u)do m[f]=w end end\
  47. if e[i].mode==\"api\"then if i==1 then h=m else h[e[i].name]=m\
  48. s[e[i].name]=m end else s[e[i].name]=m end else printError(l)break end end\
  49. if o then local d,l=loadstring(o,\"[\"..n..\"] main\")if d then\
  50. setfenv(d,s)local u,c=pcall(d,...)if not u then printError(c)end else\
  51. printError(l)end end r[n]=h return h";["SUtils.lua"]="local e={}local t={}local a={}local o local i local n=\"SUtils\"\
  52. e[1]={name=\"main\",mode='api',content=\"\\\
  53. function gfind(t,a,o)local n={}local s={t:find(a,o)}while s[1]do table.insert(n,s)\\\
  54. s={t:find(a,s[2]+1)}end local h=0 return function()h=h+1\\\
  55. if n[h]then return unpack(n[h])end end end function split(t,a,o)local i=1 local n={}for h,r in gfind(t,a,o)do table.insert(n,t:sub(i,h-1))\\\
  56. i=r+1 end table.insert(n,t:sub(i))\\\
  57. return n end\\\
  58. local function e(t,a)\\\
  59. local o=0 for i=1,a+1 do\\\
  60. o=o+ (t:sub(i,i)==\\\"\\\\t\\\"and 4 or 1)if o>a+1 then break end\\\
  61. if t:sub(i,i)==\\\"\\\\n\\\"then return t:sub(1,i),t:sub(i+1)end end if#\\\
  62. t:gsub(\\\"\\\\t\\\",\\\"    \\\")<=a then return t,false end local i\\\
  63. for n,s in gfind(t,\\\"%s+\\\")do if#\\\
  64. t:sub(1,n):gsub(\\\"\\\\t\\\",\\\"    \\\")>a+1 then break end i=s end if i then return t:sub(1,i),t:sub(i+1)end local o=0\\\
  65. for i=1,#t do o=o+ (\\\
  66. t:sub(i,i)==\\\"\\\\t\\\"and 4 or 1)if\\\
  67. o>a then\\\
  68. return t:sub(1,math.max(i-1,1)),t:sub(math.max(i-1,1)+1)end end end\\\
  69. function wordwrap(t,a,o,i,n,s)local h={}\\\
  70. if a then local r while t do r,t=e(t,a)table.insert(h,r)end else\\\
  71. h=split(t,\\\"\\\\n\\\")for i=1,#h-1 do h[i]=h[i]..\\\"\\\\n\\\"end end if o then while#h>o do table.remove(h,#h)end end\\\
  72. h.padding={}\\\
  73. if i then local r,o=i:match\\\"(%w+), ?(%w+)\\\"\\\
  74. if r then\\\
  75. if s and\\\
  76. (r==\\\"middle\\\"or r==\\\"centre\\\"or r==\\\"center\\\")then\\\
  77. h.padding.vertical=math.floor(s/2-#h/2)elseif s and r==\\\"bottom\\\"then h.padding.vertical=s-#h end\\\
  78. if n and\\\
  79. (o==\\\"middle\\\"or o==\\\"centre\\\"or o==\\\"center\\\")then for i=1,#h do\\\
  80. h.padding[i]=math.floor(n/2-#h[i]/2)end elseif n and o==\\\"right\\\"then for i=1,#h do\\\
  81. h.padding[i]=n-#h[i]end else for i=1,#h do h.padding[i]=0 end end end end return h end\"}i=1 local s=setmetatable({},{__index=getfenv()})\
  82. s.global=s s.args={...}local h={}local r=_G[\"_bundleLoaded\"]if type(r)~=\"table\"then r={}\
  83. _G[\"_bundleLoaded\"]=r end if r[n]and not o then return r[n]end\
  84. for i=1,#t do\
  85. if r and\
  86. r[t[i]:gsub(\"%.lua$\",\"\",1)]then\
  87. s[t[i]:gsub(\"%.lua$\",\"\",1)]=r[t[i]:gsub(\"%.lua$\",\"\",1)]else\
  88. local d=(_G[\"_bundleDependencyPath\"]or\"\")..\"/\"..t[i]local l,u=loadfile(d)if l then setfenv(l,getfenv())\
  89. s[t[i]:gsub(\"%.lua$\",\"\",1)]=l()else\
  90. error(n..\" requires bundle '\"..t[i]..\"'\",0)end end end\
  91. for i=1,#a do\
  92. if r and r[a[i]:gsub(\"%.lua$\",\"\",1)]then\
  93. s[a[i]:gsub(\"%.lua$\",\"\",1)]=r[a[i]:gsub(\"%.lua$\",\"\",1)]else\
  94. local d=(_G[\"_bundleDependencyPath\"]or\"\")..\"/\"..a[i]local l,u=loadfile(d)if l then setfenv(l,getfenv())\
  95. s[a[i]:gsub(\"%.lua$\",\"\",1)]=l()end end end\
  96. for i=1,#e do\
  97. local d,l=loadstring(e[i].content,\"[\"..n..\"] \"..e[i].name)\
  98. if d then local u=setmetatable({},{__index=s})setfenv(d,u)\
  99. local c,m=pcall(d,...)if not c then printError(m)break end if m==nil then m={}\
  100. for f,w in pairs(u)do m[f]=w end end\
  101. if e[i].mode==\"api\"then if i==1 then h=m else h[e[i].name]=m\
  102. s[e[i].name]=m end else s[e[i].name]=m end else printError(l)break end end\
  103. if o then local d,l=loadstring(o,\"[\"..n..\"] main\")if d then\
  104. setfenv(d,s)local u,c=pcall(d,...)if not u then printError(c)end else\
  105. printError(l)end end r[n]=h return h";["Math2D.lua"]="local files={}\
  106. local dependencies={}\
  107. local requires={}\
  108. local mainContent\
  109. local apiCount\
  110. local name=\"Math2D\"\
  111. files[1]={name=\"collision\";mode='api';content=\"\\\
  112. local function numeq( a, b )\\\
  113.     return math.abs( a - b ) < 0.0000001\\\
  114. end\\\
  115. \\\
  116. function pointInLine( lp1, lp2, point )\\\
  117.     if point.x < math.min( lp1.x, lp2.x ) or point.x > math.max( lp1.x, lp2.x ) then\\\
  118.         return false\\\
  119.     end\\\
  120.     if point.y < math.min( lp1.y, lp2.y ) or point.y > math.max( lp1.y, lp2.y ) then\\\
  121.         return false\\\
  122.     end\\\
  123. \\\
  124.     local delta = lp2 - lp1\\\
  125.     local m = delta.y / delta.x\\\
  126.     local c = lp1.y - m * lp1.x\\\
  127. \\\
  128.     if delta.y == 0 or delta.x == 0 then\\\
  129.         return true\\\
  130.     end\\\
  131. \\\
  132.     if numeq( m * point.x + c, point.y ) then\\\
  133.         return true\\\
  134.     end\\\
  135.     return false\\\
  136. end\\\
  137. \\\
  138. function pointInBox( point, position, size ) -- Vec2 point, Vec2 position, Vec2 size\\\
  139.     if point.x >= position.x\\\
  140.     and point.y >= position.y\\\
  141.     and point.x <= position.x + size.x - 1\\\
  142.     and point.y <= position.y + size.y - 1 then\\\
  143.         return Vec2( point.x - position.x + 1, point.y - position.y + 1 )\\\
  144.     end\\\
  145.     return false\\\
  146. end\\\
  147. -- Vec2 relative_coords\\\
  148. \\\
  149. function boxInBox( p1, s1, p2, s2 ) -- Vec2 position1, Vec2 size1, Vec2 position2, Vec2 size2\\\
  150.     if p1.x > p2.x + s2.x - 1 or p1.y > p2.y + s2.y - 1 then\\\
  151.         return false\\\
  152.     end\\\
  153.     if p2.x > p1.x + s1.x - 1 or p2.y > p1.y + s1.y - 1 then\\\
  154.         return false\\\
  155.     end\\\
  156.     local x, y = math.max( p1.x, p2.x ), math.max( p1.y, p2.y )\\\
  157.     local x2, y2 = math.min( p1.x + s1.x, p2.x + s2.x ) - 1, math.min( p1.y + s1.y, p2.y + s2.y ) - 1\\\
  158. \\\
  159.     return Vec2( x, y ), Vec2( x2 - x, y2 - y )\\\
  160. end\\\
  161. -- false if no collision\\\
  162. -- Vec2 position, Vec2 size if collision\\\
  163. \\\
  164. function lineIntersect( l1p1, l1p2, l2p1, l2p2 ) -- Vec2 line_1_point_1, Vec2 line_1_point_2, Vec2 line_2_point_1, Vec2 line_2_point_2\\\
  165.     local l1d = l1p1 - l1p2\\\
  166.     local l2d = l2p1 - l2p2\\\
  167. \\\
  168.     local l1m = l1d.y / l1d.x\\\
  169.     local l2m = l2d.y / l2d.x\\\
  170. \\\
  171.     local l1c = l1p1.y - l1m * l1p1.x\\\
  172.     local l2c = l2p1.y - l2m * l2p1.x\\\
  173. \\\
  174.     if l1m == l2m then\\\
  175.         return l1c == l2c\\\
  176.     end\\\
  177. \\\
  178.     local ix = ( l1c - l2c ) / ( l2m - l1m )\\\
  179. \\\
  180.     if ix < math.min( l1p1.x, l1p2.x ) or ix > math.max( l1p1.x, l1p2.x ) then\\\
  181.         return false\\\
  182.     end \\\
  183.     if ix < math.min( l2p1.x, l2p2.x ) or ix > math.max( l2p1.x, l2p2.x ) then\\\
  184.         return false\\\
  185.     end\\\
  186. \\\
  187.     local iy = l1m * l1p1.x + l1c\\\
  188. \\\
  189.     return Vec2( ix, iy )\\\
  190. end\\\
  191. -- false if no intersection\\\
  192. -- true if equal lines\\\
  193. -- Vec2 point if single intersection\\\
  194. \\\
  195. function circleInCircle( p1, r1, p2, r2 ) -- Vec2 position1, number radius1, Vec2 position2, number radius2\\\
  196.     local delta = p2 - p1\\\
  197.     return delta.x ^ 2 + delta.y ^ 2 <= ( r1 + r2 ) ^ 2\\\
  198. end\\\
  199. -- bool collision\\\
  200. \\\
  201. function pointInCircle( c, r, p ) -- Vec2 circlePosition, number radius, Vec2 point\\\
  202.     local delta = p - c\\\
  203.     return delta.x ^ 2 + delta.y ^ 2 <= r ^ 2\\\
  204. end\\\
  205. -- bool collision\"}\
  206. files[2]={name=\"normal\";mode='api';content=\"\\\
  207. return function( p1, p2, p3 ) -- line_point_1, line_point_2, normal_point\\\
  208.     local delta = p2 - p1\\\
  209.     local m = -1 / ( delta.y / delta.y )\\\
  210.     local c = p3.y - m * p3.x\\\
  211. \\\
  212.     return Vec2( 1, ( m * ( p3.x + 1 ) + c ) - p3.y )\\\
  213. end\\\
  214. -- Vec2 normal\"}\
  215. files[3]={name=\"pointOnLine\";mode='api';content=\"\\\
  216. return function( p1, p2, x, y )\\\
  217.     local delta = p2 - p1\\\
  218. \\\
  219.     if x then\\\
  220.         if delta.x == 0 then\\\
  221.             if x == p1.x then\\\
  222.                 return Vec2( x, p1.y )\\\
  223.             end\\\
  224.             return false\\\
  225.         elseif delta.y == 0 then\\\
  226.             return Vec2( x, p1.y )\\\
  227.         end\\\
  228.         local m = delta.y / delta.x\\\
  229.         local c = p1.y - m * p1.x\\\
  230.         return Vec2( x, m * x + c )\\\
  231.     elseif y then\\\
  232.         if delta.x == 0 then\\\
  233.             return Vec2( p1.x, y )\\\
  234.         elseif delta.y == 0 then\\\
  235.             if y == p1.y then\\\
  236.                 return Vec2( p1.x, y )\\\
  237.             end\\\
  238.             return false\\\
  239.         end\\\
  240.         local m = delta.y / delta.x\\\
  241.         local c = p1.y - m * p1.x\\\
  242.         return Vec2( ( y - c ) / m, y )\\\
  243.     end\\\
  244. end\"}\
  245. files[4]={name=\"Vec2\";mode='api';content=\"\\\
  246. local Vec2 = Class \\\"Vec2\\\"\\\
  247. \\\
  248. Vec2.public \\\"x\\\" \\\"number\\\"\\\
  249. Vec2.public \\\"y\\\" \\\"number\\\"\\\
  250. \\\
  251. function Vec2:Vec2( x, y )\\\
  252.     if type( x ) == \\\"number\\\" and type( y ) == \\\"number\\\" then\\\
  253.         self.x, self.y = x, y\\\
  254.     else\\\
  255.         self.x, self.y = 0, 0\\\
  256.     end\\\
  257.     return self.public\\\
  258. end\\\
  259. \\\
  260. function Vec2.public:add( other )\\\
  261.     return Vec2( self.x + other.x, self.y + other.y )\\\
  262. end\\\
  263. function Vec2.public:sub( other )\\\
  264.     return Vec2( self.x - other.x, self.y - other.y )\\\
  265. end\\\
  266. \\\
  267. function Vec2.public:mul( other )\\\
  268.     return Vec2( self.x * other, self.y * other )\\\
  269. end\\\
  270. function Vec2.public:div( other )\\\
  271.     return Vec2( self.x / other, self.y / other )\\\
  272. end\\\
  273. \\\
  274. function Vec2.public:dot( other )\\\
  275.     return self.x * other.x + self.y * other.y\\\
  276. end\\\
  277. \\\
  278. function Vec2.public:length()\\\
  279.     return math.sqrt( self.x ^ 2 + self.y ^ 2 )\\\
  280. end\\\
  281. \\\
  282. function Vec2.public:normalise()\\\
  283.     return self.public / self.public:length()\\\
  284. end\\\
  285. \\\
  286. function Vec2.meta:add( other )\\\
  287.     return self:add( other )\\\
  288. end\\\
  289. function Vec2.meta:sub( other )\\\
  290.     return self:sub( other )\\\
  291. end\\\
  292. function Vec2.meta:mul( other )\\\
  293.     return self:mul( other )\\\
  294. end\\\
  295. function Vec2.meta:div( other )\\\
  296.     return self:div( other )\\\
  297. end\\\
  298. \\\
  299. function Vec2.meta:tostring( )\\\
  300.     return \\\"Vec2(\\\" .. self.x .. \\\", \\\" .. self.y .. \\\")\\\"\\\
  301. end\\\
  302. \\\
  303. return Vec2\"}\
  304. apiCount=4\
  305. dependencies[1]=\"Class.lua\"\
  306. local env = setmetatable( {}, { __index = getfenv() } )\
  307. env.global = env\
  308. env.args = { ... }\
  309. local public = {}\
  310. local bloaded = _G[\"_bundleLoaded\"]\
  311. if type( bloaded ) ~= \"table\" then bloaded = {} _G[\"_bundleLoaded\"] = bloaded end\
  312. \
  313. if bloaded[name] and not mainContent then\
  314.     return bloaded[name]\
  315. end\
  316. \
  317. for i = 1, #dependencies do\
  318.     if bloaded and bloaded[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] then\
  319.         env[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] = bloaded[dependencies[i]:gsub(\"%.lua$\", \"\", 1)]\
  320.     else\
  321.         local path = ( _G[\"_bundleDependencyPath\"] or \"\" ) .. \"/\" .. dependencies[i]\
  322.         local f, err = loadfile( path )\
  323.         if f then\
  324.             setfenv( f, getfenv() )\
  325.             env[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] = f()\
  326.         else\
  327.             error( name .. \" requires bundle '\" .. dependencies[i] .. \"'\", 0 )\
  328.         end\
  329.     end\
  330. end\
  331. for i = 1, #requires do\
  332.     if bloaded and bloaded[requires[i]:gsub(\"%.lua$\", \"\", 1)] then\
  333.         env[requires[i]:gsub(\"%.lua$\", \"\", 1)] = bloaded[requires[i]:gsub(\"%.lua$\", \"\", 1)]\
  334.     else\
  335.         local path = ( _G[\"_bundleDependencyPath\"] or \"\" ) .. \"/\" .. requires[i]\
  336.         local f, err = loadfile( path )\
  337.         if f then\
  338.             setfenv( f, getfenv() )\
  339.             env[requires[i]:gsub(\"%.lua$\", \"\", 1)] = f()\
  340.         end\
  341.     end\
  342. end\
  343. \
  344. for i = 1, #files do\
  345.     local f, err = loadstring( files[i].content, \"[\" .. name .. \"] \" .. files[i].name )\
  346.     if f then\
  347.         local e = setmetatable( {}, { __index = env } )\
  348.         setfenv( f, e )\
  349.         local ok, data = pcall( f, ... )\
  350.         if not ok then\
  351.             printError( data )\
  352.             break\
  353.         end\
  354.         if data == nil then\
  355.             data = {}\
  356.             for k, v in pairs( e ) do\
  357.                 data[k] = v\
  358.             end\
  359.         end\
  360.         if files[i].mode == \"api\" then\
  361.             if apiCount == 1 then\
  362.                 public = data\
  363.             else\
  364.                 public[files[i].name] = data\
  365.                 env[files[i].name] = data\
  366.             end\
  367.         else\
  368.             env[files[i].name] = data\
  369.         end\
  370.     else\
  371.         printError( err )\
  372.         break\
  373.     end\
  374. end\
  375. \
  376. if mainContent then\
  377.     local f, err = loadstring( mainContent, \"[\" .. name .. \"] main\" )\
  378.     if f then\
  379.         setfenv( f, env )\
  380.         local ok, data = pcall( f, ... )\
  381.         if not ok then\
  382.             printError( data )\
  383.         end\
  384.     else\
  385.         printError( err )\
  386.     end\
  387. end\
  388. \
  389. bloaded[name] = public\
  390. return public";["Traceback.lua"]="local e={}local t={}local a={}local o local i local n=\"Traceback\"\
  391. e[1]={name=\"main\",mode='api',content=\"\\\
  392. return\\\
  393. function(e,t)t=type(t)==\\\"number\\\"and t local a=3+\\\
  394. (type(e)==\\\"number\\\"and e or 0)local o=a local i,n=nil,{}\\\
  395. repeat\\\
  396. i=select(2,pcall(error,\\\"@\\\",a)):match(\\\"^(.+): @$\\\")if i then n[#n+1]=i a=a+1 if a-o==t then return n end end until not i return n end\"}i=1 local s=setmetatable({},{__index=getfenv()})\
  397. s.global=s s.args={...}local h={}local r=_G[\"_bundleLoaded\"]if type(r)~=\"table\"then r={}\
  398. _G[\"_bundleLoaded\"]=r end if r[n]and not o then return r[n]end\
  399. for i=1,#t do\
  400. if r and\
  401. r[t[i]:gsub(\"%.lua$\",\"\",1)]then\
  402. s[t[i]:gsub(\"%.lua$\",\"\",1)]=r[t[i]:gsub(\"%.lua$\",\"\",1)]else\
  403. local d=(_G[\"_bundleDependencyPath\"]or\"\")..\"/\"..t[i]local l,u=loadfile(d)if l then setfenv(l,getfenv())\
  404. s[t[i]:gsub(\"%.lua$\",\"\",1)]=l()else\
  405. error(n..\" requires bundle '\"..t[i]..\"'\",0)end end end\
  406. for i=1,#a do\
  407. if r and r[a[i]:gsub(\"%.lua$\",\"\",1)]then\
  408. s[a[i]:gsub(\"%.lua$\",\"\",1)]=r[a[i]:gsub(\"%.lua$\",\"\",1)]else\
  409. local d=(_G[\"_bundleDependencyPath\"]or\"\")..\"/\"..a[i]local l,u=loadfile(d)if l then setfenv(l,getfenv())\
  410. s[a[i]:gsub(\"%.lua$\",\"\",1)]=l()end end end\
  411. for i=1,#e do\
  412. local d,l=loadstring(e[i].content,\"[\"..n..\"] \"..e[i].name)\
  413. if d then local u=setmetatable({},{__index=s})setfenv(d,u)\
  414. local c,m=pcall(d,...)if not c then printError(m)break end if m==nil then m={}\
  415. for f,w in pairs(u)do m[f]=w end end\
  416. if e[i].mode==\"api\"then if i==1 then h=m else h[e[i].name]=m\
  417. s[e[i].name]=m end else s[e[i].name]=m end else printError(l)break end end\
  418. if o then local d,l=loadstring(o,\"[\"..n..\"] main\")if d then\
  419. setfenv(d,s)local u,c=pcall(d,...)if not u then printError(c)end else\
  420. printError(l)end end r[n]=h return h";["Tween.lua"]="local e={}local t={}local a={}local o local i local n=\"Tween\"\
  421. e[1]={name=\"main\",mode='api',content=\"\\\
  422. local e={_VERSION='tween 2.0.0',_DESCRIPTION='tweening for lua',_URL='https://github.com/kikito/tween.lua',_LICENSE=[[\\\
  423.    MIT LICENSE\\\
  424.    Copyright (c) 2014 Enrique García Cota, Yuichi Tateno, Emmanuel Oga\\\
  425.    Permission is hereby granted, free of charge, to any person obtaining a\\\
  426.    copy of this software and associated documentation files (the\\\
  427.    \\\"Software\\\"), to deal in the Software without restriction, including\\\
  428.    without limitation the rights to use, copy, modify, merge, publish,\\\
  429.    distribute, sublicense, and/or sell copies of the Software, and to\\\
  430.    permit persons to whom the Software is furnished to do so, subject to\\\
  431.    the following conditions:\\\
  432.    The above copyright notice and this permission notice shall be included\\\
  433.    in all copies or substantial portions of the Software.\\\
  434.    THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\\\
  435.    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\\\
  436.    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\\\
  437.    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\\\
  438.    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\\\
  439.    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\\\
  440.    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\\\
  441.  ]]}\\\
  442. local t,a,o,i,n,s,h=math.pow,math.sin,math.cos,math.pi,math.sqrt,math.abs,math.asin local function r(ei,en,es,eh)return es*ei/eh+en end local function d(ei,en,es,eh)return\\\
  443. es*t(ei/eh,2)+en end local function l(ei,en,es,eh)ei=ei/eh return\\\
  444. -es*ei* (ei-2)+en end\\\
  445. local function u(ei,en,es,eh)ei=ei/eh*2 if ei<1 then return\\\
  446. es/2*t(ei,2)+en end return-es/2*\\\
  447. ((ei-1)* (ei-3)-1)+en end\\\
  448. local function c(ei,en,es,eh)if ei<eh/2 then return l(ei*2,en,es/2,eh)end return d((ei*2)-eh,en+\\\
  449. es/2,es/2,eh)end local function m(ei,en,es,eh)return es*t(ei/eh,3)+en end\\\
  450. local function f(ei,en,es,eh)return es* (\\\
  451. t(ei/eh-1,3)+1)+en end\\\
  452. local function w(ei,en,es,eh)ei=ei/eh*2\\\
  453. if ei<1 then return es/2*ei*ei*ei+en end ei=ei-2 return es/2* (ei*ei*ei+2)+en end\\\
  454. local function y(ei,en,es,eh)if ei<eh/2 then return f(ei*2,en,es/2,eh)end return m((ei*2)-eh,en+\\\
  455. es/2,es/2,eh)end local function p(ei,en,es,eh)return es*t(ei/eh,4)+en end\\\
  456. local function v(ei,en,es,eh)return-es* (\\\
  457. t(ei/eh-1,4)-1)+en end\\\
  458. local function b(ei,en,es,eh)ei=ei/eh*2 if ei<1 then return es/2*t(ei,4)+en end return\\\
  459. -es/2* (t(ei-2,4)-2)+en end\\\
  460. local function g(ei,en,es,eh)if ei<eh/2 then return v(ei*2,en,es/2,eh)end return p((ei*2)-eh,en+\\\
  461. es/2,es/2,eh)end local function k(ei,en,es,eh)return es*t(ei/eh,5)+en end\\\
  462. local function q(ei,en,es,eh)return es* (\\\
  463. t(ei/eh-1,5)+1)+en end\\\
  464. local function j(ei,en,es,eh)ei=ei/eh*2 if ei<1 then return es/2*t(ei,5)+en end return\\\
  465. es/2* (t(ei-2,5)+2)+en end\\\
  466. local function x(ei,en,es,eh)if ei<eh/2 then return q(ei*2,en,es/2,eh)end return k((ei*2)-eh,en+\\\
  467. es/2,es/2,eh)end local function z(ei,en,es,eh)\\\
  468. return-es*o(ei/eh* (i/2))+es+en end local function _(ei,en,es,eh)return\\\
  469. es*a(ei/eh* (i/2))+en end local function E(ei,en,es,eh)return-es/2*\\\
  470. (o(i*ei/eh)-1)+en end local function T(ei,en,es,eh)if\\\
  471. ei<eh/2 then return _(ei*2,en,es/2,eh)end return\\\
  472. z((ei*2)-eh,en+es/2,es/2,eh)end\\\
  473. local function A(ei,en,es,eh)if\\\
  474. ei==0 then return en end return es*t(2,10* (ei/eh-1))+en-es*\\\
  475. 0.001 end\\\
  476. local function O(ei,en,es,eh)if ei==eh then return en+es end return es*1.001*\\\
  477. (-t(2,-10*ei/eh)+1)+en end\\\
  478. local function I(ei,en,es,eh)if ei==0 then return en end if ei==eh then return en+es end ei=ei/eh*2 if ei<1 then\\\
  479. return\\\
  480. es/2*t(2,10* (ei-1))+en-es*0.0005 end return es/2*1.0005*\\\
  481. (-t(2,-10* (ei-1))+2)+en end\\\
  482. local function N(ei,en,es,eh)if ei<eh/2 then return O(ei*2,en,es/2,eh)end return A((ei*2)-eh,en+\\\
  483. es/2,es/2,eh)end local function S(ei,en,es,eh)return\\\
  484. (-es* (n(1-t(ei/eh,2))-1)+en)end\\\
  485. local function H(ei,en,es,eh)return(es*\\\
  486. n(1-t(ei/eh-1,2))+en)end\\\
  487. local function R(ei,en,es,eh)ei=ei/eh*2 if ei<1 then\\\
  488. return-es/2* (n(1-ei*ei)-1)+en end ei=ei-2 return\\\
  489. es/2* (n(1-ei*ei)+1)+en end\\\
  490. local function D(ei,en,es,eh)if ei<eh/2 then return H(ei*2,en,es/2,eh)end return S((ei*2)-eh,en+\\\
  491. es/2,es/2,eh)end\\\
  492. local function L(ei,en,es,eh)ei,en=ei or eh*0.3,en or 0 if en<s(es)then return ei,es,ei/4 end return ei,\\\
  493. en,ei/ (2*i)*h(es/en)end\\\
  494. local function U(ei,en,es,eh,er,ed)local el if ei==0 then return en end ei=ei/eh if ei==1 then return en+es end\\\
  495. ed,er,el=L(ed,er,es,eh)ei=ei-1 return\\\
  496. - (er*t(2,10*ei)*\\\
  497. a((ei*eh-el)* (2*i)/ed))+en end\\\
  498. local function C(ei,en,es,eh,er,ed)local el if ei==0 then return en end ei=ei/eh if ei==1 then return en+es end\\\
  499. ed,er,el=L(ed,er,es,eh)return\\\
  500. er*t(2,-10*ei)*a((ei*eh-el)* (2*i)/ed)+es+en end\\\
  501. local function M(ei,en,es,eh,er,ed)local el if ei==0 then return en end ei=ei/eh*2 if ei==2 then return en+es end\\\
  502. ed,er,el=L(ed,er,es,eh)ei=ei-1 if ei<0 then return\\\
  503. -0.5* (er*t(2,10*ei)*\\\
  504. a((ei*eh-el)* (2*i)/ed))+en end\\\
  505. return\\\
  506. er*\\\
  507. t(2,-10*ei)*a((ei*eh-el)* (2*i)/ed)*0.5+es+en end\\\
  508. local function F(ei,en,es,eh,er,ed)if ei<eh/2 then return C(ei*2,en,es/2,eh,er,ed)end return U(\\\
  509. (ei*2)-eh,en+es/2,es/2,eh,er,ed)end\\\
  510. local function W(ei,en,es,eh,er)er=er or 1.70158 ei=ei/eh return\\\
  511. es*ei*ei* ((er+1)*ei-er)+en end local function Y(ei,en,es,eh,er)er=er or 1.70158 ei=ei/eh-1\\\
  512. return es* (\\\
  513. ei*ei* ((er+1)*ei+er)+1)+en end\\\
  514. local function P(ei,en,es,eh,er)\\\
  515. er=(er or 1.70158)*1.525 ei=ei/eh*2 if ei<1 then return\\\
  516. es/2* (ei*ei* ((er+1)*ei-er))+en end ei=ei-2 return\\\
  517. \\\
  518. es/2* (ei*ei* ((er+1)*ei+er)+2)+en end\\\
  519. local function V(ei,en,es,eh,er)if ei<eh/2 then return Y(ei*2,en,es/2,eh,er)end return W((ei*2)-eh,\\\
  520. en+es/2,es/2,eh,er)end\\\
  521. local function B(ei,en,es,eh)ei=ei/eh if ei<1/2.75 then\\\
  522. return es* (7.5625*ei*ei)+en end\\\
  523. if ei<2/2.75 then ei=ei- (1.5/2.75)return es* (\\\
  524. 7.5625*ei*ei+0.75)+en elseif ei<2.5/\\\
  525. 2.75 then ei=ei- (2.25/2.75)return es*\\\
  526. (7.5625*ei*ei+0.9375)+en end ei=ei- (2.625/2.75)return es*\\\
  527. (7.5625*ei*ei+0.984375)+en end\\\
  528. local function G(ei,en,es,eh)return es-B(eh-ei,0,es,eh)+en end local function K(ei,en,es,eh)\\\
  529. if ei<eh/2 then return G(ei*2,0,es,eh)*0.5+en end\\\
  530. return B(ei*2-eh,0,es,eh)*0.5+es*.5+en end local function Q(ei,en,es,eh)if ei<eh/2 then return B(ei*2,en,es/\\\
  531. 2,eh)end return\\\
  532. G((ei*2)-eh,en+es/2,es/2,eh)end\\\
  533. e.easing={linear=r,inQuad=d,outQuad=l,inOutQuad=u,outInQuad=c,inCubic=m,outCubic=f,inOutCubic=w,outInCubic=y,inQuart=p,outQuart=v,inOutQuart=b,outInQuart=g,inQuint=k,outQuint=q,inOutQuint=j,outInQuint=x,inSine=z,outSine=_,inOutSine=E,outInSine=T,inExpo=A,outExpo=O,inOutExpo=I,outInExpo=N,inCirc=S,outCirc=H,inOutCirc=R,outInCirc=D,inElastic=U,outElastic=C,inOutElastic=M,outInElastic=F,inBack=W,outBack=Y,inOutBack=P,outInBack=V,inBounce=G,outBounce=B,inOutBounce=K,outInBounce=Q}\\\
  534. local function J(ei,en,es)es=es or en local eh=getmetatable(en)if\\\
  535. eh and getmetatable(ei)==nil then setmetatable(ei,eh)end for er,ed in pairs(en)do\\\
  536. if\\\
  537. type(ed)=='table'then ei[er]=J({},ed,es[er])else ei[er]=es[er]end end return ei end\\\
  538. local function X(ei,en,es)es=es or{}local eh,er\\\
  539. for ed,el in pairs(en)do eh,er=type(el),J({},es)\\\
  540. table.insert(er,tostring(ed))\\\
  541. if eh=='number'then\\\
  542. assert(type(ei[ed])=='number',\\\"Parameter '\\\"..table.concat(er,'/')..\\\
  543. \\\"' is missing from subject or isn't a number\\\")elseif eh=='table'then X(ei[ed],el,er)else\\\
  544. assert(eh=='number',\\\"Parameter '\\\"..table.concat(er,'/')..\\\
  545. \\\"' must be a number or table of numbers\\\")end end end\\\
  546. local function Z(ei,en,es,eh)\\\
  547. assert(type(ei)=='number'and ei>0,\\\"duration must be a positive number. Was \\\"..tostring(ei))local er=type(en)\\\
  548. assert(er=='table'or er=='userdata',\\\
  549. \\\"subject must be a table or userdata. Was \\\"..tostring(en))\\\
  550. assert(type(es)=='table',\\\"target must be a table. Was \\\"..tostring(es))\\\
  551. assert(type(eh)=='function',\\\"easing must be a function. Was \\\"..tostring(eh))X(en,es)end\\\
  552. local function ee(ei)ei=ei or\\\"linear\\\"\\\
  553. if type(ei)=='string'then local en=ei ei=e.easing[en]if type(ei)~=\\\
  554. 'function'then\\\
  555. error(\\\"The easing function name '\\\"..en..\\\"' is invalid\\\")end end return ei end\\\
  556. local function et(ei,en,es,eh,er,ed,el)local eu,ec,em,ef\\\
  557. for ew,ey in pairs(en)do\\\
  558. if type(ey)=='table'then\\\
  559. et(ei[ew],ey,es[ew],eh,er,ed)else eu,ec,em,ef=eh,es[ew],ey-es[ew],er if el then\\\
  560. ei[ew]=math.floor(ed(eu,ec,em,ef)+0.5)else ei[ew]=ed(eu,ec,em,ef)end end end end local ea={}local eo={__index=ea}\\\
  561. function ea:set(ei)\\\
  562. assert(type(ei)=='number',\\\"clock must be a positive number or 0\\\")self.clock=ei\\\
  563. if self.clock<=0 then self.clock=0\\\
  564. J(self.subject,self.initial)elseif self.clock>=self.duration then self.clock=self.duration\\\
  565. J(self.subject,self.target)else\\\
  566. et(self.subject,self.target,self.initial,self.clock,self.duration,self.easing,self.round)end return self.clock>=self.duration end function ea:reset()return self:set(0)end\\\
  567. function ea:update(ei)\\\
  568. assert(type(ei)=='number',\\\"dt must be a number\\\")return self:set(self.clock+ei)end\\\
  569. function e.new(ei,en,es,eh)eh=ee(eh)Z(ei,en,es,eh)return\\\
  570. setmetatable({duration=ei,subject=en,target=es,easing=eh,initial=J({},es,en),clock=0},eo)end return e\"}i=1 local s=setmetatable({},{__index=getfenv()})\
  571. s.global=s s.args={...}local h={}local r=_G[\"_bundleLoaded\"]if type(r)~=\"table\"then r={}\
  572. _G[\"_bundleLoaded\"]=r end if r[n]and not o then return r[n]end\
  573. for i=1,#t do\
  574. if r and\
  575. r[t[i]:gsub(\"%.lua$\",\"\",1)]then\
  576. s[t[i]:gsub(\"%.lua$\",\"\",1)]=r[t[i]:gsub(\"%.lua$\",\"\",1)]else\
  577. local d=(_G[\"_bundleDependencyPath\"]or\"\")..\"/\"..t[i]local l,u=loadfile(d)if l then setfenv(l,getfenv())\
  578. s[t[i]:gsub(\"%.lua$\",\"\",1)]=l()else\
  579. error(n..\" requires bundle '\"..t[i]..\"'\",0)end end end\
  580. for i=1,#a do\
  581. if r and r[a[i]:gsub(\"%.lua$\",\"\",1)]then\
  582. s[a[i]:gsub(\"%.lua$\",\"\",1)]=r[a[i]:gsub(\"%.lua$\",\"\",1)]else\
  583. local d=(_G[\"_bundleDependencyPath\"]or\"\")..\"/\"..a[i]local l,u=loadfile(d)if l then setfenv(l,getfenv())\
  584. s[a[i]:gsub(\"%.lua$\",\"\",1)]=l()end end end\
  585. for i=1,#e do\
  586. local d,l=loadstring(e[i].content,\"[\"..n..\"] \"..e[i].name)\
  587. if d then local u=setmetatable({},{__index=s})setfenv(d,u)\
  588. local c,m=pcall(d,...)if not c then printError(m)break end if m==nil then m={}\
  589. for f,w in pairs(u)do m[f]=w end end\
  590. if e[i].mode==\"api\"then if i==1 then h=m else h[e[i].name]=m\
  591. s[e[i].name]=m end else s[e[i].name]=m end else printError(l)break end end\
  592. if o then local d,l=loadstring(o,\"[\"..n..\"] main\")if d then\
  593. setfenv(d,s)local u,c=pcall(d,...)if not u then printError(c)end else\
  594. printError(l)end end r[n]=h return h";["Peripheral.lua"]="local e={}local t={}local a={}local o local i local n=\"Peripheral\"\
  595. e[1]={name=\"main\",mode='api',content=\"local e={}\\\
  596. function connect(t)if e[t]then return e[t].driver end\\\
  597. local a=peripheral.wrap(t)e[t]={driver=a,type=peripheral.getType(t)}return a end function getType(t)if e[t]then return e[t].type end local a=peripheral.wrap(t)\\\
  598. e[t]={driver=a,type=peripheral.getType(t)}return a end function disconnect(t)e[t]=\\\
  599. nil end\\\
  600. function connectVirtual(t,a,o)e[t]={driver=o,type=a}end\"}i=1 local s=setmetatable({},{__index=getfenv()})\
  601. s.global=s s.args={...}local h={}local r=_G[\"_bundleLoaded\"]if type(r)~=\"table\"then r={}\
  602. _G[\"_bundleLoaded\"]=r end if r[n]and not o then return r[n]end\
  603. for i=1,#t do\
  604. if r and\
  605. r[t[i]:gsub(\"%.lua$\",\"\",1)]then\
  606. s[t[i]:gsub(\"%.lua$\",\"\",1)]=r[t[i]:gsub(\"%.lua$\",\"\",1)]else\
  607. local d=(_G[\"_bundleDependencyPath\"]or\"\")..\"/\"..t[i]local l,u=loadfile(d)if l then setfenv(l,getfenv())\
  608. s[t[i]:gsub(\"%.lua$\",\"\",1)]=l()else\
  609. error(n..\" requires bundle '\"..t[i]..\"'\",0)end end end\
  610. for i=1,#a do\
  611. if r and r[a[i]:gsub(\"%.lua$\",\"\",1)]then\
  612. s[a[i]:gsub(\"%.lua$\",\"\",1)]=r[a[i]:gsub(\"%.lua$\",\"\",1)]else\
  613. local d=(_G[\"_bundleDependencyPath\"]or\"\")..\"/\"..a[i]local l,u=loadfile(d)if l then setfenv(l,getfenv())\
  614. s[a[i]:gsub(\"%.lua$\",\"\",1)]=l()end end end\
  615. for i=1,#e do\
  616. local d,l=loadstring(e[i].content,\"[\"..n..\"] \"..e[i].name)\
  617. if d then local u=setmetatable({},{__index=s})setfenv(d,u)\
  618. local c,m=pcall(d,...)if not c then printError(m)break end if m==nil then m={}\
  619. for f,w in pairs(u)do m[f]=w end end\
  620. if e[i].mode==\"api\"then if i==1 then h=m else h[e[i].name]=m\
  621. s[e[i].name]=m end else s[e[i].name]=m end else printError(l)break end end\
  622. if o then local d,l=loadstring(o,\"[\"..n..\"] main\")if d then\
  623. setfenv(d,s)local u,c=pcall(d,...)if not u then printError(c)end else\
  624. printError(l)end end r[n]=h return h";["SFormat.lua"]="local files={}\
  625. local dependencies={}\
  626. local requires={}\
  627. local mainContent\
  628. local apiCount\
  629. local name=\"SFormat\"\
  630. files[1]={name=\"main\";mode='api';content=\"\\\
  631. local c = {\\\
  632.     [\\\"0\\\"] = colours.white;\\\
  633.     [\\\"1\\\"] = colours.orange;\\\
  634.     [\\\"2\\\"] = colours.magenta;\\\
  635.     [\\\"3\\\"] = colours.lightBlue;\\\
  636.     [\\\"4\\\"] = colours.yellow;\\\
  637.     [\\\"5\\\"] = colours.lime;\\\
  638.     [\\\"6\\\"] = colours.pink;\\\
  639.     [\\\"7\\\"] = colours.grey;\\\
  640.     [\\\"8\\\"] = colours.lightGrey;\\\
  641.     [\\\"9\\\"] = colours.cyan;\\\
  642.     [\\\"A\\\"] = colours.purple;\\\
  643.     [\\\"B\\\"] = colours.blue;\\\
  644.     [\\\"C\\\"] = colours.brown;\\\
  645.     [\\\"D\\\"] = colours.green;\\\
  646.     [\\\"E\\\"] = colours.red;\\\
  647.     [\\\"F\\\"] = colours.black;\\\
  648.     [\\\" \\\"] = 0;\\\
  649. }\\\
  650. \\\
  651. function format( str, syntax, bc, tc, noformat )\\\
  652.     local colours = {}\\\
  653.     for i = 1, #syntax do\\\
  654.         for s, f in SUtils.gfind( str, syntax[i].pattern ) do\\\
  655.             for p = s, f do\\\
  656.                 colours[p] = colours[p] or {}\\\
  657.                 colours[p].bc = syntax[i].bc or colours[p].bc\\\
  658.                 colours[p].tc = syntax[i].tc or colours[p].tc\\\
  659.             end\\\
  660.         end\\\
  661.     end\\\
  662.     local cstream = {}\\\
  663.     if noformat then\\\
  664.         for i = 1, #str do\\\
  665.             colours[i] = colours[i] or {}\\\
  666.             colours[i].bc = colours[i].bc or bc\\\
  667.             colours[i].tc = colours[i].tc or tc\\\
  668.             cstream[#cstream+1] = {\\\
  669.                 char = str:sub( i, i );\\\
  670.                 bc = colours[i].bc;\\\
  671.                 tc = colours[i].tc;\\\
  672.             }\\\
  673.         end\\\
  674.     else\\\
  675.         local escape, ignore = false, false\\\
  676.         for i = 1, #str do\\\
  677.             colours[i] = colours[i] or {}\\\
  678.             colours[i].bc = colours[i].bc or bc\\\
  679.             colours[i].tc = colours[i].tc or tc\\\
  680.             if ignore then\\\
  681.                 ignore = false\\\
  682.                 escape = false\\\
  683.             elseif not escape and str:sub( i, i ) == \\\"\\\\\\\\\\\" then\\\
  684.                 escape = true\\\
  685.             elseif not escape and str:sub( i, i ) == \\\"&\\\" then\\\
  686.                 tc = c[str:sub( i + 1, i + 1 ):upper()] or 0\\\
  687.                 ignore = true\\\
  688.             elseif not escape and str:sub( i, i ) == \\\"#\\\" then\\\
  689.                 bc = c[str:sub( i + 1, i + 1 ):upper()] or 0\\\
  690.                 ignore = true\\\
  691.             else\\\
  692.                 cstream[#cstream+1] = {\\\
  693.                     char = str:sub( i, i );\\\
  694.                     bc = colours[i].bc;\\\
  695.                     tc = colours[i].tc;\\\
  696.                 }\\\
  697.                 escape = false\\\
  698.             end\\\
  699.         end\\\
  700.     end\\\
  701.     return cstream\\\
  702. end\\\
  703. \\\
  704. function wrapstream( stream, width, height, align, rw, rh )\\\
  705.     local s = \\\"\\\"\\\
  706.     for i = 1, #stream do\\\
  707.         s = s .. stream[i].char\\\
  708.     end\\\
  709.     local t = {}\\\
  710.     t.lines = SUtils.wordwrap( s, width, height, align, rw, rh )\\\
  711.     local l, p = {}, 0\\\
  712.     for line = 1, #t.lines do\\\
  713.         l[line], p = p, p + #t.lines[line]\\\
  714.     end\\\
  715.     function t:getChar( line, char )\\\
  716.         if l[line] and char <= #t.lines[line] then\\\
  717.             return stream[char + l[line]]\\\
  718.         end\\\
  719.     end\\\
  720.     return t\\\
  721. end\"}\
  722. apiCount=1\
  723. dependencies[1]=\"SUtils.lua\"\
  724. local env = setmetatable( {}, { __index = getfenv() } )\
  725. env.global = env\
  726. env.args = { ... }\
  727. local public = {}\
  728. local bloaded = _G[\"_bundleLoaded\"]\
  729. if type( bloaded ) ~= \"table\" then bloaded = {} _G[\"_bundleLoaded\"] = bloaded end\
  730. \
  731. if bloaded[name] and not mainContent then\
  732.     return bloaded[name]\
  733. end\
  734. \
  735. for i = 1, #dependencies do\
  736.     if bloaded and bloaded[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] then\
  737.         env[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] = bloaded[dependencies[i]:gsub(\"%.lua$\", \"\", 1)]\
  738.     else\
  739.         local path = ( _G[\"_bundleDependencyPath\"] or \"\" ) .. \"/\" .. dependencies[i]\
  740.         local f, err = loadfile( path )\
  741.         if f then\
  742.             setfenv( f, getfenv() )\
  743.             env[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] = f()\
  744.         else\
  745.             error( name .. \" requires bundle '\" .. dependencies[i] .. \"'\", 0 )\
  746.         end\
  747.     end\
  748. end\
  749. for i = 1, #requires do\
  750.     if bloaded and bloaded[requires[i]:gsub(\"%.lua$\", \"\", 1)] then\
  751.         env[requires[i]:gsub(\"%.lua$\", \"\", 1)] = bloaded[requires[i]:gsub(\"%.lua$\", \"\", 1)]\
  752.     else\
  753.         local path = ( _G[\"_bundleDependencyPath\"] or \"\" ) .. \"/\" .. requires[i]\
  754.         local f, err = loadfile( path )\
  755.         if f then\
  756.             setfenv( f, getfenv() )\
  757.             env[requires[i]:gsub(\"%.lua$\", \"\", 1)] = f()\
  758.         end\
  759.     end\
  760. end\
  761. \
  762. for i = 1, #files do\
  763.     local f, err = loadstring( files[i].content, \"[\" .. name .. \"] \" .. files[i].name )\
  764.     if f then\
  765.         local e = setmetatable( {}, { __index = env } )\
  766.         setfenv( f, e )\
  767.         local ok, data = pcall( f, ... )\
  768.         if not ok then\
  769.             printError( data )\
  770.             break\
  771.         end\
  772.         if data == nil then\
  773.             data = {}\
  774.             for k, v in pairs( e ) do\
  775.                 data[k] = v\
  776.             end\
  777.         end\
  778.         if files[i].mode == \"api\" then\
  779.             if apiCount == 1 then\
  780.                 public = data\
  781.             else\
  782.                 public[files[i].name] = data\
  783.                 env[files[i].name] = data\
  784.             end\
  785.         else\
  786.             env[files[i].name] = data\
  787.         end\
  788.     else\
  789.         printError( err )\
  790.         break\
  791.     end\
  792. end\
  793. \
  794. if mainContent then\
  795.     local f, err = loadstring( mainContent, \"[\" .. name .. \"] main\" )\
  796.     if f then\
  797.         setfenv( f, env )\
  798.         local ok, data = pcall( f, ... )\
  799.         if not ok then\
  800.             printError( data )\
  801.         end\
  802.     else\
  803.         printError( err )\
  804.     end\
  805. end\
  806. \
  807. bloaded[name] = public\
  808. return public";["UIKit.lua"]="local files={}\
  809. local dependencies={}\
  810. local requires={}\
  811. local mainContent\
  812. local apiCount\
  813. local name=\"UIKit\"\
  814. files[1]={name=\"Window\";mode='api';content=\"--@meta[type]:\\\"class\\\"\\\
  815. \\\
  816. local Window = Class \\\"Window\\\"\\\
  817. \\\
  818. Window.public \\\"x\\\" \\\"number\\\"\\\
  819. Window.public \\\"y\\\" \\\"number\\\"\\\
  820. Window.public \\\"width\\\"\\\
  821. Window.public \\\"height\\\"\\\
  822. \\\
  823. Window.public.width.write = false\\\
  824. Window.public.height.write = false\\\
  825. \\\
  826. Window.public \\\"onscreen_keyboard\\\" \\\"boolean\\\"\\\
  827. \\\
  828. Window.public \\\"displaymode\\\"\\\
  829. function Window.public.displaymode:write( value )\\\
  830.     if value == \\\"fullscreen\\\" or value == \\\"maximised\\\" then\\\
  831.         self.public:resize( value )\\\
  832.     elseif value == \\\"minimised\\\" then\\\
  833.         self.displaymode = \\\"maximised\\\"\\\
  834.     elseif value == \\\"normal\\\" then\\\
  835.         self.public:resize( self.width, self.height )\\\
  836.     else\\\
  837.         error( \\\"unknown displaymode (\\\" .. tostring( value ) .. \\\")\\\", 3 )\\\
  838.     end\\\
  839. end\\\
  840. \\\
  841. function Window:Window( width, height, maxw, maxh, wm )\\\
  842.     self.x = 1\\\
  843.     self.y = 1\\\
  844.     self.width = width\\\
  845.     self.height = height\\\
  846. \\\
  847.     self.wm = wm\\\
  848.     \\\
  849.     self.maxw = maxw\\\
  850.     self.maxh = maxh\\\
  851. \\\
  852.     self.lastx, self.lasty, self.lastt = 1, 1, nil\\\
  853. \\\
  854.     self.displaymode = \\\"normal\\\" -- /fullscreen, minimised, maximised\\\
  855.     self.onscreen_keyboard = false\\\
  856. \\\
  857.     self.callbacks = {}\\\
  858. \\\
  859.     self.elements = {}\\\
  860.     self.focus = false\\\
  861. \\\
  862.     return self.public\\\
  863. end\\\
  864. \\\
  865. function Window.public:newChild( element )\\\
  866.     if Class.typeOf( element, UIElement ) then\\\
  867.         table.insert( self.elements, element )\\\
  868.         element.parent = self.public\\\
  869.         return element\\\
  870.     else\\\
  871.         return error \\\"expected <UIElement> child\\\"\\\
  872.     end\\\
  873. end\\\
  874. \\\
  875. function Window.public:removeChild( element )\\\
  876.     if Class.typeOf( element, UIElement ) then\\\
  877.         for i = 1, #self.elements do\\\
  878.             if self.elements[i] == element then\\\
  879.                 element.parent = nil\\\
  880.                 table.remove( self.elements, i )\\\
  881.                 return\\\
  882.             end\\\
  883.         end\\\
  884.     else\\\
  885.         return error \\\"expected <UIElement> child\\\"\\\
  886.     end\\\
  887. end\\\
  888. \\\
  889. function Window.public:remove()\\\
  890.     self.wm:removeWindow( self.public )\\\
  891. end\\\
  892. \\\
  893. local function mt( t, x, y, scroll )\\\
  894.     for i = #t, 1, -1 do\\\
  895.         if x >= t[i].x and y >= t[i].y and x < t[i].x + t[i].width and y < t[i].y + t[i].height then\\\
  896.             if t[i]:type() == \\\"UIFrame\\\" then\\\
  897.                 local _t, rx, ry = mt( t[i]:getChildren(), x - t[i].x + 1 - t[i].ox, y - t[i].y + 1 - t[i].oy, scroll )\\\
  898.                 if _t then\\\
  899.                     return _t, rx, ry\\\
  900.                 end\\\
  901.                 if scroll and t[i]:getContentHeight() > t[i].height then\\\
  902.                     return t[i], x, y\\\
  903.                 end\\\
  904.             elseif scroll and t[i]:type() == \\\"UIText\\\" then\\\
  905.                 if t[i]:getContentHeight() > t[i].height then\\\
  906.                     return t[i], x - t[i].x + 1, y - t[i].y + 1\\\
  907.                 end\\\
  908.             elseif not scroll then\\\
  909.                 return t[i], x - t[i].x + 1, y - t[i].y + 1\\\
  910.             end\\\
  911.         end\\\
  912.     end\\\
  913. end\\\
  914. \\\
  915. function Window.public:click( x, y, button )\\\
  916.     local t, rx, ry = mt( self.elements, x, y )\\\
  917.     self.lastx, self.lasty = rx or x, ry or y\\\
  918.     if t then\\\
  919.         self.lastt = t\\\
  920.         if self.focus ~= t then\\\
  921.             if self.focus then\\\
  922.                 self.focus:onUnFocus()\\\
  923.             end\\\
  924.             if Class.typeOf( t, UIText ) or Class.typeOf( t, UIBuffer ) then\\\
  925.                 t:onFocus()\\\
  926.             end\\\
  927.         end\\\
  928.         if Class.typeOf( t, UIText ) or Class.typeOf( t, UIBuffer ) then\\\
  929.             self.focus = t\\\
  930.         else\\\
  931.             self.focus = nil\\\
  932.         end\\\
  933.         t:onClick( rx, ry, button )\\\
  934.     else\\\
  935.         self.focus = nil\\\
  936.         self.lastt = nil\\\
  937.         self.public:callback( \\\"onClick\\\", x, y, button )\\\
  938.     end\\\
  939. end\\\
  940. \\\
  941. function Window.public:drag( x, y, button )\\\
  942.     if self.lastt then\\\
  943.         local p = self.lastt\\\
  944.         while p:type() ~= \\\"Window\\\" do\\\
  945.             x = x - p.x + 1\\\
  946.             y = y - p.y + 1\\\
  947.             if p:type() == \\\"UIFrame\\\" then\\\
  948.                 x = x - p.ox\\\
  949.                 y = y - p.oy\\\
  950.             end\\\
  951.             p = p.parent\\\
  952.             if not p then break end\\\
  953.         end\\\
  954.         self.lastt:onDrag( x, y, button, self.lastx, self.lasty )\\\
  955.         self.lastx, self.lasty = x, y\\\
  956.     else\\\
  957.         self.public:callback( \\\"onDrag\\\", x, y, button, x - self.lastx + 1, y - self.lasty + 1 )\\\
  958.         self.lastx = x\\\
  959.         self.lasty = y\\\
  960.     end\\\
  961. end\\\
  962. \\\
  963. function Window.public:scroll( x, y, dir )\\\
  964.     local t, rx, ry = mt( self.elements, x, y, true )\\\
  965.     if t then\\\
  966.         t:onScroll( rx, ry, dir )\\\
  967.     else\\\
  968.         self.public:callback( \\\"onScroll\\\", x, y, dir )\\\
  969.     end\\\
  970. end\\\
  971. \\\
  972. function Window.public:write( text )\\\
  973.     if self.focus then\\\
  974.         self.focus:write( text )\\\
  975.     else\\\
  976.         self.public:callback( \\\"onTextInput\\\", text )\\\
  977.     end\\\
  978. end\\\
  979. \\\
  980. function Window.public:key( key, last )\\\
  981.     if self.focus then\\\
  982.         self.focus:onKey( key, last )\\\
  983.     else\\\
  984.         self.public:callback( \\\"onKeyPress\\\", key )\\\
  985.     end\\\
  986. end\\\
  987. \\\
  988. function Window.public:update( dt )\\\
  989.     for i = #self.elements, 1, -1 do\\\
  990.         self.elements[i]:update( dt )\\\
  991.     end\\\
  992. end\\\
  993. \\\
  994. function Window.public:draw()\\\
  995.     local l\\\
  996.     if self.displaymode == \\\"normal\\\" then\\\
  997.         l = Gfx2D.buffer.current():addStencil( self.x, self.y, self.width, self.height )\\\
  998.     elseif self.displaymode == \\\"maximised\\\" then\\\
  999.         l = Gfx2D.buffer.current():addStencil( 1, 1, self.maxw, self.maxh )\\\
  1000.     elseif self.displaymode == \\\"minimised\\\" then\\\
  1001.         return\\\
  1002.     end\\\
  1003.     for i = 1, #self.elements do\\\
  1004.         self.elements[i]:draw( self.x + self.elements[i].x - 1, self.y + self.elements[i].y - 1 )\\\
  1005.     end\\\
  1006.     if l then\\\
  1007.         Gfx2D.buffer.current():removeStencil( l )\\\
  1008.     end\\\
  1009. end\\\
  1010. \\\
  1011. function Window.public:setFocus( element )\\\
  1012.     if not element or Class.typeOf( element, UIText ) or Class.typeOf( element, UIBuffer ) then\\\
  1013.         if self.focus ~= element then\\\
  1014.             if self.focus then\\\
  1015.                 self.focus:onUnFocus()\\\
  1016.             end\\\
  1017.             self.focus = element\\\
  1018.             if element then\\\
  1019.                 element:onFocus()\\\
  1020.             end\\\
  1021.         end\\\
  1022.     else\\\
  1023.         return error \\\"expected [<UIElement> element] or [nil]\\\"\\\
  1024.     end\\\
  1025. end\\\
  1026. \\\
  1027. function Window.public:setCallback( name, callback )\\\
  1028.     if type( callback ) ~= \\\"function\\\" then\\\
  1029.         return error \\\"expected <function> callback\\\"\\\
  1030.     end\\\
  1031.     self.callbacks[name] = callback\\\
  1032. end\\\
  1033. \\\
  1034. function Window.public:callback( name, ... )\\\
  1035.     if self.callbacks[name] then\\\
  1036.         return self.callbacks[name]( self.public, ... )\\\
  1037.     end\\\
  1038. end\\\
  1039. \\\
  1040. function Window.public:resize( width, height )\\\
  1041.     if width == \\\"fullscreen\\\" then\\\
  1042.         self.displaymode = \\\"fullscreen\\\"\\\
  1043.         self.public:callback( \\\"onResize\\\", self.maxw, self.maxh )\\\
  1044.     elseif type( width ) == \\\"number\\\" and type( height ) == \\\"number\\\" then\\\
  1045.         self.width = width\\\
  1046.         self.height = height\\\
  1047.         self.public:callback( \\\"onResize\\\", width, height )\\\
  1048.     elseif width == \\\"maximised\\\" then\\\
  1049.         self.displaymode = \\\"maximised\\\"\\\
  1050.         self.public:callback( \\\"onResize\\\", self.maxw, self.maxh - 1 )\\\
  1051.     else\\\
  1052.         return error \\\"expected [<number> width, <number> height] or [\\\\\\\"fullscreen\\\\\\\"] or [\\\\\\\"maximised\\\\\\\"]\\\"\\\
  1053.     end\\\
  1054. end\\\
  1055. \\\
  1056. return Window\"}\
  1057. files[2]={name=\"WindowManager\";mode='api';content=\"--@meta[type]:\\\"class\\\"\\\
  1058. \\\
  1059. local WindowManager = Class \\\"WindowManager\\\"\\\
  1060. \\\
  1061. function WindowManager:WindowManager()\\\
  1062.     self.windows = {}\\\
  1063.     self.displays = {}\\\
  1064. \\\
  1065.     self.windowfocus = false\\\
  1066. \\\
  1067.     self.last_time = os.clock()\\\
  1068. \\\
  1069.     local buffer = Gfx2D.buffer.current()\\\
  1070. \\\
  1071.     self.displays.computer = {\\\
  1072.         redirects = { term.current() };\\\
  1073.         buffer = buffer;\\\
  1074.         width = buffer.pixels.width;\\\
  1075.         height = buffer.pixels.height;\\\
  1076.         windows = {};\\\
  1077.         ids = {}\\\
  1078.     }\\\
  1079. \\\
  1080.     return self.public\\\
  1081. end\\\
  1082. \\\
  1083. function WindowManager.public:newDisplay( name, id )\\\
  1084.     if name == \\\"computer\\\" then\\\
  1085.         return error \\\"cannot override computer display\\\"\\\
  1086.     end\\\
  1087.     local p = Peripheral.connect( id )\\\
  1088.     if p then\\\
  1089.         if Peripheral.getType( id ) ~= \\\"monitor\\\" then\\\
  1090.             return error \\\"could not connect to peripheral: invalid peripheral\\\"\\\
  1091.         end\\\
  1092.         self.displays[name] = {\\\
  1093.             ids = { id };\\\
  1094.             redirects = { p };\\\
  1095.             buffer = Gfx2D.buffer.create( p.getSize() );\\\
  1096.             width = p.getSize();\\\
  1097.             height = select( 2, p.getSize() );\\\
  1098.             windows = {};\\\
  1099.         }\\\
  1100.     else\\\
  1101.         return error \\\"could not connect to peripheral: peripheral not found\\\"\\\
  1102.     end\\\
  1103. end\\\
  1104. \\\
  1105. function WindowManager.public:getDisplaySize( display )\\\
  1106.     if not self.displays[display] then\\\
  1107.         return error \\\"no such display\\\"\\\
  1108.     end\\\
  1109.     return self.displays[display].redirect.getSize()\\\
  1110. end\\\
  1111. \\\
  1112. function WindowManager.public:mirrorDisplay( display, id )\\\
  1113.     if not self.displays[display] then\\\
  1114.         return error \\\"no such display\\\"\\\
  1115.     end\\\
  1116.     local p = Peripheral.connect( id )\\\
  1117.     if p then\\\
  1118.         if Peripheral.getType( id ) ~= \\\"monitor\\\" then\\\
  1119.             return error \\\"could not connect to peripheral: invalid peripheral\\\"\\\
  1120.         end\\\
  1121.         table.insert( self.displays[display].redirects, p )\\\
  1122.         table.insert( self.displays[display].ids, id )\\\
  1123.         self.displays[display].buffer.allchanged = true\\\
  1124.     else\\\
  1125.         return error \\\"could not connect to peripheral: peripheral not found\\\"\\\
  1126.     end\\\
  1127. end\\\
  1128. \\\
  1129. function WindowManager.public:newWindow( display, width, height )\\\
  1130.     if not self.displays[display] then\\\
  1131.         return error \\\"no such display\\\"\\\
  1132.     end\\\
  1133.     local maxw, maxh = self.displays[display].width, self.displays[display].height\\\
  1134.     local window = Window( width, height, maxw, maxh, self.public )\\\
  1135.     window.x, window.y = math.ceil( maxw / 2 - width / 2 ) + 1, math.ceil( maxh / 2 - height / 2 ) + 1\\\
  1136.     table.insert( self.windows, {\\\
  1137.         window = window;\\\
  1138.         display = self.displays[display];\\\
  1139.     } )\\\
  1140.     table.insert( self.displays[display].windows, window )\\\
  1141.     self.windowfocus = window\\\
  1142.     return window\\\
  1143. end\\\
  1144. \\\
  1145. function WindowManager.public:removeWindow( window )\\\
  1146.     for i = #self.windows, 1, -1 do\\\
  1147.         if self.windows[i].window == window then\\\
  1148.             local display = self.windows[i].display\\\
  1149.             table.remove( self.windows, i )\\\
  1150.             for i = #display.windows, 1, -1 do\\\
  1151.                 if display.windows[i] == window then\\\
  1152.                     table.remove( display.windows, i )\\\
  1153.                 end\\\
  1154.             end\\\
  1155.         end\\\
  1156.     end\\\
  1157. end\\\
  1158. \\\
  1159. function WindowManager.public:update()\\\
  1160.     local dt = os.clock() - self.last_time\\\
  1161.     self.last_time = os.clock()\\\
  1162.     for i = 1, #self.windows do\\\
  1163.         self.windows[i].window:update( dt )\\\
  1164.     end\\\
  1165. end\\\
  1166. \\\
  1167. function WindowManager.public:draw()\\\
  1168.     local screen = Gfx2D.buffer.current()\\\
  1169.     local t = term.current()\\\
  1170.     for k, v in pairs( self.displays ) do\\\
  1171.         v.buffer:redirect()\\\
  1172.         v.buffer:clear()\\\
  1173.         local list = {}\\\
  1174.         for i = #v.windows, 1, -1 do\\\
  1175.             if v.windows[i].displaymode ~= \\\"minimised\\\" then\\\
  1176.                 table.insert( list, 1, v.windows[i] )\\\
  1177.             end\\\
  1178.             if v.windows[i].displaymode == \\\"fullscreen\\\" then\\\
  1179.                 break\\\
  1180.             end\\\
  1181.         end\\\
  1182.         for i = 1, #list do\\\
  1183.             list[i]:draw()\\\
  1184.         end\\\
  1185.         local _t = {}\\\
  1186.         for k in pairs( t ) do\\\
  1187.             _t[k] = function( ... )\\\
  1188.                 for i = #v.redirects, 2, -1 do\\\
  1189.                     v.redirects[i][k]( ... )\\\
  1190.                 end\\\
  1191.                 return v.redirects[1][k]( ... )\\\
  1192.             end\\\
  1193.         end\\\
  1194.         term.redirect( _t )\\\
  1195.         v.buffer:draw()\\\
  1196.         v.buffer:setCursorBlink()\\\
  1197.     end\\\
  1198.     screen:redirect()\\\
  1199.     term.redirect( t )\\\
  1200. end\\\
  1201. \\\
  1202. function WindowManager.public:event( event )\\\
  1203.     local display = self.displays.computer\\\
  1204.     if event[1] == \\\"monitor_touch\\\" then\\\
  1205.         display = nil\\\
  1206.         for k, v in pairs( self.displays ) do\\\
  1207.             for i = 1, #v.ids do\\\
  1208.                 if v.ids[i] == event[2] then\\\
  1209.                     display = v\\\
  1210.                     event = {\\\
  1211.                         \\\"mouse_click\\\";\\\
  1212.                         1;\\\
  1213.                         event[3];\\\
  1214.                         event[4];\\\
  1215.                     }\\\
  1216.                 end\\\
  1217.             end\\\
  1218.         end\\\
  1219.         if not display then return end\\\
  1220.     end\\\
  1221.     if event[1] == \\\"mouse_click\\\" or event[1] == \\\"mouse_scroll\\\" then\\\
  1222.         local w, rx, ry\\\
  1223.         for i = #display.windows, 1, -1 do\\\
  1224.             local window = display.windows[i]\\\
  1225.             if event[3] >= window.x and event[4] >= window.y and event[3] < window.x + window.width and event[4] < window.y + window.height then\\\
  1226.                 w = window\\\
  1227.                 rx = event[3] - window.x + 1\\\
  1228.                 ry = event[4] - window.y + 1\\\
  1229.                 break\\\
  1230.             end\\\
  1231.         end\\\
  1232.         if w then\\\
  1233.             if event[1] == \\\"mouse_click\\\" then\\\
  1234.                 w:click( rx, ry, event[2] )\\\
  1235.             else\\\
  1236.                 w:scroll( rx, ry, event[2] )\\\
  1237.             end\\\
  1238.         end\\\
  1239.         if event[1] == \\\"mouse_click\\\" then\\\
  1240.             self.windowfocus = w\\\
  1241.         end\\\
  1242.     elseif event[1] == \\\"mouse_drag\\\" and self.windowfocus then\\\
  1243.         self.windowfocus:drag( event[3] - self.windowfocus.x + 1, event[4] - self.windowfocus.y + 1, event[2] )\\\
  1244.     elseif event[1] == \\\"key\\\" and self.windowfocus then\\\
  1245.         self.windowfocus:key( event[2] )\\\
  1246.     elseif event[1] == \\\"char\\\" and self.windowfocus then\\\
  1247.         self.windowfocus:write( event[2] )\\\
  1248.     elseif event[1] == \\\"update\\\" then\\\
  1249.         for i = #self.windows, 1, -1 do\\\
  1250.             self.windows[i]:update( event[2] )\\\
  1251.         end\\\
  1252.     elseif event[1] == \\\"paste\\\" then\\\
  1253.         self.windowfocus:write( event[2] )\\\
  1254.     end\\\
  1255. end\\\
  1256. \\\
  1257. function WindowManager.public:run( noprocess, ... )\\\
  1258.     local function run( ... )\\\
  1259.         local ok, err = pcall( function( ... )\\\
  1260.             local event = { ... }\\\
  1261.             while true do\\\
  1262.                 if event[1] == \\\"update\\\" then\\\
  1263.                     self.public:draw()\\\
  1264.                     self.public:update( event[2] )\\\
  1265.                 else\\\
  1266.                     self.public:event( event )\\\
  1267.                 end\\\
  1268.                 event = { coroutine.yield() }\\\
  1269.             end\\\
  1270.         end, ... )\\\
  1271.         if not ok then\\\
  1272.             printError( err )\\\
  1273.         end\\\
  1274.     end\\\
  1275.     if noprocess then\\\
  1276.         run( ... )\\\
  1277.     else\\\
  1278.         return Process.newThread( run )\\\
  1279.     end\\\
  1280. end\\\
  1281. \\\
  1282. return WindowManager\"}\
  1283. files[3]={name=\"UIElement\";mode='api';content=\"--@meta[type]:\\\"class\\\"\\\
  1284. \\\
  1285. local UIElement = Class \\\"UIElement\\\"\\\
  1286. \\\
  1287. UIElement.public \\\"parent\\\" (UIElement) (Window) \\\"nil\\\"\\\
  1288. \\\
  1289. UIElement.public \\\"x\\\" \\\"number\\\"\\\
  1290. UIElement.public \\\"y\\\" \\\"number\\\"\\\
  1291. UIElement.public \\\"width\\\" \\\"number\\\"\\\
  1292. UIElement.public \\\"height\\\" \\\"number\\\"\\\
  1293. \\\
  1294. UIElement.public \\\"callback\\\"\\\
  1295. UIElement.public.callback.write = false\\\
  1296. \\\
  1297. function UIElement:UIElement( x, y, width, height )\\\
  1298.     self.x = x\\\
  1299.     self.y = y\\\
  1300.     self.width = width\\\
  1301.     self.height = height\\\
  1302. \\\
  1303.     self.callbacks = {}\\\
  1304.     self.callback = setmetatable( {}, { __index = self.callbacks, __newindex = function( _, k, v )\\\
  1305.         if type( v ) == \\\"function\\\" then\\\
  1306.             self.callbacks[k] = v\\\
  1307.         else\\\
  1308.             return error \\\"expected function callback\\\"\\\
  1309.         end\\\
  1310.     end } )\\\
  1311. \\\
  1312.     self.parent = nil\\\
  1313. \\\
  1314.     return self.public\\\
  1315. end\\\
  1316. \\\
  1317. function UIElement.public:centreX( n )\\\
  1318.     if self.parent then\\\
  1319.         self.x = math.floor( self.parent.width / 2 - self.width / 2 ) + ( n or 0 ) + 1\\\
  1320.     end\\\
  1321. end\\\
  1322. \\\
  1323. function UIElement.public:centreY( n )\\\
  1324.     if self.parent then\\\
  1325.         self.y = math.floor( self.parent.height / 2 - self.height / 2 ) + ( n or 0 ) + 1\\\
  1326.     end\\\
  1327. end\\\
  1328. \\\
  1329. function UIElement.public:centre( x, y )\\\
  1330.     self.public:centreX( x )\\\
  1331.     self.public:centreY( y )\\\
  1332. end\\\
  1333. \\\
  1334. function UIElement.public:remove()\\\
  1335.     if self.parent then\\\
  1336.         self.parent:removeChild( self.public )\\\
  1337.     end\\\
  1338. end\\\
  1339. \\\
  1340. function UIElement.public:update( dt )\\\
  1341. \\\
  1342. end\\\
  1343. \\\
  1344. function UIElement.public:draw( x, y )\\\
  1345. \\\
  1346. end\\\
  1347. \\\
  1348. function UIElement.public:onClick( x, y, button )\\\
  1349. \\\
  1350. end\\\
  1351. \\\
  1352. function UIElement.public:onDrag( x, y, button, lastx, lasty )\\\
  1353. \\\
  1354. end\\\
  1355. \\\
  1356. function UIElement.public:onScroll( x, y, dir )\\\
  1357. \\\
  1358. end\\\
  1359. \\\
  1360. function UIElement.public:onKey( key )\\\
  1361. \\\
  1362. end\\\
  1363. \\\
  1364. function UIElement.public:write( text )\\\
  1365. \\\
  1366. end\\\
  1367. \\\
  1368. function UIElement.public:onFocus( )\\\
  1369. \\\
  1370. end\\\
  1371. \\\
  1372. function UIElement.public:onUnFocus( )\\\
  1373. \\\
  1374. end\\\
  1375. \\\
  1376. return UIElement\"}\
  1377. files[4]={name=\"UIBuffer\";mode='api';content=\"--@meta[type]:\\\"class\\\"\\\
  1378. \\\
  1379. local colour = term.isColour( )\\\
  1380. \\\
  1381. local function termObject( buffer )\\\
  1382.     local t = { }\\\
  1383.     function t.write( str )\\\
  1384.         if type( str ) ~= \\\"string\\\" and type( str ) ~= \\\"number\\\" then return error \\\"expected string\\\" end\\\
  1385.         str = tostring( str )\\\
  1386.         for x = 1, #str do\\\
  1387.             buffer.image:setPixel( buffer.cx, buffer.cy, buffer.bc, buffer.tc, str:sub( x, x ) )\\\
  1388.             buffer.cx = buffer.cx + 1\\\
  1389.         end\\\
  1390.     end\\\
  1391.     function t.clearLine( )\\\
  1392.         buffer.image:foreach( function( x, y, bc, tc, char )\\\
  1393.             if y == buffer.cy then\\\
  1394.                 return buffer.bc, buffer.tc, \\\" \\\"\\\
  1395.             end\\\
  1396.         end )\\\
  1397.     end\\\
  1398.     function t.clear( )\\\
  1399.         buffer.image:foreach( function( x, y, bc, tc, char )\\\
  1400.             return buffer.bc, buffer.tc, \\\" \\\"\\\
  1401.         end )\\\
  1402.     end\\\
  1403.     function t.setCursorPos( x, y )\\\
  1404.         if type( x ) ~= \\\"number\\\" or type( y ) ~= \\\"number\\\" then\\\
  1405.             return error \\\"expected number, number\\\"\\\
  1406.         end\\\
  1407.         buffer.cx = x\\\
  1408.         buffer.cy = y\\\
  1409.     end\\\
  1410.     function t.getCursorPos( )\\\
  1411.         return buffer.cx, buffer.cy\\\
  1412.     end\\\
  1413.     function t.setBackgroundColour( col )\\\
  1414.         if type( col ) ~= \\\"number\\\" then\\\
  1415.             return error \\\"expected number\\\"\\\
  1416.         end\\\
  1417.         buffer.bc = col\\\
  1418.     end\\\
  1419.     function t.setTextColour( col )\\\
  1420.         if type( col ) ~= \\\"number\\\" then\\\
  1421.             return error \\\"expected number\\\"\\\
  1422.         end\\\
  1423.         buffer.tc = col\\\
  1424.     end\\\
  1425.     function t.setBackgroundColor( col )\\\
  1426.         if type( col ) ~= \\\"number\\\" then\\\
  1427.             return error \\\"expected number\\\"\\\
  1428.         end\\\
  1429.         buffer.bc = col\\\
  1430.     end\\\
  1431.     function t.setTextColor( col )\\\
  1432.         if type( col ) ~= \\\"number\\\" then\\\
  1433.             return error \\\"expected number\\\"\\\
  1434.         end\\\
  1435.         buffer.tc = col\\\
  1436.     end\\\
  1437.     function t.scroll( dir )\\\
  1438.         buffer.image:foreach( function( x, y, bc, tc, char )\\\
  1439.             if buffer.image:getPixel( x, y + dir ) then\\\
  1440.                 return buffer.image:getPixel( x, y + dir )\\\
  1441.             else\\\
  1442.                 return buffer.bc, buffer.tc, \\\" \\\"\\\
  1443.             end\\\
  1444.         end )\\\
  1445.     end\\\
  1446.     function t.setCursorBlink( state )\\\
  1447.         buffer.cb = not not state\\\
  1448.     end\\\
  1449.     function t.isColour( )\\\
  1450.         return colour\\\
  1451.     end\\\
  1452.     function t.isColor( )\\\
  1453.         return colour\\\
  1454.     end\\\
  1455.     function t.getSize( )\\\
  1456.         return buffer.width, buffer.height\\\
  1457.     end\\\
  1458. \\\
  1459.     return t\\\
  1460. end\\\
  1461. \\\
  1462. local function luaEnvironment( canvas )\\\
  1463.     local env = { }\\\
  1464.     env.fs = fs\\\
  1465.     env.term = term\\\
  1466.     env._VERSION = _VERSION\\\
  1467.     env.pairs = pairs\\\
  1468.     env.ipairs = ipairs\\\
  1469.     env.select = select\\\
  1470.     env.unpack = unpack\\\
  1471.     env.setfenv = setfenv\\\
  1472.     env.getfenv = getfenv\\\
  1473.     env.setmetatable = setmetatable\\\
  1474.     env.getmetatable = getmetatable\\\
  1475.     env.next = next\\\
  1476.     env.rawset = rawset\\\
  1477.     env.rawget = rawget\\\
  1478.     env.rawequal = rawequal\\\
  1479.     env.type = type\\\
  1480.     env.tostring = tostring\\\
  1481.     env.tonumber = tonumber\\\
  1482.     env.pcall = pcall\\\
  1483.     env.xpcall = xpcall\\\
  1484.     env.loadstring = loadstring\\\
  1485.     env.assert = assert\\\
  1486.     env.error = error\\\
  1487.     env.sleep = sleep\\\
  1488.     env.__inext = __inext\\\
  1489.     env.math = math\\\
  1490.     env.string = string\\\
  1491.     env.table = table\\\
  1492.     env.coroutine = coroutine\\\
  1493.     env.keys = keys\\\
  1494.     env.colours = colours\\\
  1495.     env.colors = colors\\\
  1496.     env.vector = vector\\\
  1497.     env.bit = bit\\\
  1498.     env.http = http\\\
  1499.     env.write = write\\\
  1500.     env.print = print\\\
  1501.     env.printError = printError\\\
  1502.     env.read = read\\\
  1503.     env.rednet = rednet\\\
  1504.     local tAPIsLoading = { }\\\
  1505.     env.os = setmetatable( {\\\
  1506.         pullEventRaw = function( sFilter )\\\
  1507.             while true do\\\
  1508.                 local event = { coroutine.yield( ) }\\\
  1509.                 if not sFilter or sFilter == event[1] then\\\
  1510.                     return unpack( event )\\\
  1511.                 end\\\
  1512.             end\\\
  1513.         end;\\\
  1514.         pullEvent = function( sFilter )\\\
  1515.             while true do\\\
  1516.                 local event = { coroutine.yield( ) }\\\
  1517.                 if event[1] == \\\"terminate\\\" then\\\
  1518.                     error( \\\"Terminated\\\", 0 )\\\
  1519.                 end\\\
  1520.                 if not sFilter or sFilter == event[1] then\\\
  1521.                     return unpack( event )\\\
  1522.                 end\\\
  1523.             end\\\
  1524.         end;\\\
  1525.         run = function( _tEnv, _sPath, ... )\\\
  1526.             local tArgs = { ... }\\\
  1527.             local fnFile, err = env.loadfile( _sPath )\\\
  1528.             if fnFile then\\\
  1529.                 local tEnv = _tEnv\\\
  1530.                 --setmetatable( tEnv, { __index = function(t,k) return _G[k] end } )\\\
  1531.                 setmetatable( tEnv, { __index = env } )\\\
  1532.                 setfenv( fnFile, tEnv )\\\
  1533.                 local ok, err = pcall( function()\\\
  1534.                     fnFile( unpack( tArgs ) )\\\
  1535.                 end )\\\
  1536.                 if not ok then\\\
  1537.                     if err and err ~= \\\"\\\" then\\\
  1538.                         printError( err )\\\
  1539.                     end\\\
  1540.                     return false\\\
  1541.                 end\\\
  1542.                 return true\\\
  1543.             end\\\
  1544.             if err and err ~= \\\"\\\" then\\\
  1545.                 printError( err )\\\
  1546.             end\\\
  1547.             return false\\\
  1548.         end;\\\
  1549.         loadAPI = function( _sPath )\\\
  1550.             local sName = fs.getName( _sPath )\\\
  1551.             if tAPIsLoading[sName] == true then\\\
  1552.                 printError( \\\"API \\\"..sName..\\\" is already being loaded\\\" )\\\
  1553.                 return false\\\
  1554.             end\\\
  1555.             tAPIsLoading[sName] = true\\\
  1556.                 \\\
  1557.             local tEnv = {}\\\
  1558.             setmetatable( tEnv, { __index = env } )\\\
  1559.             local fnAPI, err = loadfile( _sPath )\\\
  1560.             if fnAPI then\\\
  1561.                 setfenv( fnAPI, tEnv )\\\
  1562.                 fnAPI()\\\
  1563.             else\\\
  1564.                 printError( err )\\\
  1565.                 tAPIsLoading[sName] = nil\\\
  1566.                 return false\\\
  1567.             end\\\
  1568.             \\\
  1569.             local tAPI = {}\\\
  1570.             for k,v in pairs( tEnv ) do\\\
  1571.                 tAPI[k] =  v\\\
  1572.             end\\\
  1573.             \\\
  1574.             env[sName] = tAPI    \\\
  1575.             tAPIsLoading[sName] = nil\\\
  1576.             return true\\\
  1577.         end;\\\
  1578.         unloadAPI = function( _sName )\\\
  1579.             if _sName ~= \\\"_G\\\" and type(env[_sName]) == \\\"table\\\" then\\\
  1580.                 env[_sName] = nil\\\
  1581.             end\\\
  1582.         end;\\\
  1583.     }, { __index = os } );\\\
  1584.     env.help = help\\\
  1585.     env.io = io\\\
  1586.     env.parallel = parallel\\\
  1587. \\\
  1588.     env.loadfile = function( _sFile )\\\
  1589.         local file = env.fs.open( _sFile, \\\"r\\\" )\\\
  1590.         if file then\\\
  1591.             local func, err = loadstring( file.readAll(), env.fs.getName( _sFile ) )\\\
  1592.             file.close()\\\
  1593.             if not func then\\\
  1594.                 return nil, err:gsub( \\\"UIBuffer.lua:215: \\\", \\\"\\\" )\\\
  1595.             end\\\
  1596.             return func, err\\\
  1597.         end\\\
  1598.         return nil, \\\"File not found\\\"\\\
  1599.     end\\\
  1600. \\\
  1601.     env.dofile = function( _sFile )\\\
  1602.         local fnFile, e = env.loadfile( _sFile )\\\
  1603.         if fnFile then\\\
  1604.             setfenv( fnFile, env )\\\
  1605.             return fnFile()\\\
  1606.         else\\\
  1607.             error( e, 2 )\\\
  1608.         end\\\
  1609.     end\\\
  1610. \\\
  1611.     env.shell = shell\\\
  1612.     env.multishell = multishell\\\
  1613.     env.redstone = redstone -- change in future, use device system\\\
  1614.     env.rs = rs -- change in future, use device system\\\
  1615.     env.gps = gps -- change in future, use Nova gps system\\\
  1616.     env.peripheral = peripheral -- change in future, use device system\\\
  1617.     env.disk = disk -- change in future, use filesystem\\\
  1618.     env.window = window -- oh crap...\\\
  1619.     env.textutils = textutils\\\
  1620.     env.paintutils = paintutils\\\
  1621.     env.term = term\\\
  1622. \\\
  1623.     env._G = env\\\
  1624. \\\
  1625.     return env\\\
  1626. end\\\
  1627. \\\
  1628. local UIBuffer = Class \\\"UIBuffer\\\"\\\
  1629. \\\
  1630. UIBuffer:extends( UIElement )\\\
  1631. \\\
  1632. UIBuffer.public \\\"cx\\\" \\\"number\\\"\\\
  1633. UIBuffer.public \\\"cy\\\" \\\"number\\\"\\\
  1634. UIBuffer.public \\\"cb\\\" \\\"boolean\\\"\\\
  1635. UIBuffer.public \\\"bc\\\" \\\"number\\\"\\\
  1636. UIBuffer.public \\\"tc\\\" \\\"number\\\"\\\
  1637. UIBuffer.public \\\"image\\\"\\\
  1638. UIBuffer.public.image.write = false\\\
  1639. UIBuffer.public \\\"environment\\\"\\\
  1640. UIBuffer.public.environment.write = false\\\
  1641. \\\
  1642. function UIBuffer:UIBuffer( x, y, w, h )\\\
  1643.     self:UIElement( x, y, w, h )\\\
  1644.     self.image = gfx2d.Image( w, h )\\\
  1645.     self.image:foreach( function( )\\\
  1646.         return colours.black, colours.white, \\\" \\\"\\\
  1647.     end )\\\
  1648.     self.term = termObject( self.public )\\\
  1649.     self.running = false\\\
  1650.     self.co = false\\\
  1651.     self.cx = 1\\\
  1652.     self.cy = 1\\\
  1653.     self.bc = colours.black\\\
  1654.     self.tc = colours.white\\\
  1655.     self.cb = false\\\
  1656.     self.environment = luaEnvironment( )\\\
  1657. \\\
  1658.     return self.public\\\
  1659. end\\\
  1660. \\\
  1661. function UIBuffer.public:setTask( func )\\\
  1662.     setfenv( func, self.environment )\\\
  1663.     self.co = coroutine.create( func )\\\
  1664.     self.running = true\\\
  1665. end\\\
  1666. \\\
  1667. function UIBuffer.public:passEvent( ... )\\\
  1668.     if not self.running then return end\\\
  1669.     local prev = term.redirect( self.term )\\\
  1670.     local ok, err = coroutine.resume( self.co, ... )\\\
  1671.     term.redirect( prev )\\\
  1672.     if not ok then\\\
  1673.         self.running = false\\\
  1674.         local prev = term.redirect( self.term )\\\
  1675.         printError( err )\\\
  1676.         term.redirect( prev )\\\
  1677.     end\\\
  1678.     if coroutine.status( self.co ) == \\\"dead\\\" then\\\
  1679.         self.running = false\\\
  1680.     end\\\
  1681. end\\\
  1682. \\\
  1683. function UIBuffer.public:draw( x, y )\\\
  1684.     self.image:resize( self.width, self.height, self.bc, 1, \\\" \\\" )\\\
  1685.     self.image:foreach( function( px, py, bc, tc, char )\\\
  1686.         Gfx2D.buffer.setPixel( x + px - 1, y + py - 1, bc, tc, char )\\\
  1687.         return bc, tc, char\\\
  1688.     end )\\\
  1689.     if self.cb then\\\
  1690.         Gfx2D.buffer.setCursorBlink( x + self.cx - 1, y + self.cy - 1, self.tc )\\\
  1691.     end\\\
  1692. end\\\
  1693. \\\
  1694. function UIBuffer.public:onClick( x, y, button )\\\
  1695.     self.public:passEvent( \\\"mouse_click\\\", button, x, y )\\\
  1696. end\\\
  1697. \\\
  1698. function UIBuffer.public:onDrag( x, y, button )\\\
  1699.     self.public:passEvent( \\\"mouse_drag\\\", button, x, y )\\\
  1700. end\\\
  1701. \\\
  1702. function UIBuffer.public:onScroll( x, y, dir )\\\
  1703.     self.public:passEvent( \\\"mouse_scroll\\\", dir, x, y )\\\
  1704. end\\\
  1705. \\\
  1706. function UIBuffer.public:onKey( key, lastkey )\\\
  1707.     self.public:passEvent( \\\"key\\\", key )\\\
  1708. end\\\
  1709. \\\
  1710. function UIBuffer.public:write( text, lastkey )\\\
  1711.     self.public:passEvent( \\\"char\\\", text )\\\
  1712. end\\\
  1713. \\\
  1714. return UIBuffer\"}\
  1715. files[5]={name=\"UIFrame\";mode='api';content=\"--@meta[type]:\\\"class\\\"\\\
  1716. \\\
  1717. local UIFrame = Class \\\"UIFrame\\\"\\\
  1718. \\\
  1719. UIFrame:extends( UIElement )\\\
  1720. \\\
  1721. UIFrame.public \\\"ox\\\" \\\"number\\\"\\\
  1722. UIFrame.public \\\"oy\\\" \\\"number\\\"\\\
  1723. \\\
  1724. function UIFrame:UIFrame( x, y, w, h )\\\
  1725.     self:UIElement( x, y, w, h )\\\
  1726. \\\
  1727.     self.children = {}\\\
  1728.     self.ox = 0\\\
  1729.     self.oy = 0\\\
  1730. \\\
  1731.     return self.public\\\
  1732. end\\\
  1733. \\\
  1734. function UIFrame.public:newChild( element )\\\
  1735.     if Class.typeOf( element, UIElement ) then\\\
  1736.         table.insert( self.children, element )\\\
  1737.         element.parent = self.public\\\
  1738.         return element\\\
  1739.     else\\\
  1740.         return error \\\"expected <UIElement> child\\\"\\\
  1741.     end\\\
  1742. end\\\
  1743. \\\
  1744. function UIFrame.public:removeChild( element )\\\
  1745.     if Class.typeOf( element, UIElement ) then\\\
  1746.         for i = 1, #self.children do\\\
  1747.             if self.children[i] == element then\\\
  1748.                 element.parent = nil\\\
  1749.                 table.remove( self.children, i )\\\
  1750.                 return\\\
  1751.             end\\\
  1752.         end\\\
  1753.     else\\\
  1754.         return error \\\"expected <UIElement> child\\\"\\\
  1755.     end\\\
  1756. end\\\
  1757. \\\
  1758. function UIFrame.public:clearChildren()\\\
  1759.     for i = #self.children, 1, -1 do\\\
  1760.         self.public:removeChild( self.children[i] )\\\
  1761.     end\\\
  1762. end\\\
  1763. \\\
  1764. function UIFrame.public:getChildren()\\\
  1765.     local t = {}\\\
  1766.     for i = 1, #self.children do\\\
  1767.         t[i] = self.children[i]\\\
  1768.     end\\\
  1769.     return t\\\
  1770. end\\\
  1771. \\\
  1772. function UIFrame.public:update( dt )\\\
  1773.     for i = 1, #self.children do\\\
  1774.         self.children[i]:update( dt )\\\
  1775.     end\\\
  1776. end\\\
  1777. \\\
  1778. function UIFrame.public:draw( x, y )\\\
  1779.     local l = Gfx2D.buffer.current():addStencil( x, y, self.width, self.height )\\\
  1780.     for i = 1, #self.children do\\\
  1781.         self.children[i]:draw( x + self.children[i].x - 1 + self.ox, y + self.children[i].y - 1 + self.oy )\\\
  1782.     end\\\
  1783.     Gfx2D.buffer.current():removeStencil( l )\\\
  1784. end\\\
  1785. \\\
  1786. function UIFrame.public:onScroll( x, y, dir )\\\
  1787.     self.oy = self.oy - dir\\\
  1788.     if self.oy > 0 then self.oy = 0 end\\\
  1789.     if self.oy < self.height - self.public:getContentHeight() then self.oy = self.height - self.public:getContentHeight() end\\\
  1790. end\\\
  1791. \\\
  1792. function UIFrame.public:getContentWidth()\\\
  1793.     local max = self.width\\\
  1794.     for i = 1, #self.children do\\\
  1795.         max = math.max( max, self.children[i].x + self.children[i].width - 1 )\\\
  1796.     end\\\
  1797.     return max\\\
  1798. end\\\
  1799. \\\
  1800. function UIFrame.public:getContentHeight()\\\
  1801.     local max = self.height\\\
  1802.     for i = 1, #self.children do\\\
  1803.         max = math.max( max, self.children[i].y + self.children[i].height - 1 )\\\
  1804.     end\\\
  1805.     return max\\\
  1806. end\\\
  1807. \\\
  1808. function UIFrame.public:getContentHScroll()\\\
  1809.     return -self.ox\\\
  1810. end\\\
  1811. \\\
  1812. function UIFrame.public:getContentVScroll()\\\
  1813.     return -self.oy\\\
  1814. end\\\
  1815. \\\
  1816. function UIFrame.public:setContentHScroll( n )\\\
  1817.     self.ox = -n\\\
  1818. end\\\
  1819. \\\
  1820. function UIFrame.public:setContentVScroll( n )\\\
  1821.     self.oy = -n\\\
  1822. end\\\
  1823. \\\
  1824. return UIFrame\"}\
  1825. files[6]={name=\"UIImage\";mode='api';content=\"--@meta[type]:\\\"class\\\"\\\
  1826. \\\
  1827. local UIImage = Class \\\"UIImage\\\"\\\
  1828. \\\
  1829. UIImage:extends( UIElement )\\\
  1830. \\\
  1831. UIImage.public \\\"image\\\" (Gfx2D.Image)\\\
  1832. \\\
  1833. function UIImage:UIImage( x, y, w, h, image )\\\
  1834.     self:UIElement( x, y, w, h )\\\
  1835.     self.image = image\\\
  1836.     self.xpos, self.ypos = nil, nil\\\
  1837.     return self.public\\\
  1838. end\\\
  1839. \\\
  1840. function UIImage.public:draw( x, y )\\\
  1841.     self.image:resize( self.width, self.height )\\\
  1842.     self.image:foreach( function( bc, tc, char, xx, yy )\\\
  1843.         Gfx2D.buffer.setPixel( x + xx - 1, y + yy - 1, bc, tc, char )\\\
  1844.     end )\\\
  1845. end\\\
  1846. \\\
  1847. function UIImage.public:onClick( rx, ry, button )\\\
  1848.     if self.callbacks.onClick then\\\
  1849.         self.callbacks.onClick( self.public, button, rx, ry )\\\
  1850.     end\\\
  1851. end\\\
  1852. \\\
  1853. function UIImage.public:onDrag( rx, ry, button, lx, ly )\\\
  1854.     if self.callbacks.onDrag then\\\
  1855.         self.callbacks.onDrag( self.public, button, rx, ry, lx, ly )\\\
  1856.     end\\\
  1857. end\\\
  1858. \\\
  1859. return UIImage\"}\
  1860. files[7]={name=\"UIScrollBar\";mode='api';content=\"--@meta[type]:\\\"class\\\"\\\
  1861. \\\
  1862. local UIScrollBar = Class \\\"UIScrollBar\\\"\\\
  1863. \\\
  1864. UIScrollBar:extends(UIElement)\\\
  1865. \\\
  1866. UIScrollBar.public \\\"bc\\\"  \\\"number\\\"\\\
  1867. UIScrollBar.public \\\"tc\\\"  \\\"number\\\"\\\
  1868. \\\
  1869. function UIScrollBar:UIScrollBar( x, y, w, h, direction, target )\\\
  1870.     self:UIElement( x, y, w, h )\\\
  1871. \\\
  1872.     self.bc = colours.lightGrey\\\
  1873.     self.tc = colours.grey\\\
  1874.     self.direction = direction or \\\"vertical\\\"\\\
  1875. \\\
  1876.     if target then\\\
  1877.         if Class.typeOf( target, UIElement ) then\\\
  1878.             self.target = target\\\
  1879.         else\\\
  1880.             error( \\\"expected UIElement target\\\", 3 )\\\
  1881.         end\\\
  1882.     end\\\
  1883.     return self.public\\\
  1884. end\\\
  1885. \\\
  1886. function UIScrollBar:getBar( )\\\
  1887.     if not self.target then\\\
  1888.         return 0, self.direction == \\\"vertical\\\" and self.height or self.width\\\
  1889.     end\\\
  1890.     local traysize\\\
  1891.     if self.direction == \\\"vertical\\\" then\\\
  1892.         traysize = self.height\\\
  1893.     else\\\
  1894.         traysize = self.width\\\
  1895.     end\\\
  1896.     local framesize, contentsize, contentscroll\\\
  1897.     if self.direction == \\\"vertical\\\" then\\\
  1898.         framesize = self.target.height\\\
  1899.         contentsize = self.target:getContentHeight()\\\
  1900.         contentscroll = self.target:getContentVScroll()\\\
  1901.     else\\\
  1902.         framesize = self.target.width\\\
  1903.         contentsize = self.target:getContentWidth()\\\
  1904.         contentscroll = self.target:getContentHScroll()\\\
  1905.     end\\\
  1906. \\\
  1907.     local barsize = math.max( math.floor( traysize * framesize / contentsize ), 1 )\\\
  1908. \\\
  1909.     local barpos = traysize * contentscroll / contentsize\\\
  1910.     return math.ceil( barpos ), barsize\\\
  1911. end\\\
  1912. \\\
  1913. function UIScrollBar.public:draw( x, y )\\\
  1914.     local function rect( x, y, w, h, bc )\\\
  1915.         for i = 0, w - 1 do\\\
  1916.             for n = 0, h - 1 do\\\
  1917.                 Gfx2D.buffer.setPixel( x + i, y + n, bc, 1, \\\" \\\" )\\\
  1918.             end\\\
  1919.         end\\\
  1920.     end\\\
  1921.     local l = Gfx2D.buffer.current():addStencil( x, y, self.width, self.height )\\\
  1922.     if self.target then\\\
  1923.         local pos, size = self:getBar( )\\\
  1924.         rect( x, y, self.width, self.height, self.tc )\\\
  1925.         if self.direction == \\\"vertical\\\" then\\\
  1926.             rect( x, y + pos, self.width, size, self.bc )\\\
  1927.         else\\\
  1928.             rect( x + pos, y, size, self.height, self.bc )\\\
  1929.         end\\\
  1930.     else\\\
  1931.         rect( x, y, self.width, self.height, self.bc )\\\
  1932.     end\\\
  1933.     Gfx2D.buffer.current():removeStencil( l )\\\
  1934. end\\\
  1935. \\\
  1936. function UIScrollBar.public:onClick( rx, ry, button )\\\
  1937.     if not self.target then return end\\\
  1938.     local pos, size = self:getBar( )\\\
  1939.     local traysize\\\
  1940.     if self.direction == \\\"vertical\\\" then\\\
  1941.         self.downoffset = ry - pos\\\
  1942.         if ry > pos and ry < pos + size - 1 then return end\\\
  1943.         pos = ry - 1\\\
  1944.         traysize = self.height\\\
  1945.     else\\\
  1946.         self.downoffset = rx - pos\\\
  1947.         if rx > pos and rx < pos + size - 1 then return end\\\
  1948.         pos = rx - 1\\\
  1949.         traysize = self.width\\\
  1950.     end\\\
  1951.     pos = math.max( math.min( pos, traysize - size ), 0 )\\\
  1952.     if self.direction == \\\"vertical\\\" then\\\
  1953.         self.target:setContentVScroll( math.floor( pos / traysize * self.target:getContentHeight( ) ) )\\\
  1954.     else\\\
  1955.         self.target:setContentHScroll( math.floor( pos / traysize * self.target:getContentWidth( ) ) )\\\
  1956.     end\\\
  1957. end\\\
  1958. \\\
  1959. function UIScrollBar.public:onDrag( rx, ry, cx, cy, button )\\\
  1960.     if not self.target then return end\\\
  1961.     local pos, size = self:getBar( )\\\
  1962.     local traysize\\\
  1963.     if self.direction == \\\"vertical\\\" then\\\
  1964.         pos = ry - self.downoffset\\\
  1965.         traysize = self.height\\\
  1966.     else\\\
  1967.         pos = rx - self.downoffset\\\
  1968.         traysize = self.width\\\
  1969.     end\\\
  1970.     pos = math.max( math.min( pos, traysize - size ), 0 )\\\
  1971.     if self.direction == \\\"vertical\\\" then\\\
  1972.         self.target:setContentVScroll( math.floor( pos / traysize * self.target:getContentHeight( ) ) )\\\
  1973.     else\\\
  1974.         self.target:setContentHScroll( math.floor( pos / traysize * self.target:getContentWidth( ) ) )\\\
  1975.     end\\\
  1976. end\\\
  1977. \\\
  1978. function UIScrollBar.public:onMouseScroll( rx, ry, dir )\\\
  1979.     if not self.target then return end\\\
  1980.     local pos, size = self:getBar( )\\\
  1981.     local traysize\\\
  1982.     if self.direction == \\\"vertical\\\" then\\\
  1983.         traysize = self.h\\\
  1984.     else\\\
  1985.         traysize = self.w\\\
  1986.     end\\\
  1987.     pos = math.max( math.min( pos + dir, traysize - size), 0 )\\\
  1988.     if self.direction == \\\"vertical\\\" then\\\
  1989.         self.target:setContentScrollV( math.floor( pos / traysize * self.target:getContentSizeV( ) ) )\\\
  1990.     else\\\
  1991.         self.target:setContentScrollH( math.floor( pos / traysize * self.target:getContentSizeH( ) ) )\\\
  1992.     end\\\
  1993. end\\\
  1994. \\\
  1995. return UIScrollBar\"}\
  1996. files[8]={name=\"UIText\";mode='api';content=\"--@meta[type]:\\\"class\\\"\\\
  1997. \\\
  1998. local UIText = Class \\\"UIText\\\"\\\
  1999. \\\
  2000. UIText:extends( UIElement )\\\
  2001. \\\
  2002. UIText.public \\\"text\\\"\\\
  2003. UIText.public \\\"bc\\\" \\\"number\\\" \\\"function\\\"\\\
  2004. UIText.public \\\"tc\\\" \\\"number\\\" \\\"function\\\"\\\
  2005. UIText.public \\\"hbc\\\" \\\"number\\\" \\\"function\\\"\\\
  2006. UIText.public \\\"htc\\\" \\\"number\\\" \\\"function\\\"\\\
  2007. UIText.public \\\"tbc\\\" \\\"number\\\" \\\"function\\\"\\\
  2008. UIText.public \\\"ttc\\\" \\\"number\\\" \\\"function\\\"\\\
  2009. UIText.public \\\"syntax\\\"\\\
  2010. UIText.public.syntax.write = false\\\
  2011. \\\
  2012. UIText.public \\\"input\\\" \\\"boolean\\\"\\\
  2013. UIText.public \\\"wordwrap\\\" \\\"boolean\\\"\\\
  2014. UIText.public \\\"noformat\\\" \\\"boolean\\\"\\\
  2015. UIText.public \\\"align\\\" \\\"string\\\"\\\
  2016. \\\
  2017. function UIText.public.text:write( value )\\\
  2018.     self.text = type( value ) == \\\"function\\\" and value or tostring( value == nil and \\\"\\\" or value )\\\
  2019.     self.public:reload()\\\
  2020.     self.public:wrap()\\\
  2021. end\\\
  2022. \\\
  2023. function UIText:UIText( x, y, w, h, text )\\\
  2024.     self:UIElement( x, y, w, h )\\\
  2025. \\\
  2026.     self.focussed = false\\\
  2027. \\\
  2028.     self.bc = colours.white\\\
  2029.     self.tc = colours.grey\\\
  2030.     self.hbc = colours.blue\\\
  2031.     self.htc = colours.white\\\
  2032.     self.tbc = colours.white\\\
  2033.     self.ttc = colours.white\\\
  2034.     self.syntax = {}\\\
  2035. \\\
  2036.     self.cx, self.cy = 0, 0\\\
  2037. \\\
  2038.     self.input = false\\\
  2039.     self.wordwrap = true\\\
  2040. \\\
  2041.     self.align = \\\"top left\\\"\\\
  2042. \\\
  2043.     self.cursor = {\\\
  2044.         x = 1;\\\
  2045.         y = 1;\\\
  2046.         char = 1;\\\
  2047.     }\\\
  2048.     self.selection = false\\\
  2049. \\\
  2050.     self.public.text = text\\\
  2051. \\\
  2052.     return self.public\\\
  2053. end\\\
  2054. \\\
  2055. function UIText.public:reload()\\\
  2056.     local text = self.text\\\
  2057.     if type( text ) == \\\"function\\\" then\\\
  2058.         text = text()\\\
  2059.     end\\\
  2060.     self.stream = SFormat.format( \\\" \\\" .. tostring( text ) .. \\\" \\\", self.syntax, self.bc, self.tc, self.input or self.noformat )\\\
  2061.     table.remove( self.stream, 1 )\\\
  2062.     table.remove( self.stream, #self.stream )\\\
  2063. end\\\
  2064. function UIText.public:wrap()\\\
  2065.     self.wstream = SFormat.wrapstream( self.stream, self.wordwrap and self.width, nil, self.align, self.width, self.height )\\\
  2066.     self.lines = self.wstream.lines\\\
  2067.     local function unhighlight( x, y )\\\
  2068.         if self.wstream:getChar( y, x ) then\\\
  2069.             local c = self.wstream:getChar( y, x )\\\
  2070.             c.highlight = false\\\
  2071.         end\\\
  2072.     end\\\
  2073.     if self.selection then\\\
  2074.         local ss = false\\\
  2075.         local mix, miy, max, may = self:getSelectionBounds()\\\
  2076.         local function highlight( x, y )\\\
  2077.             if self.wstream:getChar( y, x ) then\\\
  2078.                 local c = self.wstream:getChar( y, x )\\\
  2079.                 c.highlight = true\\\
  2080.             end\\\
  2081.         end\\\
  2082.         for i = 1, #self.lines do\\\
  2083.             if i == miy then\\\
  2084.                 if miy == may then\\\
  2085.                     for c = 1, mix - 1 do\\\
  2086.                         unhighlight( c, i )\\\
  2087.                     end\\\
  2088.                     for c = mix, max do\\\
  2089.                         highlight( c, i )\\\
  2090.                     end\\\
  2091.                     for c = max + 1, #self.lines[i] do\\\
  2092.                         unhighlight( c, i )\\\
  2093.                     end\\\
  2094.                 else\\\
  2095.                     for c = 1, mix - 1 do\\\
  2096.                         unhighlight( c, i )\\\
  2097.                     end\\\
  2098.                     for c = mix, #self.lines[i] do\\\
  2099.                         highlight( c, i )\\\
  2100.                     end\\\
  2101.                     ss = true\\\
  2102.                 end\\\
  2103.             elseif i == may then\\\
  2104.                 for c = 1, max do\\\
  2105.                     highlight( c, i )\\\
  2106.                 end\\\
  2107.                 for c = max + 1, #self.lines[i] do\\\
  2108.                     unhighlight( c, i )\\\
  2109.                 end\\\
  2110.                 ss = false\\\
  2111.             elseif ss then\\\
  2112.                 for c = 1, #self.lines[i] do\\\
  2113.                     highlight( c, i )\\\
  2114.                 end\\\
  2115.             else\\\
  2116.                 for c = 1, #self.lines[i] do\\\
  2117.                     unhighlight( c, i )\\\
  2118.                 end\\\
  2119.             end\\\
  2120.         end\\\
  2121.     else\\\
  2122.         for i = 1, #self.lines do\\\
  2123.             for c = 1, #self.lines[i] do\\\
  2124.                 unhighlight( c, i )\\\
  2125.             end\\\
  2126.         end\\\
  2127.     end\\\
  2128. end\\\
  2129. \\\
  2130. function UIText:charToCoords( char, noformat )\\\
  2131.     if char > #self.stream then\\\
  2132.         return #self.lines[#self.lines]:gsub( \\\"\\\\t\\\", \\\"    \\\" ) + 1, #self.lines\\\
  2133.     end\\\
  2134.     local y\\\
  2135.     for i = 1, #self.lines do\\\
  2136.         y = i\\\
  2137.         if char - #self.lines[i] > 0 then\\\
  2138.             char = char - #self.lines[i]\\\
  2139.         else\\\
  2140.             break\\\
  2141.         end\\\
  2142.     end\\\
  2143.     local x = 1\\\
  2144.     for i = 1, char - 1 do\\\
  2145.         if self.lines[y]:sub( i, i ) == \\\"\\\\t\\\" then\\\
  2146.             x = x + ( noformat and 1 or 4 )\\\
  2147.         else\\\
  2148.             x = x + 1\\\
  2149.         end\\\
  2150.     end\\\
  2151.     return x, y\\\
  2152. end\\\
  2153. function UIText:coordsToChar( x, y )\\\
  2154.     y = math.min( y, #self.lines )\\\
  2155.     if not self.lines[y] then return 1 end\\\
  2156.     x = math.min( x, #self.lines[y]:gsub( \\\"\\\\t\\\", \\\"    \\\" ):gsub( \\\"\\\\n$\\\", \\\"\\\" ) + 1 )\\\
  2157.     local pos = 1\\\
  2158.     for i = 1, y - 1 do\\\
  2159.         pos = pos + #self.lines[i]\\\
  2160.     end\\\
  2161.     for i = 1, #self.lines[y] do\\\
  2162.         local char = self.lines[y]:sub( i, i )\\\
  2163.         if char == \\\"\\\\t\\\" then\\\
  2164.             x = x - 4\\\
  2165.         else\\\
  2166.             x = x - 1\\\
  2167.         end\\\
  2168.         if x <= 0 then\\\
  2169.             return pos\\\
  2170.         end\\\
  2171.         pos = pos + 1\\\
  2172.     end\\\
  2173.     return pos\\\
  2174. end\\\
  2175. \\\
  2176. function UIText:getSelectionBounds()\\\
  2177.     local sx, sy = self:charToCoords( self.selection.char, true )\\\
  2178.     local cx, cy = self:charToCoords( self.cursor.char, true )\\\
  2179.     local mix, miy, max, may\\\
  2180.     if sy < cy then\\\
  2181.         mix, miy, max, may = sx, sy, cx, cy\\\
  2182.     elseif sy == cy then\\\
  2183.         return math.min( sx, cx ), cy, math.max( sx, cx ), cy\\\
  2184.     else\\\
  2185.         max, may, mix, miy = sx, sy, cx, cy\\\
  2186.     end\\\
  2187.     return mix, miy, max, may\\\
  2188. end\\\
  2189. \\\
  2190. function UIText.public:setCursorPos( x, y )\\\
  2191.     local x, y, char = y and x or self:charToCoords( x ), y or select( 2, self:charToCoords( x ) ), y and self:coordsToChar( x, y ) or x\\\
  2192.     self.cursor = { x = x, y = y, char = char }\\\
  2193.     if self.cursor.y + self.cy < 1 then\\\
  2194.         self.cy = -self.cursor.y + 1\\\
  2195.     elseif self.cursor.y + self.cy > self.height then\\\
  2196.         self.cy = -self.cursor.y + self.height\\\
  2197.     end\\\
  2198.     if self.cursor.x + self.cx < 1 then\\\
  2199.         self.cx = -self.cursor.x + 1\\\
  2200.     elseif self.cursor.x + self.cx > self.width then\\\
  2201.         self.cx = -self.cursor.x + self.width\\\
  2202.     end\\\
  2203. end\\\
  2204. \\\
  2205. function UIText.public:select( x, y )\\\
  2206.     if not x then\\\
  2207.         self.selection = false\\\
  2208.         return\\\
  2209.     end\\\
  2210.     local char\\\
  2211.     if not y then\\\
  2212.         char = x\\\
  2213.         x, y = self:charToCoords( x )\\\
  2214.     end\\\
  2215.     self.selection = {}\\\
  2216.     self.selection.char = char or self:coordsToChar( x - self.cx, y )\\\
  2217.     self.selection.x, self.selection.y = x, y\\\
  2218.     self.public:wrap()\\\
  2219. end\\\
  2220. \\\
  2221. function UIText.public:update( dt )\\\
  2222.     if type( self.text ) == \\\"function\\\" then\\\
  2223.         self.public:reload()\\\
  2224.         self.public:wrap()\\\
  2225.     end\\\
  2226. end\\\
  2227. \\\
  2228. function UIText.public:draw( x, y )\\\
  2229.     local l = Gfx2D.buffer.current():addStencil( x, y, self.width, self.height )\\\
  2230.     if self.bc ~= 0 then\\\
  2231.         for xx = 1, self.width do\\\
  2232.             for yy = 1, self.height do\\\
  2233.                 Gfx2D.buffer.setPixel( x + xx - 1, y + yy - 1, self.bc, self.tc, \\\" \\\" )\\\
  2234.             end\\\
  2235.         end\\\
  2236.     end\\\
  2237.     for i = 1, #self.lines do\\\
  2238.         local ypos = i + ( self.lines.padding.vertical or 0 ) + self.cy\\\
  2239.         if ypos >= 1 and ypos <= self.height then\\\
  2240.             local xpos = ( self.lines.padding[i] or 0 ) + self.cx\\\
  2241.             for c = 1, #self.lines[i] do\\\
  2242.                 local char = self.wstream:getChar( i, c )\\\
  2243.                 if char then\\\
  2244.                     local bc, tc = char.bc, char.tc\\\
  2245.                     if char.char == \\\"\\\\t\\\" then\\\
  2246.                         bc, tc = self.tbc, self.ttc\\\
  2247.                         if char.highlight then\\\
  2248.                             bc, tc = self.hbc, self.htc\\\
  2249.                         end\\\
  2250.                         for i = 1, 3 do\\\
  2251.                             Gfx2D.buffer.setPixel( x + xpos, y + ypos - 1, bc, tc, \\\" \\\" )\\\
  2252.                             xpos = xpos + 1\\\
  2253.                         end\\\
  2254.                         Gfx2D.buffer.setPixel( x + xpos, y + ypos - 1, bc, tc, \\\":\\\" )\\\
  2255.                     else\\\
  2256.                         local ch = char.char\\\
  2257.                         if char.char == \\\"\\\\n\\\" then\\\
  2258.                             ch = \\\" \\\"\\\
  2259.                         end\\\
  2260.                         if char.highlight then\\\
  2261.                             bc, tc = self.hbc, self.htc\\\
  2262.                         end\\\
  2263.                         Gfx2D.buffer.setPixel( x + xpos, y + ypos - 1, bc, tc, ch )\\\
  2264.                     end\\\
  2265.                 end\\\
  2266.                 xpos = xpos + 1\\\
  2267.             end\\\
  2268.         end\\\
  2269.     end\\\
  2270.     if self.focussed and not self.selection and self.input then\\\
  2271.         local _x = x + self.cx + ( self.lines.padding[self.cursor.y] or 0 ) + self.cursor.x - 1\\\
  2272.         local _y = y + self.cy + ( self.lines.padding.vertical or 0 ) + self.cursor.y - 1\\\
  2273.         if self.lines[self.cursor.y] then\\\
  2274.             _x = math.min( _x, x + self.cx + ( self.lines.padding[self.cursor.y] or 0 ) + #self.lines[self.cursor.y]:gsub( \\\"\\\\t\\\", \\\"    \\\" ):gsub( \\\"\\\\n$\\\", \\\"\\\" ) )\\\
  2275.         end\\\
  2276.         Gfx2D.buffer.setCursorBlink( _x, _y, self.tc )\\\
  2277.     end\\\
  2278.     Gfx2D.buffer.current():removeStencil( l )\\\
  2279. end\\\
  2280. \\\
  2281. function UIText.public:onClick( rx, ry, button )\\\
  2282.     if self.callbacks.onClick then\\\
  2283.         self.callbacks.onClick( self.public, rx, ry, button )\\\
  2284.     end\\\
  2285.     ry = math.min( ry - ( self.lines.padding.vertical or 0 ), #self.lines )\\\
  2286.     if self.lines[ry] then\\\
  2287.         rx = rx - ( self.lines.padding[ry] or 0 )\\\
  2288.     elseif #self.lines > 0 then\\\
  2289.         rx, ry = #self.lines[#self.lines]:gsub( \\\"\\\\n$\\\", \\\"\\\" ) + 1, #self.lines\\\
  2290.     else\\\
  2291.         rx, ry = 1, 1\\\
  2292.     end\\\
  2293.     self.cursor.char = self:coordsToChar( rx - self.cx, ry - self.cy )\\\
  2294.     self.public:setCursorPos( self.cursor.char )\\\
  2295.     self.selection = false\\\
  2296.     self.public:wrap()\\\
  2297. end\\\
  2298. \\\
  2299. function UIText.public:onDrag( rx, ry, button, lx, ly )\\\
  2300.     if self.callbacks.onDrag then\\\
  2301.         self.callbacks.onDrag( self.public, rx, ry, button, lx, ly )\\\
  2302.     else\\\
  2303.         ry = math.min( ry - ( self.lines.padding.vertical or 0 ), #self.lines )\\\
  2304.         if self.lines[ry] then\\\
  2305.             rx = rx - ( self.lines.padding[ry] or 0 )\\\
  2306.         elseif #self.lines > 0 then\\\
  2307.             rx, ry = #self.lines[#self.lines]:gsub( \\\"\\\\n$\\\", \\\"\\\" ) + 1, #self.lines\\\
  2308.         else\\\
  2309.             rx, ry = 1, 1\\\
  2310.         end\\\
  2311.         self.public:select( self:coordsToChar( rx - self.cx, ry - self.cy ) )\\\
  2312.     end\\\
  2313. end\\\
  2314. \\\
  2315. function UIText.public:onScroll( rx, ry, dir )\\\
  2316.     if dir == -1 and self.cy < 0 then\\\
  2317.         self.cy = self.cy + 1\\\
  2318.     elseif dir == 1 and -self.cy < self.public:getContentHeight() - self.height then\\\
  2319.         self.cy = self.cy - 1\\\
  2320.     end\\\
  2321. end\\\
  2322. \\\
  2323. function UIText.public:onKey( key, last )\\\
  2324.     local changed\\\
  2325.     if self.input and key == keys.left then\\\
  2326.         if self.selection then\\\
  2327.             self.public:setCursorPos( math.max( math.min( self.cursor.char, self.selection.char ), 1 ) )\\\
  2328.             self.selection = false\\\
  2329.             self.public:wrap()\\\
  2330.         else\\\
  2331.             self.public:setCursorPos( math.max( self.cursor.char - 1, 1 ) )\\\
  2332.         end\\\
  2333.     elseif self.input and key == keys.right then\\\
  2334.         if self.selection then\\\
  2335.             self.public:setCursorPos( math.min( math.max( self.cursor.char, self.selection.char ), #self.stream + 1 ) )\\\
  2336.             self.selection = false\\\
  2337.             self.public:wrap()\\\
  2338.         else\\\
  2339.             self.public:setCursorPos( math.min( self.cursor.char + 1, #self.stream + 1 ) )\\\
  2340.         end\\\
  2341.     elseif self.input and key == keys.up then\\\
  2342.         if self.selection then\\\
  2343.             self.public:setCursorPos( math.max( math.min( self.cursor.char, self.selection.char ), 1 ) )\\\
  2344.             self.selection = false\\\
  2345.             self.public:wrap()\\\
  2346.         elseif self.cursor.y > 1 then\\\
  2347.             self.public:setCursorPos( self.cursor.x, self.cursor.y - 1 )\\\
  2348.         end\\\
  2349.     elseif self.input and key == keys.down then\\\
  2350.         if self.selection then\\\
  2351.             self.public:setCursorPos( math.min( math.max( self.cursor.char, self.selection.char ), #self.stream + 1 ) )\\\
  2352.             self.selection = false\\\
  2353.             self.public:wrap()\\\
  2354.         elseif self.cursor.y < #self.lines then\\\
  2355.             self.public:setCursorPos( self.cursor.x, self.cursor.y + 1 )\\\
  2356.         end\\\
  2357.     elseif self.input and key == keys.home then\\\
  2358.         if self.selection then\\\
  2359.             self.public:setCursorPos( math.max( math.min( self.cursor.char, self.selection.char ), 1 ) )\\\
  2360.             self.selection = false\\\
  2361.             self.public:wrap()\\\
  2362.         else\\\
  2363.             self.public:setCursorPos( 1, self.cursor.y )\\\
  2364.         end\\\
  2365.     elseif self.input and key == keys[\\\"end\\\"] then\\\
  2366.         if self.selection then\\\
  2367.             self.public:setCursorPos( math.min( math.max( self.cursor.char, self.selection.char ), #self.stream + 1 ) )\\\
  2368.             self.selection = false\\\
  2369.             self.public:wrap()\\\
  2370.         else\\\
  2371.             self.public:setCursorPos( #( self.lines[self.cursor.y] or \\\"\\\" ):gsub( \\\"\\\\t\\\", \\\"    \\\" ) + 1, self.cursor.y )\\\
  2372.         end\\\
  2373.     elseif self.input and key == keys.enter then\\\
  2374.         if self.callbacks.onEnter then\\\
  2375.             self.callbacks.onEnter( self.public )\\\
  2376.         else\\\
  2377.             self.public:write \\\"\\\\n\\\"\\\
  2378.             changed = true\\\
  2379.         end\\\
  2380.     elseif self.input and key == keys.backspace then\\\
  2381.         if self.selection then\\\
  2382.             self.public:write \\\"\\\"\\\
  2383.         elseif self.cursor.char > 1 then\\\
  2384.             if type( self.text ) == \\\"function\\\" then\\\
  2385.                 self.text = self.text()\\\
  2386.             end\\\
  2387.             self.text = tostring( self.text ):sub( 1, self.cursor.char - 2 ) .. tostring( self.text ):sub( self.cursor.char )\\\
  2388.             self.public:setCursorPos( self.cursor.char - 1 )\\\
  2389.             self.public:reload()\\\
  2390.             self.public:wrap()\\\
  2391.         end\\\
  2392.         changed = true\\\
  2393.     elseif self.input and key == keys.delete then\\\
  2394.         if self.selection then\\\
  2395.             self.public:write \\\"\\\"\\\
  2396.         elseif #self.text > 0 then\\\
  2397.             if type( self.text ) == \\\"function\\\" then\\\
  2398.                 self.text = self.text()\\\
  2399.             end\\\
  2400.             self.text = tostring( self.text ):sub( 1, self.cursor.char - 1 ) .. tostring( self.text ):sub( self.cursor.char + 1 )\\\
  2401.             self.public:reload()\\\
  2402.             self.public:wrap()\\\
  2403.         end\\\
  2404.         changed = true\\\
  2405.     elseif self.input and key == keys.tab then\\\
  2406.         if self.selection then\\\
  2407.             local mix, miy, may, may = self:getSelectionBounds()\\\
  2408.             for i = miy, may do\\\
  2409.                 self.lines[i] = \\\"\\\\t\\\" .. self.lines[i]\\\
  2410.             end\\\
  2411.             self.text = table.concat( self.lines, \\\"\\\" )\\\
  2412.             self.public:reload()\\\
  2413.             self.public:wrap()\\\
  2414.         else\\\
  2415.             self.public:write \\\"\\\\t\\\"\\\
  2416.         end\\\
  2417.         changed = true\\\
  2418.     end\\\
  2419.     if changed then\\\
  2420.         if self.callbacks.onChange then\\\
  2421.             self.callbacks.onChange( self.public )\\\
  2422.         end\\\
  2423.     end\\\
  2424. end\\\
  2425. \\\
  2426. function UIText.public:write( text )\\\
  2427.     if not self.input then return end\\\
  2428.     if self.selection then\\\
  2429.         if type( self.text ) == \\\"function\\\" then\\\
  2430.             self.text = tostring( self.text() )\\\
  2431.         end\\\
  2432.         self.text = tostring( self.text ):sub( 1, math.min( self.selection.char, self.cursor.char ) - 1 ) .. text .. tostring( self.text ):sub( math.max( self.selection.char, self.cursor.char ) + 1 )\\\
  2433.         self.public:setCursorPos( math.min( self.selection.char, self.cursor.char ) + #text )\\\
  2434.         self.public:reload()\\\
  2435.         self.selection = false\\\
  2436.         self.public:wrap()\\\
  2437.     else\\\
  2438.         if type( self.text ) == \\\"function\\\" then\\\
  2439.             self.text = tostring( self.text() )\\\
  2440.         end\\\
  2441.         self.text = tostring( self.text ):sub( 1, self.cursor.char - 1 ) .. text .. tostring( self.text ):sub( self.cursor.char )\\\
  2442.         self.public:reload()\\\
  2443.         self.public:wrap()\\\
  2444.         self.public:setCursorPos( self.cursor.char + #text )\\\
  2445.     end\\\
  2446.     if self.callbacks.onChange then\\\
  2447.         self.callbacks.onChange( self.public )\\\
  2448.     end\\\
  2449. end\\\
  2450. \\\
  2451. function UIText.public:onFocus()\\\
  2452.     self.focussed = true\\\
  2453. end\\\
  2454. function UIText.public:onUnFocus()\\\
  2455.     self.focussed = false\\\
  2456.     if self.selection then\\\
  2457.         self.selection = false\\\
  2458.         self.public:wrap()\\\
  2459.     end\\\
  2460. end\\\
  2461. \\\
  2462. function UIText.public:getContentWidth()\\\
  2463.     local max = self.width\\\
  2464.     for i = 1, #self.lines do\\\
  2465.         max = math.max( max, #self.lines[i] )\\\
  2466.     end\\\
  2467.     return max\\\
  2468. end\\\
  2469. \\\
  2470. function UIText.public:getContentHeight()\\\
  2471.     return math.max( #self.lines, self.height )\\\
  2472. end\\\
  2473. \\\
  2474. function UIText.public:getContentHScroll()\\\
  2475.     return -self.cx\\\
  2476. end\\\
  2477. \\\
  2478. function UIText.public:getContentVScroll()\\\
  2479.     return -self.cy\\\
  2480. end\\\
  2481. \\\
  2482. function UIText.public:setContentHScroll( n )\\\
  2483.     self.cx = -n\\\
  2484. end\\\
  2485. \\\
  2486. function UIText.public:setContentVScroll( n )\\\
  2487.     self.cy = -n\\\
  2488. end\\\
  2489. \\\
  2490. function UIText.public:focusOn()\\\
  2491.     local p = self.parent\\\
  2492.     while p and p:type() ~= \\\"Window\\\" do\\\
  2493.         p = p.parent\\\
  2494.     end\\\
  2495.     if p then\\\
  2496.         p:setFocus( self.public )\\\
  2497.     else\\\
  2498.         return error \\\"no Window parent\\\"\\\
  2499.     end\\\
  2500. end\\\
  2501. \\\
  2502. return UIText\"}\
  2503. files[9]={name=\"UIVideo\";mode='api';content=\"--@meta[type]:\\\"class\\\"\\\
  2504. \\\
  2505. local UIVideo = Class \\\"UIVideo\\\"\\\
  2506. \\\
  2507. UIVideo:extends( UIElement )\\\
  2508. \\\
  2509. UIVideo.public \\\"video\\\" (Gfx2D.Video)\\\
  2510. UIVideo.public \\\"speed\\\" \\\"number\\\"\\\
  2511. UIVideo.public \\\"state\\\" \\\"string\\\"\\\
  2512. \\\
  2513. function UIVideo:UIVideo( x, y, w, h, video )\\\
  2514.     self:UIElement( x, y, w, h )\\\
  2515.     self.public.video = video\\\
  2516. \\\
  2517.     self.speed = 1\\\
  2518.     self.state = \\\"running\\\"\\\
  2519. \\\
  2520.     return self.public\\\
  2521. end\\\
  2522. \\\
  2523. function UIVideo.public:update( dt )\\\
  2524.     self.video:resize( self.width, self.height )\\\
  2525.     if self.state == \\\"running\\\" then\\\
  2526.         self.video:step( dt * self.speed )\\\
  2527.     end\\\
  2528. end\\\
  2529. \\\
  2530. function UIVideo.public:draw( x, y )\\\
  2531.     local frame = self.video:getFrame()\\\
  2532.     if frame then\\\
  2533.         frame:foreach( function( xx, yy, bc, tc, char )\\\
  2534.             Gfx2D.buffer.setPixel( x + xx - 1, y + yy - 1, bc, tc, char )\\\
  2535.         end )\\\
  2536.     else\\\
  2537.         for xx = 1, self.width do\\\
  2538.             for yy = 1, self.height do\\\
  2539.                 Gfx2D.buffer.setPixel( x + xx - 1, y + yy - 1, colours.grey, 1, \\\" \\\" )\\\
  2540.             end\\\
  2541.         end\\\
  2542.         local lines = SUtils.wordwrap( \\\"Video has finished!\\\", self.width, self.height )\\\
  2543.         y = y + math.ceil( self.height / 2 - #lines / 2 )\\\
  2544.         for i = 1, #lines do\\\
  2545.             lines[i] = lines[i]:sub( 1, self.width )\\\
  2546.             local x = x + math.ceil( self.width / 2 - #lines[i] / 2 )\\\
  2547.             for c = 1, #lines[i] do\\\
  2548.                 Gfx2D.buffer.setPixel( x, y, colours.grey, 1, lines[i]:sub( c, c ) )\\\
  2549.                 x = x + 1\\\
  2550.             end\\\
  2551.             y = y + 1\\\
  2552.         end\\\
  2553.     end\\\
  2554. end\\\
  2555. \\\
  2556. return UIVideo\"}\
  2557. apiCount=9\
  2558. dependencies[1]=\"Class.lua\"\
  2559. dependencies[2]=\"Gfx2D.lua\"\
  2560. dependencies[3]=\"Peripheral.lua\"\
  2561. dependencies[4]=\"Process.lua\"\
  2562. dependencies[5]=\"SUtils.lua\"\
  2563. dependencies[6]=\"SFormat.lua\"\
  2564. local env = setmetatable( {}, { __index = getfenv() } )\
  2565. env.global = env\
  2566. env.args = { ... }\
  2567. local public = {}\
  2568. local bloaded = _G[\"_bundleLoaded\"]\
  2569. if type( bloaded ) ~= \"table\" then bloaded = {} _G[\"_bundleLoaded\"] = bloaded end\
  2570. \
  2571. if bloaded[name] and not mainContent then\
  2572.     return bloaded[name]\
  2573. end\
  2574. \
  2575. for i = 1, #dependencies do\
  2576.     if bloaded and bloaded[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] then\
  2577.         env[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] = bloaded[dependencies[i]:gsub(\"%.lua$\", \"\", 1)]\
  2578.     else\
  2579.         local path = ( _G[\"_bundleDependencyPath\"] or \"\" ) .. \"/\" .. dependencies[i]\
  2580.         local f, err = loadfile( path )\
  2581.         if f then\
  2582.             setfenv( f, getfenv() )\
  2583.             env[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] = f()\
  2584.         else\
  2585.             error( name .. \" requires bundle '\" .. dependencies[i] .. \"'\", 0 )\
  2586.         end\
  2587.     end\
  2588. end\
  2589. for i = 1, #requires do\
  2590.     if bloaded and bloaded[requires[i]:gsub(\"%.lua$\", \"\", 1)] then\
  2591.         env[requires[i]:gsub(\"%.lua$\", \"\", 1)] = bloaded[requires[i]:gsub(\"%.lua$\", \"\", 1)]\
  2592.     else\
  2593.         local path = ( _G[\"_bundleDependencyPath\"] or \"\" ) .. \"/\" .. requires[i]\
  2594.         local f, err = loadfile( path )\
  2595.         if f then\
  2596.             setfenv( f, getfenv() )\
  2597.             env[requires[i]:gsub(\"%.lua$\", \"\", 1)] = f()\
  2598.         end\
  2599.     end\
  2600. end\
  2601. \
  2602. for i = 1, #files do\
  2603.     local f, err = loadstring( files[i].content, \"[\" .. name .. \"] \" .. files[i].name )\
  2604.     if f then\
  2605.         local e = setmetatable( {}, { __index = env } )\
  2606.         setfenv( f, e )\
  2607.         local ok, data = pcall( f, ... )\
  2608.         if not ok then\
  2609.             printError( data )\
  2610.             break\
  2611.         end\
  2612.         if data == nil then\
  2613.             data = {}\
  2614.             for k, v in pairs( e ) do\
  2615.                 data[k] = v\
  2616.             end\
  2617.         end\
  2618.         if files[i].mode == \"api\" then\
  2619.             if apiCount == 1 then\
  2620.                 public = data\
  2621.             else\
  2622.                 public[files[i].name] = data\
  2623.                 env[files[i].name] = data\
  2624.             end\
  2625.         else\
  2626.             env[files[i].name] = data\
  2627.         end\
  2628.     else\
  2629.         printError( err )\
  2630.         break\
  2631.     end\
  2632. end\
  2633. \
  2634. if mainContent then\
  2635.     local f, err = loadstring( mainContent, \"[\" .. name .. \"] main\" )\
  2636.     if f then\
  2637.         setfenv( f, env )\
  2638.         local ok, data = pcall( f, ... )\
  2639.         if not ok then\
  2640.             printError( data )\
  2641.         end\
  2642.     else\
  2643.         printError( err )\
  2644.     end\
  2645. end\
  2646. \
  2647. bloaded[name] = public\
  2648. return public";["Class.lua"]="local e={}local t={}local a={}local o local i local n=\"Class\"\
  2649. e[1]={name=\"main\",mode='api',content=\"local e={}\\\
  2650. function e.new(t)local a={}local o={}a.public={}a.private={}a.static={}a.name=t\\\
  2651. a.extends=false a.class=o o.name=t local i=false local n=false local s={}\\\
  2652. function o:new(...)local r={}local d={}r.class=o r.public=d\\\
  2653. setmetatable(r,{__index=a.private})function d:type(c)return r.class:type(c)end function d:typeOf(e)return\\\
  2654. r.class:typeOf(e)end local l={}\\\
  2655. l.__index=function(c,m)\\\
  2656. if a.public[m]then\\\
  2657. if\\\
  2658. a.public[m].read then local f\\\
  2659. if i then if type(i)==\\\"function\\\"then return i(r,m)else return i[m]end elseif\\\
  2660. type(a.public[m].read)==\\\"function\\\"then f=a.public[m].read(r)elseif\\\
  2661. a.public[m].value~=nil then f=a.public[m].value else f=r[m]end\\\
  2662. if type(f)==\\\"function\\\"then return\\\
  2663. function(w,...)if w==d then return f(r,...)end return f(w,...)end end return f else error(\\\"variable has no read access\\\",2)end elseif i then if type(i)==\\\"function\\\"then return i(r,m)else return i[m]end else\\\
  2664. error(\\\
  2665. \\\"no such variable \\\\\\\"\\\"..tostring(m)..\\\"\\\\\\\"\\\",2)end end\\\
  2666. l.__newindex=function(c,m,f)\\\
  2667. if a.public[m]then\\\
  2668. if a.public[m].write then\\\
  2669. if n then if type(n)==\\\"function\\\"then return n(r,m,f)else\\\
  2670. n[m]=f end elseif\\\
  2671. type(a.public[m].write)==\\\"function\\\"then a.public[m].write(r,f)else r[m]=f end else error(\\\"variable has no write access\\\",2)end else\\\
  2672. error(\\\"no such variable \\\\\\\"\\\"..tostring(m)..\\\"\\\\\\\"\\\",2)end end l.__tostring=function()return a.name end\\\
  2673. l.__metatable={SwiftClassObject=true,__type=a.name}for c,m in pairs(s)do l[\\\"__\\\"..tostring(c)]=m end\\\
  2674. setmetatable(d,l)local u=a while true do if type(u.private[u.name])==\\\"function\\\"then return\\\
  2675. u.private[u.name](r,...)end\\\
  2676. if u.extends then u=u.extends else break end end return d end\\\
  2677. function o:type(r)local d=\\\"\\\"if r then local l=a.extends\\\
  2678. while l do d=l.name..\\\".\\\"..d l=l.extends end end return d..a.name end\\\
  2679. function o:typeOf(r)\\\
  2680. if type(r)==\\\"table\\\"then\\\
  2681. if pcall(function()\\\
  2682. assert(getmetatable(r).SwiftClass)end,\\\"err\\\")then local d=a while d do if d.class==r then\\\
  2683. return true end d=d.extends end end end return false end function o:extends(r)r:extend(a)end\\\
  2684. function o:extend(r)\\\
  2685. setmetatable(r.static,{__index=a.static})setmetatable(r.public,{__index=a.public})\\\
  2686. setmetatable(r.private,{__index=a.private})r.extends=a end local h={}\\\
  2687. h.__index=function(r,d)\\\
  2688. if d==\\\"static\\\"then return\\\
  2689. setmetatable({},{__newindex=function(r,d,l)a.static[d]=l end,__metatable={}})elseif d==\\\"public\\\"then\\\
  2690. return\\\
  2691. setmetatable({},{__newindex=function(r,d,l)\\\
  2692. a.public[d]={read=true,write=false,value=l}end,__call=function(r,d)\\\
  2693. a.public[d]={read=true,write=true,value=nil}\\\
  2694. return\\\
  2695. function(l)local u={l}\\\
  2696. a.public[d].write=function(m,f)\\\
  2697. for i=1,#u do if e.typeOf(f,u[i])then m[d]=f return end end if e.type(u[1])==\\\"Class\\\"then\\\
  2698. error(\\\"expected \\\"..u[1]:type()..\\\" \\\"..d,3)else\\\
  2699. error(\\\"expected \\\"..tostring(u[1])..\\\" \\\"..d,3)end end local function c(l)table.insert(u,l)return c end return c end end,__index=function(r,d)\\\
  2700. if\\\
  2701. a.public[d]then\\\
  2702. return\\\
  2703. setmetatable({},{__newindex=function(r,t,l)\\\
  2704. if t==\\\"read\\\"then\\\
  2705. if type(l)==\\\"boolean\\\"or type(l)==\\\"function\\\"then\\\
  2706. a.public[d].read=l else error(\\\"invalid modifier value\\\",2)end elseif t==\\\"write\\\"then\\\
  2707. if type(l)==\\\"boolean\\\"or type(l)==\\\"function\\\"then\\\
  2708. a.public[d].write=l else error(\\\"invalid modifier value\\\",2)end else error(\\\"invalid modifier name\\\",2)end end,__metatable={}})else\\\
  2709. error(\\\"public index \\\"..tostring(d)..\\\" not found\\\",2)end end,__metatable={}})elseif d==\\\"meta\\\"then\\\
  2710. return\\\
  2711. setmetatable({},{__index=function(r,d)\\\
  2712. if d==\\\"index\\\"then return i elseif d==\\\"newindex\\\"then return n else return s[d]end end,__newindex=function(r,d,l)\\\
  2713. if d==\\\"metatable\\\"then\\\
  2714. error(\\\"cannot change this metamethod\\\",2)elseif d==\\\"index\\\"then if\\\
  2715. type(l)==\\\"function\\\"or type(l)==\\\"table\\\"or l==nil then i=l else\\\
  2716. error(\\\"cannot use type \\\"..type(l)..\\\" for index metamethod\\\",2)end elseif\\\
  2717. d==\\\"newindex\\\"then if\\\
  2718. type(l)==\\\"function\\\"or type(l)==\\\"table\\\"or l==nil then n=l else\\\
  2719. error(\\\"cannot use type \\\"..type(l)..\\\" for newindex metamethod\\\",2)end else s[d]=l end end,__metatable={}})else return a.static[d]end end h.__newindex=function(r,d,l)a.private[d]=l end h.__call=function(r,...)return\\\
  2720. r:new(...)end\\\
  2721. h.__tostring=function()return\\\"Class\\\"end h.__metatable={SwiftClass=true,__type=\\\"Class\\\"}\\\
  2722. setmetatable(o,h)return o end function e.public(t)local a=e.new(t)getfenv()[t]=a end\\\
  2723. function e.type(t)\\\
  2724. if\\\
  2725. type(t)==\\\"table\\\"then\\\
  2726. if pcall(function()\\\
  2727. assert(getmetatable(t).SwiftClass)end,\\\"err\\\")then return\\\"Class\\\"end if pcall(function()\\\
  2728. assert(getmetatable(t).SwiftClassObject)end,\\\"err\\\")then\\\
  2729. return t:type()end end return type(t)end\\\
  2730. function e.typeOf(t,...)local a={...}\\\
  2731. for i=1,#a do\\\
  2732. if\\\
  2733. type(t)==\\\"table\\\"and pcall(function()\\\
  2734. assert(getmetatable(t).SwiftClassObject)end,\\\"err\\\")then if t:typeOf(a[i])then return a[i]end elseif\\\
  2735. type(t)==\\\"table\\\"and pcall(function()\\\
  2736. assert(getmetatable(t).SwiftClass)end,\\\"err\\\")then if a[i]==\\\"Class\\\"then return\\\"Class\\\"end else\\\
  2737. if type(t)==a[i]then return a[i]end end end return false end\\\
  2738. setmetatable(e,{__call=function(t,...)return e.new(...)end})return e\"}i=1 local s=setmetatable({},{__index=getfenv()})\
  2739. s.global=s s.args={...}local h={}local r=_G[\"_bundleLoaded\"]if type(r)~=\"table\"then r={}\
  2740. _G[\"_bundleLoaded\"]=r end if r[n]and not o then return r[n]end\
  2741. for i=1,#t do\
  2742. if r and\
  2743. r[t[i]:gsub(\"%.lua$\",\"\",1)]then\
  2744. s[t[i]:gsub(\"%.lua$\",\"\",1)]=r[t[i]:gsub(\"%.lua$\",\"\",1)]else\
  2745. local d=(_G[\"_bundleDependencyPath\"]or\"\")..\"/\"..t[i]local l,u=loadfile(d)if l then setfenv(l,getfenv())\
  2746. s[t[i]:gsub(\"%.lua$\",\"\",1)]=l()else\
  2747. error(n..\" requires bundle '\"..t[i]..\"'\",0)end end end\
  2748. for i=1,#a do\
  2749. if r and r[a[i]:gsub(\"%.lua$\",\"\",1)]then\
  2750. s[a[i]:gsub(\"%.lua$\",\"\",1)]=r[a[i]:gsub(\"%.lua$\",\"\",1)]else\
  2751. local d=(_G[\"_bundleDependencyPath\"]or\"\")..\"/\"..a[i]local l,u=loadfile(d)if l then setfenv(l,getfenv())\
  2752. s[a[i]:gsub(\"%.lua$\",\"\",1)]=l()end end end\
  2753. for i=1,#e do\
  2754. local d,l=loadstring(e[i].content,\"[\"..n..\"] \"..e[i].name)\
  2755. if d then local u=setmetatable({},{__index=s})setfenv(d,u)\
  2756. local c,m=pcall(d,...)if not c then printError(m)break end if m==nil then m={}\
  2757. for f,w in pairs(u)do m[f]=w end end\
  2758. if e[i].mode==\"api\"then if i==1 then h=m else h[e[i].name]=m\
  2759. s[e[i].name]=m end else s[e[i].name]=m end else printError(l)break end end\
  2760. if o then local d,l=loadstring(o,\"[\"..n..\"] main\")if d then\
  2761. setfenv(d,s)local u,c=pcall(d,...)if not u then printError(c)end else\
  2762. printError(l)end end r[n]=h return h";["Gfx2D.lua"]="local files={}\
  2763. local dependencies={}\
  2764. local requires={}\
  2765. local mainContent\
  2766. local apiCount\
  2767. local name=\"Gfx2D\"\
  2768. files[1]={name=\"pixeldata\";mode='lib';content=\"\\\
  2769. return function( width, height )\\\
  2770.     local t = {}\\\
  2771. \\\
  2772.     t.width = width\\\
  2773.     t.height = height\\\
  2774. \\\
  2775.     for y = 1, height do\\\
  2776.         t[y] = {}\\\
  2777.         for x = 1, width do\\\
  2778.             t[y][x] = { bc = 1, tc = 1, char = \\\" \\\" }\\\
  2779.         end\\\
  2780.     end\\\
  2781. \\\
  2782.     function t:setPixel( x, y, bc, tc, char )\\\
  2783.         x, y = math.floor( x + 0.5 ), math.floor( y + 0.5 )\\\
  2784.         if self[y] and self[y][x] then\\\
  2785.             local _bc, _tc, _char = self:getPixel( x, y )\\\
  2786.             if type( bc ) == \\\"function\\\" then bc = bc( _bc ) end\\\
  2787.             if bc == 0 then bc = _bc end\\\
  2788.             if type( tc ) == \\\"function\\\" then tc = tc( _tc ) end\\\
  2789.             if tc == 0 then tc, char = _tc, _char end\\\
  2790.             if char ~= \\\"\\\" then\\\
  2791.                 self[y][x].bc = bc\\\
  2792.                 self[y][x].tc = tc\\\
  2793.                 self[y][x].char = char\\\
  2794.             end\\\
  2795.             return true\\\
  2796.         end\\\
  2797.         return false\\\
  2798.     end\\\
  2799.     function t:getPixel( x, y )\\\
  2800.         x, y = math.floor( x + 0.5 ), math.floor( y + 0.5 )\\\
  2801.         if self[y] and self[y][x] then\\\
  2802.             return self[y][x].bc, self[y][x].tc, self[y][x].char\\\
  2803.         end\\\
  2804.     end\\\
  2805. \\\
  2806.     function t:resize( width, height, bc, tc, char )\\\
  2807.         bc = bc or 1\\\
  2808.         tc = tc or 1\\\
  2809.         char = char or \\\" \\\"\\\
  2810.         while self.height < height do\\\
  2811.             local t = {}\\\
  2812.             for i = 1, self.width do\\\
  2813.                 t[i] = { bc = bc, tc = tc, char = char }\\\
  2814.             end\\\
  2815.             table.insert( self, t )\\\
  2816.             if self.last then\\\
  2817.                 local t2 = {}\\\
  2818.                 for i = 1, self.width do\\\
  2819.                     t2[i] = { bc = bc + 1, tc = tc + 1 }\\\
  2820.                 end\\\
  2821.                 table.insert( self.last, t2 )\\\
  2822.             end\\\
  2823.             self.height = self.height + 1\\\
  2824.         end\\\
  2825.         while self.height > height do\\\
  2826.             table.remove( self, #self )\\\
  2827.             if self.last then\\\
  2828.                 table.remove( self.last, #self.last )\\\
  2829.             end\\\
  2830.             self.height = self.height - 1\\\
  2831.         end\\\
  2832.         while self.width < width do\\\
  2833.             for i = 1, self.height do\\\
  2834.                 table.insert( self[i], { bc = bc, tc = tc, char = char } )\\\
  2835.                 if self.last then\\\
  2836.                     table.insert( self.last[i], { bc = bc + 1, tc = tc + 1 } )\\\
  2837.                 end\\\
  2838.             end\\\
  2839.             self.width = self.width + 1\\\
  2840.         end\\\
  2841.         while self.width > width do\\\
  2842.             for i = 1, self.height do\\\
  2843.                 table.remove( self[i], #self[i] )\\\
  2844.                 if self.last then\\\
  2845.                     table.remove( self.last[i], #self.last[i] )\\\
  2846.                 end\\\
  2847.             end\\\
  2848.             self.width = self.width - 1\\\
  2849.         end\\\
  2850.     end\\\
  2851. \\\
  2852.     function t:foreach( f )\\\
  2853.         for x = 1, self.width do\\\
  2854.             for y = 1, self.height do\\\
  2855.                 local bc, tc, char = self:getPixel( x, y )\\\
  2856.                 local _bc, _tc, _char = f( bc, tc, char, x, y )\\\
  2857.                 _bc = _bc or bc\\\
  2858.                 _tc = _tc or tc\\\
  2859.                 _char = _char or char\\\
  2860.                 if _bc ~= bc or _tc ~= tc or _char ~= char then\\\
  2861.                     self:setPixel( x, y, _bc, _tc, _char )\\\
  2862.                 end\\\
  2863.             end\\\
  2864.         end\\\
  2865.     end\\\
  2866. \\\
  2867.     return t\\\
  2868. end\"}\
  2869. files[2]={name=\"mode\";mode='api';content=\"\\\
  2870. local bc = 1\\\
  2871. local tc = 1\\\
  2872. local char = \\\" \\\"\\\
  2873. local pixel = function( x, y, bc, tc, char )\\\
  2874.     return buffer.setPixel( x, y, bc, tc, char )\\\
  2875. end\\\
  2876. \\\
  2877. function getMode()\\\
  2878.     return bc, tc, char\\\
  2879. end\\\
  2880. \\\
  2881. function setMode( b, t, c )\\\
  2882.     bc, tc, char = b or bc, t or tc, c or char\\\
  2883. end\\\
  2884. \\\
  2885. function getPixelFunction()\\\
  2886.     return pixel\\\
  2887. end\\\
  2888. function setPixelFunction( f )\\\
  2889.     pixel = f\\\
  2890. end\"}\
  2891. files[3]={name=\"shader\";mode='api';content=\"--@meta[type]:\\\"lib\\\"\\\
  2892. \\\
  2893. local maps = {}\\\
  2894. maps.darken = {\\\
  2895.     [colours.white] = colours.lightGrey, [colours.orange] = colours.red, [colours.magenta] = colours.purple, [colours.lightBlue] = colours.cyan;\\\
  2896.     [colours.yellow] = colours.orange, [colours.lime] = colours.green, [colours.pink] = colours.magenta, [colours.grey] = colours.black;\\\
  2897.     [colours.lightGrey] = colours.grey, [colours.cyan] = colours.blue, [colours.purple] = colours.black, [colours.blue] = colours.black;\\\
  2898.     [colours.brown] = colours.black, [colours.green] = colours.black, [colours.red] = colours.brown, [colours.black] = colours.black;\\\
  2899. }\\\
  2900. maps.lighten = {\\\
  2901.     [colours.white] = colours.white, [colours.orange] = colours.yellow, [colours.magenta] = colours.pink, [colours.lightBlue] = colours.white;\\\
  2902.     [colours.yellow] = colours.white, [colours.lime] = colours.white, [colours.pink] = colours.white, [colours.grey] = colours.lightGrey;\\\
  2903.     [colours.lightGrey] = colours.white, [colours.cyan] = colours.lightBlue, [colours.purple] = colours.magenta, [colours.blue] = colours.cyan;\\\
  2904.     [colours.brown] = colours.red, [colours.green] = colours.lime, [colours.red] = colours.orange, [colours.black] = colours.grey;\\\
  2905. }\\\
  2906. maps.greyscale = {\\\
  2907.     [colours.white] = 1, [colours.orange] = 256, [colours.magenta] = 256, [colours.lightBlue] = 256;\\\
  2908.     [colours.yellow] = 1, [colours.lime] = 256, [colours.pink] = 1, [colours.grey] = 256;\\\
  2909.     [colours.lightGrey] = 256, [colours.cyan] = 128, [colours.purple] = 128, [colours.blue] = 32768;\\\
  2910.     [colours.brown] = 32768, [colours.green] = 128, [colours.red] = 128, [colours.black] = 32768;\\\
  2911. }\\\
  2912. maps.sepia = {\\\
  2913.     [colours.white] = 1, [colours.orange] = 2, [colours.magenta] = 2, [colours.lightBlue] = 2;\\\
  2914.     [colours.yellow] = 1, [colours.lime] = 2, [colours.pink] = 1, [colours.grey] = 2;\\\
  2915.     [colours.lightGrey] = 2, [colours.cyan] = 16, [colours.purple] = 16, [colours.blue] = 4096;\\\
  2916.     [colours.brown] = 4096, [colours.green] = 16, [colours.red] = 16, [colours.black] = 4096;\\\
  2917. }\\\
  2918. --[[\\\
  2919. maps.inverse = {\\\
  2920.     [colours.white] = colours.black, [colours.orange] = colours.purple, [colours.magenta] = colours.yellow, [colours.lightBlue] = colours.orange;\\\
  2921.     [colours.yellow] = colours.magenta, [colours.lime] = colours.red, \\\
  2922.     \\\
  2923.     TODO:\\\
  2924.     [colours.pink] = colours.white, [colours.grey] = colours.lightGrey;\\\
  2925.     [colours.lightGrey] = colours.white, [colours.cyan] = colours.lightBlue, [colours.purple] = colours.magenta, [colours.blue] = colours.cyan;\\\
  2926.     [colours.brown] = colours.red, [colours.green] = colours.orange, [colours.red] = colours.lime, [colours.black] = colours.white;\\\
  2927. }\\\
  2928. ]]\\\
  2929. \\\
  2930. function darken( col )\\\
  2931.     return maps.darken[col] or 0\\\
  2932. end\\\
  2933. \\\
  2934. function lighten( col )\\\
  2935.     return maps.lighten[col] or 0\\\
  2936. end\\\
  2937. \\\
  2938. function greyscale( col )\\\
  2939.     return maps.greyscale[col] or 0\\\
  2940. end\\\
  2941. \\\
  2942. function sepia( col )\\\
  2943.     return maps.sepia[col] or 0\\\
  2944. end\\\
  2945. \\\
  2946. --[[\\\
  2947. function inverse( col )\\\
  2948.     return maps.inverse[col] or 0\\\
  2949. end\\\
  2950. ]]\"}\
  2951. files[4]={name=\"buffer\";mode='api';content=\"--@meta[type]:\\\"lib\\\"\\\
  2952. \\\
  2953. local c\\\
  2954. \\\
  2955. local buffer = {}\\\
  2956. \\\
  2957. function buffer.create( w, h )\\\
  2958. \\\
  2959.     local pixels = pixeldata( w, h )\\\
  2960.     pixels.last = {}\\\
  2961.     for y = 1, h do\\\
  2962.         pixels.last[y] = {}\\\
  2963.         for x = 1, w do\\\
  2964.             pixels.last[y][x] = { }\\\
  2965.         end\\\
  2966.     end\\\
  2967. \\\
  2968.     local buffer = setmetatable( {}, { __type = \\\"buffer\\\" } )\\\
  2969.     buffer.textScale = 1\\\
  2970.     buffer.allchanged = false\\\
  2971.     buffer.cursor = false\\\
  2972. \\\
  2973.     buffer.pixels = pixels\\\
  2974. \\\
  2975.     buffer.stencils = {}\\\
  2976.     buffer.stencil = false\\\
  2977. \\\
  2978.     function buffer:setPixel( x, y, bc, tc, char )\\\
  2979.         x, y = math.floor( x + 0.5 ), math.floor( y + 0.5 )\\\
  2980.         if self.stencil then\\\
  2981.             if x < self.stencil.x or y < self.stencil.y\\\
  2982.             or x >= self.stencil.x + self.stencil.w\\\
  2983.             or y >= self.stencil.y + self.stencil.h then\\\
  2984.                 return false\\\
  2985.             end\\\
  2986.         end\\\
  2987.         if self.pixels[y] and self.pixels[y][x] then\\\
  2988.             local _bc, _tc, _char = self.pixels:getPixel( x, y )\\\
  2989.             if type( bc ) == \\\"function\\\" then bc = bc( _bc ) end\\\
  2990.             if bc == 0 then bc = _bc end\\\
  2991.             if type( tc ) == \\\"function\\\" then tc = tc( _tc ) end\\\
  2992.             if tc == 0 then tc, char = _tc, _char end\\\
  2993.             if char ~= \\\"\\\" then\\\
  2994.                 self.pixels[y][x].bc = bc\\\
  2995.                 self.pixels[y][x].tc = tc\\\
  2996.                 self.pixels[y][x].char = char\\\
  2997.             end\\\
  2998.             return true\\\
  2999.         end\\\
  3000.         return false\\\
  3001.     end\\\
  3002.     function buffer:getPixel( x, y )\\\
  3003.         return self.pixels:getPixel( x, y )\\\
  3004.     end\\\
  3005.     function buffer:clear( bc, tc, char )\\\
  3006.         bc = bc or 1\\\
  3007.         tc = tc or 1\\\
  3008.         char = char or \\\" \\\"\\\
  3009.         for y = 1, self.pixels.height do\\\
  3010.             for x = 1, self.pixels.width do\\\
  3011.                 self.pixels:setPixel( x, y, bc, tc, char )\\\
  3012.             end\\\
  3013.         end\\\
  3014.     end\\\
  3015.     function buffer:foreach( f )\\\
  3016.         return self.pixels:foreach( f )\\\
  3017.     end\\\
  3018. \\\
  3019.     function buffer:setStencil( x, y, w, h )\\\
  3020.         if x then\\\
  3021.             self.stencil = { x = x, y = y, w = w, h = h }\\\
  3022.         else\\\
  3023.             self.stencil = false\\\
  3024.         end\\\
  3025.     end\\\
  3026.     function buffer:addStencil( x, y, w, h )\\\
  3027.         table.insert( self.stencils, { x = x, y = y, w = w, h = h } )\\\
  3028.         if self.stencil then\\\
  3029.             local xx, yy = math.max( x, self.stencil.x ), math.max( y, self.stencil.y )\\\
  3030.             local x2, y2 = math.min( x + w, self.stencil.x + self.stencil.w ) - 1, math.min( y + h, self.stencil.y + self.stencil.h ) - 1\\\
  3031.             self:setStencil( xx, yy, x2 - xx + 1, y2 - yy + 1 )\\\
  3032.         else\\\
  3033.             self:setStencil( x, y, w, h )\\\
  3034.         end\\\
  3035.         return #self.stencils\\\
  3036.     end\\\
  3037.     function buffer:removeStencil( index )\\\
  3038.         while self.stencils[index] do\\\
  3039.             table.remove( self.stencils, index )\\\
  3040.         end\\\
  3041.         self:setStencil()\\\
  3042.         for i, v in ipairs( self.stencils ) do\\\
  3043.             self:addStencil( v.x, v.y, v.w, v.h )\\\
  3044.             table.remove( self.stencils, #self.stencils )\\\
  3045.         end\\\
  3046.     end\\\
  3047. \\\
  3048.     function buffer:setCursorBlink( x, y, tc )\\\
  3049.         if x then\\\
  3050.             x, y = math.floor( x + 0.5 ), math.floor( y + 0.5 )\\\
  3051.             self.cursor = { x = x, y = y, tc = tc or 1 }\\\
  3052.         else\\\
  3053.             self.cursor = false\\\
  3054.         end\\\
  3055.     end\\\
  3056. \\\
  3057.     function buffer:hasChanged( x, y )\\\
  3058.         x, y = math.floor( x + 0.5 ), math.floor( y + 0.5 )\\\
  3059.         if not y then\\\
  3060.             for i = 1, self.width do\\\
  3061.                 if self:hasChanged( i, x ) then\\\
  3062.                     return true\\\
  3063.                 end\\\
  3064.             end\\\
  3065.         end\\\
  3066.         if self.pixels[y] and self.pixels[y][x] then\\\
  3067.             return self.pixels[y][x].bc ~= self.pixels.last[y][x].bc\\\
  3068.             or self.pixels[y][x].char ~= self.pixels.last[y][x].char\\\
  3069.             or ( self.pixels[y][x].tc ~= self.pixels.last[y][x].tc and self.pixels[y][x].char ~= \\\" \\\" )\\\
  3070.         end\\\
  3071.     end\\\
  3072.     function buffer:draw( target, _x, _y )\\\
  3073.         if self.allchanged then\\\
  3074.             return self:drawAll()\\\
  3075.         end\\\
  3076.         target = target or term\\\
  3077.         _x = _x or 1\\\
  3078.         _y = _y or 1\\\
  3079.         if target.setTextScale then\\\
  3080.             target.setTextScale( self.textScale )\\\
  3081.         end\\\
  3082.         for y = 1, self.pixels.height do\\\
  3083.             local last\\\
  3084.             for x = 1, self.pixels.width do\\\
  3085.                 if self:hasChanged( x, y ) then\\\
  3086.                     if last then\\\
  3087.                         if last.bc == self.pixels[y][x].bc and ( last.tc == self.pixels[y][x].tc or self.pixels[y][x].char == \\\" \\\" ) then\\\
  3088.                             last.char = last.char .. self.pixels[y][x].char\\\
  3089.                         else\\\
  3090.                             target.setCursorPos( last.x + _x - 1, last.y + _y - 1 )\\\
  3091.                             target.setBackgroundColour( last.bc )\\\
  3092.                             target.setTextColour( last.tc )\\\
  3093.                             target.write( last.char )\\\
  3094.                             last = { x = x, y = y, bc = self.pixels[y][x].bc, tc = self.pixels[y][x].tc, char = self.pixels[y][x].char }\\\
  3095.                         end\\\
  3096.                     else\\\
  3097.                         last = { x = x, y = y, bc = self.pixels[y][x].bc, tc = self.pixels[y][x].tc, char = self.pixels[y][x].char }\\\
  3098.                     end\\\
  3099.                     self.pixels.last[y][x] = { bc = self.pixels[y][x].bc, tc = self.pixels[y][x].tc, char = self.pixels[y][x].char }\\\
  3100.                 elseif last then\\\
  3101.                     target.setCursorPos( last.x + _x - 1, last.y + _y - 1 )\\\
  3102.                     target.setBackgroundColour( last.bc )\\\
  3103.                     target.setTextColour( last.tc )\\\
  3104.                     target.write( last.char )\\\
  3105.                     last = nil\\\
  3106.                 end\\\
  3107.             end\\\
  3108.             if last then\\\
  3109.                 target.setCursorPos( last.x + _x - 1, last.y + _y - 1 )\\\
  3110.                 target.setBackgroundColour( last.bc )\\\
  3111.                 target.setTextColour( last.tc )\\\
  3112.                 target.write( last.char )\\\
  3113.             end\\\
  3114.         end\\\
  3115.         if self.cursor then\\\
  3116.             target.setCursorPos( _x + self.cursor.x - 1, _y + self.cursor.y - 1 )\\\
  3117.             target.setTextColour( self.cursor.tc )\\\
  3118.             target.setCursorBlink( true )\\\
  3119.         else\\\
  3120.             target.setCursorBlink( false )\\\
  3121.         end\\\
  3122.     end\\\
  3123.     function buffer:drawAll( target, _x, _y )\\\
  3124.         self.allchanged = false\\\
  3125.         target = target or term\\\
  3126.         _x = _x or 1\\\
  3127.         _y = _y or 1\\\
  3128.         if target.setTextScale then\\\
  3129.             target.setTextScale( self.textScale )\\\
  3130.         end\\\
  3131.         for y = 1, self.pixels.height do\\\
  3132.             target.setCursorPos( _x, y + _y - 1 )\\\
  3133.             for x = 1, self.pixels.width do\\\
  3134.                 local bc, tc, char = self.pixels:getPixel( x, y )\\\
  3135.                 target.setBackgroundColour( bc )\\\
  3136.                 target.setTextColour( tc )\\\
  3137.                 target.write( char )\\\
  3138.                 if char == \\\"\\\" then\\\
  3139.                     target.setCursorPos( _x + x, y + _y - 1 )\\\
  3140.                 end\\\
  3141.             end\\\
  3142.         end\\\
  3143.         if self.cursor then\\\
  3144.             target.setCursorPos( _x + self.cursor.x - 1, _y + self.cursor.y - 1 )\\\
  3145.             target.setTextColour( self.cursor.tc )\\\
  3146.             target.setCursorBlink( true )\\\
  3147.         else\\\
  3148.             target.setCursorBlink( false )\\\
  3149.         end\\\
  3150.     end\\\
  3151. \\\
  3152.     function buffer:resize( width, height, bc, tc, char )\\\
  3153.         return self.pixels:resize( width, height, bc, tc, char )\\\
  3154.     end\\\
  3155. \\\
  3156.     function buffer:redirect()\\\
  3157.         c = self\\\
  3158.     end\\\
  3159. \\\
  3160.     return buffer\\\
  3161. end\\\
  3162. \\\
  3163. local methods = {\\\
  3164.     \\\"setPixel\\\";\\\
  3165.     \\\"getPixel\\\";\\\
  3166.     \\\"clear\\\";\\\
  3167.     \\\"foreach\\\";\\\
  3168.     \\\"setStencil\\\";\\\
  3169.     \\\"addStencil\\\";\\\
  3170.     \\\"removeStencil\\\";\\\
  3171.     \\\"setCursorBlink\\\";\\\
  3172.     \\\"draw\\\";\\\
  3173.     \\\"drawAll\\\";\\\
  3174.     \\\"resize\\\";\\\
  3175. }\\\
  3176. \\\
  3177. function buffer.setPixel( ... )\\\
  3178.     return c:setPixel( ... )\\\
  3179. end\\\
  3180. function buffer.getPixel( ... )\\\
  3181.     return c:getPixel( ... )\\\
  3182. end\\\
  3183. \\\
  3184. function buffer.setCursorBlink( ... )\\\
  3185.     return c:setCursorBlink( ... )\\\
  3186. end\\\
  3187. \\\
  3188. function buffer.redirect( buffer )\\\
  3189.     if type( buffer ) ~= \\\"table\\\" then\\\
  3190.         return error( \\\"expected (table) buffer, got \\\" .. type( buffer ) )\\\
  3191.     end\\\
  3192.     for i = 1, #methods do\\\
  3193.         if type( buffer[methods[i]] ) ~= \\\"function\\\" then\\\
  3194.             return error( \\\"buffer missing method \\\" .. methods[i] )\\\
  3195.         end\\\
  3196.     end\\\
  3197.     local old = c\\\
  3198.     c = buffer\\\
  3199.     return old\\\
  3200. end\\\
  3201. function buffer.current( )\\\
  3202.     return c\\\
  3203. end\\\
  3204. \\\
  3205. c = buffer.create( term.getSize() )\\\
  3206. \\\
  3207. return setmetatable( buffer, { __call = function( self, ... ) return self.create( ... ) end } )\"}\
  3208. files[5]={name=\"Image\";mode='api';content=\"\\\
  3209. local colourLookup = {\\\
  3210.     [\\\"0\\\"] = colours.white;\\\
  3211.     [\\\"1\\\"] = colours.orange;\\\
  3212.     [\\\"2\\\"] = colours.magenta;\\\
  3213.     [\\\"3\\\"] = colours.lightBlue;\\\
  3214.     [\\\"4\\\"] = colours.yellow;\\\
  3215.     [\\\"5\\\"] = colours.lime;\\\
  3216.     [\\\"6\\\"] = colours.pink;\\\
  3217.     [\\\"7\\\"] = colours.grey;\\\
  3218.     [\\\"8\\\"] = colours.lightGrey;\\\
  3219.     [\\\"9\\\"] = colours.cyan;\\\
  3220.     [\\\"A\\\"] = colours.purple;\\\
  3221.     [\\\"B\\\"] = colours.blue;\\\
  3222.     [\\\"C\\\"] = colours.brown;\\\
  3223.     [\\\"D\\\"] = colours.green;\\\
  3224.     [\\\"E\\\"] = colours.red;\\\
  3225.     [\\\"F\\\"] = colours.black;\\\
  3226.     [\\\" \\\"] = 0;\\\
  3227. }\\\
  3228. \\\
  3229. local colourSave = { }\\\
  3230. for k, v in pairs( colourLookup ) do\\\
  3231.     colourSave[v] = k\\\
  3232. end\\\
  3233. \\\
  3234. local Image = Class \\\"Image\\\"\\\
  3235. \\\
  3236. function Image:Image( w, h )\\\
  3237.     self.pixels = pixeldata( w, h )\\\
  3238. \\\
  3239.     return self.public\\\
  3240. end\\\
  3241. \\\
  3242. function Image.public:setPixel( x, y, bc, tc, char )\\\
  3243.     return self.pixels:setPixel( x, y, bc, tc, char )\\\
  3244. end\\\
  3245. \\\
  3246. function Image.public:getPixel( x, y )\\\
  3247.     return self.pixels:getPixel( x, y )\\\
  3248. end\\\
  3249. \\\
  3250. function Image.public:foreach( f )\\\
  3251.     return self.pixels:foreach( f )\\\
  3252. end\\\
  3253. \\\
  3254. function Image.public:savestr( str )\\\
  3255.     local w, h = #( self.pixels[1] or { } ), #self.pixels\\\
  3256.     local str = \\\"\\\"\\\
  3257.     for y = 1, h do\\\
  3258.         for x = 1, w do\\\
  3259.             local bc = colourSave[self.pixels[y][x].bc]\\\
  3260.             local tc = colourSave[self.pixels[y][x].tc]\\\
  3261.             local char = self.pixels[y][x].char\\\
  3262.             if #char == 0 then\\\
  3263.                 char = \\\" \\\"\\\
  3264.                 bc = colourSave[0]\\\
  3265.             end\\\
  3266.             str = str .. bc .. tc .. char\\\
  3267.         end\\\
  3268.         str = str .. \\\"\\\\n\\\"\\\
  3269.     end\\\
  3270.     return str:sub( 1, -2 )\\\
  3271. end\\\
  3272. \\\
  3273. function Image.public:loadstr( str )\\\
  3274.     local lines = { }\\\
  3275.     local last = 1\\\
  3276.     for i = 1, #str do\\\
  3277.         if str:sub( i, i ) == \\\"\\\\n\\\" then\\\
  3278.             table.insert( lines, str:sub( last, i - 1 ) )\\\
  3279.             last = i + 1\\\
  3280.         end\\\
  3281.     end\\\
  3282.     table.insert( lines, str:sub( last ) )\\\
  3283.     local width = #lines[1] / 3\\\
  3284.     local height = #lines\\\
  3285.     self.public:resize( width, height )\\\
  3286.     for i = 1, #lines do\\\
  3287.         local x = 1\\\
  3288.         for pixel in lines[i]:gmatch( \\\"[0123456789ABCDEF ][0123456789ABCDEF ].\\\" ) do\\\
  3289.             local bc = pixel:sub( 1, 1 )\\\
  3290.             local tc = pixel:sub( 2, 2 )\\\
  3291.             local ch = pixel:sub( 3, 3 )\\\
  3292.             if self.pixels[i] and self.pixels[i][x] then\\\
  3293.                 self.pixels[i][x] = {\\\
  3294.                     bc = colourLookup[bc];\\\
  3295.                     tc = colourLookup[tc];\\\
  3296.                     char = ch;\\\
  3297.                 }\\\
  3298.             end\\\
  3299.             x = x + 1\\\
  3300.         end\\\
  3301.     end\\\
  3302.     return self.public\\\
  3303. end\\\
  3304. \\\
  3305. function Image.public:resize( w, h, bc, tc, char )\\\
  3306.     return self.pixels:resize( w, h, bc, tc, char )\\\
  3307. end\\\
  3308. \\\
  3309. function Image.public:getSize()\\\
  3310.     return self.pixels.width, self.pixels.height\\\
  3311. end\\\
  3312. \\\
  3313. return Image\"}\
  3314. files[6]={name=\"Video\";mode='api';content=\"--@meta[type]:\\\"class\\\"\\\
  3315. \\\
  3316. local Video = Class \\\"Video\\\"\\\
  3317. \\\
  3318. function Video:Video( width, height, framerate )\\\
  3319.     self.frame = 0\\\
  3320.     self.frames = {}\\\
  3321.     self.width = width\\\
  3322.     self.height = height\\\
  3323.     self.framerate = framerate\\\
  3324.     self.frametime = 0\\\
  3325. \\\
  3326.     return self.public\\\
  3327. end\\\
  3328. \\\
  3329. function Video.public:step( dt, back )\\\
  3330.     self.frametime = self.frametime + dt\\\
  3331.     while self.frametime > self.framerate do\\\
  3332.         self.public:nextFrame()\\\
  3333.         self.frametime = self.frametime - self.framerate\\\
  3334.     end\\\
  3335.     while self.frametime < 0 do\\\
  3336.         self.public:lastFrame()\\\
  3337.         self.frametime = self.frametime + self.framerate\\\
  3338.     end\\\
  3339. end\\\
  3340. \\\
  3341. function Video.public:nextFrame()\\\
  3342.     self.frame = self.frame + 1\\\
  3343. end\\\
  3344. \\\
  3345. function Video.public:lastFrame()\\\
  3346.     self.frame = self.frame + 1\\\
  3347. end\\\
  3348. \\\
  3349. function Video.public:getFrame( )\\\
  3350.     return self.frames[self.frame]\\\
  3351. end\\\
  3352. \\\
  3353. function Video.public:newFrame( frame )\\\
  3354.     if Class.typeOf( frame, Image ) then\\\
  3355.         table.insert( self.frames, frame )\\\
  3356.     else\\\
  3357.         return error \\\"expected Image frame\\\"\\\
  3358.     end\\\
  3359. end\\\
  3360. \\\
  3361. function Video.public:hasEnded( )\\\
  3362.     return #self.frames < self.frame\\\
  3363. end\\\
  3364. \\\
  3365. function Video.public:resize( w, h )\\\
  3366.     for i = 1, #self.frames do\\\
  3367.         self.frames[i]:resize( w, h )\\\
  3368.     end\\\
  3369. end\\\
  3370. \\\
  3371. function Video.public:savestr()\\\
  3372.     local t = {}\\\
  3373.     for i = 1, #self.frames do\\\
  3374.         t[i] = self.frames[i]:savestr()\\\
  3375.     end\\\
  3376.     return table.concat( t, \\\"---\\\" )\\\
  3377. end\\\
  3378. \\\
  3379. function Video.public:loadstr( str )\\\
  3380.     self.frames = {}\\\
  3381.     local frames = sutils.split( str, \\\"%-%-%-\\\" )\\\
  3382.     for i = 1, #frames do\\\
  3383.         self.frames[i] = Image()\\\
  3384.         self.frames[i]:loadstr( frames[i] )\\\
  3385.     end\\\
  3386. end\\\
  3387. \\\
  3388. return Video\"}\
  3389. files[7]={name=\"drawBox\";mode='lib';content=\"\\\
  3390. return function( x, y, w, h )\\\
  3391.     local bc, tc, char = mode.getMode()\\\
  3392.     local pixel = mode.getPixelFunction()\\\
  3393. \\\
  3394.     for i = x, x + w - 1 do\\\
  3395.         pixel( i, y, bc, tc, char )\\\
  3396.         pixel( i, y + h - 1, bc, tc, char )\\\
  3397.     end\\\
  3398.     for i = y + 1, y + h - 2 do\\\
  3399.         pixel( x, i, bc, tc, char )\\\
  3400.         pixel( x + w - 1, i, bc, tc, char )\\\
  3401.     end\\\
  3402. \\\
  3403.     return true\\\
  3404. end\"}\
  3405. files[8]={name=\"drawFilledBox\";mode='lib';content=\"\\\
  3406. return function( x, y, w, h )\\\
  3407.     local bc, tc, char = mode.getMode()\\\
  3408.     local pixel = mode.getPixelFunction()\\\
  3409. \\\
  3410.     for x = x, x + w - 1 do\\\
  3411.         for y = y, y + h - 1 do\\\
  3412.             pixel( x, y, bc, tc, char )\\\
  3413.         end\\\
  3414.     end\\\
  3415. \\\
  3416.     return true\\\
  3417. end\"}\
  3418. files[9]={name=\"drawCircle\";mode='lib';content=\"\\\
  3419. local correction = .7\\\
  3420. \\\
  3421. return function( x, y, r )\\\
  3422.     local bc, tc, char = mode.getMode()\\\
  3423.     local pixel = mode.getPixelFunction()\\\
  3424. \\\
  3425.     local c = 2 * math.pi * r\\\
  3426.     local n = 2 * math.pi * 2 / c\\\
  3427.     local c8 = c / 8\\\
  3428.     for i = 0, c8 do\\\
  3429.         local _x, _y = math.sin( i * n ) * r, math.cos( i * n ) * r\\\
  3430.         pixel( x + _x, y + _y * correction, bc, tc, char )\\\
  3431.         pixel( x + _x, y - _y * correction, bc, tc, char )\\\
  3432.         pixel( x - _x, y + _y * correction, bc, tc, char )\\\
  3433.         pixel( x - _x, y - _y * correction, bc, tc, char )\\\
  3434.         pixel( x + _y, y + _x * correction, bc, tc, char )\\\
  3435.         pixel( x - _y, y + _x * correction, bc, tc, char )\\\
  3436.         pixel( x + _y, y - _x * correction, bc, tc, char )\\\
  3437.         pixel( x - _y, y - _x * correction, bc, tc, char )\\\
  3438.     end\\\
  3439. end\"}\
  3440. files[10]={name=\"drawFilledCircle\";mode='lib';content=\"\\\
  3441. local correction = .7\\\
  3442. \\\
  3443. return function( x, y, r )\\\
  3444.     local bc, tc, char = mode.getMode()\\\
  3445.     local pixel = mode.getPixelFunction()\\\
  3446. \\\
  3447.     local r2 = ( r + 1 ) ^ 2\\\
  3448.     for _x = x - r, x + r do\\\
  3449.         for _y = -r, r do\\\
  3450.             if ( ( x - _x ) ^ 2 + ( y / correction ) ^ 2 ) <= r2 then\\\
  3451.                 pixel( _x, y + _y, bc, tc, char )\\\
  3452.             end\\\
  3453.         end\\\
  3454.     end\\\
  3455. \\\
  3456.     return true\\\
  3457. end\"}\
  3458. files[11]={name=\"drawEllipse\";mode='lib';content=\"\\\
  3459. -- Credits to Xenthera\\\
  3460. \\\
  3461. return function( x, y, w, h )\\\
  3462.     local bc, tc, char = mode.getMode()\\\
  3463.     local pixel = mode.getPixelFunction()\\\
  3464.     local rx, ry = w / 2, h / 2\\\
  3465.     local xc, yc = x + rx, y + ry\\\
  3466.     local rxSq, rySq = rx ^ 2, ry ^ 2\\\
  3467.     local x, y = 0, ry\\\
  3468.     local px, py = 0, 2 * rxSq * y\\\
  3469.     pixel( xc+x, yc+y, bc, tc, char )\\\
  3470.     pixel( xc-x, yc+y, bc, tc, char )\\\
  3471.     pixel( xc+x, yc-y, bc, tc, char )\\\
  3472.     pixel( xc-x, yc-y, bc, tc, char )\\\
  3473.     local p = rySq - (rxSq * ry) + (0.25 * rxSq)\\\
  3474.     while (px < py) do\\\
  3475.         x = x + 1\\\
  3476.         px = px + 2 * rySq\\\
  3477.         if (p < 0) then\\\
  3478.             p = p + rySq + px\\\
  3479.         else\\\
  3480.             y = y - 1\\\
  3481.             py = py - 2 * rxSq;\\\
  3482.             p = p + rySq + px - py;\\\
  3483.         end\\\
  3484.         pixel( xc+x, yc+y, bc, tc, char )\\\
  3485.         pixel( xc-x, yc+y, bc, tc, char )\\\
  3486.         pixel( xc+x, yc-y, bc, tc, char )\\\
  3487.         pixel( xc-x, yc-y, bc, tc, char )\\\
  3488.     end\\\
  3489.     p = rySq*(x+0.5)*(x+0.5) + rxSq*(y-1)*(y-1) - rxSq*rySq\\\
  3490.     while (y > 0) do\\\
  3491.         y = y - 1\\\
  3492.         py = py - 2 * rxSq\\\
  3493.         if (p > 0) then\\\
  3494.             p = p + rxSq - py\\\
  3495.         else\\\
  3496.             x = x + 1\\\
  3497.             px = px + 2 * rySq\\\
  3498.             p = p + rxSq - py + px\\\
  3499.         end\\\
  3500.         pixel( xc+x, yc+y, bc, tc, char )\\\
  3501.         pixel( xc-x, yc+y, bc, tc, char )\\\
  3502.         pixel( xc+x, yc-y, bc, tc, char )\\\
  3503.         pixel( xc-x, yc-y, bc, tc, char )\\\
  3504.     end\\\
  3505. end\"}\
  3506. files[12]={name=\"drawFilledEllipse\";mode='lib';content=\"\\\
  3507. -- Credits to Xenthera\\\
  3508. \\\
  3509. return function( x, y, w, h )\\\
  3510.     local bc, tc, char = mode.getMode()\\\
  3511.     local pixel = mode.getPixelFunction()\\\
  3512. \\\
  3513.     local ww, hh, x0, dx = w ^ 2, h ^ 2, w, 0\\\
  3514.     local hhww = hh*ww\\\
  3515.     for _x = -w, w do\\\
  3516.         pixel( x + _x, y, bc, tc, char )\\\
  3517.     end\\\
  3518.     for _y = 1, h do\\\
  3519.         local x1 = x0 - (dx - 1)\\\
  3520.         for i = x1, 0, -1 do\\\
  3521.             if (x1*x1*hh + _y*_y*ww <= hhww) then\\\
  3522.                 break\\\
  3523.             end\\\
  3524.             x1 = x1 - 1\\\
  3525.         end\\\
  3526.         dx, x0 = x0 - x1, x1\\\
  3527.         for _x = -x0, x0 do\\\
  3528.             pixel( x + _x, y - _y, bc, tc, char )\\\
  3529.             pixel( x + _x, y + _y, bc, tc, char )\\\
  3530.         end\\\
  3531.     end\\\
  3532. end\"}\
  3533. files[13]={name=\"drawImage\";mode='lib';content=\"\\\
  3534. return function( x, y, image )\\\
  3535.     local pixel = mode.getPixelFunction()\\\
  3536. \\\
  3537.     image:foreach( function( bc, tc, char, _x, _y )\\\
  3538.         pixel( x + _x - 1, y + _y - 1, bc, tc, char )\\\
  3539.     end )\\\
  3540. \\\
  3541.     return true\\\
  3542. end\"}\
  3543. files[14]={name=\"drawLine\";mode='lib';content=\"\\\
  3544. return function( x1, y1, x2, y2 )\\\
  3545.     local bc, tc, char = mode.getMode()\\\
  3546.     local pixel = mode.getPixelFunction()\\\
  3547. \\\
  3548.     if x1 > x2 then\\\
  3549.         x2, x1 = x1, x2\\\
  3550.         y2, y1 = y1, y2\\\
  3551.     end\\\
  3552. \\\
  3553.     if x1 == x2 then\\\
  3554.         for i = math.min( y1, y2 ), math.max( y1, y2 ) do\\\
  3555.             pixel( x1, i, bc, tc, char )\\\
  3556.         end\\\
  3557.         return true\\\
  3558.     end\\\
  3559. \\\
  3560.     local dx, dy = x2 - x1, y2 - y1\\\
  3561.     local m = dy / dx\\\
  3562.     local c = y1 - m * x1\\\
  3563. \\\
  3564.     for x = x1, x2, math.min( 1 / m, 1 ) do\\\
  3565.         local y = m * x + c\\\
  3566.         pixel( x, y, bc, tc, char )\\\
  3567.     end\\\
  3568. \\\
  3569.     return true\\\
  3570. end\"}\
  3571. files[15]={name=\"drawPoint\";mode='lib';content=\"\\\
  3572. return function( x, y )\\\
  3573.     local bc, tc, char = mode.getMode()\\\
  3574.     local pixel = mode.getPixelFunction()\\\
  3575.     pixel( x, y, bc, tc, char )\\\
  3576. end\"}\
  3577. files[16]={name=\"drawPolygon\";mode='lib';content=\"\\\
  3578. return function( points )\\\
  3579.     local bc, tc, char = mode.getMode()\\\
  3580.     local pixel = mode.getPixelFunction()\\\
  3581. \\\
  3582.     for i = 1, #points do\\\
  3583.         local p1, p2 = points[i], points[i+1] or points[1]\\\
  3584.         drawLine( p1.x, p1.y, p2.x, p2.y )\\\
  3585.     end\\\
  3586. \\\
  3587.     return true\\\
  3588. end\"}\
  3589. files[17]={name=\"drawFilledPolygon\";mode='lib';content=\"\\\
  3590. return function( points )\\\
  3591.     local bc, tc, char = mode.getMode()\\\
  3592.     local pixel = mode.getPixelFunction()\\\
  3593. \\\
  3594.     local lines = {}\\\
  3595.     for i = 1, #points do\\\
  3596.         lines[i] = {\\\
  3597.             points[i];\\\
  3598.             points[i+1] or points[1];\\\
  3599.         }\\\
  3600.     end\\\
  3601.     for i = #lines, 1, -1 do\\\
  3602.         if lines[i][1].y == lines[i][2].y then\\\
  3603.             table.remove( lines, i )\\\
  3604.         end\\\
  3605.     end\\\
  3606. \\\
  3607.     local miny, maxy = lines[1][1].y, lines[1][1].y\\\
  3608.     for i = 1, #lines do\\\
  3609.         miny = math.min( math.min( lines[i][1].y, lines[i][2].y ), miny )\\\
  3610.         maxy = math.max( math.max( lines[i][1].y, lines[i][2].y ), maxy )\\\
  3611.     end\\\
  3612. \\\
  3613.     miny = math.ceil( miny - 0.5 )\\\
  3614.     maxy = math.floor( maxy + 0.5 )\\\
  3615. \\\
  3616.     local intersections = {}\\\
  3617. \\\
  3618.     for l = 1, #lines do\\\
  3619.         local v1 = Math2D.Vec2( lines[l][1].x, lines[l][1].y )\\\
  3620.         local v2 = Math2D.Vec2( lines[l][2].x, lines[l][2].y )\\\
  3621.         for i = miny, maxy do\\\
  3622.             intersections[i] = intersections[i] or {}\\\
  3623. \\\
  3624.             local point = Math2D.pointOnLine( v1, v2, nil, i )\\\
  3625.             if point and Math2D.collision.pointInLine( v1, v2, point ) then\\\
  3626.                 table.insert( intersections[i], math.floor( point.x + .5 ) )\\\
  3627.             end\\\
  3628.         end\\\
  3629.     end\\\
  3630. \\\
  3631.     local points = {}\\\
  3632. \\\
  3633.     for i = miny, maxy do\\\
  3634.         table.sort( intersections[i] )\\\
  3635.         local state = false\\\
  3636.         local last = 1\\\
  3637.         local p = {}\\\
  3638.         for int = 1, #intersections[i] do\\\
  3639.             if last ~= intersections[i][int] then\\\
  3640.                 for _p = last, intersections[i][int] do\\\
  3641.                     p[_p] = state\\\
  3642.                 end\\\
  3643.                 state = not state\\\
  3644.                 last = intersections[i][int]\\\
  3645.             else\\\
  3646.                 p[last] = state\\\
  3647.             end\\\
  3648.         end\\\
  3649. \\\
  3650.         for x = 1, #p do\\\
  3651.             if p[x] then\\\
  3652.                 pixel( x, i, bc, tc, char )\\\
  3653.             end\\\
  3654.         end\\\
  3655.     end\\\
  3656. end\"}\
  3657. files[18]={name=\"drawText\";mode='lib';content=\"\\\
  3658. return function( x, y, text )\\\
  3659.     local bc, tc = mode.getMode()\\\
  3660.     local pixel = mode.getPixelFunction()\\\
  3661. \\\
  3662.     for i = 1, #text do\\\
  3663.         pixel( x, y, bc, tc, text:sub( i, i ) )\\\
  3664.         x = x + 1\\\
  3665.     end\\\
  3666. \\\
  3667.     return true\\\
  3668. end\"}\
  3669. files[19]={name=\"drawWrappedText\";mode='lib';content=\"\\\
  3670. return function( x, y, w, h, text, align )\\\
  3671.     local lines = SUtils.wordwrap( text, w, h, align, w, h )\\\
  3672.     for i = 1, #lines do\\\
  3673.         drawText( x + ( lines.padding[i] or 0 ), y + i + ( lines.padding.vertical or 0 ) - 1, lines[i] )\\\
  3674.     end\\\
  3675. \\\
  3676.     return true\\\
  3677. end\"}\
  3678. files[20]={name=\"draw\";mode='api';content=\"\\\
  3679. function point( x, y )\\\
  3680.     return drawPoint( x, y )\\\
  3681. end\\\
  3682. \\\
  3683. function box( x, y, w, h )\\\
  3684.     return drawBox( x, y, w, h )\\\
  3685. end\\\
  3686. \\\
  3687. function filledBox( x, y, w, h )\\\
  3688.     return drawFilledBox( x, y, w, h )\\\
  3689. end\\\
  3690. \\\
  3691. function circle( x, y, r )\\\
  3692.     return drawCircle( x, y, r )\\\
  3693. end\\\
  3694. \\\
  3695. function filledCircle( x, y, r )\\\
  3696.     return drawFilledCircle( x, y, r )\\\
  3697. end\\\
  3698. \\\
  3699. function ellipse( x, y, w, h )\\\
  3700.     return drawEllipse( x, y, w, h )\\\
  3701. end\\\
  3702. \\\
  3703. function filledEllipse( x, y, w, h )\\\
  3704.     return drawFilledEllipse( x, y, w, h )\\\
  3705. end\\\
  3706. \\\
  3707. function image( x, y, image )\\\
  3708.     return drawImage( x, y, image )\\\
  3709. end\\\
  3710. \\\
  3711. function line( x1, y1, x2, y2 )\\\
  3712.     return drawLine( x1, y1, x2, y2 )\\\
  3713. end\\\
  3714. \\\
  3715. function polygon( ... )\\\
  3716.     if #arg == 1 and type( arg[1] ) == \\\"table\\\" then arg = arg[1] end\\\
  3717.     local points = {}\\\
  3718.     for i = 1, #arg / 2 do\\\
  3719.         points[i] = {\\\
  3720.             x = arg[2 * i - 1];\\\
  3721.             y = arg[2 * i];\\\
  3722.         }\\\
  3723.     end\\\
  3724.     return drawPolygon( points )\\\
  3725. end\\\
  3726. \\\
  3727. function filledPolygon( ... )\\\
  3728.     if #arg == 1 and type( arg[1] ) == \\\"table\\\" then arg = arg[1] end\\\
  3729.     local points = {}\\\
  3730.     for i = 1, #arg / 2 do\\\
  3731.         points[i] = {\\\
  3732.             x = arg[2 * i - 1];\\\
  3733.             y = arg[2 * i];\\\
  3734.         }\\\
  3735.     end\\\
  3736.     return drawFilledPolygon( points )\\\
  3737. end\\\
  3738. \\\
  3739. function text( x, y, text )\\\
  3740.     return drawText( x, y, text )\\\
  3741. end\\\
  3742. \\\
  3743. function wrappedText( x, y, w, h, text, align )\\\
  3744.     return drawWrappedText( x, y, w, h, text, align )\\\
  3745. end\"}\
  3746. apiCount=6\
  3747. dependencies[1]=\"Class.lua\"\
  3748. dependencies[2]=\"Math2D.lua\"\
  3749. dependencies[3]=\"SUtils.lua\"\
  3750. local env = setmetatable( {}, { __index = getfenv() } )\
  3751. env.global = env\
  3752. env.args = { ... }\
  3753. local public = {}\
  3754. local bloaded = _G[\"_bundleLoaded\"]\
  3755. if type( bloaded ) ~= \"table\" then bloaded = {} _G[\"_bundleLoaded\"] = bloaded end\
  3756. \
  3757. if bloaded[name] and not mainContent then\
  3758.     return bloaded[name]\
  3759. end\
  3760. \
  3761. for i = 1, #dependencies do\
  3762.     if bloaded and bloaded[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] then\
  3763.         env[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] = bloaded[dependencies[i]:gsub(\"%.lua$\", \"\", 1)]\
  3764.     else\
  3765.         local path = ( _G[\"_bundleDependencyPath\"] or \"\" ) .. \"/\" .. dependencies[i]\
  3766.         local f, err = loadfile( path )\
  3767.         if f then\
  3768.             setfenv( f, getfenv() )\
  3769.             env[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] = f()\
  3770.         else\
  3771.             error( name .. \" requires bundle '\" .. dependencies[i] .. \"'\", 0 )\
  3772.         end\
  3773.     end\
  3774. end\
  3775. for i = 1, #requires do\
  3776.     if bloaded and bloaded[requires[i]:gsub(\"%.lua$\", \"\", 1)] then\
  3777.         env[requires[i]:gsub(\"%.lua$\", \"\", 1)] = bloaded[requires[i]:gsub(\"%.lua$\", \"\", 1)]\
  3778.     else\
  3779.         local path = ( _G[\"_bundleDependencyPath\"] or \"\" ) .. \"/\" .. requires[i]\
  3780.         local f, err = loadfile( path )\
  3781.         if f then\
  3782.             setfenv( f, getfenv() )\
  3783.             env[requires[i]:gsub(\"%.lua$\", \"\", 1)] = f()\
  3784.         end\
  3785.     end\
  3786. end\
  3787. \
  3788. for i = 1, #files do\
  3789.     local f, err = loadstring( files[i].content, \"[\" .. name .. \"] \" .. files[i].name )\
  3790.     if f then\
  3791.         local e = setmetatable( {}, { __index = env } )\
  3792.         setfenv( f, e )\
  3793.         local ok, data = pcall( f, ... )\
  3794.         if not ok then\
  3795.             printError( data )\
  3796.             break\
  3797.         end\
  3798.         if data == nil then\
  3799.             data = {}\
  3800.             for k, v in pairs( e ) do\
  3801.                 data[k] = v\
  3802.             end\
  3803.         end\
  3804.         if files[i].mode == \"api\" then\
  3805.             if apiCount == 1 then\
  3806.                 public = data\
  3807.             else\
  3808.                 public[files[i].name] = data\
  3809.                 env[files[i].name] = data\
  3810.             end\
  3811.         else\
  3812.             env[files[i].name] = data\
  3813.         end\
  3814.     else\
  3815.         printError( err )\
  3816.         break\
  3817.     end\
  3818. end\
  3819. \
  3820. if mainContent then\
  3821.     local f, err = loadstring( mainContent, \"[\" .. name .. \"] main\" )\
  3822.     if f then\
  3823.         setfenv( f, env )\
  3824.         local ok, data = pcall( f, ... )\
  3825.         if not ok then\
  3826.             printError( data )\
  3827.         end\
  3828.     else\
  3829.         printError( err )\
  3830.     end\
  3831. end\
  3832. \
  3833. bloaded[name] = public\
  3834. return public"};["Nightfall.lua"]="local files={}\
  3835. local dependencies={}\
  3836. local requires={}\
  3837. local mainContent\
  3838. local apiCount\
  3839. local name=\"NightFall\"\
  3840. files[1]={name=\"config\";mode='lib';content=\"\\\
  3841. target = \\\"computer\\\"\\\
  3842. width, height = term.getSize()\\\
  3843. \\\
  3844. atime = 0.4\\\
  3845. sleep = 1\\\
  3846. \\\
  3847. installpath = \\\".nightfall\\\"\"}\
  3848. files[2]={name=\"images\";mode='lib';content=\"logo = Gfx2D.Image( 0, 0 ):loadstr [[70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
  3849. 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
  3850. 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
  3851. 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70N70i70g70h70t70 70F70a70l70l70 70 70 70 70 70 70 \\\
  3852. 70 70 70 70 70 70 70 70 70 F0 F0 F0 F0 F0 F0 F0 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
  3853. 70 70 70 70 70 70 70 70 70 F0 70 70 70 70 70 F0 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
  3854. 70 70 70 70 70 70 70 70 70 F0 F0 F0 F0 F0 F0 F0 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
  3855. 70 70 70 70 70 70 70 70 70 F0 F0 F0 F0 F0 F0 F0 80 80 80 80 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
  3856. 70 70 70 70 70 70 70 70 80 F0 F0 F0 F0 F0 F0 F0 80 80 80 80 80 80 80 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
  3857. 70 70 70 70 70 70 80 80 80 F0 F0 F0 F0 F0 F0 F0 80 00 00 00 80 80 80 80 80 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
  3858. 70 70 70 70 70 80 80 80 80 F0 F0 F0 F0 F0 F0 F0 80 80 80 80 00 00 80 80 80 80 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
  3859. 70 70 70 70 80 80 80 80 80 F0 F0 F0 F0 F0 F0 F0 80 80 80 80 80 80 00 80 80 80 80 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
  3860. 70 70 70 70 80 80 80 80 80 F0 F0 F0 F0 F0 F0 F0 80 80 80 80 80 80 80 80 80 80 80 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
  3861. 70 70 70 80 80 80 80 80 80 F0 F0 F0 F0 F0 F0 F0 80 80 80 80 80 80 80 80 80 80 80 80 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
  3862. 70 70 70 80 80 80 80 80 80 F0 F0 F0 F0 F0 F0 F0 80 80 80 80 80 80 80 80 80 80 80 80 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
  3863. 70 70 70 80 80 80 80 80 80 F0 F0 F0 F0 F0 F0 F0 80 80 80 80 80 80 80 80 80 80 80 80 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
  3864. F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 \\\
  3865. F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 \\\
  3866. F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 ]]\\\
  3867. \\\
  3868. plus = Gfx2D.Image( 0, 0 ):loadstr [[70 70 70 70 70 \\\
  3869. 70 70 00 70 70 \\\
  3870. 70 00 00 00 70 \\\
  3871. 70 70 00 70 70 \\\
  3872. 70 70 70 70 70 ]]\\\
  3873. \\\
  3874. move = Gfx2D.Image( 0, 0 ):loadstr [[70 70 70^70 70 \\\
  3875. 70 70 70|70 70 \\\
  3876. 70<70-70+70-70>\\\
  3877. 70 70 70|70 70 \\\
  3878. 70 70 70v70 70 ]]\\\
  3879. \\\
  3880. delete = Gfx2D.Image( 0, 0 ):loadstr [[70 70 70 70 70 \\\
  3881. 70 E0 70 E0 70 \\\
  3882. 70 70 E0 70 70 \\\
  3883. 70 E0 70 E0 70 \\\
  3884. 70 70 70 70 70 ]]\"}\
  3885. files[3]={name=\"waves\";mode='lib';content=\"local t = {}\\\
  3886. \\\
  3887. t[1] = {\\\
  3888.     1;\\\
  3889.     1;\\\
  3890.     1;\\\
  3891.     1;\\\
  3892.     1;\\\
  3893. }\\\
  3894. \\\
  3895. t[2] = {\\\
  3896.     1;\\\
  3897.     1;\\\
  3898.     1;\\\
  3899.     1;\\\
  3900.     1;\\\
  3901.     2;\\\
  3902.     2;\\\
  3903.     2;\\\
  3904.     1;\\\
  3905.     1;\\\
  3906. }\\\
  3907. \\\
  3908. t[3] = {\\\
  3909.     5;\\\
  3910.     5;\\\
  3911.     5;\\\
  3912.     6;\\\
  3913.     7;\\\
  3914.     8;\\\
  3915.     6;\\\
  3916.     7;\\\
  3917.     8;\\\
  3918. }\\\
  3919. \\\
  3920. return t\"}\
  3921. files[4]={name=\"listMaps\";mode='lib';content=\"\\\
  3922. return function( w, h, onClick )\\\
  3923.     local frame = UIKit.UIFrame( 0, 0, w, h )\\\
  3924. \\\
  3925.     local maps = fs.list( config.installpath .. \\\"/assets/maps\\\" )\\\
  3926. \\\
  3927.     local cframe = frame:newChild( UIKit.UIFrame( 1, 1, w, h ) )\\\
  3928.     if #maps > h then\\\
  3929.         cframe.width = w - 1\\\
  3930.         local scrollbar = frame:newChild( UIKit.UIScrollBar( w, 1, 1, h, \\\"vertical\\\", cframe ) )\\\
  3931.     end\\\
  3932. \\\
  3933.     for i = 1, #maps do\\\
  3934.         local t = cframe:newChild( UIKit.UIText( 1, i, cframe.width, 1, maps[i] ) )\\\
  3935.         t.bc = colours.grey\\\
  3936.         t.tc = colours.lightGrey\\\
  3937.         t.wordwrap = false\\\
  3938.         function t.callback:onClick()\\\
  3939.             onClick( maps[i], t )\\\
  3940.         end\\\
  3941.         t:reload()\\\
  3942.         t:wrap()\\\
  3943.     end\\\
  3944. \\\
  3945.     if #maps == 0 then\\\
  3946.         frame:newChild( UIKit.UIText( 0, 0, 8, 1, \\\"#7&8No maps!\\\" ) ):centre()\\\
  3947.     end\\\
  3948. \\\
  3949.     return frame\\\
  3950. end\"}\
  3951. files[5]={name=\"saveLoader\";mode='lib';content=\"\"}\
  3952. files[6]={name=\"saveSaver\";mode='lib';content=\"\"}\
  3953. files[7]={name=\"loadGameUI\";mode='lib';content=\"\\\
  3954. return function()\\\
  3955.     local frame = window:newChild( UIKit.UIFrame( config.width + 1, 7, 19, 8 ) )\\\
  3956.     newTween( config.atime, frame, { x = config.width - frame.width + 1 }, \\\"outSine\\\" ).round = true\\\
  3957.     frame:newChild( UIKit.UIText( 1, 1, frame.width, frame.height ) ).bc = colours.grey\\\
  3958. \\\
  3959.     frame:newChild( UIKit.UIText( 0, 1, 9, 1, \\\"#7&0Load Game\\\" ) ):centreX()\\\
  3960.     local back = frame:newChild( UIKit.UIText( 1, 1, 1, 1, \\\"#7&8<\\\" ) )\\\
  3961.     function back.callback:onClick()\\\
  3962.         local r = newTween( config.atime, frame, { x = config.width + 1 }, \\\"inOutSine\\\" )\\\
  3963.         r.round = true\\\
  3964.         function r:onFinish()\\\
  3965.             frame:remove()\\\
  3966.             menuUI()\\\
  3967.         end\\\
  3968.     end\\\
  3969. \\\
  3970.     local f = frame:newChild( UIKit.UIFrame( 1, 3, frame.width, frame.height - 2 ) )\\\
  3971. \\\
  3972.     local saves = fs.list( config.installpath .. \\\"/saves\\\" )\\\
  3973. \\\
  3974.     local cframe = f:newChild( UIKit.UIFrame( 1, 1, f.width, f.height ) )\\\
  3975.     if #saves > f.height then\\\
  3976.         cframe.width = w - 1\\\
  3977.         local scrollbar = f:newChild( UIKit.UIScrollBar( f.width, 1, 1, f.height, \\\"vertical\\\", cframe ) )\\\
  3978.     end\\\
  3979. \\\
  3980.     for i = 1, #saves do\\\
  3981.         local t = cframe:newChild( UIKit.UIText( 1, i, cframe.width, 1, saves[i] ) )\\\
  3982.         t.bc = colours.grey\\\
  3983.         t.tc = colours.lightGrey\\\
  3984.         t.wordwrap = false\\\
  3985.         function t.callback:onClick()\\\
  3986.             local r = newTween( config.atime, frame, { x = config.width + 1 }, \\\"inSine\\\" )\\\
  3987.             newTween( config.atime, background, { y = 1 - config.height }, \\\"inSine\\\" )\\\
  3988.             r.round = true\\\
  3989.             function r:onFinish()\\\
  3990.                 frame:remove()\\\
  3991.                 gameUI( saves[i] )\\\
  3992.             end\\\
  3993.         end\\\
  3994.         t:reload()\\\
  3995.         t:wrap()\\\
  3996.     end\\\
  3997. \\\
  3998.     if #saves == 0 then\\\
  3999.         f:newChild( UIKit.UIText( 0, 0, 9, 1, \\\"#7&8No saves!\\\" ) ):centre()\\\
  4000.     end\\\
  4001. end\"}\
  4002. files[8]={name=\"newGameUI\";mode='lib';content=\"\\\
  4003. return function()\\\
  4004.     local frame = window:newChild( UIKit.UIFrame( config.width + 1, 7, 19, 10 ) )\\\
  4005.     newTween( config.atime, frame, { x = config.width - frame.width + 1 }, \\\"outSine\\\" ).round = true\\\
  4006.     frame:newChild( UIKit.UIText( 1, 1, frame.width, frame.height ) ).bc = colours.grey\\\
  4007. \\\
  4008.     frame:newChild( UIKit.UIText( 0, 1, 8, 1, \\\"#7&0New Game\\\" ) ):centreX()\\\
  4009.     local back = frame:newChild( UIKit.UIText( 1, 1, 1, 1, \\\"#7&8<\\\" ) )\\\
  4010.     function back.callback:onClick()\\\
  4011.         local r = newTween( config.atime, frame, { x = config.width + 1 }, \\\"inOutSine\\\" )\\\
  4012.         r.round = true\\\
  4013.         function r:onFinish()\\\
  4014.             frame:remove()\\\
  4015.             menuUI()\\\
  4016.         end\\\
  4017.     end\\\
  4018. \\\
  4019.     local name = frame:newChild( UIKit.UIText( 1, 3, 4, 1, \\\"#7&8Name\\\" ) )\\\
  4020.     local ni = frame:newChild( UIKit.UIText( 6, 3, frame.width - 6, 1, \\\"\\\" ) )\\\
  4021.     ni.bc = colours.lightGrey\\\
  4022.     ni.hbc = 32768\\\
  4023.     ni.input = true\\\
  4024.     ni.wordwrap = false\\\
  4025. \\\
  4026.     function ni.callback:onChange()\\\
  4027.         if fs.exists( config.installpath .. \\\"/saves/\\\" .. self.text ) then\\\
  4028.             self.bc = colours.yellow\\\
  4029.         else\\\
  4030.             self.bc = colours.lightGrey\\\
  4031.         end\\\
  4032.         self:reload()\\\
  4033.         self:wrap()\\\
  4034.     end\\\
  4035. \\\
  4036.     local mapname\\\
  4037.     local button\\\
  4038.     local f = frame:newChild( listMaps( frame.width, frame.height - 6, function( map, b )\\\
  4039.         mapname = map\\\
  4040.         if button then\\\
  4041.             button.bc = colours.grey\\\
  4042.             button:reload()\\\
  4043.             button:wrap()\\\
  4044.         end\\\
  4045.         button = b\\\
  4046.         button.bc = colours.black\\\
  4047.         button:reload()\\\
  4048.         button:wrap()\\\
  4049.     end ) )\\\
  4050.     f.x = 1\\\
  4051.     f.y = 5\\\
  4052. \\\
  4053.     local c = frame:newChild( UIKit.UIText( 1, frame.height, 6, 1, \\\"#7&3create\\\" ) )\\\
  4054.     c:centreX()\\\
  4055.     function c.callback:onClick()\\\
  4056.         local name = ni.text\\\
  4057.         if name == \\\"\\\" then\\\
  4058.             local t = window:newChild( UIKit.UIText( 0, config.height - 1, 24, 1, \\\"# &EPlease type a save name.\\\" ) )\\\
  4059.             t.bc = 0\\\
  4060.             t:centreX()\\\
  4061.             Process.newThread( function()\\\
  4062.                 sleep( 1.5 )\\\
  4063.                 t:remove()\\\
  4064.             end )\\\
  4065.         elseif fs.exists( config.installpath .. \\\"/saves/\\\" .. name ) then\\\
  4066.             local t = window:newChild( UIKit.UIText( 0, config.height - 1, 39, 1, \\\"# &EThere is already a save with that name.\\\" ) )\\\
  4067.             t.bc = 0\\\
  4068.             t:centreX()\\\
  4069.             Process.newThread( function()\\\
  4070.                 sleep( 1.5 )\\\
  4071.                 t:remove()\\\
  4072.             end )\\\
  4073.         elseif not mapname then\\\
  4074.             local t = window:newChild( UIKit.UIText( 0, config.height - 1, 27, 1, \\\"# &EPlease select a map to use.\\\" ) )\\\
  4075.             t.bc = 0\\\
  4076.             t:centreX()\\\
  4077.             Process.newThread( function()\\\
  4078.                 sleep( 1.5 )\\\
  4079.                 t:remove()\\\
  4080.             end )\\\
  4081.         else\\\
  4082.             local h = fs.open( config.installpath .. \\\"/saves/\\\" .. name, \\\"w\\\" )\\\
  4083.             h.write( \\\"map=\\\" .. (\\\"%q\\\"):format( mapname ) .. \\\";\\\\nturrets={};\\\\nstage=0;\\\\nmoney=0;\\\\ntraps={};\\\\nhealth=0;\\\\ninitialised=false;\\\" )\\\
  4084.             h.close()\\\
  4085.             local r = newTween( config.atime, frame, { x = config.width + 1 }, \\\"inSine\\\" )\\\
  4086.             newTween( config.atime, background, { y = 1 - config.height }, \\\"inSine\\\" )\\\
  4087.             r.round = true\\\
  4088.             function r:onFinish()\\\
  4089.                 frame:remove()\\\
  4090.                 gameUI( name )\\\
  4091.             end\\\
  4092.         end\\\
  4093.     end\\\
  4094. \\\
  4095.     function ni.callback:onEnter()\\\
  4096.         c.callback:onClick()\\\
  4097.     end\\\
  4098. \\\
  4099.     ni:focusOn()\\\
  4100. end\"}\
  4101. files[9]={name=\"createMapUI\";mode='lib';content=\"\\\
  4102. return function()\\\
  4103.     local frame = window:newChild( UIKit.UIFrame( config.width + 1, 7, 19, 8 ) )\\\
  4104.     newTween( config.atime, frame, { x = config.width - frame.width + 1 }, \\\"outSine\\\" ).round = true\\\
  4105.     frame:newChild( UIKit.UIText( 1, 1, frame.width, frame.height ) ).bc = colours.grey\\\
  4106. \\\
  4107.     frame:newChild( UIKit.UIText( 0, 1, 10, 1, \\\"#7&0Create Map\\\" ) ):centreX()\\\
  4108.     local back = frame:newChild( UIKit.UIText( 1, 1, 1, 1, \\\"#7&8<\\\" ) )\\\
  4109.     function back.callback:onClick()\\\
  4110.         local r = newTween( config.atime, frame, { x = config.width + 1 }, \\\"inOutSine\\\" )\\\
  4111.         r.round = true\\\
  4112.         function r:onFinish()\\\
  4113.             frame:remove()\\\
  4114.             menuUI()\\\
  4115.         end\\\
  4116.     end\\\
  4117. \\\
  4118.     local n = frame:newChild( UIKit.UIText( 1, 3, 4, 1, \\\"#7&8Name\\\" ) )\\\
  4119.     local ni = frame:newChild( UIKit.UIText( 6, 3, frame.width - 6, 1, \\\"\\\" ) )\\\
  4120.     ni.bc = colours.lightGrey\\\
  4121.     ni.hbc = 32768\\\
  4122.     ni.input = true\\\
  4123.     ni.wordwrap = false\\\
  4124. \\\
  4125.     function ni.callback:onChange()\\\
  4126.         if fs.exists( config.installpath .. \\\"/assets/maps/\\\" .. self.text ) then\\\
  4127.             self.bc = colours.yellow\\\
  4128.         else\\\
  4129.             self.bc = colours.lightGrey\\\
  4130.         end\\\
  4131.         self:reload()\\\
  4132.         self:wrap()\\\
  4133.     end\\\
  4134. \\\
  4135.     local w = frame:newChild( UIKit.UIText( 1, 5, 5, 1, \\\"#7&8Width\\\" ) )\\\
  4136.     local h = frame:newChild( UIKit.UIText( 1, 6, 6, 1, \\\"#7&8Height\\\" ) )\\\
  4137. \\\
  4138.     local wd = frame:newChild( UIKit.UIText( 8, 5, 4, 1, \\\"#835\\\" ) )\\\
  4139.     wd.bc = colours.lightGrey\\\
  4140.     wd.hbc = 32768\\\
  4141. \\\
  4142.     local hd = frame:newChild( UIKit.UIText( 8, 6, 4, 1, \\\"#818\\\" ) )\\\
  4143.     hd.bc = colours.lightGrey\\\
  4144.     hd.hbc = 32768\\\
  4145. \\\
  4146.     local wdown = frame:newChild( UIKit.UIText( 13, 5, 1, 1, \\\"#7&0-\\\" ) )\\\
  4147.     function wdown.callback:onClick()\\\
  4148.         wd.text = \\\"#8\\\" .. math.max( ( tonumber( wd.text:sub( 3 ) ) or 0 ) - 1, 1 )\\\
  4149.     end\\\
  4150.     local wup = frame:newChild( UIKit.UIText( 15, 5, 1, 1, \\\"#7&0+\\\" ) )\\\
  4151.     function wup.callback:onClick()\\\
  4152.         wd.text = \\\"#8\\\" .. math.min( ( tonumber( wd.text:sub( 3 ) ) or 0 ) + 1, 9999 )\\\
  4153.     end\\\
  4154. \\\
  4155.     local hdown = frame:newChild( UIKit.UIText( 13, 6, 1, 1, \\\"#7&0-\\\" ) )\\\
  4156.     function hdown.callback:onClick()\\\
  4157.         hd.text = \\\"#8\\\" .. math.max( ( tonumber( hd.text:sub( 3 ) ) or 0 ) - 1, 1 )\\\
  4158.     end\\\
  4159.     local hup = frame:newChild( UIKit.UIText( 15, 6, 1, 1, \\\"#7&0+\\\" ) )\\\
  4160.     function hup.callback:onClick()\\\
  4161.         hd.text = \\\"#8\\\" .. math.min( ( tonumber( hd.text:sub( 3 ) ) or 0 ) + 1, 9999 )\\\
  4162.     end\\\
  4163. \\\
  4164.     local c = frame:newChild( UIKit.UIText( 1, frame.height, 6, 1, \\\"#7&3create\\\" ) )\\\
  4165.     c:centreX()\\\
  4166.     function c.callback:onClick()\\\
  4167.         local width, height = tonumber( wd.text:sub( 3 ) ) or 0, tonumber( hd.text:sub( 3 ) ) or 0\\\
  4168.         local name = ni.text\\\
  4169.         if name == \\\"\\\" then\\\
  4170.             local t = window:newChild( UIKit.UIText( 0, config.height - 1, 19, 1, \\\"# &EPlease type a name.\\\" ) )\\\
  4171.             t.bc = 0\\\
  4172.             t:centreX()\\\
  4173.             Process.newThread( function()\\\
  4174.                 sleep( 1.5 )\\\
  4175.                 t:remove()\\\
  4176.             end )\\\
  4177.         elseif fs.exists( config.installpath .. \\\"/assets/maps/\\\" .. name ) then\\\
  4178.             local t = window:newChild( UIKit.UIText( 0, config.height - 1, 38, 1, \\\"# &EThere is already a map with that name.\\\" ) )\\\
  4179.             t.bc = 0\\\
  4180.             t:centreX()\\\
  4181.             Process.newThread( function()\\\
  4182.                 sleep( 1.5 )\\\
  4183.                 t:remove()\\\
  4184.             end )\\\
  4185.         else\\\
  4186.             local h = fs.open( config.installpath .. \\\"/assets/maps/\\\" .. name, \\\"w\\\" )\\\
  4187.             h.write( \\\"width=\\\" .. width .. \\\";\\\\nheight=\\\" .. height .. \\\";\\\\npath={};\\\\nstart={x=1,y=1};\\\\nfinish={x=\\\" .. width .. \\\",y=\\\" .. height .. \\\"};\\\\nassets={};\\\" )\\\
  4188.             h.close()\\\
  4189.             local r = newTween( config.atime, frame, { x = config.width + 1 }, \\\"inSine\\\" )\\\
  4190.             newTween( config.atime, background, { y = 1 - config.height }, \\\"inSine\\\" )\\\
  4191.             r.round = true\\\
  4192.             function r:onFinish()\\\
  4193.                 frame:remove()\\\
  4194.                 mapUI( name )\\\
  4195.                 fs.delete( config.installpath .. \\\"/assets/maps/\\\" .. name )\\\
  4196.             end\\\
  4197.         end\\\
  4198.     end\\\
  4199. \\\
  4200.     function ni.callback:onEnter()\\\
  4201.         c.callback:onClick()\\\
  4202.     end\\\
  4203. \\\
  4204.     ni:focusOn()\\\
  4205. end\"}\
  4206. files[10]={name=\"editMapUI\";mode='lib';content=\"\\\
  4207. return function()\\\
  4208.     local frame = window:newChild( UIKit.UIFrame( config.width + 1, 7, 19, 8 ) )\\\
  4209.     newTween( config.atime, frame, { x = config.width - frame.width + 1 }, \\\"outSine\\\" ).round = true\\\
  4210.     frame:newChild( UIKit.UIText( 1, 1, frame.width, frame.height ) ).bc = colours.grey\\\
  4211. \\\
  4212.     frame:newChild( UIKit.UIText( 0, 1, 8, 1, \\\"#7&0Edit Map\\\" ) ):centreX()\\\
  4213.     local back = frame:newChild( UIKit.UIText( 1, 1, 1, 1, \\\"#7&8<\\\" ) )\\\
  4214.     function back.callback:onClick()\\\
  4215.         local r = newTween( config.atime, frame, { x = config.width + 1 }, \\\"inOutSine\\\" )\\\
  4216.         r.round = true\\\
  4217.         function r:onFinish()\\\
  4218.             frame:remove()\\\
  4219.             menuUI()\\\
  4220.         end\\\
  4221.     end\\\
  4222. \\\
  4223.     local f = frame:newChild( listMaps( frame.width, frame.height - 2, function( map )\\\
  4224.         local r = newTween( config.atime, frame, { x = config.width + 1 }, \\\"inOutSine\\\" )\\\
  4225.         newTween( config.atime, background, { y = 1 - config.height }, \\\"inSine\\\" )\\\
  4226.         r.round = true\\\
  4227.         function r:onFinish()\\\
  4228.             frame:remove()\\\
  4229.             mapUI( map )\\\
  4230.         end\\\
  4231.     end ) )\\\
  4232.     f.x = 1\\\
  4233.     f.y = 3\\\
  4234. end\"}\
  4235. files[11]={name=\"gameUI\";mode='lib';content=\"\\\
  4236. local states = {}\\\
  4237. \\\
  4238. local units = {}\\\
  4239. local files = fs.list( config.installpath .. \\\"/assets/units\\\" )\\\
  4240. for i = 1, #files do\\\
  4241.     local h = fs.open( config.installpath .. \\\"/assets/units/\\\" .. files[i], \\\"r\\\" )\\\
  4242.     local content = h.readAll()\\\
  4243.     h.close()\\\
  4244.     units[i] = textutils.unserialize( \\\"{\\\" .. content .. \\\"}\\\" )\\\
  4245.     units[i].image = Gfx2D.Image( 0, 0 ):loadstr( units[i].image )\\\
  4246. end\\\
  4247. local turrets = {}\\\
  4248. local files = fs.list( config.installpath .. \\\"/assets/turrets\\\" )\\\
  4249. for i = 1, #files do\\\
  4250.     local h = fs.open( config.installpath .. \\\"/assets/turrets/\\\" .. files[i], \\\"r\\\" )\\\
  4251.     local content = h.readAll()\\\
  4252.     h.close()\\\
  4253.     turrets[i] = textutils.unserialize( \\\"{\\\" .. content .. \\\"}\\\" )\\\
  4254.     turrets[i].image = Gfx2D.Image( 0, 0 ):loadstr( turrets[i].image )\\\
  4255.     turrets[i].image:resize( 3, 2 )\\\
  4256. end\\\
  4257. \\\
  4258. local function endState( state )\\\
  4259.     local s = states[state]\\\
  4260.     if s then\\\
  4261.         local r = newTween( config.atime, s.frame, { x = config.width + 1 }, \\\"inOutSine\\\" )\\\
  4262.         newTween( config.atime, background, { y = 1 }, \\\"inOutSine\\\" ).round = true\\\
  4263.         r.round = true\\\
  4264.         s.UIProcess:stop()\\\
  4265.         s.timerProcess:stop()\\\
  4266.         s.turretHandler:stop()\\\
  4267.         function r:onFinish()\\\
  4268.             s.frame:remove()\\\
  4269.             menuUI()\\\
  4270.         end\\\
  4271.     end\\\
  4272. end\\\
  4273. local function saveState( state )\\\
  4274.     local h = fs.open( config.installpath .. \\\"/saves/\\\" .. states[state].savename, \\\"w\\\" )\\\
  4275.     if not h then\\\
  4276.         return\\\
  4277.     end\\\
  4278.     local savedata = states[state].savedata\\\
  4279.     local turrets = {}\\\
  4280.     for i = 1, #savedata.turrets do\\\
  4281.         turrets[i] = {\\\
  4282.             turret = savedata.turrets[i].turret.name;\\\
  4283.             x = savedata.turrets[i].x;\\\
  4284.             y = savedata.turrets[i].y;\\\
  4285.             lastfire = 0;\\\
  4286.         }\\\
  4287.     end\\\
  4288.     local data = {\\\
  4289.         map = savedata.map;\\\
  4290.         turrets = turrets;\\\
  4291.         stage=savedata.stage;\\\
  4292.         money=savedata.money;\\\
  4293.         traps=savedata.traps;\\\
  4294.         health=savedata.health;\\\
  4295.         initialised=savedata.initialised;\\\
  4296.     }\\\
  4297.     h.write( textutils.serialize( data ):sub( 2, -2 ) )\\\
  4298.     h.close()\\\
  4299. end\\\
  4300. \\\
  4301. local function loaddata( name, state )\\\
  4302.     local h = fs.open( config.installpath .. \\\"/saves/\\\" .. name, \\\"r\\\" )\\\
  4303.     if not h then\\\
  4304.         content:newChild( UIKit.UIText( 0, 0, 19, 1, \\\"&ECouldn't load save.\\\" ) ):centre()\\\
  4305.         return\\\
  4306.     end\\\
  4307.     local savedata = textutils.unserialize( \\\"{\\\" .. h.readAll() .. \\\"}\\\" )\\\
  4308.     h.close()\\\
  4309.     if type( savedata ) ~= \\\"table\\\" then\\\
  4310.         content:newChild( UIKit.UIText( 0, 0, 13, 1, \\\"&ECorrupt save.\\\" ) ):centre()\\\
  4311.         return\\\
  4312.     end\\\
  4313. \\\
  4314.     local h = fs.open( config.installpath .. \\\"/assets/maps/\\\" .. savedata.map, \\\"r\\\" )\\\
  4315.     if not h then\\\
  4316.         content:newChild( UIKit.UIText( 0, 0, 19, 1, \\\"&ECouldn't load map.\\\" ) ):centre()\\\
  4317.         return\\\
  4318.     end\\\
  4319.     local mapdata = textutils.unserialize( \\\"{\\\" .. h.readAll() .. \\\"}\\\" )\\\
  4320.     h.close()\\\
  4321.     if type( mapdata ) ~= \\\"table\\\" then\\\
  4322.         content:newChild( UIKit.UIText( 0, 0, 12, 1, \\\"&ECorrupt map.\\\" ) ):centre()\\\
  4323.         return\\\
  4324.     end\\\
  4325. \\\
  4326.     if not savedata.initialised then\\\
  4327.         savedata.health = 100\\\
  4328.         savedata.stage = 1\\\
  4329.         savedata.money = 100\\\
  4330.         savedata.initialised = true\\\
  4331.     end\\\
  4332. \\\
  4333.     for i = 1, #savedata.turrets do\\\
  4334.         for t = 1, #turrets do\\\
  4335.             if turrets[t].name == savedata.turrets[i].turret then\\\
  4336.                 savedata.turrets[i].turret = turrets[t]\\\
  4337.             end\\\
  4338.         end\\\
  4339.     end\\\
  4340. \\\
  4341.     states[state].savedata, states[state].mapdata = savedata, mapdata\\\
  4342.     return true\\\
  4343. end\\\
  4344. \\\
  4345. local function displayVars( state )\\\
  4346.     local s = states[state]\\\
  4347. \\\
  4348.     s.scrollx, s.scrolly = 0, 0\\\
  4349.     s.changed = true\\\
  4350.     s.buffer = Gfx2D.Image( s.content.width, s.content.height )\\\
  4351.     s.display = s.content:newChild( UIKit.UIImage( 1, 1, s.content.width, s.content.height, s.buffer ) )\\\
  4352. \\\
  4353.     function s.display.callback:onDrag( button, x, y, lx, ly )\\\
  4354.         s.scrollx = s.scrollx - x + lx\\\
  4355.         s.scrolly = s.scrolly - y + ly\\\
  4356.         s.changed = true\\\
  4357.     end\\\
  4358. end\\\
  4359. \\\
  4360. local function mapDisplay( state )\\\
  4361.     local s = states[state]\\\
  4362. \\\
  4363.     local map = Gfx2D.Image( s.mapdata.width, s.mapdata.height )\\\
  4364.     map:foreach( function()\\\
  4365.         return colours.green\\\
  4366.     end )\\\
  4367.     for i = 1, s.mapdata.width * s.mapdata.height / 10 do\\\
  4368.         local x = math.random( 1, s.mapdata.width )\\\
  4369.         local y = math.random( 2, s.mapdata.height )\\\
  4370.         map:setPixel( x, y, colours.green, colours.lime, \\\"v\\\" )\\\
  4371.     end\\\
  4372.     for i = 1, #s.mapdata.path do\\\
  4373.         local x, y = s.mapdata.path[i].x, s.mapdata.path[i].y\\\
  4374.         map:setPixel( x, y, colours.grey, 1, \\\" \\\" )\\\
  4375.     end\\\
  4376.     map:setPixel( s.mapdata.start.x, s.mapdata.start.y, colours.blue, 1, \\\" \\\" )\\\
  4377.     map:setPixel( s.mapdata.finish.x, s.mapdata.finish.y, colours.magenta, 1, \\\" \\\" )\\\
  4378. \\\
  4379.     s.map = map\\\
  4380. end\\\
  4381. \\\
  4382. local function cloneT( t )\\\
  4383.     local t2 = {}\\\
  4384.     for i = 1, #t do\\\
  4385.         t2[i] = t[i]\\\
  4386.     end\\\
  4387.     return t2\\\
  4388. end\\\
  4389. \\\
  4390. local function recursivePoint( x, y, map, finx, finy, paths, path, checked )\\\
  4391.     checked[y] = checked[y] or {}\\\
  4392.     if checked[y][x] then return end\\\
  4393.     checked[y][x] = true\\\
  4394.     table.insert( path, { x = x, y = y } )\\\
  4395.     if x == finx and y == finy then\\\
  4396.         table.insert( paths, cloneT( path ) )\\\
  4397.         table.remove( path, #path )\\\
  4398.         return\\\
  4399.     end\\\
  4400.     if map[y] and map[y][x] then\\\
  4401.         recursivePoint( x - 1, y, map, finx, finy, paths, path, checked )\\\
  4402.         recursivePoint( x + 1, y, map, finx, finy, paths, path, checked )\\\
  4403.         recursivePoint( x, y - 1, map, finx, finy, paths, path, checked )\\\
  4404.         recursivePoint( x, y + 1, map, finx, finy, paths, path, checked )\\\
  4405.     end\\\
  4406.     table.remove( path, #path )\\\
  4407. end\\\
  4408. \\\
  4409. local function findPath( state )\\\
  4410.     local t = states[state].mapdata.path\\\
  4411.     local map = {}\\\
  4412.     for i = 1, #t do\\\
  4413.         map[t[i].y] = map[t[i].y] or {}\\\
  4414.         map[t[i].y][t[i].x] = true\\\
  4415.     end\\\
  4416.     local paths = {}\\\
  4417.     recursivePoint( states[state].mapdata.start.x, states[state].mapdata.start.y, map, states[state].mapdata.finish.x, states[state].mapdata.finish.y, paths, {}, {} )\\\
  4418.     if not paths[1] then\\\
  4419.         return\\\
  4420.     end\\\
  4421.     local min = #paths[1]\\\
  4422.     local minc = 1\\\
  4423.     for i = 2, #paths do\\\
  4424.         if #paths[i] < min then\\\
  4425.             min = #paths[i]\\\
  4426.             minc = i\\\
  4427.         end\\\
  4428.     end\\\
  4429.     local path = paths[minc]\\\
  4430.     states[state].path = path\\\
  4431. end\\\
  4432. \\\
  4433. local function unitDisplay( state )\\\
  4434.     states[state].units = {}\\\
  4435. \\\
  4436. end\\\
  4437. \\\
  4438. local function dispatcher( state )\\\
  4439.     local function dispatch( unit )\\\
  4440.         local t = {\\\
  4441.             unit = setmetatable( {}, { __index = units[unit] } );\\\
  4442.             pos = 1;\\\
  4443.         }\\\
  4444.         states[state].timerProcess:newThread( function()\\\
  4445.             for i = 2, #states[state].path do\\\
  4446.                 sleep( 1 / units[unit].speed )\\\
  4447.                 t.pos = t.pos + 1\\\
  4448.                 states[state].changed = true\\\
  4449.             end\\\
  4450.             if not t.unit.dead then\\\
  4451.                 states[state].savedata.health = states[state].savedata.health - t.unit.health\\\
  4452.                 saveState( state )\\\
  4453.             end\\\
  4454.             for i = 1, #states[state].units do\\\
  4455.                 if states[state].units[i] == t then\\\
  4456.                     table.remove( states[state].units, i )\\\
  4457.                     break\\\
  4458.                 end\\\
  4459.             end\\\
  4460.         end )\\\
  4461.         table.insert( states[state].units, t )\\\
  4462.     end\\\
  4463.     states[state].dispatch = function( unit, ... )\\\
  4464.         local units = { ... }\\\
  4465.         dispatch( unit )\\\
  4466.         if #units > 0 then\\\
  4467.             states[state].timerProcess:newThread( function()\\\
  4468.                 for i = 1, #units do\\\
  4469.                     sleep( .5 )\\\
  4470.                     dispatch( units[i] )\\\
  4471.                 end\\\
  4472.             end )\\\
  4473.         end\\\
  4474.     end\\\
  4475. end\\\
  4476. \\\
  4477. local function waveDispatcher( state )\\\
  4478.     local s = states[state]\\\
  4479.     s.timerProcess:newThread( function()\\\
  4480.         for i = s.savedata.stage, #waves do\\\
  4481.             if s.savedata.stage ~= i then\\\
  4482.                 s.savedata.stage = i\\\
  4483.                 saveState( state )\\\
  4484.             end\\\
  4485.             s.countdown = 15\\\
  4486.             for _ = 1, 15 do\\\
  4487.                 s.countdown = s.countdown - 1\\\
  4488.                 sleep( 1 )\\\
  4489.             end\\\
  4490.             s.countdown = nil\\\
  4491.             s.dispatch( unpack( waves[i] ) )\\\
  4492.             sleep( #waves[i] * .5 )\\\
  4493.             while #s.units > 0 do\\\
  4494.                 coroutine.yield()\\\
  4495.             end\\\
  4496.         end\\\
  4497.         fs.delete( config.installpath .. \\\"/saves/\\\" .. s.savename )\\\
  4498.         s.completed = true\\\
  4499.         s.changed = true\\\
  4500.     end ).onException = function( _ , err )\\\
  4501.         error( err, 0 )\\\
  4502.     end\\\
  4503. end\\\
  4504. \\\
  4505. local function coreUI( state )\\\
  4506.     local s = states[state]\\\
  4507.     local frame = s.frame\\\
  4508. \\\
  4509.     frame:newChild( UIKit.UIText( 1, frame.height, frame.width - 6, 1, \\\"\\\" ) ).bc = colours.lightGrey\\\
  4510.     frame:newChild( UIKit.UIText( 1, frame.height, 7, 1, \\\"#8&FHealth:\\\" ) )\\\
  4511.     frame:newChild( UIKit.UIText( 8, frame.height, 3, 1, function()\\\
  4512.         return \\\"#8&F\\\" .. s.savedata.health\\\
  4513.     end ) ).bc = colours.lightGrey\\\
  4514. \\\
  4515.     frame:newChild( UIKit.UIText( 13, frame.height, 6, 1, \\\"#8&FMoney:\\\" ) )\\\
  4516.     frame:newChild( UIKit.UIText( 19, frame.height, 5, 1, function()\\\
  4517.         return \\\"#8&F\\\" .. s.savedata.money\\\
  4518.     end ) ).bc = colours.lightGrey\\\
  4519. \\\
  4520.     frame:newChild( UIKit.UIText( 26, frame.height, 6, 1, \\\"#8&FStage:\\\" ) )\\\
  4521.     frame:newChild( UIKit.UIText( 32, frame.height, 2, 1, function()\\\
  4522.         return \\\"#8&F\\\" .. s.savedata.stage\\\
  4523.     end ) ).bc = colours.lightGrey\\\
  4524. \\\
  4525.     frame:newChild( UIKit.UIText( 35, frame.height, frame.width - 40, 1, function()\\\
  4526.         if s.countdown then\\\
  4527.             return \\\"#8&Fwave in \\\" .. s.countdown\\\
  4528.         end\\\
  4529.         return \\\"\\\"\\\
  4530.     end ) ).bc = colours.lightGrey\\\
  4531. end\\\
  4532. \\\
  4533. local function placementMap( state )\\\
  4534.     local banned = {}\\\
  4535.     local s = states[state]\\\
  4536.     local turrets = s.savedata.turrets\\\
  4537.     local path = s.mapdata.path\\\
  4538. \\\
  4539.     local function ban( x, y, w, h )\\\
  4540.         for _y = 1, h do\\\
  4541.             banned[y + _y - 1] = banned[y + _y - 1] or {}\\\
  4542.             for _x = 1, w do\\\
  4543.                 banned[y + _y - 1][x + _x - 1] = true\\\
  4544.             end\\\
  4545.         end\\\
  4546.     end\\\
  4547. \\\
  4548.     for i = 1, #path do\\\
  4549.         ban( path[i].x - 1, path[i].y, 3, 2 )\\\
  4550.     end\\\
  4551.     for i = 1, #turrets do\\\
  4552.         ban( turrets[i].x - 2, turrets[i].y - 1, 5, 3 )\\\
  4553.     end\\\
  4554. \\\
  4555.     local t = {}\\\
  4556.     for x = 1, s.mapdata.width do\\\
  4557.         for y = 1, s.mapdata.height do\\\
  4558.             if not banned[y] or not banned[y][x] then\\\
  4559.                 t[#t+1] = { x = x, y = y }\\\
  4560.             end\\\
  4561.         end\\\
  4562.     end\\\
  4563. \\\
  4564.     s.placementMap = t\\\
  4565. end\\\
  4566. \\\
  4567. local function showTurretInfo( state, turret )\\\
  4568.     local frame = states[state].frame:newChild( UIKit.UIFrame( states[state].frame.width + 1, 1, 16, states[state].frame.height - 1 ) )\\\
  4569. \\\
  4570.     frame:newChild( UIKit.UIText( 1, 1, 1, frame.height, \\\"\\\" ) ).bc = colours.lightGrey\\\
  4571.     frame:newChild( UIKit.UIText( 2, 1, frame.width - 1, frame.height, \\\"\\\" ) )\\\
  4572. \\\
  4573.     newTween( config.atime, frame, { x = states[state].frame.width - 15 }, \\\"inOutSine\\\" ).round = true\\\
  4574. \\\
  4575.     local c = frame:newChild( UIKit.UIText( 1, 1, 1, 1, \\\"#7&0>\\\" ) )\\\
  4576.     function c.callback:onClick()\\\
  4577.         local r = newTween( config.atime, frame, { x = states[state].frame.width + 1 }, \\\"inOutSine\\\" )\\\
  4578.         r.round = true\\\
  4579.         function r:onFinish()\\\
  4580.             frame:remove()\\\
  4581.         end\\\
  4582.     end\\\
  4583. \\\
  4584.     frame:newChild( UIKit.UIText( 2, 1, frame.width - 1, 1, \\\"#7&0 \\\" .. turret.name ) ).bc = colours.grey\\\
  4585.     frame:newChild( UIKit.UIText( 3, 5, frame.width - 3, 1, \\\"&8range\\\" ) )\\\
  4586.     frame:newChild( UIKit.UIText( 3, 6, frame.width - 3, 1, turret.range ) )\\\
  4587.     frame:newChild( UIKit.UIText( 3, 8, frame.width - 3, 1, \\\"&8rate of fire\\\" ) )\\\
  4588.     frame:newChild( UIKit.UIText( 3, 9, frame.width - 3, 1, turret.rateOfFire ) )\\\
  4589.     frame:newChild( UIKit.UIText( 3, 11, frame.width - 3, 1, \\\"&8damage\\\" ) )\\\
  4590.     frame:newChild( UIKit.UIText( 3, 12, frame.width - 3, 1, turret.damage ) )\\\
  4591.     frame:newChild( UIKit.UIText( 3, 14, frame.width - 3, 1, \\\"&8cost\\\" ) )\\\
  4592.     frame:newChild( UIKit.UIText( 3, 15, frame.width - 3, 1, turret.cost ) )\\\
  4593. \\\
  4594.     frame:newChild( UIKit.UIText( 3, 3, 5, 1, \\\"&8image\\\" ) )\\\
  4595.     local w, h = turret.image:getSize()\\\
  4596.     local image = frame:newChild( UIKit.UIImage( frame.width - w, 3, w, h, turret.image ) )\\\
  4597. \\\
  4598.     local place = frame:newChild( UIKit.UIText( 7, frame.height - 1, 5, 1, \\\"&9place\\\" ) )\\\
  4599.     function place.callback:onClick()\\\
  4600.         local s = states[state]\\\
  4601.         if s.savedata.money < turret.cost then\\\
  4602.             local message = s.frame:newChild( UIKit.UIText( 0, s.frame.height - 1, 17, 1, \\\"# &ENot enough money!\\\" ) )\\\
  4603.             message.bc = 0\\\
  4604.             message:centreX()\\\
  4605.             Process.newThread( function()\\\
  4606.                 sleep( 1.5 )\\\
  4607.                 message:remove()\\\
  4608.             end )\\\
  4609.             return\\\
  4610.         end\\\
  4611.         s.savedata.money = s.savedata.money - turret.cost\\\
  4612.         saveState( state )\\\
  4613.         local places = s.placementMap\\\
  4614.         local buttons = {}\\\
  4615.         for i = 1, #places do\\\
  4616.             local b = s.content:newChild( UIKit.UIText( places[i].x - s.scrollx, places[i].y - s.scrolly, 1, 1, \\\"#9&  \\\" ) )\\\
  4617.             function b.callback:onClick()\\\
  4618.                 for i = 1, #buttons do\\\
  4619.                     buttons[i]:remove()\\\
  4620.                 end\\\
  4621.                 table.insert( s.savedata.turrets, {\\\
  4622.                     turret = turret;\\\
  4623.                     lastfire = os.clock() - 1/turret.rateOfFire;\\\
  4624.                     x = places[i].x;\\\
  4625.                     y = places[i].y;\\\
  4626.                 } )\\\
  4627.                 placementMap( state )\\\
  4628.                 saveState( state )\\\
  4629.                 s.changed = true\\\
  4630.             end\\\
  4631.             table.insert( buttons, b )\\\
  4632.         end\\\
  4633.     end\\\
  4634. end\\\
  4635. \\\
  4636. local function turretUI( state )\\\
  4637.     local frame = states[state].frame:newChild( UIKit.UIFrame( states[state].frame.width - 15, 1, 16, states[state].frame.height - 1 ) )\\\
  4638. \\\
  4639.     frame:newChild( UIKit.UIText( 1, 1, 1, frame.height, \\\"\\\" ) ).bc = colours.lightGrey\\\
  4640.     frame:newChild( UIKit.UIText( 2, 1, frame.width - 1, frame.height, \\\"\\\" ) )\\\
  4641.     local content = frame:newChild( UIKit.UIFrame( 3, 2, frame.width - 4, frame.height - 2 ) )\\\
  4642.     local scrollbar = frame:newChild( UIKit.UIScrollBar( frame.width - 1, 2, 1, frame.height - 2, \\\"vertical\\\", content ) )\\\
  4643. \\\
  4644.     content:newChild( UIKit.UIText( 0, 1, 8, 1, \\\"Turrets:\\\" ) ):centreX()\\\
  4645.     local y = 3\\\
  4646.     for i = 1, #turrets do\\\
  4647.         local im = turrets[i].image\\\
  4648.         local w, h = im:getSize()\\\
  4649.         local name = content:newChild( UIKit.UIText( 0, y, #turrets[i].name, 1, turrets[i].name ) )\\\
  4650.         name:centreX()\\\
  4651.         local image = content:newChild( UIKit.UIImage( 0, y + 1, w, h, im ) )\\\
  4652.         image:centreX()\\\
  4653.         y = y + h + 2\\\
  4654.         function image.callback:onClick()\\\
  4655.             showTurretInfo( state, turrets[i] )\\\
  4656.         end\\\
  4657.         function name.callback:onClick()\\\
  4658.             showTurretInfo( state, turrets[i] )\\\
  4659.         end\\\
  4660.     end\\\
  4661. end\\\
  4662. \\\
  4663. local function turretHandler( state )\\\
  4664.     local s = states[state]\\\
  4665.     s.bullets = {}\\\
  4666.     s.turretHandler = Process \\\"TurretHandler\\\"\\\
  4667. \\\
  4668.     s.turretHandler:newThread( function()\\\
  4669.         while true do\\\
  4670.             local time = os.clock()\\\
  4671.             for i = 1, #s.savedata.turrets do\\\
  4672.                 local t = s.savedata.turrets[i]\\\
  4673.                 if time - t.lastfire >= 1/t.turret.rateOfFire then\\\
  4674.                     local r2 = t.turret.range ^ 2\\\
  4675.                     for i = 1, #s.units do\\\
  4676.                         if ( s.path[s.units[i].pos].x - t.x ) ^ 2 + ( s.path[s.units[i].pos].y - t.y ) ^ 2 <= r2 then\\\
  4677.                             \\\
  4678.                             local b = { x = t.x, y = t.y - 1, bc = t.turret.bullet.bc, tc = t.turret.bullet.tc, char = t.turret.bullet.char }\\\
  4679.                             local bt = newTween( .3, b, { x = s.path[s.units[i].pos].x, y = s.path[s.units[i].pos].y }, \\\"inSine\\\" )\\\
  4680.                             bt.round = true\\\
  4681.                             function bt:onFinish()\\\
  4682.                                 s.timerProcess:newThread( function()\\\
  4683.                                     sleep( .1 )\\\
  4684.                                     for i = 1, #s.bullets do\\\
  4685.                                         if s.bullets[i] == b then\\\
  4686.                                             table.remove( s.bullets, i )\\\
  4687.                                             break\\\
  4688.                                         end\\\
  4689.                                     end\\\
  4690.                                 end )\\\
  4691.                             end\\\
  4692.                             table.insert( s.bullets, b )\\\
  4693.                             if type( b.bc ) == \\\"function\\\" then setfenv( b.bc, { math = math } ) end\\\
  4694.                             if type( b.tc ) == \\\"function\\\" then setfenv( b.tc, { math = math } ) end\\\
  4695.                             if type( b.char ) == \\\"function\\\" then setfenv( b.char, { math = math } ) end\\\
  4696. \\\
  4697.                             s.units[i].unit.health = s.units[i].unit.health - t.turret.damage\\\
  4698.                             if s.units[i].unit.health <= 0 then\\\
  4699.                                 s.units[i].dead = true\\\
  4700.                                 s.savedata.money = s.savedata.money + s.units[i].unit.reward\\\
  4701.                                 table.remove( s.units, i )\\\
  4702.                                 s.changed = true\\\
  4703.                             end\\\
  4704.                             t.lastfire = time\\\
  4705.                             break\\\
  4706.                         end\\\
  4707.                     end\\\
  4708.                 end\\\
  4709.             end\\\
  4710.             coroutine.yield()\\\
  4711.         end\\\
  4712.     end ).onException = function( _, err )\\\
  4713.         error( err, 0 )\\\
  4714.     end\\\
  4715. end\\\
  4716. \\\
  4717. return function( savename )\\\
  4718. \\\
  4719.     local state = {}\\\
  4720.     states[state] = {}\\\
  4721.     states[state].savename = savename\\\
  4722. \\\
  4723.     local frame = window:newChild( UIKit.UIFrame( 1 - config.width, 1, config.width, config.height ) )\\\
  4724.     local content = frame:newChild( UIKit.UIFrame( 1, 1, frame.width, frame.height ) )\\\
  4725.     local back = frame:newChild( UIKit.UIText( frame.width - 5, frame.height, 6, 1, \\\"#7&8< exit\\\" ) )\\\
  4726.     function back.callback:onClick()\\\
  4727.         endState( state )\\\
  4728.     end\\\
  4729. \\\
  4730.     local i = newTween( config.atime, frame, { x = 1 }, \\\"outSine\\\" )\\\
  4731.     i.round = true\\\
  4732. \\\
  4733.     states[state].frame = frame\\\
  4734.     states[state].content = content\\\
  4735.     states[state].UIProcess = Process \\\"UIProcess\\\"\\\
  4736.     states[state].timerProcess = Process \\\"TimerProcess\\\"\\\
  4737. \\\
  4738.     if not loaddata( savename, state ) then\\\
  4739.         return\\\
  4740.     end\\\
  4741.     displayVars( state )\\\
  4742.     mapDisplay( state )\\\
  4743.     findPath( state )\\\
  4744.     unitDisplay( state )\\\
  4745.     dispatcher( state )\\\
  4746.     placementMap( state )\\\
  4747.     coreUI( state )\\\
  4748.     turretUI( state )\\\
  4749.     turretHandler( state )\\\
  4750.     waveDispatcher( state )\\\
  4751. \\\
  4752.     states[state].UIProcess:newThread( function()\\\
  4753.         local s = states[state]\\\
  4754.         local function pixel( x, y, bc, tc, char )\\\
  4755.             s.buffer:setPixel( x - s.scrollx, y - s.scrolly, bc, tc, char )\\\
  4756.         end\\\
  4757.         while true do\\\
  4758.             if s.changed then\\\
  4759.                 s.buffer:foreach( function()\\\
  4760.                     return 1, 1, \\\" \\\"\\\
  4761.                 end )\\\
  4762.                 if s.completed then\\\
  4763.                     s.display:remove()\\\
  4764.                     s.frame:newChild( UIKit.UIText( math.floor( ( s.frame.width - 16 ) / 2 - 5 ), math.floor( s.frame.height / 2 ), 10, 1, \\\"Completed!\\\" ) )\\\
  4765.                     s.UIProcess:stop()\\\
  4766.                     s.timerProcess:stop()\\\
  4767.                     s.turretHandler:stop()\\\
  4768.                 else\\\
  4769.                     s.map:foreach( function( bc, tc, char, x, y )\\\
  4770.                         pixel( x, y, bc, tc, char )\\\
  4771.                     end )\\\
  4772.                     for i = 1, #s.savedata.turrets do\\\
  4773.                         local im = s.savedata.turrets[i].turret.image\\\
  4774.                         im:foreach( function( bc, tc, char, xx, yy )\\\
  4775.                             local posx = xx + s.savedata.turrets[i].x - im:getSize() / 2 - 1\\\
  4776.                             local posy = yy + s.savedata.turrets[i].y - select( 2, im:getSize() )\\\
  4777.                             pixel( posx, posy, bc, tc, char )\\\
  4778.                         end )\\\
  4779.                     end\\\
  4780.                     for i = 1, #s.units do\\\
  4781.                         local im = s.units[i].unit.image\\\
  4782.                         im:foreach( function( bc, tc, char, xx, yy )\\\
  4783.                             local posx = xx + s.path[s.units[i].pos].x - im:getSize() / 2 - 1\\\
  4784.                             local posy = yy + s.path[s.units[i].pos].y - select( 2, im:getSize() )\\\
  4785.                             pixel( posx, posy, bc, tc, char )\\\
  4786.                         end )\\\
  4787.                     end\\\
  4788.                     for i = 1, #s.bullets do\\\
  4789.                         pixel( s.bullets[i].x, s.bullets[i].y, s.bullets[i].bc, s.bullets[i].tc, s.bullets[i].char )\\\
  4790.                     end\\\
  4791.                 end\\\
  4792.                 s.changed = false\\\
  4793.             end\\\
  4794.             coroutine.yield()\\\
  4795.         end\\\
  4796.     end ).onException = function( _, err )\\\
  4797.         error( err, 0 )\\\
  4798.     end\\\
  4799. end\"}\
  4800. files[12]={name=\"mapUI\";mode='lib';content=\"\\\
  4801. return function( map )\\\
  4802. \\\
  4803.     local frame = window:newChild( UIKit.UIFrame( 1 - config.width, 1, config.width, config.height ) )\\\
  4804.     local i = newTween( config.atime, frame, { x = 1 }, \\\"outSine\\\" )\\\
  4805.     i.round = true\\\
  4806. \\\
  4807.     local content = frame:newChild( UIKit.UIFrame( 1, 1, frame.width, frame.height ) )\\\
  4808. \\\
  4809.     local UIProcess = Process \\\"UIProcess\\\"\\\
  4810. \\\
  4811.     local back = frame:newChild( UIKit.UIText( 1, frame.height, 6, 1, \\\"#7&8< back\\\" ) )\\\
  4812.     function back.callback:onClick()\\\
  4813.         local r = newTween( config.atime, frame, { x = config.width + 1 }, \\\"inOutSine\\\" )\\\
  4814.         newTween( config.atime, background, { y = 1 }, \\\"inOutSine\\\" ).round = true\\\
  4815.         r.round = true\\\
  4816.         UIProcess:stop()\\\
  4817.         function r:onFinish()\\\
  4818.             frame:remove()\\\
  4819.             menuUI()\\\
  4820.         end\\\
  4821.     end\\\
  4822. \\\
  4823.     local h = fs.open( config.installpath .. \\\"/assets/maps/\\\" .. map, \\\"r\\\" )\\\
  4824.     if not h then\\\
  4825.         content:newChild( UIKit.UIText( 0, 0, 19, 1, \\\"&ECouldn't load map.\\\" ) ):centre()\\\
  4826.         return\\\
  4827.     end\\\
  4828. \\\
  4829.     local mapdata = textutils.unserialize( \\\"{\\\" .. h.readAll() .. \\\"}\\\" )\\\
  4830.     h.close()\\\
  4831. \\\
  4832.     if type( mapdata ) ~= \\\"table\\\" then\\\
  4833.         content:newChild( UIKit.UIText( 0, 0, 12, 1, \\\"&ECorrupt map.\\\" ) ):centre()\\\
  4834.         return\\\
  4835.     end\\\
  4836. \\\
  4837.     local background = Gfx2D.Image( mapdata.width, mapdata.height )\\\
  4838.     background:foreach( function()\\\
  4839.         return colours.green\\\
  4840.     end )\\\
  4841.     for i = 1, mapdata.width * mapdata.height / 10 do\\\
  4842.         local x = math.random( 1, mapdata.width )\\\
  4843.         local y = math.random( 2, mapdata.height )\\\
  4844.         background:setPixel( x, y, colours.green, colours.lime, \\\"v\\\" )\\\
  4845.     end\\\
  4846. \\\
  4847.     local scrollx, scrolly = 0, 0\\\
  4848. \\\
  4849.     local buffer = Gfx2D.Image( content.width, content.height )\\\
  4850.     local display = content:newChild( UIKit.UIImage( 1, 1, content.width, content.height, buffer ) )\\\
  4851.     local changed = true\\\
  4852. \\\
  4853.     local function drawAll()\\\
  4854.         local function pixel( x, y, bc, tc, char )\\\
  4855.             buffer:setPixel( x - scrollx, y - scrolly, bc, tc, char )\\\
  4856.         end\\\
  4857. \\\
  4858.         while true do\\\
  4859.             if changed then\\\
  4860.                 buffer:foreach( function()\\\
  4861.                     return 1, 1, \\\" \\\"\\\
  4862.                 end )\\\
  4863.                 background:foreach( function( bc, tc, char, x, y )\\\
  4864.                     pixel( x, y, bc, tc, char )\\\
  4865.                 end )\\\
  4866.                 for i = 1, #mapdata.path do\\\
  4867.                     pixel( mapdata.path[i].x, mapdata.path[i].y, colours.grey, 1, \\\" \\\" )\\\
  4868.                 end\\\
  4869.                 pixel( mapdata.start.x, mapdata.start.y, colours.blue, 1, \\\" \\\" )\\\
  4870.                 pixel( mapdata.finish.x, mapdata.finish.y, colours.magenta, 1, \\\" \\\" )\\\
  4871.                 changed = false\\\
  4872.             end\\\
  4873.             coroutine.yield()\\\
  4874.         end\\\
  4875.     end\\\
  4876. \\\
  4877.     frame:newChild( UIKit.UIText( frame.width - 5, 1, 6, frame.height, \\\"\\\" ) ).bc = colours.lightGrey\\\
  4878.     local plus = frame:newChild( UIKit.UIImage( frame.width - 4, 1, 5, 5, images.plus ) )\\\
  4879.     local move = frame:newChild( UIKit.UIImage( frame.width - 4, 7, 5, 5, images.move ) )\\\
  4880.     local delete = frame:newChild( UIKit.UIImage( frame.width - 4, 13, 5, 5, images.delete ) )\\\
  4881.     local save = frame:newChild( UIKit.UIText( frame.width - 4, frame.height, 4, 1, \\\"#8&7save\\\" ) )\\\
  4882.     \\\
  4883.     local tool = \\\"move\\\"\\\
  4884. \\\
  4885.     function plus.callback:onClick()\\\
  4886.         tool = \\\"add\\\"\\\
  4887.     end\\\
  4888.     function move.callback:onClick()\\\
  4889.         tool = \\\"move\\\"\\\
  4890.     end\\\
  4891.     function delete.callback:onClick()\\\
  4892.         tool = \\\"delete\\\"\\\
  4893.     end\\\
  4894. \\\
  4895.     function display.callback:onClick( button, x, y )\\\
  4896.         if tool == \\\"delete\\\" then\\\
  4897.             for i = 1, #mapdata.path do\\\
  4898.                 if mapdata.path[i].x == x + scrollx and mapdata.path[i].y == y + scrolly then\\\
  4899.                     table.remove( mapdata.path, i )\\\
  4900.                     changed = true\\\
  4901.                     return\\\
  4902.                 end\\\
  4903.             end\\\
  4904.         elseif tool == \\\"add\\\" then\\\
  4905.             for i = 1, #mapdata.path do\\\
  4906.                 if mapdata.path[i].x == x + scrollx and mapdata.path[i].y == y + scrolly then\\\
  4907.                     return\\\
  4908.                 end\\\
  4909.             end\\\
  4910.             changed = true\\\
  4911.             table.insert( mapdata.path, { x = x + scrollx, y = y + scrolly } )\\\
  4912.         end\\\
  4913.     end\\\
  4914. \\\
  4915.     function display.callback:onDrag( button, x, y, lx, ly )\\\
  4916.         if tool == \\\"move\\\" then\\\
  4917.             changed = true\\\
  4918.             scrollx = scrollx - x + lx\\\
  4919.             scrolly = scrolly - y + ly\\\
  4920.         elseif tool == \\\"delete\\\" then\\\
  4921.             for i = 1, #mapdata.path do\\\
  4922.                 if mapdata.path[i].x == x + scrollx and mapdata.path[i].y == y + scrolly then\\\
  4923.                     table.remove( mapdata.path, i )\\\
  4924.                     changed = true\\\
  4925.                     return\\\
  4926.                 end\\\
  4927.             end\\\
  4928.         elseif tool == \\\"add\\\" then\\\
  4929.             for i = 1, #mapdata.path do\\\
  4930.                 if mapdata.path[i].x == x + scrollx and mapdata.path[i].y == y + scrolly then\\\
  4931.                     return\\\
  4932.                 end\\\
  4933.             end\\\
  4934.             changed = true\\\
  4935.             table.insert( mapdata.path, { x = x + scrollx, y = y + scrolly } )\\\
  4936.         end\\\
  4937.     end\\\
  4938. \\\
  4939.     function save.callback:onClick()\\\
  4940.         local h = fs.open( config.installpath .. \\\"/assets/maps/\\\" .. map, \\\"w\\\" )\\\
  4941.         if h then\\\
  4942.             h.write( textutils.serialize( mapdata ):sub( 2, -2 ) )\\\
  4943.             h.close()\\\
  4944.         else\\\
  4945.             local t = frame:newChild( UIKit.UIText( 1, 1, 14, 1, \\\"# &ECouldn't save.\\\" ) )\\\
  4946.             UIProcess:newThread( function()\\\
  4947.                 sleep( config.sleep )\\\
  4948.                 t:remove()\\\
  4949.             end )\\\
  4950.         end\\\
  4951.     end\\\
  4952. \\\
  4953.     function i:onFinish()\\\
  4954.         UIProcess:newThread( drawAll ).onException = function( _, err )\\\
  4955.             error( err, 0 )\\\
  4956.         end\\\
  4957.     end\\\
  4958. end\"}\
  4959. files[13]={name=\"menuUI\";mode='lib';content=\"\\\
  4960. return function()\\\
  4961.     local menuFrame = window:newChild( UIKit.UIFrame( 1, 1, config.width, config.height ) )\\\
  4962. \\\
  4963.     local ng = menuFrame:newChild( UIKit.UIText( config.width + 1, 7, 8, 1, \\\"#7&8New Game\\\" ) )\\\
  4964.     local lg = menuFrame:newChild( UIKit.UIText( config.width + 1, 8, 9, 1, \\\"#7&8Load Game\\\" ) )\\\
  4965.     local cm = menuFrame:newChild( UIKit.UIText( config.width + 1, 10, 10, 1, \\\"#7&8Create Map\\\" ) )\\\
  4966.     local em = menuFrame:newChild( UIKit.UIText( config.width + 1, 11, 8, 1, \\\"#7&8Edit Map\\\" ) )\\\
  4967.     local qg = menuFrame:newChild( UIKit.UIText( config.width + 1, 14, 9, 1, \\\"#7&8Quit Game\\\" ) )\\\
  4968.     newTween( config.atime, ng, { x = 33 }, \\\"outSine\\\" ).round = true\\\
  4969.     newTween( config.atime, lg, { x = 33 }, \\\"outSine\\\" ).round = true\\\
  4970.     newTween( config.atime, cm, { x = 33 }, \\\"outSine\\\" ).round = true\\\
  4971.     newTween( config.atime, em, { x = 33 }, \\\"outSine\\\" ).round = true\\\
  4972.     newTween( config.atime, qg, { x = 33 }, \\\"outSine\\\" ).round = true\\\
  4973. \\\
  4974.     function ng.callback:onClick()\\\
  4975.         local r = newTween( config.atime, menuFrame, { x = config.width + 1 }, \\\"inSine\\\" )\\\
  4976.         r.round = true\\\
  4977.         function r:onFinish()\\\
  4978.             menuFrame:remove()\\\
  4979.             newGameUI()\\\
  4980.         end\\\
  4981.     end\\\
  4982.     function lg.callback:onClick()\\\
  4983.         local r = newTween( config.atime, menuFrame, { x = config.width + 1 }, \\\"inSine\\\" )\\\
  4984.         r.round = true\\\
  4985.         function r:onFinish()\\\
  4986.             menuFrame:remove()\\\
  4987.             loadGameUI()\\\
  4988.         end\\\
  4989.     end\\\
  4990.     function cm.callback:onClick()\\\
  4991.         local r = newTween( config.atime, menuFrame, { x = config.width + 1 }, \\\"inSine\\\" )\\\
  4992.         r.round = true\\\
  4993.         function r:onFinish()\\\
  4994.             menuFrame:remove()\\\
  4995.             createMapUI()\\\
  4996.         end\\\
  4997.     end\\\
  4998.     function em.callback:onClick()\\\
  4999.         local r = newTween( config.atime, menuFrame, { x = config.width + 1 }, \\\"inSine\\\" )\\\
  5000.         r.round = true\\\
  5001.         function r:onFinish()\\\
  5002.             menuFrame:remove()\\\
  5003.             editMapUI()\\\
  5004.         end\\\
  5005.     end\\\
  5006.     function qg.callback:onClick()\\\
  5007.         global.running = false\\\
  5008.     end\\\
  5009. end\"}\
  5010. apiCount=0\
  5011. dependencies[1]=\"Gfx2D.lua\"\
  5012. dependencies[2]=\"Math2D.lua\"\
  5013. dependencies[3]=\"Process.lua\"\
  5014. dependencies[4]=\"Traceback.lua\"\
  5015. dependencies[5]=\"Tween.lua\"\
  5016. dependencies[6]=\"UIKit.lua\"\
  5017. mainContent=\"\\\
  5018. Gfx2D.buffer.current().allchanged = true\\\
  5019. \\\
  5020. global.windowManager = UIKit.WindowManager()\\\
  5021. global.window = windowManager:newWindow( config.target, config.width, config.height )\\\
  5022. global.tweens = {}\\\
  5023. global.running = true\\\
  5024. \\\
  5025. local p = windowManager:run()\\\
  5026. p.onException = function( _, err )\\\
  5027.     error( err, 0 )\\\
  5028. end\\\
  5029. \\\
  5030. local ok, err = xpcall( function()\\\
  5031. \\\
  5032. function global.newTween( ... )\\\
  5033.     local tween = Tween.new( ... )\\\
  5034.     table.insert( tweens, tween )\\\
  5035.     return tween\\\
  5036. end\\\
  5037. \\\
  5038. global.background = window:newChild( UIKit.UIImage( 1, 1, config.width, config.height, images.logo ) )\\\
  5039. \\\
  5040. local creators = window:newChild( UIKit.UIText( 33, 9, 15, 3, \\\"#7&8by\\\\n&0Benedict Allen\\\\nRequiem\\\" ) )\\\
  5041. creators.bc = colours.grey\\\
  5042. creators.align = \\\"top, centre\\\"\\\
  5043. creators:wrap()\\\
  5044. creators:reload()\\\
  5045. \\\
  5046. Process.newThread( function()\\\
  5047.     sleep( config.sleep )\\\
  5048.     local ct = newTween( config.atime, creators, { x = config.width + 1 }, \\\"inSine\\\" )\\\
  5049.     ct.round = true\\\
  5050.     function ct:onFinish()\\\
  5051.         creators:remove()\\\
  5052.         menuUI()\\\
  5053.     end\\\
  5054. end ).onException = function( _, err )\\\
  5055.     error( err, 0 )\\\
  5056. end\\\
  5057. \\\
  5058. -----------------------------------------------------------------------------------------------------------\\\
  5059. \\\
  5060. local _running = true\\\
  5061. \\\
  5062. local time = os.clock()\\\
  5063. local timer = os.startTimer( 0 )\\\
  5064. while running or _running do\\\
  5065.     if not running then\\\
  5066.         local backwin = windowManager:newWindow( config.target, config.width, config.height )\\\
  5067.         backwin:newChild( UIKit.UIText( 1, 1, config.width, config.height ) ).bc = 32768\\\
  5068.         backwin.y = config.height\\\
  5069.         local r = newTween( config.atime, window, { y = 1 - config.height }, \\\"inOutSine\\\" )\\\
  5070.         newTween( config.atime, backwin, { y = 1 }, \\\"inOutSine\\\" ).round = true\\\
  5071.         r.round = true\\\
  5072.         function r:onFinish()\\\
  5073.             backwin:remove()\\\
  5074.             _running = false\\\
  5075.         end\\\
  5076.         _running = config.atime\\\
  5077.     end\\\
  5078.     local ev = { coroutine.yield() }\\\
  5079.     if ev[1] == \\\"timer\\\" and ev[2] == timer then\\\
  5080.         local dt = os.clock() - time\\\
  5081.         time = os.clock()\\\
  5082.         timer = os.startTimer( 0.05 )\\\
  5083. \\\
  5084.         if type( _running ) == \\\"number\\\" then\\\
  5085.             _running = _running - dt\\\
  5086.         end\\\
  5087. \\\
  5088.         for i = #tweens, 1, -1 do\\\
  5089.             tweens[i]:update( dt )\\\
  5090.             if tweens[i].clock == tweens[i].duration then\\\
  5091.                 if type( tweens[i].onFinish ) == \\\"function\\\" then\\\
  5092.                     tweens[i]:onFinish()\\\
  5093.                 end\\\
  5094.                 table.remove( tweens, i )\\\
  5095.             end\\\
  5096.         end\\\
  5097.         Process.resume( \\\"update\\\", dt )\\\
  5098.     elseif ev[1] == \\\"terminate\\\" then\\\
  5099.         running = false\\\
  5100.     else\\\
  5101.         Process.resume( unpack( ev ) )\\\
  5102.     end\\\
  5103. end\\\
  5104. \\\
  5105. end, function( err, lvl )\\\
  5106.     local t = Traceback( 2 )\\\
  5107.     local str = tostring( err )\\\
  5108.     local x = false\\\
  5109.     for i = 1, #t do\\\
  5110.         if t[i] == \\\"xpcall\\\" then\\\
  5111.             x = true\\\
  5112.         end\\\
  5113.         if x and t[i] == \\\"[NightFall] main:14\\\" then\\\
  5114.             for e = 1, i - 2 do\\\
  5115.                 str = str .. \\\"\\\\n  in \\\" .. t[e]\\\
  5116.             end\\\
  5117.             break\\\
  5118.         end\\\
  5119.     end\\\
  5120.     term.setBackgroundColour( colours.black )\\\
  5121.     printError( str )\\\
  5122. end )\\\
  5123. \\\
  5124. window:remove()\\\
  5125. p:stop()\\\
  5126. \\\
  5127. if not ok then\\\
  5128.     return\\\
  5129. end\\\
  5130. \\\
  5131. term.setBackgroundColour( 32768 )\\\
  5132. term.clear()\\\
  5133. term.setCursorPos( 1, 1 )\\\
  5134. \\\
  5135. print \\\"Thank you for playing NightFall\\\"\"\
  5136. local env = setmetatable( {}, { __index = getfenv() } )\
  5137. env.global = env\
  5138. env.args = { ... }\
  5139. local public = {}\
  5140. local bloaded = _G[\"_bundleLoaded\"]\
  5141. if type( bloaded ) ~= \"table\" then bloaded = {} _G[\"_bundleLoaded\"] = bloaded end\
  5142. \
  5143. if bloaded[name] and not mainContent then\
  5144.     return bloaded[name]\
  5145. end\
  5146. \
  5147. for i = 1, #dependencies do\
  5148.     if bloaded and bloaded[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] then\
  5149.         env[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] = bloaded[dependencies[i]:gsub(\"%.lua$\", \"\", 1)]\
  5150.     else\
  5151.         local path = ( _G[\"_bundleDependencyPath\"] or \"\" ) .. \"/\" .. dependencies[i]\
  5152.         local f, err = loadfile( path )\
  5153.         if f then\
  5154.             setfenv( f, getfenv() )\
  5155.             env[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] = f()\
  5156.         else\
  5157.             error( name .. \" requires bundle '\" .. dependencies[i] .. \"'\", 0 )\
  5158.         end\
  5159.     end\
  5160. end\
  5161. for i = 1, #requires do\
  5162.     if bloaded and bloaded[requires[i]:gsub(\"%.lua$\", \"\", 1)] then\
  5163.         env[requires[i]:gsub(\"%.lua$\", \"\", 1)] = bloaded[requires[i]:gsub(\"%.lua$\", \"\", 1)]\
  5164.     else\
  5165.         local path = ( _G[\"_bundleDependencyPath\"] or \"\" ) .. \"/\" .. requires[i]\
  5166.         local f, err = loadfile( path )\
  5167.         if f then\
  5168.             setfenv( f, getfenv() )\
  5169.             env[requires[i]:gsub(\"%.lua$\", \"\", 1)] = f()\
  5170.         end\
  5171.     end\
  5172. end\
  5173. \
  5174. for i = 1, #files do\
  5175.     local f, err = loadstring( files[i].content, \"[\" .. name .. \"] \" .. files[i].name )\
  5176.     if f then\
  5177.         local e = setmetatable( {}, { __index = env } )\
  5178.         setfenv( f, e )\
  5179.         local ok, data = pcall( f, ... )\
  5180.         if not ok then\
  5181.             printError( data )\
  5182.             break\
  5183.         end\
  5184.         if data == nil then\
  5185.             data = {}\
  5186.             for k, v in pairs( e ) do\
  5187.                 data[k] = v\
  5188.             end\
  5189.         end\
  5190.         if files[i].mode == \"api\" then\
  5191.             if apiCount == 1 then\
  5192.                 public = data\
  5193.             else\
  5194.                 public[files[i].name] = data\
  5195.                 env[files[i].name] = data\
  5196.             end\
  5197.         else\
  5198.             env[files[i].name] = data\
  5199.         end\
  5200.     else\
  5201.         printError( err )\
  5202.         break\
  5203.     end\
  5204. end\
  5205. \
  5206. if mainContent then\
  5207.     local f, err = loadstring( mainContent, \"[\" .. name .. \"] main\" )\
  5208.     if f then\
  5209.         setfenv( f, env )\
  5210.         local ok, data = pcall( f, ... )\
  5211.         if not ok then\
  5212.             printError( data )\
  5213.         end\
  5214.     else\
  5215.         printError( err )\
  5216.     end\
  5217. end\
  5218. \
  5219. bloaded[name] = public\
  5220. return public";["assets"]={["turrets"]={["5"]="name=\"Laser\";\
  5221. range=20;\
  5222. rateOfFire=.5;\
  5223. damage=10;\
  5224. cost=250;\
  5225. image=\"   E0    \\nF0 80 F0 \";\
  5226. bullet = {\
  5227.     bc = 16384;\
  5228.     tc = 1;\
  5229.     char = \" \";\
  5230. };";["4"]="name=\"Cannon\";\
  5231. range=4;\
  5232. rateOfFire=.1;\
  5233. damage=10;\
  5234. cost=100;\
  5235. image=\"F0 F0 80 \\n   80 80 \";\
  5236. bullet = {\
  5237.     bc = 0;\
  5238.     tc = 16;\
  5239.     char = \"@\";\
  5240. };";["1"]="name=\"Heavy Gun\";\
  5241. range=6;\
  5242. rateOfFire=.25;\
  5243. damage=2;\
  5244. cost=40;\
  5245. image=\" F-F0 80 \\n80 80 80 \";\
  5246. bullet = {\
  5247.     bc = 0;\
  5248.     tc = 16;\
  5249.     char = \"o\";\
  5250. };";["0"]="name=\"Basic Gun\";\
  5251. range=5;\
  5252. rateOfFire=.5;\
  5253. damage=1;\
  5254. cost=20;\
  5255. image=\" F-F0    \\n   80    \";\
  5256. bullet = {\
  5257.     bc = 0;\
  5258.     tc = 16;\
  5259.     char = \".\";\
  5260. };";["3"]="name=\"Flamethrower\";\
  5261. range=10;\
  5262. rateOfFire=10;\
  5263. damage=.2;\
  5264. cost=50;\
  5265. image=\" F-F0 E0 \\n80 80 E0 \";\
  5266. bullet = {\
  5267.     bc = function()\
  5268.         local cols = { 2 ^ 14, 16, 2 }\
  5269.         return cols[math.random( 1, 3 )]\
  5270.     end;\
  5271.     tc = 1;\
  5272.     char = \" \";\
  5273. };";["2"]="name=\"Machine Gun\";\
  5274. range=8;\
  5275. rateOfFire=3;\
  5276. damage=.5;\
  5277. cost=50;\
  5278. image=\" F-F0 8F=\\n80 80 8F=\";\
  5279. bullet = {\
  5280.     bc = 0;\
  5281.     tc = 16;\
  5282.     char = \".\";\
  5283. };"};["maps"]={["map1"]="\
  5284.  start = {\
  5285.    y = 1,\
  5286.    x = 1,\
  5287.  },\
  5288.  width = 35,\
  5289.  assets = {},\
  5290.  height = 18,\
  5291.  finish = {\
  5292.    y = 18,\
  5293.    x = 35,\
  5294.  },\
  5295.  path = {\
  5296.    {\
  5297.      y = 1,\
  5298.      x = 1,\
  5299.    },\
  5300.    {\
  5301.      y = 1,\
  5302.      x = 2,\
  5303.    },\
  5304.    {\
  5305.      y = 1,\
  5306.      x = 3,\
  5307.    },\
  5308.    {\
  5309.      y = 1,\
  5310.      x = 4,\
  5311.    },\
  5312.    {\
  5313.      y = 1,\
  5314.      x = 5,\
  5315.    },\
  5316.    {\
  5317.      y = 1,\
  5318.      x = 6,\
  5319.    },\
  5320.    {\
  5321.      y = 1,\
  5322.      x = 7,\
  5323.    },\
  5324.    {\
  5325.      y = 1,\
  5326.      x = 8,\
  5327.    },\
  5328.    {\
  5329.      y = 1,\
  5330.      x = 9,\
  5331.    },\
  5332.    {\
  5333.      y = 1,\
  5334.      x = 10,\
  5335.    },\
  5336.    {\
  5337.      y = 1,\
  5338.      x = 11,\
  5339.    },\
  5340.    {\
  5341.      y = 1,\
  5342.      x = 12,\
  5343.    },\
  5344.    {\
  5345.      y = 1,\
  5346.      x = 13,\
  5347.    },\
  5348.    {\
  5349.      y = 1,\
  5350.      x = 14,\
  5351.    },\
  5352.    {\
  5353.      y = 1,\
  5354.      x = 15,\
  5355.    },\
  5356.    {\
  5357.      y = 2,\
  5358.      x = 15,\
  5359.    },\
  5360.    {\
  5361.      y = 3,\
  5362.      x = 15,\
  5363.    },\
  5364.    {\
  5365.      y = 4,\
  5366.      x = 15,\
  5367.    },\
  5368.    {\
  5369.      y = 5,\
  5370.      x = 15,\
  5371.    },\
  5372.    {\
  5373.      y = 6,\
  5374.      x = 15,\
  5375.    },\
  5376.    {\
  5377.      y = 7,\
  5378.      x = 15,\
  5379.    },\
  5380.    {\
  5381.      y = 7,\
  5382.      x = 14,\
  5383.    },\
  5384.    {\
  5385.      y = 7,\
  5386.      x = 13,\
  5387.    },\
  5388.    {\
  5389.      y = 7,\
  5390.      x = 12,\
  5391.    },\
  5392.    {\
  5393.      y = 7,\
  5394.      x = 11,\
  5395.    },\
  5396.    {\
  5397.      y = 7,\
  5398.      x = 10,\
  5399.    },\
  5400.    {\
  5401.      y = 7,\
  5402.      x = 9,\
  5403.    },\
  5404.    {\
  5405.      y = 7,\
  5406.      x = 8,\
  5407.    },\
  5408.    {\
  5409.      y = 7,\
  5410.      x = 7,\
  5411.    },\
  5412.    {\
  5413.      y = 7,\
  5414.      x = 6,\
  5415.    },\
  5416.    {\
  5417.      y = 7,\
  5418.      x = 5,\
  5419.    },\
  5420.    {\
  5421.      y = 8,\
  5422.      x = 5,\
  5423.    },\
  5424.    {\
  5425.      y = 9,\
  5426.      x = 5,\
  5427.    },\
  5428.    {\
  5429.      y = 10,\
  5430.      x = 5,\
  5431.    },\
  5432.    {\
  5433.      y = 11,\
  5434.      x = 5,\
  5435.    },\
  5436.    {\
  5437.      y = 11,\
  5438.      x = 22,\
  5439.    },\
  5440.    {\
  5441.      y = 4,\
  5442.      x = 25,\
  5443.    },\
  5444.    {\
  5445.      y = 4,\
  5446.      x = 26,\
  5447.    },\
  5448.    {\
  5449.      y = 4,\
  5450.      x = 27,\
  5451.    },\
  5452.    {\
  5453.      y = 4,\
  5454.      x = 28,\
  5455.    },\
  5456.    {\
  5457.      y = 4,\
  5458.      x = 29,\
  5459.    },\
  5460.    {\
  5461.      y = 18,\
  5462.      x = 31,\
  5463.    },\
  5464.    {\
  5465.      y = 18,\
  5466.      x = 32,\
  5467.    },\
  5468.    {\
  5469.      y = 18,\
  5470.      x = 33,\
  5471.    },\
  5472.    {\
  5473.      y = 18,\
  5474.      x = 34,\
  5475.    },\
  5476.    {\
  5477.      y = 18,\
  5478.      x = 35,\
  5479.    },\
  5480.    {\
  5481.      y = 4,\
  5482.      x = 24,\
  5483.    },\
  5484.    {\
  5485.      y = 10,\
  5486.      x = 22,\
  5487.    },\
  5488.    {\
  5489.      y = 9,\
  5490.      x = 22,\
  5491.    },\
  5492.    {\
  5493.      y = 8,\
  5494.      x = 22,\
  5495.    },\
  5496.    {\
  5497.      y = 7,\
  5498.      x = 22,\
  5499.    },\
  5500.    {\
  5501.      y = 6,\
  5502.      x = 22,\
  5503.    },\
  5504.    {\
  5505.      y = 5,\
  5506.      x = 22,\
  5507.    },\
  5508.    {\
  5509.      y = 4,\
  5510.      x = 22,\
  5511.    },\
  5512.    {\
  5513.      y = 4,\
  5514.      x = 23,\
  5515.    },\
  5516.    {\
  5517.      y = 13,\
  5518.      x = 22,\
  5519.    },\
  5520.    {\
  5521.      y = 13,\
  5522.      x = 21,\
  5523.    },\
  5524.    {\
  5525.      y = 13,\
  5526.      x = 20,\
  5527.    },\
  5528.    {\
  5529.      y = 13,\
  5530.      x = 19,\
  5531.    },\
  5532.    {\
  5533.      y = 13,\
  5534.      x = 18,\
  5535.    },\
  5536.    {\
  5537.      y = 13,\
  5538.      x = 17,\
  5539.    },\
  5540.    {\
  5541.      y = 13,\
  5542.      x = 16,\
  5543.    },\
  5544.    {\
  5545.      y = 13,\
  5546.      x = 15,\
  5547.    },\
  5548.    {\
  5549.      y = 13,\
  5550.      x = 14,\
  5551.    },\
  5552.    {\
  5553.      y = 13,\
  5554.      x = 13,\
  5555.    },\
  5556.    {\
  5557.      y = 13,\
  5558.      x = 12,\
  5559.    },\
  5560.    {\
  5561.      y = 13,\
  5562.      x = 11,\
  5563.    },\
  5564.    {\
  5565.      y = 13,\
  5566.      x = 10,\
  5567.    },\
  5568.    {\
  5569.      y = 13,\
  5570.      x = 9,\
  5571.    },\
  5572.    {\
  5573.      y = 13,\
  5574.      x = 8,\
  5575.    },\
  5576.    {\
  5577.      y = 13,\
  5578.      x = 7,\
  5579.    },\
  5580.    {\
  5581.      y = 13,\
  5582.      x = 6,\
  5583.    },\
  5584.    {\
  5585.      y = 13,\
  5586.      x = 5,\
  5587.    },\
  5588.    {\
  5589.      y = 12,\
  5590.      x = 5,\
  5591.    },\
  5592.    {\
  5593.      y = 12,\
  5594.      x = 22,\
  5595.    },\
  5596.    {\
  5597.      y = 9,\
  5598.      x = 30,\
  5599.    },\
  5600.    {\
  5601.      y = 10,\
  5602.      x = 30,\
  5603.    },\
  5604.    {\
  5605.      y = 11,\
  5606.      x = 30,\
  5607.    },\
  5608.    {\
  5609.      y = 12,\
  5610.      x = 30,\
  5611.    },\
  5612.    {\
  5613.      y = 18,\
  5614.      x = 30,\
  5615.    },\
  5616.    {\
  5617.      y = 17,\
  5618.      x = 30,\
  5619.    },\
  5620.    {\
  5621.      y = 16,\
  5622.      x = 30,\
  5623.    },\
  5624.    {\
  5625.      y = 15,\
  5626.      x = 30,\
  5627.    },\
  5628.    {\
  5629.      y = 13,\
  5630.      x = 30,\
  5631.    },\
  5632.    {\
  5633.      y = 14,\
  5634.      x = 30,\
  5635.    },\
  5636.    {\
  5637.      y = 8,\
  5638.      x = 30,\
  5639.    },\
  5640.    {\
  5641.      y = 7,\
  5642.      x = 30,\
  5643.    },\
  5644.    {\
  5645.      y = 6,\
  5646.      x = 30,\
  5647.    },\
  5648.    {\
  5649.      y = 5,\
  5650.      x = 30,\
  5651.    },\
  5652.    {\
  5653.      y = 4,\
  5654.      x = 30,\
  5655.    },\
  5656.  },";["map2"]="\
  5657.  start = {\
  5658.    y = 1,\
  5659.    x = 1,\
  5660.  },\
  5661.  width = 35,\
  5662.  assets = {},\
  5663.  height = 18,\
  5664.  finish = {\
  5665.    y = 18,\
  5666.    x = 35,\
  5667.  },\
  5668.  path = {\
  5669.    {\
  5670.      y = 1,\
  5671.      x = 1,\
  5672.    },\
  5673.    {\
  5674.      y = 1,\
  5675.      x = 2,\
  5676.    },\
  5677.    {\
  5678.      y = 1,\
  5679.      x = 3,\
  5680.    },\
  5681.    {\
  5682.      y = 1,\
  5683.      x = 4,\
  5684.    },\
  5685.    {\
  5686.      y = 1,\
  5687.      x = 5,\
  5688.    },\
  5689.    {\
  5690.      y = 1,\
  5691.      x = 6,\
  5692.    },\
  5693.    {\
  5694.      y = 1,\
  5695.      x = 7,\
  5696.    },\
  5697.    {\
  5698.      y = 1,\
  5699.      x = 8,\
  5700.    },\
  5701.    {\
  5702.      y = 1,\
  5703.      x = 9,\
  5704.    },\
  5705.    {\
  5706.      y = 1,\
  5707.      x = 10,\
  5708.    },\
  5709.    {\
  5710.      y = 2,\
  5711.      x = 10,\
  5712.    },\
  5713.    {\
  5714.      y = 3,\
  5715.      x = 10,\
  5716.    },\
  5717.    {\
  5718.      y = 4,\
  5719.      x = 10,\
  5720.    },\
  5721.    {\
  5722.      y = 5,\
  5723.      x = 10,\
  5724.    },\
  5725.    {\
  5726.      y = 6,\
  5727.      x = 10,\
  5728.    },\
  5729.    {\
  5730.      y = 6,\
  5731.      x = 9,\
  5732.    },\
  5733.    {\
  5734.      y = 7,\
  5735.      x = 9,\
  5736.    },\
  5737.    {\
  5738.      y = 8,\
  5739.      x = 9,\
  5740.    },\
  5741.    {\
  5742.      y = 8,\
  5743.      x = 8,\
  5744.    },\
  5745.    {\
  5746.      y = 8,\
  5747.      x = 7,\
  5748.    },\
  5749.    {\
  5750.      y = 9,\
  5751.      x = 7,\
  5752.    },\
  5753.    {\
  5754.      y = 10,\
  5755.      x = 7,\
  5756.    },\
  5757.    {\
  5758.      y = 11,\
  5759.      x = 7,\
  5760.    },\
  5761.    {\
  5762.      y = 12,\
  5763.      x = 7,\
  5764.    },\
  5765.    {\
  5766.      y = 12,\
  5767.      x = 6,\
  5768.    },\
  5769.    {\
  5770.      y = 12,\
  5771.      x = 5,\
  5772.    },\
  5773.    {\
  5774.      y = 12,\
  5775.      x = 4,\
  5776.    },\
  5777.    {\
  5778.      y = 13,\
  5779.      x = 4,\
  5780.    },\
  5781.    {\
  5782.      y = 14,\
  5783.      x = 4,\
  5784.    },\
  5785.    {\
  5786.      y = 15,\
  5787.      x = 4,\
  5788.    },\
  5789.    {\
  5790.      y = 15,\
  5791.      x = 5,\
  5792.    },\
  5793.    {\
  5794.      y = 15,\
  5795.      x = 6,\
  5796.    },\
  5797.    {\
  5798.      y = 15,\
  5799.      x = 7,\
  5800.    },\
  5801.    {\
  5802.      y = 15,\
  5803.      x = 8,\
  5804.    },\
  5805.    {\
  5806.      y = 15,\
  5807.      x = 9,\
  5808.    },\
  5809.    {\
  5810.      y = 15,\
  5811.      x = 10,\
  5812.    },\
  5813.    {\
  5814.      y = 15,\
  5815.      x = 11,\
  5816.    },\
  5817.    {\
  5818.      y = 15,\
  5819.      x = 12,\
  5820.    },\
  5821.    {\
  5822.      y = 15,\
  5823.      x = 13,\
  5824.    },\
  5825.    {\
  5826.      y = 15,\
  5827.      x = 14,\
  5828.    },\
  5829.    {\
  5830.      y = 15,\
  5831.      x = 15,\
  5832.    },\
  5833.    {\
  5834.      y = 15,\
  5835.      x = 16,\
  5836.    },\
  5837.    {\
  5838.      y = 15,\
  5839.      x = 17,\
  5840.    },\
  5841.    {\
  5842.      y = 15,\
  5843.      x = 18,\
  5844.    },\
  5845.    {\
  5846.      y = 14,\
  5847.      x = 18,\
  5848.    },\
  5849.    {\
  5850.      y = 13,\
  5851.      x = 18,\
  5852.    },\
  5853.    {\
  5854.      y = 12,\
  5855.      x = 18,\
  5856.    },\
  5857.    {\
  5858.      y = 11,\
  5859.      x = 18,\
  5860.    },\
  5861.    {\
  5862.      y = 10,\
  5863.      x = 18,\
  5864.    },\
  5865.    {\
  5866.      y = 10,\
  5867.      x = 19,\
  5868.    },\
  5869.    {\
  5870.      y = 10,\
  5871.      x = 20,\
  5872.    },\
  5873.    {\
  5874.      y = 10,\
  5875.      x = 21,\
  5876.    },\
  5877.    {\
  5878.      y = 10,\
  5879.      x = 22,\
  5880.    },\
  5881.    {\
  5882.      y = 9,\
  5883.      x = 22,\
  5884.    },\
  5885.    {\
  5886.      y = 8,\
  5887.      x = 22,\
  5888.    },\
  5889.    {\
  5890.      y = 7,\
  5891.      x = 22,\
  5892.    },\
  5893.    {\
  5894.      y = 6,\
  5895.      x = 22,\
  5896.    },\
  5897.    {\
  5898.      y = 5,\
  5899.      x = 22,\
  5900.    },\
  5901.    {\
  5902.      y = 5,\
  5903.      x = 23,\
  5904.    },\
  5905.    {\
  5906.      y = 5,\
  5907.      x = 24,\
  5908.    },\
  5909.    {\
  5910.      y = 5,\
  5911.      x = 25,\
  5912.    },\
  5913.    {\
  5914.      y = 5,\
  5915.      x = 26,\
  5916.    },\
  5917.    {\
  5918.      y = 5,\
  5919.      x = 27,\
  5920.    },\
  5921.    {\
  5922.      y = 5,\
  5923.      x = 28,\
  5924.    },\
  5925.    {\
  5926.      y = 5,\
  5927.      x = 29,\
  5928.    },\
  5929.    {\
  5930.      y = 6,\
  5931.      x = 29,\
  5932.    },\
  5933.    {\
  5934.      y = 7,\
  5935.      x = 29,\
  5936.    },\
  5937.    {\
  5938.      y = 8,\
  5939.      x = 29,\
  5940.    },\
  5941.    {\
  5942.      y = 9,\
  5943.      x = 29,\
  5944.    },\
  5945.    {\
  5946.      y = 10,\
  5947.      x = 29,\
  5948.    },\
  5949.    {\
  5950.      y = 11,\
  5951.      x = 29,\
  5952.    },\
  5953.    {\
  5954.      y = 12,\
  5955.      x = 29,\
  5956.    },\
  5957.    {\
  5958.      y = 13,\
  5959.      x = 29,\
  5960.    },\
  5961.    {\
  5962.      y = 14,\
  5963.      x = 29,\
  5964.    },\
  5965.    {\
  5966.      y = 15,\
  5967.      x = 29,\
  5968.    },\
  5969.    {\
  5970.      y = 16,\
  5971.      x = 29,\
  5972.    },\
  5973.    {\
  5974.      y = 17,\
  5975.      x = 29,\
  5976.    },\
  5977.    {\
  5978.      y = 18,\
  5979.      x = 29,\
  5980.    },\
  5981.    {\
  5982.      y = 18,\
  5983.      x = 30,\
  5984.    },\
  5985.    {\
  5986.      y = 18,\
  5987.      x = 31,\
  5988.    },\
  5989.    {\
  5990.      y = 18,\
  5991.      x = 32,\
  5992.    },\
  5993.    {\
  5994.      y = 18,\
  5995.      x = 33,\
  5996.    },\
  5997.    {\
  5998.      y = 18,\
  5999.      x = 34,\
  6000.    },\
  6001.    {\
  6002.      y = 18,\
  6003.      x = 35,\
  6004.    },\
  6005.  },"};["units"]={["1"]="name=\"Rifleman\";\
  6006. health=1;\
  6007. speed=5;\
  6008. image=\"50 \\nF0 \";\
  6009. reward=15;";["0"]="name=\"Scout\";\
  6010. health=1;\
  6011. speed=8;\
  6012. image=\"80 \\nF0 \";\
  6013. reward=10;";["3"]="name=\"Sniper\";\
  6014. health=3;\
  6015. speed=3;\
  6016. image=\"B0 \\nF0 \";\
  6017. reward=25;";["2"]="name=\"Machine Gunner\";\
  6018. health=2;\
  6019. speed=5;\
  6020. image=\"70 \\nF0 \";\
  6021. reward=20;";["5"]="name=\"Artillery\";\
  6022. health=20;\
  6023. speed=2;\
  6024. image=\"8F             \\n   8F 8F 8F    \\nF7oF7oF7oF7oF7o\";\
  6025. reward=50;";["4"]="name=\"Mortar\";\
  6026. health=4;\
  6027. speed=3;\
  6028. image=\"80 \\n80 \";\
  6029. reward=30;";["7"]="name=\"Motorbike\";\
  6030. health=4;\
  6031. speed=10;\
  6032. image=\"   D0    \\n FoF0  Fo\";\
  6033. reward=30;";["6"]="name=\"Tank\";\
  6034. health=25;\
  6035. speed=2;\
  6036. image=\" F-5F-5F 5F    \\n5F 5F 5F 5F 5F \\nF7oF7oF7oF7oF7o\";\
  6037. reward=80;"}};["launcher"]="\
  6038. _G[\"_bundleDependencyPath\"] = \".nightfall/bundles\"\
  6039. shell.run \".nightfall/NightFall.lua\"";["saves"]={}}
  6040. function ttf( table, dir )
  6041.     if not fs.isDir( dir ) then
  6042.         fs.makeDir( dir )
  6043.     end
  6044.     for k, v in pairs( table ) do
  6045.         if type( v ) == "table" then
  6046.             ttf( v, dir.."/"..k )
  6047.         elseif type( v ) == "string" then
  6048.             local f = fs.open( dir.."/"..k, "w" )
  6049.             f.write( v )
  6050.             f.close( )
  6051.         end
  6052.     end
  6053. end
  6054. ttf( files, path )
RAW Paste Data