{"events":[],"handlers":[{"code":"--[[\n DU-Nested-Coroutines by Jericho\n Permit to easier avoid CPU Load Errors\n Source available here: https://github.com/Jericho1060/du-nested-coroutines\n]]--\n\nif coroutine.status(MainCoroutine) == \"dead\" then\n MainCoroutine = coroutine.create(runCoroutines)\nend\nif coroutine.status(MainCoroutine) == \"suspended\" then\n assert(coroutine.resume(MainCoroutine))\nend","filter":{"args":[],"signature":"onUpdate()","slotKey":"-4"},"key":"3"},{"code":"if tonumber(text) then\n if #text > 8 then\n system.print(\"the value should not be higher than 99 999 999.\")\n else\n craft_quantity_digits = {\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"}\n for i = #text, 1, -1 do\n local c = text:sub(i,i)\n craft_quantity_digits[9-(#text-(i-1))] = c\n end\n end\nelse\n system.print(\"You must type a Number\")\nend","filter":{"args":[{"variable":"*"}],"signature":"onInputText(text)","slotKey":"-4"},"key":"4"},{"code":"if hud.actions.stop[action] ~= nil then\n local success, message = pcall(hud.actions.stop[action])\n if not success then\n system.print(\"Action Stop '\" .. action .. \"' Error : \" .. message) \n end\nend","filter":{"args":[{"variable":"*"}],"signature":"onActionStop(action)","slotKey":"-4"},"key":"5"},{"code":"if hud.actions.start[action] ~= nil then\n local success, message = pcall(hud.actions.start[action])\n if not success then\n system.print(\"Action Start '\" .. action .. \"' Error : \" .. message) \n end\nend","filter":{"args":[{"variable":"*"}],"signature":"onActionStart(action)","slotKey":"-4"},"key":"6"},{"code":"Storage.clear()","filter":{"args":[],"signature":"onStop()","slotKey":"-1"},"key":"1"},{"code":"version = \"v4.4.0\"\n--[[\n DU Industry HUD By Jericho\n]]\nlocal log_split = \"=================================================\"\n--printing version in lua chat\nsystem.print(log_split)local a=\"\"local b=math.ceil((50-#version-2)/2)for c=1,b,1 do a=a..'='end;a=a..\" \"..version..\" \"for c=1,b,1 do a=a..'='end;system.print(a)system.print(log_split)\n--[[\n Lua parameters\n]]\nfontSize = 12 --export: the fonct size\nshowRecipeData = true --export: display the recipe ingredients in the machine detail\n\nenableRefinerMonitoring = true --export: enable or disable the Refiners monitoring\nenableAssemblyMonitoring = true --export: enable or disable the Assembly lines monitoring\nenableSmelterMonitoring = true --export: enable or disable the Smelters monitoring\nenableChemicalMonitoring = true --export: enable or disable the Chemical industries monitoring\nenableElectronicsMonitoring = true --export: enable or disable the Electronics Industries monitoring\nenableGlassMonitoring = true --export: enable or disable the Glass Furnace monitoring\nenableHoneycombMonitoring = true --export: enable or disable the Honeycomb Refineries monitoring\nenableRecyclerMonitoring = true --export: enable or disable the Recyclers monitoring\nenableMetalworkMonitoring = true --export: enable or disable the Metalworks monitoring\nenable3DPrinterMonitoring = true --export: enable or disable the 3D Printers monitoring\nenableTransferMonitoring = true --export: enable or disable the transfer units monitoring\nenableStorageMonitoring = true --export: enable or disable the storage monitoring\nenableRemoteControl = true --export: enable the HUD to control machines (start/stop/batch/maintain)\nelementsByPage = 20 --export: maximum amount of elements displayed on a single page\ndateFormat = \"en\" --export: the country code to format the date\nmaxAmountOfElementsLoadedByFrame = 500 --export: if cpu load errors at start, lower that value\nmachinesRefreshedByFrame = 100 --how many machines are refreshed by frame\nmachineDetailDisplayDistance = 0 --export: the distance in meters to display the machine details\nARMaxDistance = 225 --export: the maximum distance from you in meters to display AR info on machine\ndisplayType = 0 --export: the default display type: 0=ALL, 1=Table, 2=Augmented Reality\ndisplayMode = 0 --export: the default display type: 0=ALL, 1=Industry Only, 2=Storage Only, 3=None\nsortingType = 1 --export: the default sorting of elements in table: 1=Element Name, 2=Item in containers or product of industries, 3=Element ID\n\n\n--[[\n\treceivers channels for each type of machine\n]]\nchannel_for_refiner = \"receiver_refiner\" --export: receiver channel to send orders to refiners\nchannel_for_assembly = \"receiver_assembly\" --export: receiver channel to send orders to assembly lines\nchannel_for_smelter = \"receiver_smelters\" --export: receiver channel to send orders to smelters\nchannel_for_chemical = \"receiver_chemical\" --export: receiver channel to send orders to chemical indutries\nchannel_for_electronics = \"receiver_electronics\" --export: receiver channel to send orders to electronic industries\nchannel_for_glass = \"receiver_glass\" --export: receiver channel to send orders to glass furnace\nchannel_for_honeycomb = \"receiver_honeycomb_recycler\" --export: receiver channel to send orders to honeycomb refiniries\nchannel_for_recycler = \"receiver_honeycomb_recycler\" --export: receiver channel to send orders to recylers\nchannel_for_metalwork = \"receiver_metalworks\" --export: receiver channel to send orders to metalworks\nchannel_for_3d_printer = \"receiver_3dprinters\" --export: receiver channel to send orders to 3d printers\nchannel_for_transfer = \"receiver_transfert\" --export: receiver channel to send orders to tranfer units\n\n--Storage options\ncontainerProficiencyLvl = 5 --export: Talent level for Container Proficiency\ncontainerOptimizationLvl = 0 --export: Talent level for Container Optimization\nstorages_prefix_list = 's1,s2,s3,s4,s5,s6,s7,s8,s9' --export: the list of the prefixes used for the storage monitoring, comma separated values\n\n--split a string on a delimiter By jericho\nfunction strSplit(a,b)result={}for c in(a..b):gmatch(\"(.-)\"..b)do table.insert(result,c)end;return result end\n--formatting numbers by adding a space between thousands by Jericho\nfunction format_number(a)local b=a;while true do b,k=string.gsub(b,\"^(-?%d+)(%d%d%d)\",'%1 %2')if k==0 then break end end;return b end\n--Utility functions By jericho, see full source at https://github.com/Jericho1060/DualUniverse\nfunction removeDuplicatesInTable(a)local b={}local c={}for d,e in ipairs(a)do if not b[e]then c[#c+1]=e;b[e]=true end end;return c end;function strSplit(a,b)result={}for c in(a..b):gmatch(\"(.-)\"..b)do table.insert(result,c)end;return result end;function SecondsToClockString(a)local a=tonumber(a)if a==nil or a<=0 then return\"-\"else days=string.format(\"%2.f\",math.floor(a/(3600*24)))hours=string.format(\"%2.f\",math.floor(a/3600-days*24))mins=string.format(\"%2.f\",math.floor(a/60-hours*60-days*24*60))secs=string.format(\"%2.f\",math.floor(a-hours*3600-days*24*60*60-mins*60))str=\"\"if tonumber(days)>0 then str=str..days..\"d \"end;if tonumber(hours)>0 then str=str..hours..\"h \"end;if tonumber(mins)>0 then str=str..mins..\"m \"end;if tonumber(secs)>0 then str=str..secs..\"s\"end;return str end end;function removeQualityInName(a)if not a then return''end;return a:lower():gsub('basic ',''):gsub('uncommon ',''):gsub('advanced ',''):gsub('rare ',''):gsub('exotic ','')end;function has_value(a,b)for c,d in ipairs(a)do if d==b then return true end end;return false end\n--return RGB colors calculated from a gradient between two colors\nfunction getRGBGradient(a,b,c,d,e,f,g,h,i,j)a=-1*math.cos(a*math.pi)/2+0.5;local k=0;local l=0;local m=0;if a>=.5 then a=(a-0.5)*2;k=e-a*(e-h)l=f-a*(f-i)m=g-a*(g-j)else a=a*2;k=b-a*(b-e)l=c-a*(c-f)m=d-a*(d-g)end;return k,l,m end\n--time script to get client date and time by Jericho, see full source at https://github.com/Jericho1060/DualUniverse\nfunction DUCurrentDateTime(a)local b=system.getUtcTime()if not a then b=b+system.getUtcOffset()end;local c=24*60*60;local d=365*c;local e=d+c;local f=4*d+c;local g=4;local h=1970;local i={-1,30,58,89,119,150,180,211,242,272,303,333,364}local j={}for k=1,2 do j[k]=i[k]end;for k=3,13 do j[k]=i[k]+1 end;local l,m,n,o,p,q,r,s;local t=i;s=b;l=math.floor(s/f)s=s-l*f;l=l*4+h;if s>=d then l=l+1;s=s-d;if s>=d then l=l+1;s=s-d;if s>=e then l=l+1;s=s-e else t=j end end end;m=math.floor(s/c)s=s-m*c;local n=1;while t[n]=0 and math.floor(u+0.5)or math.ceil(u-0.5)end;s=round(s-r*60)local w={\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\",\"Sunday\"}local x={\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\",\"Sun\"}local y={\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\",\"August\",\"September\",\"October\",\"November\",\"December\"}local z={\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"}return l,n,o,q,r,s,p,w[p],x[p],y[n],z[n],m+1 end\n \n--databank hub library By Jericho, see full source at https://github.com/Jericho1060/DualUniverse\nbankhub={}function bankhub:new(banks)o={}setmetatable(o,self)self.__index=self;o.banks=banks or{}function o.clear()return o:_clear()end;function o.getNbKeys()return o:_getNbKeys()end;function o.getKeys()return o:_getKeys()end;function o.hasKey(a)return o:_hasKey(a)end;function o.getStringValue(a)return o:_getStringValue(a)end;function o.getIntValue(a)return o:_getIntValue(a)end;function o.getFloatValue(a)return o:_getFloatValue(a)end;return o end;function bankhub:add(b)table.insert(self.banks,b)self.banks_size=#self.banks end;function bankhub:_clear()for c,d in pairs(self.banks)do d.clear()end end;function bankhub:_getNbKeys()local e=0;for c,d in pairs(self.banks)do e=e+d.getNbKeys()end;return e end;function bankhub:_getKeys()local e={}for c,d in pairs(self.banks)do local f=json.decode(d.getKeys())for c,g in pairs(f)do table.insert(e,g)end end;return json.encode(e)end;function bankhub:_hasKey(a)for c,d in pairs(self.banks)do if d.hasKey(a)==1 then return 1 end end;return 0 end;function bankhub:_getStringValue(a)for c,d in pairs(self.banks)do if d.hasKey(a)==1 then return d.getStringValue(a)end end;return nil end;function bankhub:_getIntValue(a)for c,d in pairs(self.banks)do if d.hasKey(a)==1 then return banks.getIntValue(a)end end;return nil end;function bankhub:_getFloatValue(a)for c,d in pairs(self.banks)do if d.hasKey(a)==1 then return banks.getFloatValue(a)end end;return nil end\n--time script to get client date and time by Jericho, see full source at https://github.com/Jericho1060/DualUniverse\nfunction DUCurrentDateTime(a)local b=system.getUtcTime()if not a then b=b+system.getUtcOffset()end;local c=24*60*60;local d=365*c;local e=d+c;local f=4*d+c;local g=4;local h=1970;local i={-1,30,58,89,119,150,180,211,242,272,303,333,364}local j={}for k=1,2 do j[k]=i[k]end;for k=3,13 do j[k]=i[k]+1 end;local l,m,n,o,p,q,r,s;local t=i;s=b;l=math.floor(s/f)s=s-l*f;l=l*4+h;if s>=d then l=l+1;s=s-d;if s>=d then l=l+1;s=s-d;if s>=e then l=l+1;s=s-e else t=j end end end;m=math.floor(s/c)s=s-m*c;local n=1;while t[n]=0 and math.floor(u+0.5)or math.ceil(u-0.5)end;s=round(s-r*60)local w={\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\",\"Sunday\"}local x={\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\",\"Sun\"}local y={\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\",\"August\",\"September\",\"October\",\"November\",\"December\"}local z={\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"}return l,n,o,q,r,s,p,w[p],x[p],y[n],z[n],m+1 end\n\nstatusList = {\"STOPPED\",\"RUNNING\",\"MISSING INGREDIENT\",\"OUTPUT FULL\",\"NO OUTPUT CONTAINER\",\"PENDING\",\"MISSING SCHEMATIC\",\"SERVER ERROR\", \"STOP REQUESTED\"}\nfunction getIndustryStatusClass(status)\n if status == 1 then\n return \"text-info\"\n elseif status == 2 then\n return \"text-success\"\n elseif ((status >= 3) and (status <= 5)) or (status == 7) then\n return \"text-danger\"\n elseif status == 6 then\n return \"text-primary\"\n elseif status >= 8 and status <= 9 then\n return \"text-warning\"\n end\n return \"\" --default value for other status that can be added\nend\nfunction getIndustryStatusBgClass(status)\n if status then\n if status == 1 then\n return \"bg-info\"\n elseif status == 2 then\n return \"bg-success\"\n elseif ((status >= 3) and (status <= 5)) or (status == 7) then\n return \"bg-danger\"\n elseif status == 6 then\n return \"bg-primary\"\n elseif status >= 8 and status <= 9 then\n return \"bg-warning\"\n end\n end\n return \"\" --default value for other status that can be added\nend\nfunction getIndustryStatusBorderClass(status)\n if status then\n if status == 1 then\n return \"border-info\"\n elseif status == 2 then\n return \"border-success\"\n elseif ((status >= 3) and (status <= 5)) or (status == 7) then\n return \"border-danger\"\n elseif status == 6 then\n return \"border-primary\"\n elseif status >= 8 and status <= 9 then\n return \"border-warning\"\n end\n end\n return \"\" --default value for other status that can be added\nend\nfunction ConvertLocalToWorld(a,b,c,d,e)local f={a[1]*c[1],a[1]*c[2],a[1]*c[3]}local g={a[2]*d[1],a[2]*d[2],a[2]*d[3]}local h={a[3]*e[1],a[3]*e[2],a[3]*e[3]}return{f[1]+g[1]+h[1]+b[1],f[2]+g[2]+h[2]+b[2],f[3]+g[3]+h[3]+b[3]}end\n\n\nchannels = {}\nchannels['refiner'] = channel_for_refiner\nchannels['assembly line'] = channel_for_assembly\nchannels['smelter'] = channel_for_smelter\nchannels['chemical industry'] = channel_for_chemical\nchannels['electronics industry'] = channel_for_electronics\nchannels['glass furnace'] = channel_for_glass\nchannels['honeycomb refinery'] = channel_for_honeycomb\nchannels['recycler'] = channel_for_recycler\nchannels['metalwork industry'] = channel_for_metalwork\nchannels['3d printer'] = channel_for_3d_printer\nchannels['transfer unit'] = channel_for_transfer\n\nbootstrap_css_colors = [[]]\nbase_css = [[]]\n\n\ndatabanks = {}\ncore = nil\nemitter = nil\nindustries_id = {}\nstorages_id = {}\nindustries = {}\nstorages = {}\nelementsTypes = {}\nstoragesTypes = {}\nschematicContainer = nil\nschematicContainerId = construct.getSchematicContainerId()\nschematicStorage = {}\nfor slot_name, slot in pairs(unit) do\n if\n type(slot) == \"table\"\n and type(slot.export) == \"table\"\n and slot.getClass\n then\n if slot.getClass():lower() == 'databankunit' then\n table.insert(databanks, slot)\n elseif slot.getClass():lower():find(\"coreunit\") then\n core = slot\n elseif slot.getClass():lower() == 'emitterunit' then\n emitter = slot\n elseif schematicContainerId ~= nil and slot.getClass():lower():find('container') then\n if slot.getId() == schematicContainerId then\n schematicContainer = slot\n end\n end\n end\nend\n\nif core == nil then\n system.print(\"Connection to the core is missing\")\n unit.exit()\nend\nif schematicContainerId == nil then\n system.print(\"No Schematic Container set on the Construct\")\nend\nif schematicContainer == nil then\n system.print(\"Schematic Container is not linked to the board\")\nend\n\nif emitter == nil then \n enableRemoteControl = false\n system.print(\"Connect an Emitter to enable machine control from industry\")\nend\nif #databanks == 0 then \n enableRemoteControl = false\n system.print(\"No Databank linked\")\nend\n\n--init of bank hub\nStorage = bankhub:new(databanks)\n\n--construct pos for AR data\nconstructPos = construct.getWorldPosition()\nconstructRight = construct.getWorldRight()\nconstructForward = construct.getWorldForward()\nconstructUp = construct.getWorldUp()\n\n--script variables\nstorage_prefix = strSplit(storages_prefix_list, ',')\ndisplayTypes = {\"ALL\", \"Table\", \"Augmented Reality\"}\ndisplayModes = {\"ALL\", \"Industry\", \"Storage\", \"None\"}\nif not enableStorageMonitoring then\n displayModes = {\"ALL\", \"Industry\", \"None\"}\nend\nsortingTypes = {\"Element Name\", \"Item\", \"Element ID\"}\ninit = false\ninitIndex = 1\nelementsIdList = {}\nmachines_count = {}\nstorages_count = {}\nmachines_positions = {}\nstorages_positions = {}\nsystem.showScreen(true)\nstatusFilter = 0\nstatusFilterType = 0\nmaxFilterType = 0\nmaxOnPage=1\nhtml_filters = \"\"\nhtml_filters_types = \"\"\nhtml_filter_storage = \"\"\nhtml_machines = \"\"\nhtml_storage = \"\"\nhtml_time = \"\"\nhtml_ar_selected = \"\"\nhtml_control = \"\"\nhtml_credits = [[
]] .. version .. [[ - Powered By jericho1060
]]\n\n--pagination var\npage = 1\nmaxPage = 1\nselectedRow = 1\nselected_machine=nil\nselected_container=nil\n\n--control machine var\ncommand_1 = \"\"\ncommand_2 = \"\"\ncommand_3 = \"\"\ncraft_quantity_digits = {\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"}\n\n--keyPressed\nctrlPressed = false\n\n\n--[[\n DU INDUSTRY HUD By Jericho\n]]\nschematicRefreshTime = 0\nhud = {}\nhud.coroutines = {}\nif schematicContainer ~= nil then\n hud.coroutines.getSchematics = function ()\n schematicRefreshTime = math.ceil(schematicContainer.updateContent())\n end\nend\nhud.coroutines.init = function()\n if not init then\n elementsTypes = {}\n industries_id = {}\n industries = {}\n\n storagesTypes = {}\n storages_id = {}\n storages = {}\n\n elementsIdList = core.getElementIdList()\n\n for index,id in ipairs(elementsIdList) do\n elementType = core.getElementDisplayNameById(id):lower()\n if (elementType:find(\"assembly line\") and enableAssemblyMonitoring == true) or\n (elementType:find(\"glass furnace\") and enableGlassMonitoring == true) or\n (elementType:find(\"3d printer\") and enable3DPrinterMonitoring == true) or\n (elementType:find(\"smelter\") and enableSmelterMonitoring == true) or\n (elementType:find(\"recycler\") and enableRecyclerMonitoring == true) or\n (elementType:find(\"refinery\") and enableHoneycombMonitoring == true) or\n (elementType:find(\"refiner\") and enableRefinerMonitoring == true) or\n (elementType:find(\"industry\")\n and (\n (elementType:find(\"chemical\") and enableChemicalMonitoring == true) or\n (elementType:find(\"electronics\") and enableElectronicsMonitoring == true) or\n (elementType:find(\"metalwork\") and enableMetalworkMonitoring == true)\n )\n ) or\n (elementType == \"transfer unit\" and enableTransferMonitoring == true) or\n elementType:lower():find(\"container\")\n then\n local formatedType = removeQualityInName(elementType)\n local pos = core.getElementPositionById(id)\n if elementType:lower():find(\"container\") and enableStorageMonitoring then\n if storages_count[formatedType] ~= nil then\n storages_count[formatedType] = storages_count[formatedType] + 1\n else\n storages_count[formatedType] = 1\n end\n table.insert(storages_id, id)\n storages_positions['i'..id] = pos\n table.insert(storagesTypes, formatedType)\n elseif not elementType:lower():find(\"container\") then\n pos[3] = pos[3] + 1\n if machines_count[formatedType] ~= nil then\n machines_count[formatedType] = machines_count[formatedType] + 1\n else\n machines_count[formatedType] = 1\n end\n table.insert(industries_id, id)\n machines_positions['i'..id] = pos\n table.insert(elementsTypes, formatedType)\n end\n end\n\n if index % maxAmountOfElementsLoadedByFrame == 0 then\n coroutine.yield()\n end\n end\n elementsTypes = removeDuplicatesInTable(elementsTypes)\n table.sort(elementsTypes, function(a,b) return a:lower() < b:lower() end)\n selected_type = elementsTypes[1]\n init = true\n system.print(\"All elements loaded\")\n system.print(#storages_id .. \" storage elements found\")\n system.print(#industries_id .. \" industries found\")\n end\nend\nhud.coroutines.loadIndustries = function()\n if init and (displayMode == 0 or displayMode == 1) then\n for index,id in ipairs(industries_id) do\n local pos = machines_positions['i'..id]\n local data = core.getElementIndustryInfoById(id)\n if industries[\"i\"..tostring(id)] == nil then industries[\"i\"..tostring(id)] = {} end\n local mode = \"\"\n local tableMode = \"\"\n local maintainOrBatchQuantity = 0\n if data.maintainProductAmount > 0 then\n mode = \"
Mode: Maintain \" .. math.floor(data.currentProductAmount) ..\"/\" .. math.floor(data.maintainProductAmount) .. \"
\"\n tableMode = \"Maintain \" .. math.floor(data.currentProductAmount) ..\"/\" .. math.floor(data.maintainProductAmount)\n maintainOrBatchQuantity=math.floor(data.maintainProductAmount)\n elseif data.batchesRequested > 0 and data.batchesRequested <= 99999999 then\n local current = data.batchesRequested - data.batchesRemaining\n if data.batchesRemaining < 0 then current = 0 end\n mode = \"
Mode: Produce \" .. math.floor(current) .. \"/\" .. math.floor(data.batchesRequested) .. \"
\"\n tableMode = \"Produce \" .. math.floor(current) .. \"/\" .. math.floor(data.batchesRequested)\n maintainOrBatchQuantity=math.floor(data.batchesRequested)\n end\n local production = {locDisplayNameWithSize=\"No recipe selected\", tier=0}\n local schematicName = \"\"\n local tableSchematicName = \"\"\n local tableSchematicQuantity = \"\"\n local schematicColor = \"success\"\n local state = data.state\n local time=\"\"\n local tableTime=\"\"\n local recipe=\"\"\n local industryType = core.getElementDisplayNameById(id)\n local schematicId = data.requiredSchematicIds[1] or 0\n if schematicId > 0 and not industryType:lower():find(\"transfer\") then\n local sch = system.getItem(schematicId)\n local shematicQuantity = schematicStorage[\"s\" .. schematicId] or 0\n if shematicQuantity < data.requiredSchematicAmount then schematicColor = \"danger\" end\n schematicName = '
Schematic: ' .. format_number(shematicQuantity):gsub(\".0\", \"\") .. \"/\" .. format_number(data.requiredSchematicAmount) .. \" \" .. sch.locDisplayNameWithSize .. \"
\"\n tableSchematicName = sch.locDisplayNameWithSize\n tableSchematicQuantity = format_number(shematicQuantity):gsub(\".0\", \"\") .. \"/\" .. format_number(data.requiredSchematicAmount)\n end\n if #data.currentProducts > 0 then\n local item_id = data.currentProducts[1].id\n production = system.getItem(item_id)\n if id ~= \"947806142\" and id ~= \"1010524904\" and not industryType:lower():find(\"transfer\") then\n if showRecipeData then\n local rdata = system.getRecipes(item_id)\n if #rdata > 0 then\n local r = nil\n for _,recipe in pairs(rdata) do\n if recipe.products[1].id == item_id then\n r = recipe\n break\n end\n end\n if r then\n recipe = \"
Recipe:\"\n for _,v in pairs(r.ingredients) do\n local item = system.getItem(v.id)\n recipe = recipe .. \"
    - \" .. v.quantity .. \" x \" .. item.locDisplayNameWithSize\n end\n recipe = recipe .. \"
\"\n end\n end\n end\n end\n if data.remainingTime == 0 and data.state == 2 then\n state = 8\n end\n if data.stopRequested and data.state ~= 1 then\n state = 9\n end\n if data.remainingTime > 0 then\n time = \"
Time: \" .. SecondsToClockString(data.remainingTime) .. \"
\"\n tableTime = SecondsToClockString(data.remainingTime)\n end\n end\n local productionName = '
Product: ' .. production.locDisplayNameWithSize .. '
'\n local productId = ''\n if production.id then\n productId = \"
Main Product ID: \" .. production.id .. \"
\"\n end\n local elementName = core.getElementNameById(id)\n industries[\"i\"..tostring(id)] = {\n id=id,\n screenPos=library.getPointOnScreen(ConvertLocalToWorld(pos, constructPos, constructRight, constructForward, constructUp)),\n name=\"
Industry Name: [\" .. id .. \"] \" .. elementName .. \"
\",\n tableName=elementName,\n type=\"
Industry Type: \" .. industryType .. \"
\",\n tableType=industryType,\n typeFilter=removeQualityInName(industryType),\n state=state,\n production=production,\n productId=productId,\n productionName=productionName,\n mode=mode,\n tableMode=tableMode,\n remainingTime=time,\n tableTime=tableTime,\n schematic=schematicName,\n schematicColor=schematicColor,\n maintainOrBatchQuantity=maintainOrBatchQuantity,\n tableSchematic=tableSchematicName,\n tableSchematicQuantity=tableSchematicQuantity,\n recipe=recipe,\n stopRequested=data.stopRequested\n }\n if index % machinesRefreshedByFrame == 0 then\n coroutine.yield()\n end\n end\n end\nend\nif enableStorageMonitoring then\n hud.coroutines.loadStorage = function()\n if init and (displayMode == 0 or displayMode == 2) then\n for index,id in ipairs(storages_id) do\n local pos = storages_positions['i'..id]\n local elementType = core.getElementDisplayNameById(id)\n local base_name = core.getElementNameById(id)\n local splitted = strSplit(base_name,'_')\n local item_id = nil\n local prefix = nil\n if #splitted > 1 then\n prefix = splitted[1]\n item_id = splitted[2]\n end\n local container = {\n id = id,\n type=elementType,\n name = \"[\" .. id .. \"] \" .. base_name,\n tableName = base_name,\n prefix = prefix,\n item_id = item_id,\n monitor = false,\n screenPos=library.getPointOnScreen(ConvertLocalToWorld(pos, constructPos, constructRight, constructForward, constructUp)),\n }\n if item_id and prefix then\n for _,sprefix in ipairs(storage_prefix) do\n if prefix:lower() == sprefix:lower() then\n container.monitor = true\n container.item = system.getItem(item_id)\n break\n end\n end\n end\n local container_size = \"XS\"\n local container_empty_mass = 0\n local container_volume = 0\n local contentQuantity = 0\n local percent_fill = 0\n if not elementType:lower():find(\"hub\") then\n local containerMaxHP = core.getElementMaxHitPointsById(id)\n if containerMaxHP > 68000 then\n container_size = \"XXL\"\n container_empty_mass = 88410\n container_volume = 512000 * (containerProficiencyLvl * 0.1) + 512000\n elseif containerMaxHP > 33000 then\n container_size = \"XL\"\n container_empty_mass = 44210\n container_volume = 256000 * (containerProficiencyLvl * 0.1) + 256000\n elseif containerMaxHP > 17000 then\n container_size = \"L\"\n container_empty_mass = 14842.7\n container_volume = 128000 * (containerProficiencyLvl * 0.1) + 128000\n elseif containerMaxHP > 7900 then\n container_size = \"M\"\n container_empty_mass = 7421.35\n container_volume = 64000 * (containerProficiencyLvl * 0.1) + 64000\n elseif containerMaxHP > 900 then\n container_size = \"S\"\n container_empty_mass = 1281.31\n container_volume = 8000 * (containerProficiencyLvl * 0.1) + 8000\n else\n container_size = \"XS\"\n container_empty_mass = 229.09\n container_volume = 1000 * (containerProficiencyLvl * 0.1) + 1000\n end\n else\n if splitted[3] then\n container_size = splitted[3]\n end\n if splitted[4] then\n container_amount = splitted[4]\n end\n local volume = 0\n container_volume_list = {xxl=512000, xl=256000, l=128000, m=64000, s=8000, xs=1000}\n container_size = container_size:lower()\n if container_volume_list[container_size] then\n volume = container_volume_list[container_size]\n end\n container_volume = (volume * containerProficiencyLvl * 0.1 + volume)\n container_empty_mass = 55.8\n end\n local totalMass = core.getElementMassById(id)\n local contentMassKg = totalMass - container_empty_mass\n container.totalMass = totalMass\n container.emptyMass = container_empty_mass\n container.contentMass = contentMassKg\n container.maxVolume = container_volume\n container.size = container_size\n if container.item == nil or container.item.name == \"InvalidItem\" then\n container.percent = 0\n container.quantity = 0\n else\n container.quantity = contentMassKg / (container.item.unitMass - (container.item.unitMass * (containerOptimizationLvl * 0.05)))\n container.percent = utils.round((container.item.unitVolume * container.quantity) * 100 / container_volume)\n end\n storages['i'..id] = container\n if index % machinesRefreshedByFrame == 0 then\n coroutine.yield()\n end\n end\n end\n end\nend\nhud.coroutines.renderHelper = function()\n local year, month, day, hour, minute, second = DUCurrentDateTime()\n html_time = [[
]] .. string.format(\"%02d/%02d/%04d %02d:%02d:%02d\",day,month,year,hour,minute,second) .. [[

]]\n for i,v in ipairs(sortingTypes) do\n html_time = html_time .. '' .. v .. ''\n if i < #sortingTypes then html_time = html_time .. \"|\" end\n end\n html_time = html_time .. ' - Sorting Type - Alt + 6
'\n for i,v in ipairs(displayTypes) do\n html_time = html_time .. '' .. v .. ''\n if i < #displayTypes then html_time = html_time .. \"|\" end\n end\n html_time = html_time .. ' - Display Type - Alt + 7
'\n for i,v in ipairs(displayModes) do\n html_time = html_time .. '' .. v .. ''\n if i < #displayModes then html_time = html_time .. \"|\" end\n end\n html_time = html_time .. ' - Display Mode - Alt + 8
'\n html_time = html_time .. '
Reload HUD - Alt + 9
'\n if schematicContainer ~= nil then\n html_time = html_time .. '
Schematic Storage Refresh in ' .. schematicRefreshTime .. 's
'\n end\n html_time = html_time .. '
'\nend\nhud.coroutines.renderIndustries = function()\n local html = \"\"\n local html_table = \"\"\n local lastMachine = 0\n local firstMachine = 0\n local totalPage = 1\n local selectedMachine = nil\n if displayMode == 0 or displayMode == 1 then\n local selectedIndustries = {}\n for k,industry in pairs(industries) do\n if (statusFilter == 0 or industry.state == statusFilter) and (statusFilterType == 0 or (statusFilterType <= #elementsTypes and industry.typeFilter:lower() == elementsTypes[statusFilterType])) then\n if displayType == 0 then\n table.insert(selectedIndustries, industry)\n elseif displayType == 1 then\n table.insert(selectedIndustries, industry)\n elseif displayType == 2 then\n if industry.screenPos[1] > 0 and industry.screenPos[1] < 1 and industry.screenPos[2] > 0 and industry.screenPos[2] < 1 then\n table.insert(selectedIndustries, industry)\n end\n end\n end\n end\n if (displayType == 0 or displayType == 1) and statusFilterType <= #elementsTypes then\n totalPage = math.ceil(#selectedIndustries/elementsByPage)\n firstMachine = (page - 1) * elementsByPage + 1\n lastMachine = page * elementsByPage\n if lastMachine > #selectedIndustries then\n lastMachine = #selectedIndustries\n end\n html_table = html_table .. '
↑    Arrow Up
←    Arrow Left Page ' .. page .. '/' .. totalPage .. ' (from ' .. firstMachine .. ' to ' .. lastMachine .. ' on ' .. #selectedIndustries .. ')Arrow Right    →
'\n end\n local count = 1\n if sortingType == 1 then\n table.sort(selectedIndustries, function(a,b) return a.tableName < b.tableName end)\n elseif sortingType == 2 then\n table.sort(selectedIndustries, function(a,b) return a.production.locDisplayNameWithSize < b.production.locDisplayNameWithSize end)\n elseif sortingType == 3 then\n table.sort(selectedIndustries, function(a,b) return a.id < b.id end)\n end\n for k,industry in pairs(selectedIndustries) do\n if (displayType == 0 or displayType == 2) and industry.screenPos[1] > 0 and industry.screenPos[1] < 1 and industry.screenPos[2] > 0 and industry.screenPos[2] < 1 and industry.screenPos[3] <= ARMaxDistance then\n local showDetail = false\n if industry.screenPos[3] <= machineDetailDisplayDistance then\n showDetail = true\n elseif industry.screenPos[1] < 0.55 and industry.screenPos[1] > 0.45 and industry.screenPos[2] < 0.55 and industry.screenPos[2] > 0.45 then\n showDetail = true\n end\n local font_size = fontSize * ((200-industry.screenPos[3])/200)\n local zindex = utils.round(1000 - industry.screenPos[3])\n html = html .. [[
T]] .. industry.production.tier .. [[]] .. industry.production.locDisplayNameWithSize .. [[
]]\n if showDetail then\n html = html .. [[
]] .. statusList[industry.state] .. [[
]] .. industry.productId .. industry.name .. industry.type .. industry.mode .. industry.schematic .. industry.remainingTime .. industry.recipe ..[[
]]\n end\n html = html .. [[
]]\n end\n if (displayType == 0 or displayType == 1) then\n local selectedClass = \"\"\n if selectedRow == (count + 1 - firstMachine)then\n selectedClass = \"row_selected\"\n selectedMachine = industry\n end\n if count >= firstMachine and count <= lastMachine then\n html_table = html_table .. ''\n end\n end\n count = count + 1\n end\n if (displayType == 0 or displayType == 1) and statusFilterType <= #elementsTypes then\n html_table = html_table .. '
idMachine Name & TypeSelected Recipe & schematicStatusModeTime Remaining
' .. industry.id .. '' .. industry.tableName .. '
' .. industry.tableType .. '
' .. industry.production.locDisplayNameWithSize .. '
' .. industry.tableSchematicQuantity .. \" \" .. industry.tableSchematic .. '
' .. statusList[industry.state] .. '' .. industry.tableMode .. '' .. industry.tableTime .. '
←    Arrow Left Page ' .. page .. '/' .. totalPage .. ' (from ' .. firstMachine .. ' to ' .. lastMachine .. ' on ' .. #selectedIndustries .. ')Arrow Right    →
↓    Arrow Down
'\n maxPage = totalPage\n maxOnPage = lastMachine-firstMachine+1\n end\n end\n html_machines = html .. html_table\n selected_machine = selectedMachine\nend\nif enableStorageMonitoring then\n hud.coroutines.renderStorage = function()\n local html = \"\"\n local html_table = \"\"\n local lastStorage = 0\n local firstStorage = 0\n local totalPage = 1\n local selectedStorage = nil\n if displayMode == 0 or displayMode == 2 then\n local selectedStorages = {}\n for k,storage in pairs(storages) do\n if statusFilterType >= maxFilterType and storage.monitor then\n if displayType == 0 then\n table.insert(selectedStorages, storage)\n elseif displayType == 1 then\n table.insert(selectedStorages, storage)\n end\n end\n end\n if (displayType == 0 or displayType == 2) then\n for k,storage in pairs(storages) do\n if storage.screenPos[1] > 0 and storage.screenPos[1] < 1 and storage.screenPos[2] > 0 and storage.screenPos[2] < 1 and storage.screenPos[3] <= ARMaxDistance then\n local showDetail = false\n if storage.screenPos[3] <= machineDetailDisplayDistance then\n showDetail = true\n elseif storage.screenPos[1] < 0.55 and storage.screenPos[1] > 0.45 and storage.screenPos[2] < 0.55 and storage.screenPos[2] > 0.45 then\n showDetail = true\n end\n local font_size = fontSize * ((200-storage.screenPos[3])/200)\n local zindex = utils.round(1000 - storage.screenPos[3])\n local displayName = storage.name\n local tierBox = ''\n local itemBox = ''\n local fillGauge = ''\n if storage.item ~= nil and storage.item.name ~= \"InvalidItem\" then\n displayName = format_number(utils.round(storage.quantity*100)/100) .. \" \" .. storage.item.locDisplayNameWithSize .. \" (\" .. storage.percent .. \"%)\"\n tierBox = 'T' .. storage.item.tier .. ''\n local i = storage.item\n local gaugePercent = storage.percent\n if storage.percent > 100 then\n gaugePercent = 100\n end\n local r,g,b = getRGBGradient(gaugePercent/100,177,42,42,249,212,123,34,177,76)\n r = utils.round(r)\n g = utils.round(g)\n b = utils.round(b)\n itemBox = [[
Item ID: ]] .. i.id .. [[
Item Name: ]] .. i.locDisplayNameWithSize .. [[
Item Unit Mass: ]] .. i.unitMass .. [[ kg
Item Unit Volume: ]] .. i.unitVolume .. [[ m3
]]\n fillGauge = '
'\n end\n html = html .. [[
]] .. tierBox .. [[]] .. displayName .. [[]] .. fillGauge .. [[
]]\n if showDetail then\n html = html .. [[
Container Type: ]] .. storage.type .. \" \" .. storage.size .. [[
]] .. itemBox .. [[
]]\n end\n html = html .. [[]]\n end\n end\n end\n if (displayType == 0 or displayType == 1) and statusFilterType >= maxFilterType then\n totalPage = math.ceil(#selectedStorages/elementsByPage)\n firstStorage = (page - 1) * elementsByPage + 1\n lastStorage = page * elementsByPage\n if lastStorage > #selectedStorages then\n lastStorage = #selectedStorages\n end\n html_table = html_table .. '
↑    Arrow Up
←    Arrow Left Page ' .. page .. '/' .. totalPage .. ' (from ' .. firstStorage .. ' to ' .. lastStorage .. ' on ' .. #selectedStorages .. ')Arrow Right    →
'\n local count = 1\n if sortingType == 1 then\n table.sort(selectedStorages, function(a,b) return a.tableName < b.tableName end)\n elseif sortingType == 2 then\n table.sort(selectedStorages, function(a,b) return a.item.locDisplayNameWithSize < b.item.locDisplayNameWithSize end)\n elseif sortingType == 3 then\n table.sort(selectedStorages, function(a,b) return a.id < b.id end)\n end\n for k,storage in pairs(selectedStorages) do\n if count >= firstStorage and count <= lastStorage then\n local selectedClass = \"\"\n if selectedRow == (count + 1 - firstStorage)then\n selectedClass = \"row_selected\"\n selectedStorage = storage\n end\n local item_name = \"\"\n if storage.item ~= nil and storage.item.name ~= \"InvalidItem\" then\n item_name = storage.item.locDisplayNameWithSize\n end\n local gaugePercent = storage.percent\n if storage.percent > 100 then\n gaugePercent = 100\n end\n local r,g,b = getRGBGradient(gaugePercent/100,177,42,42,249,212,123,34,177,76)\n r = utils.round(r)\n g = utils.round(g)\n b = utils.round(b)\n html_table = html_table .. ''\n end\n count = count + 1\n end\n html_table = html_table .. '
idStorage Name & TypeItem NameQuantityPercent fill
' .. storage.id .. '' .. storage.tableName .. '
' .. storage.type .. ' ' .. storage.size .. '
' .. item_name .. '' .. format_number(utils.round(storage.quantity*100)/100) .. '' .. storage.percent .. '%
←    Arrow Left Page ' .. page .. '/' .. totalPage .. ' (from ' .. firstStorage .. ' to ' .. lastStorage .. ' on ' .. #selectedStorages .. ')Arrow Right    →
↓    Arrow Down
'\n maxPage = totalPage\n maxOnPage = lastStorage-firstStorage+1\n end\n end\n html_storage = html .. html_table\n selected_storage = selectedStorage\n end\nend\nhud.coroutines.renderFilterStatus = function()\n html_filters = \"\"\n html_filters = html_filters .. [[
ALL|]]\n for i,status in ipairs(statusList) do\n html_filters = html_filters .. [[]] .. statusList[i] .. [[]]\n if i < #statusList then html_filters = html_filters .. '|' end\n end\n html_filters = html_filters .. '
'\n html_filters = html_filters .. [[
←    Ctrl+Arrow LeftCtrl+Arrow Right    →
]]\nend\nhud.coroutines.renderFilterType = function()\n if displayMode < #displayModes-1 then\n maxFilterType = #elementsTypes\n if displayMode == 0 and enableStorageMonitoring then\n maxFilterType = #elementsTypes + 1\n elseif displayMode == 2 then\n maxFilterType = 0\n end\n html_filters_types = \"\"\n html_filters_types = html_filters_types .. '
↑    Ctrl+Arrow Up

'\n if displayMode == 0 or displayMode == 1 then\n html_filters_types = html_filters_types .. '
ALL Industries (' .. #industries_id .. ')
'\n for i,v in ipairs(elementsTypes) do\n html_filters_types = html_filters_types .. '
' .. v .. ' (' .. machines_count[v] .. ')
'\n end\n end\n if enableStorageMonitoring and (displayMode == 0 or displayMode == 2) then\n local bgtclass = 'bgt' .. (#elementsTypes + 2)\n if displayMode == 2 then\n bgtclass = 'bgt1'\n end\n html_filters_types = html_filters_types .. '
Storage (' .. #storages_id .. ')
'\n end\n html_filters_types = html_filters_types .. '
↓    Ctrl+Arrow Down
'\n else\n html_filters_types = \"\"\n end\nend\nhud.coroutines.renderSelectedAR = function()\n local html = \"\"\n if displayType == 0 or displayType == 1 then\n if selected_machine then\n local industry = selected_machine\n html = html .. [[
T]] .. industry.production.tier .. [[]] .. industry.production.locDisplayNameWithSize .. [[
]] .. statusList[industry.state] .. [[
]] .. industry.productId .. industry.name .. industry.type .. industry.mode .. industry.schematic .. industry.remainingTime .. industry.recipe ..[[
]]\n elseif selected_storage then\n local storage = selected_storage\n local displayName = storage.name\n local tierBox = ''\n local itemBox = ''\n local fillGauge = ''\n local gaugePercent = storage.percent\n if storage.percent > 100 then\n gaugePercent = 100\n end\n local r,g,b = getRGBGradient(gaugePercent/100,177,42,42,249,212,123,34,177,76)\n r = utils.round(r)\n g = utils.round(g)\n b = utils.round(b)\n if storage.item ~= nil and storage.item.name ~= \"InvalidItem\" then\n displayName = format_number(utils.round(storage.quantity*100)/100) .. \" \" .. storage.item.locDisplayNameWithSize .. \" (\" .. storage.percent .. \"%)\"\n tierBox = 'T' .. storage.item.tier .. ''\n local i = storage.item\n\n itemBox = [[
Item ID: ]] .. i.id .. [[
Item Name: ]] .. i.locDisplayNameWithSize .. [[
Item Unit Mass: ]] .. i.unitMass .. [[ kg
Item Unit Volume: ]] .. i.unitVolume .. [[ m3
]]\n fillGauge = '
'\n end\n html = html .. [[
]] .. tierBox .. [[]] .. displayName .. [[]] .. fillGauge .. [[
Container Type: ]] .. storage.type .. \" \" .. storage.size .. [[
]] .. itemBox .. [[
]]\n html = html .. [[]]\n end\n end\n html_ar_selected = html\nend\nhud.coroutines.renderControlSelectedIndustry = function()\n local html = \"\"\n if #databanks > 0 and emitter ~= nil and selected_machine ~= nil and (displayType == 0 or displayType == 1) then\n local industry = selected_machine\n html = '
' .. industry.tableName .. '
' .. statusList[industry.state] .. '

' .. industry.production.locDisplayNameWithSize .. '
'\n if industry.state == 1 or industry.state == (#statusList - 1) then\n command_1 = \"START\"\n command_2 = \"BATCH\"\n command_3 = \"MAINTAIN\"\n html = html .. '
STARTAlt+1
START BATCHQuantity:
'\n local has_quantity = false\n for k,v in pairs(craft_quantity_digits) do\n if tonumber(v) == nil then v = 0 end\n if tonumber(v) > 0 then\n has_quantity = true\n end\n end\n if not has_quantity then\n local value = tostring(math.floor(industry.maintainOrBatchQuantity))\n for i = #value, 1, -1 do\n local c = value:sub(i,i)\n craft_quantity_digits[9-(#value-(i-1))] = c\n end\n end\n for digit_index,digit in pairs(craft_quantity_digits) do\n html = html .. digit\n end\n html = html .. '
ALT+2
MAINTAINALT+3
'\n elseif industry.state < #statusList then\n command_1 = \"STOP\"\n command_2 = \"SOFT_STOP\"\n command_3 = \"HARD_STOP\"\n html = html .. [[
STOPALT+1
FINISH AND STOPALT+2
STOP AND ALLOW MATERIAL LOSSALT+3
]]\n else\n html = html .. '
Pending stop, please wait
'\n end\n html = html .. '
'\n end\n html_control = html\nend\nhud.coroutines.renderHud = function()\n local html = bootstrap_css_colors .. base_css .. html_ar_selected\n if displayMode ~= 3 then\n html = html .. html_filters_types\n if displayMode == 0 or displayMode == 1 then\n html = html .. html_machines .. html_filters .. html_control\n end\n if displayMode == 0 or displayMode == 2 then\n html = html .. html_storage\n end\n end\n html = html .. html_time .. html_credits\n system.setScreen(html)\nend\nhud.actions = {}\nhud.actions.start = {}\nhud.actions.stop = {}\nhud.actions.start.brake = function() ctrlPressed = true end\nhud.actions.stop.brake = function() ctrlPressed = false end\nhud.actions.start.down = function()\n if ctrlPressed and displayMode < 3 then\n statusFilterType = statusFilterType + 1\n if statusFilterType > maxFilterType then statusFilterType = 0 end\n onFilterChange()\n elseif displayMode < 3 then\n selectedRow = selectedRow + 1\n if selectedRow > maxOnPage then selectedRow = 1 end\n onRowChange()\n end\nend\nhud.actions.start.up = function()\n if ctrlPressed and displayMode < 3 then\n statusFilterType = statusFilterType - 1\n local max = #elementsTypes\n if statusFilterType < 0 then statusFilterType = maxFilterType end\n onFilterChange()\n elseif displayMode < 3 then\n selectedRow = selectedRow - 1\n if selectedRow < 1 then selectedRow = maxOnPage end\n onRowChange()\n end\nend\nhud.actions.start.option1 = function()\n if #databanks > 0 and emitter ~= nil and selected_machine ~= nil and (displayType == 0 or displayType == 1) then\n --Send Command 1\n for _,db in pairs(databanks) do\n db.setStringValue(selected_machine.id, command_1)\n end\n emitter.send(channels[selected_machine.typeFilter:lower()], \"\")\n end\nend\nhud.actions.start.option2 = function()\n if #databanks > 0 and emitter ~= nil and selected_machine ~= nil and (displayType == 0 or displayType == 1) then\n --Send Command 2\n for _,db in pairs(databanks) do\n if command_2:find(\"MAINTAIN\") or command_2:find(\"BATCH\") then\n craft_quantity = \"\"\n for _,digit in pairs(craft_quantity_digits) do\n craft_quantity = craft_quantity .. digit\n end\n command_2 = command_2 .. \"_\" .. craft_quantity\n end\n db.setStringValue(selected_machine.id, command_2)\n if command_2:find(\"MAINTAIN\") then command_2 = \"MAINTAIN\" end\n if command_2:find(\"BATCH\") then command_2 = \"BATCH\" end\n end\n emitter.send(channels[selected_machine.typeFilter:lower()], \"\")\n end\nend\nhud.actions.start.option3 = function()\n if #databanks > 0 and emitter ~= nil and selected_machine ~= nil and (displayType == 0 or displayType == 1) then\n --Send Command 3\n for _,db in pairs(databanks) do\n if command_3:find(\"MAINTAIN\") or command_3:find(\"BATCH\") then\n craft_quantity = \"\"\n for _,digit in pairs(craft_quantity_digits) do\n craft_quantity = craft_quantity .. digit\n end\n command_3 = command_3 .. \"_\" .. craft_quantity\n end\n db.setStringValue(selected_machine.id, command_3)\n if command_3:find(\"MAINTAIN\") then command_3 = \"MAINTAIN\" end\n if command_3:find(\"BATCH\") then command_3 = \"BATCH\" end\n end\n emitter.send(channels[selected_machine.typeFilter:lower()], \"\")\n end\nend\nhud.actions.start.option6 = function()\n sortingType = sortingType + 1\n if sortingType < 0 then sortingType = #sortingTypes end\n if sortingType > (#sortingTypes) then sortingType = 1 end\nend\nhud.actions.start.option7 = function()\n displayType = displayType + 1\n if displayType < 0 then displayType = (#displayTypes-1) end\n if displayType > (#displayTypes-1) then displayType = 0 end\nend\nhud.actions.start.option8 = function()\n displayMode = displayMode + 1\n if displayMode < 0 then displayMode = (#displayModes-1) end\n if displayMode > (#displayModes-1) then displayMode = 0 end\nend\nhud.actions.start.option9 = function()\n init = false\nend\nhud.actions.start.strafeleft = function()\n if ctrlPressed and (displayMode == 0 or displayMode == 1) then\n statusFilter = statusFilter - 1\n if statusFilter < 0 then statusFilter = #statusList end\n onFilterChange()\n elseif (displayType == 0 or displayType == 1) then\n page = page - 1\n if page < 1 then page = maxPage end\n onTablePageChange()\n end\nend\nhud.actions.start.straferight = function()\n if ctrlPressed and (displayMode == 0 or displayMode == 1) then\n statusFilter = statusFilter + 1\n if statusFilter > #statusList then statusFilter = 0 end\n onFilterChange()\n elseif (displayType == 0 or displayType == 1) then\n page = page + 1\n if page > maxPage then page = 1 end\n onTablePageChange()\n end\nend\n\n--[[\n DU-Nested-Coroutines by Jericho\n Permit to easier avoid CPU Load Errors\n Source available here: https://github.com/Jericho1060/du-nested-coroutines\n]]--\n\ncoroutinesTable = {}\n\nfunction initCoroutines()\n for k,f in pairs(hud.coroutines) do\n coroutinesTable[k] = coroutine.create(f)\n end\nend\n\ninitCoroutines()\n\nfor k,f in pairs(coroutinesTable) do system.print(k) end\n\nrunCoroutines = function()\n for k,co in pairs(coroutinesTable) do\n if coroutine.status(co) == \"dead\" then\n coroutinesTable[k] = coroutine.create(hud.coroutines[k])\n end\n if coroutine.status(co) == \"suspended\" then\n assert(coroutine.resume(co))\n end\n end\nend\n\nMainCoroutine = coroutine.create(runCoroutines)\n\nunit.hideWidget()\n\nfunction onTablePageChange()\n selectedRow = 1\n onRowChange()\nend\n\nfunction onFilterChange()\n onTablePageChange()\n page = 1\nend\n\nfunction onRowChange()\n craft_quantity_digits = {\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"}\nend\n","filter":{"args":[],"signature":"onStart()","slotKey":"-1"},"key":"2"},{"code":"local content = schematicContainer.getContent()\nfor _,s in pairs(content) do\n schematicStorage[\"s\" .. s.id] = s.quantity\nend","filter":{"args":[],"signature":"onContentUpdate()","slotKey":"0"},"key":"0"}],"methods":[],"slots":{"0":{"name":"slot1","type":{"events":[],"methods":[]}},"1":{"name":"slot2","type":{"events":[],"methods":[]}},"2":{"name":"slot3","type":{"events":[],"methods":[]}},"3":{"name":"slot4","type":{"events":[],"methods":[]}},"4":{"name":"slot5","type":{"events":[],"methods":[]}},"5":{"name":"slot6","type":{"events":[],"methods":[]}},"6":{"name":"slot7","type":{"events":[],"methods":[]}},"7":{"name":"slot8","type":{"events":[],"methods":[]}},"8":{"name":"slot9","type":{"events":[],"methods":[]}},"9":{"name":"slot10","type":{"events":[],"methods":[]}},"-5":{"name":"library","type":{"events":[],"methods":[]}},"-4":{"name":"system","type":{"events":[],"methods":[]}},"-3":{"name":"player","type":{"events":[],"methods":[]}},"-2":{"name":"construct","type":{"events":[],"methods":[]}},"-1":{"name":"unit","type":{"events":[],"methods":[]}}}}