code:
Basic idea: place this chest down at the end of a pipeline. Feed stuff into it. Attach a luacontroller to it with a digiline in between. Program the luacontroller to turn on a wire to stop the pipeline when the chest is full. Don't put more than one kind of item down the pipeline into the chest, unless you want weird tricksy behavior.

...[F]===[C]--{L}
    |__________|
   [B]
F: filter
B: blinky plant
C: digiline chest
L: luacontroller
==: pipe
__: mesecons
--: digiline

Make sure you use mem in the luacontroller to keep the mesecon wire on indefinitely after the chest signals full. When it signals "take" someone took an item out and you can start the pipeline up again.
This may be a bad idea if they only take half a stack or something. Oh well.

When you put something in, you get a "put" to indicate it's OK (sort of (still buggy)) and can fit inside the chest. When you get a "lost", that means it won't fit inside the chest, and will bounce, possibly popping out. When you get a "overflow" that means you tried to add something to a chest that just filled up, and the stack will bounce. When you get a "full" that means the chest just filled up.

"Filled up" for all intents and purposes, means taking the type of whatever just went into the chest, and seeing if at least 1 of that type can be added to the chest. If it cannot, then it's filled up. That means a chest full of stacks of 30 copper and one spot of 98 gold, and you add one gold to that, it will say it's full. Add 30 copper to it, and it won't.

Generally you'll be working with full stacks in pipeworks. Even the non-mese filters will accumulate items in a chest, and not spread them out into multiple stacks. And generally your destination chests will each have one of any kind of item. So all you have to worry about is when you've got 99 everywhere, and one space possibly free. A mese filter can fail on that in fact, for instance if you have room for 45 gold, and it tries to push a stack of 50 gold. All 50 will bounce! The code for chests isn't smart enough to add the 45 and bounce the leftover 5. So only use mese filters when you're sure a full stack has accumulated for the filter to push, and there are no partial stacks at the destination.

For some reason when an "overflow" happens, when it checks if the stack can fit inside the chest, the answer is yes it can fit! Then it doesn't. Sort of buggy.

itemstack - the qualified name, a space, then the amount. If the space and amount are ommitted, that represents just 1.

examples: "default:chest 33" "default:coal" "default:axe_diamond"

bounce
    - when an item cannot enter the destination container it will travel back up the tube it came from, going along alternate routes if they exist, but otherwise popping out of the tube.

popping out
    - the little thingy travelling through the tube disappears, and an entity of the item appears, as if it was just dropped. This entity can expire, losing your items permanently!

The messages are:

put <itemstack>
    - this means that the inventory claimed it could fit that stack of items inside it. Inventories lie. But with the above caveats this is quite usable.
lost <itemstack>
    - the stack couldn't fit in the chest and bounces.
full <itemstack> <count>
    - the chest has been filled. The itemstack is what filled it. count is what's leftover.
      until chests can suck up part of a stack and not bounce the whole stack, that count will
      always be 0
overflow <itemstack> <count>
    - generally this is the same as lost, except that the "put" event happened, meaning that the
      itemstack was allowed in the chest.
    - this will happen with two stacks in rapid succession, the first filling the chest, and the
      second bouncing. the <count> in this case will be the amount of the second.
    - overflow can't happen with two different kinds of items, you'll get a put, maybe full, then lost for the second kind

Tricky situation:
if you have a blank spot and put say 82 torches down your pipeline, followed by 99 coal, the 82 torches will go in the chest, and the chest will see that 1 more torch can fit since that would only go to 83. Since 1 more torch can fit, no "full" message will fire off. Then when the coal hits the chest, the "fail" message will fire and the coal will bounce out. The chest couldn't predict that coal would be coming next, so it couldn't know that the chest is full, for coal, while not full for torches.

TODO:
    - make chest.lua a mixin that gets both default and locked chests
    - digiline aware furnaces
    - digiline aware technic machines, grinders, alloy furnaces, etc
    - the pipes going into the chests don't snap to the pipe holes in the digiline chests. They still act fine as pipeworks destinations though.
    - digiline chests seem to be immune to filters. But it's late and I'm shipping this. Someone else can figure out why the chests aren't acting like pipeworks chests, despite cloning the pipeworks chest's object. Oh who am I kidding. I'll do it myself I guess, once I've lost hope of aid again.


code:
Digilines
==========
- The minetest counterpart for bus systems like i2c, SPI, RS232, USB -

This mod adds digiline wires, an RTC (Real Time Clock), a light sensor as well as an LCD Screen.
Can be used together with the luacontroller from mesecons. See the luacontroller manual for more information.

Send "GET" to RTC or light sensor to retrieve Data, send any text to LCD to display it.
Select channel by right-clicking items.

License:
  Code: LGPL
  Textures: WTFPL

repo_name: korkut/MeseCraft

license: mit


path: mods/ITEMS/digilines/characters


code:
digilines = {}

-- Backwards compatibility code.
-- We define a proxy table whose methods can be called with the
-- `foo:bar` notation, and it will redirect the call to the
-- real function, dropping the first implicit argument.
local digiline; digiline = setmetatable({}, {
	__index = function(_, k)
		-- Get method from real table.
		local v = digilines[k]
		if type(v) == "function" then
			-- We need to wrap functions in order to ignore
			-- the implicit `self` argument.
			local f = v
			return function(self, ...)
				-- Trap invalid calls of the form `digiline.foo(...)`.
				assert(self == digiline)
				return f(...)
			end
		end
		return v
	end,
})
rawset(_G, "digiline", digiline)

-- Let's test our proxy table.
function digilines._testproxy(x)
	return x
end

-- Test using old `digiline:foobar` form.
assert(digiline:_testproxy("foobar") == "foobar")

-- Test using new `digilines.foobar` form.
assert(digilines._testproxy("foobar") == "foobar")

-- Test calling incorrect form raises an error.
assert(not pcall(function() digiline._testproxy("foobar") end))

local modpath = minetest.get_modpath("digilines")
dofile(modpath .. "/presetrules.lua")
dofile(modpath .. "/util.lua")
dofile(modpath .. "/internal.lua")
dofile(modpath .. "/wires_common.lua")
dofile(modpath .. "/wire_std.lua")

function digilines.receptor_send(pos, rules, channel, msg)
	local checked = {}
	checked[minetest.hash_node_position(pos)] = true -- exclude itself
	for _,rule in ipairs(rules) do
		if digilines.rules_link(pos, digilines.addPosRule(pos, rule)) then
			digilines.transmit(digilines.addPosRule(pos, rule), channel, msg, checked)
		end
	end
end

minetest.register_craft({
	output = 'digilines:wire_std_00000000 2',
	recipe = {
		{'mesecons_materials:fiber', 'mesecons_materials:fiber', 'mesecons_materials:fiber'},
		{'mesecons_insulated:insulated_off', 'mesecons_insulated:insulated_off', 'default:gold_ingot'},
		{'mesecons_materials:fiber', 'mesecons_materials:fiber', 'mesecons_materials:fiber'},
	}
})

-- For minetest 0.4 support returned nil are also tested:  ~= false
if minetest.settings:get_bool("digilines_enable_inventory", true) ~= false then
	dofile(modpath .. "/inventory.lua")
end

if minetest.settings:get_bool("digilines_enable_lcd", true) ~= false then
	dofile(modpath .. "/lcd.lua")
end

if minetest.settings:get_bool("digilines_enable_lightsensor", true) ~= false then
	dofile(modpath .. "/lightsensor.lua")
end

if minetest.settings:get_bool("digilines_enable_rtc", true) ~= false then
	dofile(modpath .. "/rtc.lua")
end


code:
function digilines.getspec(node)
	local def = minetest.registered_nodes[node.name]
	if not def then return false end
	return def.digilines or def.digiline
end

function digilines.importrules(spec, node)
	if type(spec) == 'function' then
		return spec(node)
	elseif spec then
		return spec
	else
		return digilines.rules.default
	end
end

function digilines.getAnyInputRules(pos)
	local node = digilines.get_node_force(pos)
	local spec = digilines.getspec(node)
	if not spec then return end

	if spec.wire then
		return digilines.importrules(spec.wire.rules, node)
	end
	if spec.effector then
		return digilines.importrules(spec.effector.rules, node)
	end
end

function digilines.getAnyOutputRules(pos)
	local node = digilines.get_node_force(pos)
	local spec = digilines.getspec(node)
	if not spec then return end

	if spec.wire then
		return digilines.importrules(spec.wire.rules, node)
	end
	if spec.receptor then
		return digilines.importrules(spec.receptor.rules, node)
	end
end

function digilines.rules_link(output, input)
	local outputrules = digilines.getAnyOutputRules(output)
	local inputrules  = digilines.getAnyInputRules (input)

	if not outputrules or not inputrules then return false end

	for _, orule in ipairs(outputrules) do
		if digilines.cmpPos(digilines.addPosRule(output, orule), input) then
			for _, irule in ipairs(inputrules) do
				if digilines.cmpPos(digilines.addPosRule(input, irule), output) then
					return true
				end
			end
		end
	end
	return false
end

function digilines.rules_link_anydir(output, input)
	return digilines.rules_link(output, input)
	or     digilines.rules_link(input, output)
end

local function queue_new()
	return {nextRead = 1, nextWrite = 1}
end

local function queue_empty(queue)
	return queue.nextRead == queue.nextWrite
end

local function queue_enqueue(queue, object)
	local nextWrite = queue.nextWrite
	queue[nextWrite] = object
	queue.nextWrite = nextWrite + 1
end

local function queue_dequeue(queue)
	local nextRead = queue.nextRead
	local object = queue[nextRead]
	queue[nextRead] = nil
	queue.nextRead = nextRead + 1
	return object
end

function digilines.transmit(pos, channel, msg, checked)
	local checkedID = minetest.hash_node_position(pos)
	if checked[checkedID] then
		return
	end
	checked[checkedID] = true

	digilines.vm_begin()
	local queue = queue_new()
	queue_enqueue(queue, pos)
	while not queue_empty(queue) do
		local curPos = queue_dequeue(queue)
		local node = digilines.get_node_force(curPos)
		local spec = digilines.getspec(node)
		if spec then
			-- Effector actions --> Receive
			if spec.effector then
				spec.effector.action(curPos, node, channel, msg)
			end

			-- Cable actions --> Transmit
			if spec.wire then
				local rules = digilines.importrules(spec.wire.rules, node)
				for _, rule in ipairs(rules) do
					local nextPos = digilines.addPosRule(curPos, rule)
					if digilines.rules_link(curPos, nextPos) then
						local checkedID = minetest.hash_node_position(nextPos)
						if not checked[checkedID] then
							checked[checkedID] = true
							queue_enqueue(queue, nextPos)
						end
					end
				end
			end
		end
	end
	digilines.vm_end()
end


code:
local pipeworks_enabled = minetest.get_modpath("pipeworks") ~= nil

-- Sends a message onto the Digilines network.
-- pos: the position of the Digilines chest node.
-- action: the action string indicating what happened.
-- stack: the ItemStack that the action acted on (optional).
-- from_slot: the slot number that is taken from (optional).
-- to_slot: the slot number that is put into (optional).
-- side: which side of the chest the action occurred (optional).
local function send_message(pos, action, stack, from_slot, to_slot, side)
	local channel = minetest.get_meta(pos):get_string("channel")
	local msg = {
		action = action,
		stack = stack and stack:to_table(),
		from_slot = from_slot,
		to_slot = to_slot,
		-- Duplicate the vector in case the caller expects it not to change.
		side = side and vector.new(side)
	}
	digilines.receptor_send(pos, digilines.rules.default, channel, msg)
end

-- Checks if the inventory has become empty and, if so, sends an empty message.
local function check_empty(pos)
	if minetest.get_meta(pos):get_inventory():is_empty("main") then
		send_message(pos, "empty")
	end
end

-- Checks if the inventory has become full for a particular type of item and,
-- if so, sends a full message.
local function check_full(pos, stack)
	local one_item_stack = ItemStack(stack)
	one_item_stack:set_count(1)
	if not minetest.get_meta(pos):get_inventory():room_for_item("main", one_item_stack) then
		send_message(pos, "full", one_item_stack)
	end
end

local tubeconn = pipeworks_enabled and "^pipeworks_tube_connection_wooden.png" or ""
local tubescan = pipeworks_enabled and function(pos) pipeworks.scan_for_tube_objects(pos) end or nil

-- A place to remember things from allow_metadata_inventory_put to
-- on_metadata_inventory_put. This is a hack due to issue
-- minetest/minetest#6534 that should be removed once that’s fixed.
local last_inventory_put_index
local last_inventory_put_stack

-- A place to remember things from allow_metadata_inventory_take to
-- tube.remove_items. This is a hack due to issue minetest-mods/pipeworks#205
-- that should be removed once that’s fixed.
local last_inventory_take_index

minetest.register_alias("digilines_inventory:chest", "digilines:chest")
minetest.register_node("digilines:chest", {
	description = "Digiline Chest",
	tiles = {
		"default_chest_top.png"..tubeconn,
		"default_chest_top.png"..tubeconn,
		"default_chest_side.png"..tubeconn,
		"default_chest_side.png"..tubeconn,
		"default_chest_side.png"..tubeconn,
		"default_chest_front.png",
	},
	paramtype2 = "facedir",
	legacy_facedir_simple = true,
	groups = {choppy=2, oddly_breakable_by_hand=2, tubedevice=1, tubedevice_receiver=1},
	sounds = default.node_sound_wood_defaults(),
	on_construct = function(pos)
		local meta = minetest.get_meta(pos)
		meta:set_string("infotext", "Digiline Chest")
		meta:set_string("formspec", "size[8,10]"..
			((default and default.gui_bg) or "")..
			((default and default.gui_bg_img) or "")..
			((default and default.gui_slots) or "")..
			"label[0,0;Digiline Chest]"..
			"list[current_name;main;0,1;8,4;]"..
			"field[2,5.5;5,1;channel;Channel;${channel}]"..
			((default and default.get_hotbar_bg) and default.get_hotbar_bg(0,6) or "")..
			"list[current_player;main;0,6;8,4;]"..
			"listring[]")
		local inv = meta:get_inventory()
		inv:set_size("main", 8*4)
	end,
	after_place_node = tubescan,
	after_dig_node = tubescan,
	can_dig = function(pos)
		return minetest.get_meta(pos):get_inventory():is_empty("main")
	end,
	on_receive_fields = function(pos, _, fields, sender)
		local name = sender:get_player_name()
		if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, {protection_bypass=true}) then
			minetest.record_protection_violation(pos, name)
			return
		end
		if fields.channel ~= nil then
			minetest.get_meta(pos):set_string("channel",fields.channel)
		end
	end,
	digiline = {
		receptor = {},
		effector = {
			action = function() end
		}
	},
	tube = {
		connect_sides = {left=1, right=1, back=1, front=1, bottom=1, top=1},
		connects = function(i,param2)
			return not pipeworks.connects.facingFront(i,param2)
		end,
		input_inventory = "main",
		can_insert = function(pos, _, stack, direction)
			local ret = minetest.get_meta(pos):get_inventory():room_for_item("main", stack)
			if not ret then
				-- The stack cannot be accepted. It will never be passed to
				-- insert_object, but it should be reported as a toverflow.
				-- Here, direction = direction item is moving, which is into
				-- side.
				local side = vector.multiply(direction, -1)
				send_message(pos, "toverflow", stack, nil, nil, side)
			end
			return ret
		end,
		insert_object = function(pos, _, original_stack, direction)
			-- Here, direction = direction item is moving, which is into side.
			local side = vector.multiply(direction, -1)
			local inv = minetest.get_meta(pos):get_inventory()
			local inv_contents = inv:get_list("main")
			local any_put = false
			local stack = original_stack
			local stack_name = stack:get_name()
			local stack_count = stack:get_count()
			-- Walk the inventory, adding items to existing stacks of the same
			-- type.
			for i = 1, #inv_contents do
				local existing_stack = inv_contents[i]
				if not existing_stack:is_empty() and existing_stack:get_name() == stack_name then
					local leftover = existing_stack:add_item(stack)
					local leftover_count = leftover:get_count()
					if leftover_count ~= stack_count then
						-- We put some items into the slot. Update the slot in
						-- the inventory, tell Digilines listeners about it,
						-- and keep looking for the a place to put the
						-- leftovers if any.
						any_put = true
						inv:set_stack("main", i, existing_stack)
						local stack_that_was_put
						if leftover_count == 0 then
							stack_that_was_put = stack
						else
							stack_that_was_put = ItemStack(stack)
							stack_that_was_put:set_count(stack_count - leftover_count)
						end
						send_message(pos, "tput", stack_that_was_put, nil, i, side)
						stack = leftover
						stack_count = leftover_count
						if stack_count == 0 then
							break
						end
					end
				end
			end
			if stack_count ~= 0 then
				-- Walk the inventory, adding items to empty slots.
				for i = 1, #inv_contents do
					local existing_stack = inv_contents[i]
					if existing_stack:is_empty() then
						local leftover = existing_stack:add_item(stack)
						local leftover_count = leftover:get_count()
						if leftover_count ~= stack_count then
							-- We put some items into the slot. Update the slot in
							-- the inventory, tell Digilines listeners about it,
							-- and keep looking for the a place to put the
							-- leftovers if any.
							any_put = true
							inv:set_stack("main", i, existing_stack)
							local stack_that_was_put
							if leftover_count == 0 then
								stack_that_was_put = stack
							else
								stack_that_was_put = ItemStack(stack)
								stack_that_was_put:set_count(stack_count - leftover_count)
							end
							send_message(pos, "tput", stack_that_was_put, nil, i, side)
							stack = leftover
							stack_count = leftover_count
							if stack_count == 0 then
								break
							end
						end
					end
				end
			end
			if any_put then
				check_full(pos, original_stack)
			end
			if stack_count ~= 0 then
				-- Some items could not be added and bounced back. Report them.
				send_message(pos, "toverflow", stack, nil, nil, side)
			end
			return stack
		end,
		remove_items = function(pos, _, stack, dir, count)
			-- Here, stack is the ItemStack in our own inventory that is being
			-- pulled from, NOT the stack that is actually pulled out.
			-- Combining it with count gives the stack that is pulled out.
			-- Also, note that Pipeworks doesn’t pass the index to this
			-- function, so we use the one recorded in
			-- allow_metadata_inventory_take; because we don’t implement
			-- tube.can_remove, Pipeworks will call
			-- allow_metadata_inventory_take instead and will pass it the
			-- index.
			local taken = stack:take_item(count)
			minetest.get_meta(pos):get_inventory():set_stack("main", last_inventory_take_index, stack)
			send_message(pos, "ttake", taken, last_inventory_take_index, nil, dir)
			check_empty(pos)
			return taken
		end,
	},
	allow_metadata_inventory_put = function(pos, _, index, stack)
		-- Remember what was in the target slot before the put; see
		-- on_metadata_inventory_put for why we care.
		last_inventory_put_index = index
		last_inventory_put_stack = minetest.get_meta(pos):get_inventory():get_stack("main", index)
		return stack:get_count()
	end,
	allow_metadata_inventory_take = function(_, _, index, stack)
		-- Remember the index value; see tube.remove_items for why we care.
		last_inventory_take_index = index
		return stack:get_count()
	end,
	on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
		-- See what would happen if we were to move the items back from in the
		-- opposite direction. In the event of a normal move, this must
		-- succeed, because a normal move subtracts some items from the from
		-- stack and adds them to the to stack; the two stacks naturally must
		-- be compatible and so the reverse operation must succeed. However, if
		-- the user *swaps* the two stacks instead, then due to issue
		-- minetest/minetest#6534, this function is only called once; however,
		-- when it is called, the stack that used to be in the to stack has
		-- already been moved to the from stack, so we can detect the situation
		-- by the fact that the reverse move will fail due to the from stack
		-- being incompatible with its former contents.
		local inv = minetest.get_meta(pos):get_inventory()
		local from_stack = inv:get_stack("main", from_index)
		local to_stack = inv:get_stack("main", to_index)
		local reverse_move_stack = ItemStack(to_stack)
		reverse_move_stack:set_count(count)
		local swapped = from_stack:add_item(reverse_move_stack):get_count() == count
		if swapped then
			local channel = minetest.get_meta(pos):get_string("channel")
			to_stack:set_count(count)
			local msg = {
				action = "uswap",
				-- The slot and stack do not match because this function is
				-- called after the action has taken place, but the Digilines
				-- message is from the perspective of a viewer who hasn’t
				-- observed the movement yet.
				x_stack = to_stack:to_table(),
				x_slot = from_index,
				y_stack = from_stack:to_table(),
				y_slot = to_index,
			}
			digilines.receptor_send(pos, digilines.rules.default, channel, msg)
		else
			to_stack:set_count(count)
			send_message(pos, "umove", to_stack, from_index, to_index)
		end
		minetest.log("action", player:get_player_name().." moves stuff in chest at "..minetest.pos_to_string(pos))
	end,
	on_metadata_inventory_put = function(pos, _, index, stack, player)
		-- Get what was in the target slot before the put; it has disappeared
		-- by now (been replaced by the result of the put action) but we saved
		-- it in allow_metadata_inventory_put. This should always work
		-- (allow_metadata_inventory_put should AFAICT always be called
		-- immediately before on_metadata_inventory_put), but in case of
		-- something weird happening, just fall back to using an empty
		-- ItemStack rather than crashing.
		local old_stack
		if last_inventory_put_index == index then
			old_stack = last_inventory_put_stack
			last_inventory_put_index = nil
			last_inventory_put_stack = nil
		else
			old_stack = ItemStack(nil)
		end
		-- If the player tries to place a stack into an inventory, there’s
		-- already a stack there, and the existing stack is either of a
		-- different item type or full, then obviously the stacks can’t be
		-- merged; instead the stacks are swapped. This information is not
		-- reported to mods (Minetest core neither tells us that a particular
		-- action was a swap, nor tells us a take followed by a put). In core,
		-- the condition for swapping is that you try to add the new stack to
		-- the existing stack and the leftovers are as big as the original
		-- stack to put. Replicate that logic here using the old stack saved in
		-- allow_metadata_inventory_put. If a swap happened, report it to the
		-- Digilines network as a utake followed by a uput.
		local leftovers = old_stack:add_item(stack)
		if leftovers:get_count() == stack:get_count() then
			send_message(pos, "utake", old_stack, index)
		end
		send_message(pos, "uput", stack, nil, index)
		check_full(pos, stack)
		minetest.log("action", player:get_player_name().." puts stuff into chest at "..minetest.pos_to_string(pos))
	end,
	on_metadata_inventory_take = function(pos, _, index, stack, player)
		send_message(pos, "utake", stack, index)
		check_empty(pos)
		minetest.log("action", player:get_player_name().." takes stuff from chest at "..minetest.pos_to_string(pos))
	end
})

minetest.register_craft({
	type = "shapeless",
	output = "digilines:chest",
	recipe = {"default:chest", "digilines:wire_std_00000000"}
})


code:
--* parts are currently not possible because you cannot set the pitch of an entity from lua

-- Font: 04.jp.org

-- load characters map
local chars_file = io.open(minetest.get_modpath("digilines").."/characters", "r")
local charmap = {}
local max_chars = 12
if not chars_file then
	print("[digilines] E: LCD: character map file not found")
else
	while true do
		local char = chars_file:read("*l")
		if char == nil then
			break
		end
		local img = chars_file:read("*l")
		chars_file:read("*l")
		charmap[char] = img
	end
end

-- CONSTANTS
local LCD_WITH = 100
local LCD_PADDING = 8

local LINE_LENGTH = 12
local NUMBER_OF_LINES = 5

local LINE_HEIGHT = 14
local CHAR_WIDTH = 5

local create_lines = function(text)
	local line = ""
	local line_num = 1
	local tab = {}
	for word in string.gmatch(text, "%S+") do
		if string.len(line)+string.len(word) < LINE_LENGTH and word ~= "|" then
			if line ~= "" then
				line = line.." "..word
			else
				line = word
			end
		else
			table.insert(tab, line)
			if word ~= "|" then
				line = word
			else
				line = ""
			end
			line_num = line_num+1
			if line_num > NUMBER_OF_LINES then
				return tab
			end
		end
	end
	table.insert(tab, line)
	return tab
end

local generate_line = function(s, ypos)
	local i = 1
	local parsed = {}
	local width = 0
	local chars = 0
	while chars < max_chars and i <= #s do
		local file = nil
		if charmap[s:sub(i, i)] ~= nil then
			file = charmap[s:sub(i, i)]
			i = i + 1
		elseif i < #s and charmap[s:sub(i, i + 1)] ~= nil then
			file = charmap[s:sub(i, i + 1)]
			i = i + 2
		else
			print("[digilines] W: LCD: unknown symbol in '"..s.."' at "..i)
			i = i + 1
		end
		if file ~= nil then
			width = width + CHAR_WIDTH
			table.insert(parsed, file)
			chars = chars + 1
		end
	end
	width = width - 1

	local texture = ""
	local xpos = math.floor((LCD_WITH - 2 * LCD_PADDING - width) / 2 + LCD_PADDING)
	for ii = 1, #parsed do
		texture = texture..":"..xpos..","..ypos.."="..parsed[ii]..".png"
		xpos = xpos + CHAR_WIDTH + 1
	end
	return texture
end

local generate_texture = function(lines)
	local texture = "[combine:"..LCD_WITH.."x"..LCD_WITH
	local ypos = 16
	for i = 1, #lines do
		texture = texture..generate_line(lines[i], ypos)
		ypos = ypos + LINE_HEIGHT
	end
	return texture
end

local lcds = {
	-- on ceiling
	--* [0] = {delta = {x = 0, y = 0.4, z = 0}, pitch = math.pi / -2},
	-- on ground
	--* [1] = {delta = {x = 0, y =-0.4, z = 0}, pitch = math.pi /  2},
	-- sides
	[2] = {delta = {x =  0.437, y = 0, z = 0}, yaw = math.pi / -2},
	[3] = {delta = {x = -0.437, y = 0, z = 0}, yaw = math.pi /  2},
	[4] = {delta = {x = 0, y = 0, z =  0.437}, yaw = 0},
	[5] = {delta = {x = 0, y = 0, z = -0.437}, yaw = math.pi},
}

local reset_meta = function(pos)
	minetest.get_meta(pos):set_string("formspec", "field[channel;Channel;${channel}]")
end

local clearscreen = function(pos)
	local objects = minetest.get_objects_inside_radius(pos, 0.5)
	for _, o in ipairs(objects) do
		local o_entity = o:get_luaentity()
		if o_entity and o_entity.name == "digilines_lcd:text" then
			o:remove()
		end
	end
end

local set_texture = function(ent)
	local meta = minetest.get_meta(ent.object:get_pos())
	local text = meta:get_string("text")
	ent.object:set_properties({
		textures = {
			generate_texture(create_lines(text))
		}
	})
end

local get_entity = function(pos)
	local lcd_entity
	local objects = minetest.get_objects_inside_radius(pos, 0.5)
	for _, o in ipairs(objects) do
		local o_entity = o:get_luaentity()
		if o_entity and o_entity.name == "digilines_lcd:text" then
			if not lcd_entity then
				lcd_entity = o_entity
			else
				-- Remove extras, if any
				o:remove()
			end
		end
	end
	return lcd_entity
end

local rotate_text = function(pos, param)
	local entity = get_entity(pos)
	if not entity then
		return
	end
	local lcd_info = lcds[param or minetest.get_node(pos).param2]
	if not lcd_info then
		return
	end
	entity.object:set_pos(vector.add(pos, lcd_info.delta))
	entity.object:set_yaw(lcd_info.yaw or 0)
end

local prepare_writing = function(pos)
	local entity = get_entity(pos)
	if entity then
		set_texture(entity)
		rotate_text(pos)
	end
end

local spawn_entity = function(pos)
	if not get_entity(pos) then
		minetest.add_entity(pos, "digilines_lcd:text")
		rotate_text(pos)
	end
end

local on_digiline_receive = function(pos, _, channel, msg)
	local meta = minetest.get_meta(pos)
	local setchan = meta:get_string("channel")
	if setchan ~= channel then return end

	meta:set_string("text", msg)
	meta:set_string("infotext", msg)

	if msg ~= "" then
		prepare_writing(pos)
	end
end

local lcd_box = {
	type = "wallmounted",
	wall_top = {-8/16, 7/16, -8/16, 8/16, 8/16, 8/16}
}

minetest.register_alias("digilines_lcd:lcd", "digilines:lcd")
minetest.register_node("digilines:lcd", {
	drawtype = "nodebox",
	description = "Digiline LCD",
	inventory_image = "lcd_lcd.png",
	wield_image = "lcd_lcd.png",
	tiles = {"lcd_anyside.png"},
	paramtype = "light",
	sunlight_propagates = true,
	light_source = 6,
	paramtype2 = "wallmounted",
	node_box = lcd_box,
	selection_box = lcd_box,
	groups = {choppy = 3, dig_immediate = 2},
	after_place_node = function(pos)
		local param2 = minetest.get_node(pos).param2
		if param2 == 0 or param2 == 1 then
			minetest.add_node(pos, {name = "digilines:lcd", param2 = 3})
		end
		spawn_entity(pos)
		prepare_writing(pos)
	end,
	on_construct = reset_meta,
	on_destruct = clearscreen,
	on_punch = function(pos, node, puncher, pointed_thing)
		if minetest.is_player(puncher) then
			spawn_entity(pos)
		end
	end,
	on_rotate = function(pos, node, user, mode, new_param2)
		if mode ~= screwdriver.ROTATE_FACE then
			return false
		end
		rotate_text(pos, new_param2)
	end,
	on_receive_fields = function(pos, _, fields, sender)
		local name = sender:get_player_name()
		if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, {protection_bypass=true}) then
			minetest.record_protection_violation(pos, name)
			return
		end
		if (fields.channel) then
			minetest.get_meta(pos):set_string("channel", fields.channel)
		end
	end,
	digiline = {
		receptor = {},
		effector = {
			action = on_digiline_receive
		},
	},
})

minetest.register_lbm({
	label = "Replace Missing Text Entities",
	name = "digilines:replace_text",
	nodenames = {"digilines:lcd"},
	run_at_every_load = true,
	action = spawn_entity,
})

minetest.register_entity(":digilines_lcd:text", {
	collisionbox = { 0, 0, 0, 0, 0, 0 },
	visual = "upright_sprite",
	textures = {},
	on_activate = set_texture,
})

minetest.register_craft({
	output = "digilines:lcd 2",
	recipe = {
		{"default:steel_ingot", "digilines:wire_std_00000000", "default:steel_ingot"},
		{"mesecons_lightstone:lightstone_green_off","mesecons_lightstone:lightstone_green_off","mesecons_lightstone:lightstone_green_off"},
		{"default:glass","default:glass","default:glass"}
	}
})


code:
local GET_COMMAND = "GET"

local lsensor_nodebox =
{
	type = "fixed",
	fixed = {
		{ -8/16, -8/16, -8/16, 8/16, -7/16, 8/16 }, -- bottom slab

		{ -7/16, -7/16, -7/16, -4/16, -5/16,  7/16 }, -- bonds
		{  4/16, -7/16, -7/16,  7/16, -5/16,  7/16 },
		{ -7/16, -7/16, -7/16,  7/16, -5/16, -4/16 },
		{ -7/16, -7/16,  4/16,  7/16, -5/16,  7/16 },

		{ -1/16, -7/16, -1/16, 1/16, -5/16, 1/16 }, -- pin thing in the middle
	}
}

local lsensor_selbox =
{
	type = "fixed",
	fixed = {{ -8/16, -8/16, -8/16, 8/16, -3/16, 8/16 }}
}

local on_digiline_receive = function (pos, _, channel, msg)
	local setchan = minetest.get_meta(pos):get_string("channel")
	if channel == setchan and msg == GET_COMMAND then
		local lightval = minetest.get_node_light(pos)
		digilines.receptor_send(pos, digilines.rules.default, channel, lightval)
	end
end

minetest.register_alias("digilines_lightsensor:lightsensor", "digilines:lightsensor")
minetest.register_node("digilines:lightsensor", {
	description = "Digiline Lightsensor",
	drawtype = "nodebox",
	tiles = {"digilines_lightsensor.png"},

	paramtype = "light",
	groups = {dig_immediate=2},
	selection_box = lsensor_selbox,
	node_box = lsensor_nodebox,
	digiline =
	{
		receptor = {},
		effector = {
			action = on_digiline_receive
		},
	},
	on_construct = function(pos)
		local meta = minetest.get_meta(pos)
		meta:set_string("formspec", "field[channel;Channel;${channel}]")
	end,
	on_receive_fields = function(pos, _, fields, sender)
		local name = sender:get_player_name()
		if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, {protection_bypass=true}) then
			minetest.record_protection_violation(pos, name)
			return
		end
		if (fields.channel) then
			minetest.get_meta(pos):set_string("channel", fields.channel)
		end
	end,
})


code:
name = digilines
author = Jeija
description = This mod adds digiline wires, an RTC (Real Time Clock), a light sensor as well as an LCD Screen. Can be used together with the luacontroller from mesecons.
depends = default
optional_depends =


code:
local GET_COMMAND = "GET"

local rtc_nodebox =
{
	type = "fixed",
	fixed = {
		{ -8/16, -8/16, -8/16, 8/16, -7/16, 8/16 }, -- bottom slab

		{ -7/16, -7/16, -7/16, 7/16, -5/16,  7/16 },
	}
}

local rtc_selbox =
{
	type = "fixed",
	fixed = {{ -8/16, -8/16, -8/16, 8/16, -3/16, 8/16 }}
}

local on_digiline_receive = function (pos, _, channel, msg)
	local setchan = minetest.get_meta(pos):get_string("channel")
	if channel == setchan and msg == GET_COMMAND then
		local timeofday = minetest.get_timeofday()
		digilines.receptor_send(pos, digilines.rules.default, channel, timeofday)
	end
end

minetest.register_alias("digilines_rtc:rtc", "digilines:rtc")
minetest.register_node("digilines:rtc", {
	description = "Digiline Real Time Clock (RTC)",
	drawtype = "nodebox",
	tiles = {"digilines_rtc.png"},

	paramtype = "light",
	paramtype2 = "facedir",
	groups = {dig_immediate=2},
	selection_box = rtc_selbox,
	node_box = rtc_nodebox,
	digiline =
	{
		receptor = {},
		effector = {
			action = on_digiline_receive
		},
	},
	on_construct = function(pos)
		local meta = minetest.get_meta(pos)
		meta:set_string("formspec", "field[channel;Channel;${channel}]")
	end,
	on_receive_fields = function(pos, _, fields, sender)
		local name = sender:get_player_name()
		if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, {protection_bypass=true}) then
			minetest.record_protection_violation(pos, name)
			return
		end
		if (fields.channel) then
			minetest.get_meta(pos):set_string("channel", fields.channel)
		end
	end,
})


code:
# If enabled, makes some nodes with inventories (like chests) send signals
# when items are moved in the inventory.
digilines_enable_inventory (Enable inventory signals) bool true

# Enable or disable the LCD panel with visible text.
digilines_enable_lcd (Enable LCD) bool true

# Enable or disable the light sensor component.
digilines_enable_lightsensor (Enable light sensor) bool true

# Enable or disable the real time clock component.
digilines_enable_rtc (Enable RTC) bool true


code:
function digilines.addPosRule(p, r)
	return {x = p.x + r.x, y = p.y + r.y, z = p.z + r.z}
end

function digilines.cmpPos(p1, p2)
	return (p1.x == p2.x and p1.y == p2.y and p1.z == p2.z)
end

--Rules rotation Functions:
function digilines.rotate_rules_right(rules)
	local nr={}
	for i, rule in ipairs(rules) do
		nr[i]={}
		nr[i].z=rule.x
		nr[i].x=-rule.z
		nr[i].y=rule.y
	end
	return nr
end

function digilines.rotate_rules_left(rules)
	local nr={}
	for i, rule in ipairs(rules) do
		nr[i]={}
		nr[i].z=-rule.x
		nr[i].x=rule.z
		nr[i].y=rule.y
	end
	return nr
end

function digilines.rotate_rules_down(rules)
	local nr={}
	for i, rule in ipairs(rules) do
		nr[i]={}
		nr[i].y=rule.x
		nr[i].x=-rule.y
		nr[i].z=rule.z
	end
	return nr
end

function digilines.rotate_rules_up(rules)
	local nr={}
	for i, rule in ipairs(rules) do
		nr[i]={}
		nr[i].y=-rule.x
		nr[i].x=rule.y
		nr[i].z=rule.z
	end
	return nr
end

function digilines.tablecopy(table) -- deep table copy
	if type(table) ~= "table" then return table end -- no need to copy
	local newtable = {}

	for idx, item in pairs(table) do
		if type(item) == "table" then
			newtable[idx] = digilines.tablecopy(item)
		else
			newtable[idx] = item
		end
	end

	return newtable
end

-- VoxelManipulator-based node access functions:

-- Maps from a hashed mapblock position (as returned by hash_blockpos) to a
-- table.
--
-- Contents of the table are:
-- “va” → the VoxelArea
-- “data” → the data array
-- “param1” → the param1 array
-- “param2” → the param2 array
--
-- Nil if no bulk-VM operation is in progress.
local vm_cache = nil

-- Starts a bulk-VoxelManipulator operation.
--
-- During a bulk-VoxelManipulator operation, calls to get_node_force operate
-- directly on VM-loaded arrays, which should be faster for reading many nodes
-- in rapid succession. However, the cache must be flushed with vm_end once the
-- scan is finished, to avoid using stale data in future.
function digilines.vm_begin()
	vm_cache = {}
end

-- Ends a bulk-VoxelManipulator operation, freeing the cached data.
function digilines.vm_end()
	vm_cache = nil
end

-- The dimension of a mapblock in nodes.
local MAPBLOCKSIZE = 16

-- Converts a node position into a hash of a mapblock position.
local function vm_hash_blockpos(pos)
	return minetest.hash_node_position({
		x = math.floor(pos.x / MAPBLOCKSIZE),
		y = math.floor(pos.y / MAPBLOCKSIZE),
		z = math.floor(pos.z / MAPBLOCKSIZE)
	})
end

-- Gets the cache entry covering a position, populating it if necessary.
local function vm_get_or_create_entry(pos)
	local hash = vm_hash_blockpos(pos)
	local tbl = vm_cache[hash]
	if not tbl then
		local vm = minetest.get_voxel_manip(pos, pos)
		local min_pos, max_pos = vm:get_emerged_area()
		local va = VoxelArea:new{MinEdge = min_pos, MaxEdge = max_pos}
		tbl = {va = va, data = vm:get_data(), param1 = vm:get_light_data(), param2 = vm:get_param2_data()}
		vm_cache[hash] = tbl
	end
	return tbl
end

-- Gets the node at a position during a bulk-VoxelManipulator operation.
local function vm_get_node(pos)
	local tbl = vm_get_or_create_entry(pos)
	local index = tbl.va:indexp(pos)
	local node_value = tbl.data[index]
	local node_param1 = tbl.param1[index]
	local node_param2 = tbl.param2[index]
	return {name = minetest.get_name_from_content_id(node_value), param1 = node_param1, param2 = node_param2}
end

-- Gets the node at a given position, regardless of whether it is loaded or
-- not.
--
-- Outside a bulk-VoxelManipulator operation, if the mapblock is not loaded, it
-- is pulled into the server’s main map data cache and then accessed from
-- there.
--
-- Inside a bulk-VoxelManipulator operation, the operation’s VM cache is used.
function digilines.get_node_force(pos)
	if vm_cache then
		return vm_get_node(pos)
	end
	local node = minetest.get_node(pos)
	if node.name == "ignore" then
		-- Node is not currently loaded; use a VoxelManipulator to prime
		-- the mapblock cache and try again.
		minetest.get_voxel_manip(pos, pos)
		node = minetest.get_node(pos)
	end
	return node
end


code:
-- naming scheme: wire:(xp)(zp)(xm)(zm)_on/off
-- The conditions in brackets define whether there is a digiline at that place or not
-- 1 = there is one; 0 = there is none
-- y always means y+

local box_center = {-1/16, -.5, -1/16, 1/16, -.5+1/16, 1/16}
local box_bump1 =  { -2/16, -8/16,  -2/16, 2/16, -13/32, 2/16 }
local box_bump2 =  { -3/32, -13/32, -3/32, 3/32, -12/32, 3/32 }

local box_xp = {1/16, -.5, -1/16, 8/16, -.5+1/16, 1/16}
local box_zp = {-1/16, -.5, 1/16, 1/16, -.5+1/16, 8/16}
local box_xm = {-8/16, -.5, -1/16, -1/16, -.5+1/16, 1/16}
local box_zm = {-1/16, -.5, -8/16, 1/16, -.5+1/16, -1/16}

local box_xpy = {.5-1/16, -.5+1/16, -1/16, .5, .4999+1/16, 1/16}
local box_zpy = {-1/16, -.5+1/16, .5-1/16, 1/16, .4999+1/16, .5}
local box_xmy = {-.5, -.5+1/16, -1/16, -.5+1/16, .4999+1/16, 1/16}
local box_zmy = {-1/16, -.5+1/16, -.5, 1/16, .4999+1/16, -.5+1/16}

for xp=0, 1 do
for zp=0, 1 do
for xm=0, 1 do
for zm=0, 1 do
for xpy=0, 1 do
for zpy=0, 1 do
for xmy=0, 1 do
for zmy=0, 1 do
	if (xpy == 1 and xp == 0) or (zpy == 1 and zp == 0)
	or (xmy == 1 and xm == 0) or (zmy == 1 and zm == 0) then break end

	local groups
	local nodeid = 	tostring(xp )..tostring(zp )..tostring(xm )..tostring(zm )..
			tostring(xpy)..tostring(zpy)..tostring(xmy)..tostring(zmy)

	local wiredesc

	if nodeid == "00000000" then
		groups = {dig_immediate = 3}
		wiredesc = "Digiline"
	else
		groups = {dig_immediate = 3, not_in_creative_inventory = 1}
	end

	local nodebox = {}
	local adjx = false
	local adjz = false
	if xp == 1 then table.insert(nodebox, box_xp) adjx = true end
	if zp == 1 then table.insert(nodebox, box_zp) adjz = true end
	if xm == 1 then table.insert(nodebox, box_xm) adjx = true end
	if zm == 1 then table.insert(nodebox, box_zm) adjz = true end
	if xpy == 1 then table.insert(nodebox, box_xpy) end
	if zpy == 1 then table.insert(nodebox, box_zpy) end
	if xmy == 1 then table.insert(nodebox, box_xmy) end
	if zmy == 1 then table.insert(nodebox, box_zmy) end

	local tiles
	if adjx and adjz and (xp + zp + xm + zm > 2) then
		table.insert(nodebox, box_bump1)
		table.insert(nodebox, box_bump2)
		tiles = {
			"digiline_std_bump.png",
			"digiline_std_bump.png",
			"digiline_std_vertical.png",
			"digiline_std_vertical.png",
			"digiline_std_vertical.png",
			"digiline_std_vertical.png"
		}
	else
		table.insert(nodebox, box_center)
		tiles = {
			"digiline_std.png",
			"digiline_std.png",
			"digiline_std_vertical.png",
			"digiline_std_vertical.png",
			"digiline_std_vertical.png",
			"digiline_std_vertical.png"
		}
	end

	if nodeid == "00000000" then
		nodebox = {-8/16, -.5, -1/16, 8/16, -.5+1/16, 1/16}
	end

	minetest.register_node("digilines:wire_std_"..nodeid, {
		description = wiredesc,
		drawtype = "nodebox",
		tiles = tiles,
		inventory_image = "digiline_std_inv.png",
		wield_image = "digiline_std_inv.png",
		paramtype = "light",
		paramtype2 = "facedir",
		sunlight_propagates = true,
		digiline =
		{
			wire =
			{
				basename = "digilines:wire_std_",
				use_autoconnect = true
			}
		},
		selection_box = {
			type = "fixed",
			fixed = {-.5, -.5, -.5, .5, -.5+1/16, .5}
		},
		node_box = {
			type = "fixed",
			fixed = nodebox
		},
		groups = groups,
		walkable = false,
		stack_max = 99,
		drop = "digilines:wire_std_00000000"
	})
end
end
end
end
end
end
end
end


code:
minetest.register_on_placenode(function(pos, node)
	if minetest.registered_nodes[node.name].digiline then
		digilines.update_autoconnect(pos)
	end
end)

minetest.register_on_dignode(function(pos, node)
	if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].digiline then
-- need to make sure that node exists (unknown nodes!)
		digilines.update_autoconnect(pos)
	end
end)

function digilines.update_autoconnect(pos, secondcall)
	local xppos = {x=pos.x+1, y=pos.y, z=pos.z}
	local zppos = {x=pos.x, y=pos.y, z=pos.z+1}
	local xmpos = {x=pos.x-1, y=pos.y, z=pos.z}
	local zmpos = {x=pos.x, y=pos.y, z=pos.z-1}
	local xpympos = {x=pos.x+1, y=pos.y-1, z=pos.z}
	local zpympos = {x=pos.x, y=pos.y-1, z=pos.z+1}
	local xmympos = {x=pos.x-1, y=pos.y-1, z=pos.z}
	local zmympos = {x=pos.x, y=pos.y-1, z=pos.z-1}
	local xpypos = {x=pos.x+1, y=pos.y+1, z=pos.z}
	local zpypos = {x=pos.x, y=pos.y+1, z=pos.z+1}
	local xmypos = {x=pos.x-1, y=pos.y+1, z=pos.z}
	local zmypos = {x=pos.x, y=pos.y+1, z=pos.z-1}

	if secondcall == nil then
		digilines.update_autoconnect(xppos, true)
		digilines.update_autoconnect(zppos, true)
		digilines.update_autoconnect(xmpos, true)
		digilines.update_autoconnect(zmpos, true)

		digilines.update_autoconnect(xpypos, true)
		digilines.update_autoconnect(zpypos, true)
		digilines.update_autoconnect(xmypos, true)
		digilines.update_autoconnect(zmypos, true)

		digilines.update_autoconnect(xpympos, true)
		digilines.update_autoconnect(zpympos, true)
		digilines.update_autoconnect(xmympos, true)
		digilines.update_autoconnect(zmympos, true)
	end

	local def = minetest.registered_nodes[minetest.get_node(pos).name]
	local digilinespec = def and def.digiline
	if not (digilinespec and digilinespec.wire and
			digilinespec.wire.use_autoconnect) then
		return nil
	end

	local zmg = 	digilines.rules_link_anydir(pos, zmpos)
	local zmymg = 	digilines.rules_link_anydir(pos, zmympos)
	local xmg = 	digilines.rules_link_anydir(pos, xmpos)
	local xmymg = 	digilines.rules_link_anydir(pos, xmympos)
	local zpg = 	digilines.rules_link_anydir(pos, zppos)
	local zpymg = 	digilines.rules_link_anydir(pos, zpympos)
	local xpg = 	digilines.rules_link_anydir(pos, xppos)
	local xpymg = 	digilines.rules_link_anydir(pos, xpympos)

	local xpyg = digilines.rules_link_anydir(pos, xpypos)
	local zpyg = digilines.rules_link_anydir(pos, zpypos)
	local xmyg = digilines.rules_link_anydir(pos, xmypos)
	local zmyg = digilines.rules_link_anydir(pos, zmypos)

	local zm, xm, zp, xp, xpy, zpy, xmy, zmy
	if zmg or zmymg then zm = 1 else zm = 0 end
	if xmg or xmymg then xm = 1 else xm = 0 end
	if zpg or zpymg then zp = 1 else zp = 0 end
	if xpg or xpymg then xp = 1 else xp = 0 end

	if xpyg then xpy = 1 else xpy = 0 end
	if zpyg then zpy = 1 else zpy = 0 end
	if xmyg then xmy = 1 else xmy = 0 end
	if zmyg then zmy = 1 else zmy = 0 end

	if xpy == 1 then xp = 1 end
	if zpy == 1 then zp = 1 end
	if xmy == 1 then xm = 1 end
	if zmy == 1 then zm = 1 end

	local nodeid = 	tostring(xp )..tostring(zp )..tostring(xm )..tostring(zm )..
				tostring(xpy)..tostring(zpy)..tostring(xmy)..tostring(zmy)

	minetest.set_node(pos, {name = digilinespec.wire.basename..nodeid})
end


code:
name: luacheck

on: [push, pull_request]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v1
    - name: apt
      run: sudo apt-get install -y luarocks
    - name: luacheck install
      run: luarocks install --local luacheck
    - name: luacheck run
      run: $HOME/.luarocks/bin/luacheck ./


code:
## Eclipse project files & directories
.project
.settings


code:
unused = false
max_line_length = 240

globals = {
	"drawers"
}

read_globals = {
	-- Stdlib
	string = {fields = {"split"}},
	table = {fields = {"copy", "getn"}},

	-- Minetest
	"vector", "ItemStack",
	"dump", "VoxelArea",

	-- deps
	"minetest",
	"core",
	"default",
	"mcl_core",
	"mcl_sounds",
	"pipeworks",
	"screwdriver",
	"intllib",
	"digilines",
	"mesecon"
}


code:
# Minetest Mod Storage Drawers

[![ContentDB](https://content.minetest.net/packages/LNJ/drawers/shields/downloads/)](https://content.minetest.net/packages/LNJ/drawers/)
![](https://github.com/minetest-mods/drawers/workflows/luacheck/badge.svg)

Version 0.6.5, License: MIT

## Description
This mod adds simple item storages showing the item's inventory image in the
front. By left- or right-clicking the image you can take or add stacks. If you
also hold the shift-key only a single item will be removed/added.

There's also a 'Drawer Controller' which can insert items automatically into a
network of drawers. Just place the drawers next to each other, so they are
connected and the drawer controller will sort the items automatically. If you
want to connect drawers, but you don't want to place another drawer, just use
the 'Drawer Trim'.

Do you have too many cobblestones for one drawer? No problem, just add some
drawer upgrades to your drawer! They are available in different sizes and are
crafted by steel, gold, obsidian, diamonds or mithril.

## Notes
This mod requires Minetest 0.4.14 or later. The `default` mod from MTG or the
MineClone 2 mods are only optional dependencies for crafting recipes.

## To-Do
- [x] Add usable 1x1 drawer
- [x] Add a drawer controller for auto-sorting items into a drawer-network
- [ ] Add half-sized drawers
- [x] Add 2x2 and 1x2 drawers
- [ ] Add compacting drawers for auto-crafting blocks/ingots/fragments
- [ ] Add a key (or something similar) for locking the item (so the item is
      also displayed at count 0)
- [ ] Add duct tape to transport drawers
- [x] Support pipeworks
- [ ] Support hoppers (needs hoppers mod change)
- [x] Make drawers upgradable
- [x] Add drawers in all wood types
- [x] Make them digilines compatible

## Bug reports and suggestions
You can report bugs and suggest ideas on [GitHub](http://github.com/lnj2/drawers/issues/new),
alternatively you can also [email](mailto:git@lnj.li) me.

## Credits
#### Thanks to:
* Justin Aquadro ([@jaquadro](http://github.com/jaquadro)), developer of the
	original Minecraft Mod (also licensed under MIT :smiley:) — Textures and Ideas
* Mango Tango <<mtango688@gmail.com>> ([@mtango688](http://github.com/mtango688)),
	creator of the Minetest Mod ["Caches"](https://github.com/mtango688/caches/)
	— I reused some code by you. :)

## Links
* [Minetest Forums](https://forum.minetest.net/viewtopic.php?f=9&t=17134)
* [Minetest Wiki](http://wiki.minetest.net/Mods/Storage_Drawers)
* [Weblate](https://hosted.weblate.org/projects/minetest/mod-storage-drawers/)
* [GitHub](http://github.com/minetest-mods/drawers/)


code:
--[[
Minetest Mod Storage Drawers - A Mod adding storage drawers

Copyright (C) 2017-2020 Linus Jahn <lnj@kaidan.im>

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]]

-- Load support for intllib.
local MP = core.get_modpath(core.get_current_modname())
local S, NS = dofile(MP.."/intllib.lua")

drawers = {}
drawers.drawer_visuals = {}

drawers.WOOD_ITEMSTRING = "group:wood"
if core.get_modpath("default") and default then
	drawers.WOOD_SOUNDS = default.node_sound_wood_defaults()
	drawers.CHEST_ITEMSTRING = "default:chest"
elseif core.get_modpath("mcl_core") and mcl_core then -- MineClone 2
	drawers.CHEST_ITEMSTRING = "mcl_chests:chest"
	if core.get_modpath("mcl_sounds") and mcl_sounds then
		drawers.WOOD_SOUNDS = mcl_sounds.node_sound_wood_defaults()
	end
else
	drawers.CHEST_ITEMSTRING = "chest"
end

drawers.enable_1x1 = not core.settings:get_bool("drawers_disable_1x1")
drawers.enable_1x2 = not core.settings:get_bool("drawers_disable_1x2")
drawers.enable_2x2 = not core.settings:get_bool("drawers_disable_2x2")

drawers.CONTROLLER_RANGE = 14

--
-- GUI
--

drawers.gui_bg = "bgcolor[#080808BB;true]"
drawers.gui_slots = "listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF]"
if (core.get_modpath("mcl_core")) and mcl_core then -- MCL2
	drawers.gui_bg_img = "background[5,5;1,1;crafting_creative_bg.png;true]"
else
	drawers.gui_bg_img = "background[5,5;1,1;gui_formbg.png;true]"
end

--
-- Load API
--

dofile(MP .. "/lua/helpers.lua")
dofile(MP .. "/lua/visual.lua")
dofile(MP .. "/lua/api.lua")
dofile(MP .. "/lua/controller.lua")

--
-- Register drawers
--

if core.get_modpath("default") and default then
	drawers.register_drawer("drawers:wood", {
		description = S("Wooden"),
		tiles1 = drawers.node_tiles_front_other("drawers_wood_front_1.png",
			"drawers_wood.png"),
		tiles2 = drawers.node_tiles_front_other("drawers_wood_front_2.png",
			"drawers_wood.png"),
		tiles4 = drawers.node_tiles_front_other("drawers_wood_front_4.png",
			"drawers_wood.png"),
		groups = {choppy = 3, oddly_breakable_by_hand = 2},
		sounds = drawers.WOOD_SOUNDS,
		drawer_stack_max_factor = 32, -- 4 * 8 normal chest size
		material = drawers.WOOD_ITEMSTRING
	})
end

--
-- Register drawer upgrades
--

if core.get_modpath("default") and default then
	drawers.register_drawer_upgrade("drawers:upgrade_steel", {
		description = S("Steel Drawer Upgrade (x2)"),
		inventory_image = "drawers_upgrade_steel.png",
		groups = {drawer_upgrade = 100},
		recipe_item = "default:steel_ingot"
	})

	drawers.register_drawer_upgrade("drawers:upgrade_gold", {
		description = S("Gold Drawer Upgrade (x3)"),
		inventory_image = "drawers_upgrade_gold.png",
		groups = {drawer_upgrade = 200},
		recipe_item = "default:gold_ingot"
	})

	drawers.register_drawer_upgrade("drawers:upgrade_obsidian", {
		description = S("Obsidian Drawer Upgrade (x4)"),
		inventory_image = "drawers_upgrade_obsidian.png",
		groups = {drawer_upgrade = 300},
		recipe_item = "default:obsidian"
	})

	drawers.register_drawer_upgrade("drawers:upgrade_diamond", {
		description = S("Diamond Drawer Upgrade (x8)"),
		inventory_image = "drawers_upgrade_diamond.png",
		groups = {drawer_upgrade = 700},
		recipe_item = "default:diamond"
	})
end

if core.get_modpath("moreores") then
	drawers.register_drawer_upgrade("drawers:upgrade_mithril", {
		description = S("Mithril Drawer Upgrade (x13)"),
		inventory_image = "drawers_upgrade_mithril.png",
		groups = {drawer_upgrade = 1200},
		recipe_item = "moreores:mithril_ingot"
	})
end

--
-- Register drawer upgrade template
--

core.register_craftitem("drawers:upgrade_template", {
	description = S("Drawer Upgrade Template"),
	inventory_image = "drawers_upgrade_template.png"
})

core.register_craft({
	output = "drawers:upgrade_template 4",
	recipe = {
		{"group:stick", "group:stick", "group:stick"},
		{"group:stick", "group:drawer", "group:stick"},
		{"group:stick", "group:stick", "group:stick"}
	}
})


code:
-- Fallback functions for when `intllib` is not installed.
-- Code released under Unlicense <http://unlicense.org>.

-- Get the latest version of this file at:
--   https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua

local function format(str, ...)
	local args = { ... }
	local function repl(escape, open, num, close)
		if escape == "" then
			local replacement = tostring(args[tonumber(num)])
			if open == "" then
				replacement = replacement..close
			end
			return replacement
		else
			return "@"..open..num..close
		end
	end
	return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl))
end

local gettext, ngettext
if minetest.get_modpath("intllib") then
	if intllib.make_gettext_pair then
		-- New method using gettext.
		gettext, ngettext = intllib.make_gettext_pair()
	else
		-- Old method using text files.
		gettext = intllib.Getter()
	end
end

-- Fill in missing functions.

gettext = gettext or function(msgid, ...)
	return format(msgid, ...)
end

ngettext = ngettext or function(msgid, msgid_plural, n, ...)
	return format(n==1 and msgid or msgid_plural, ...)
end

return gettext, ngettext


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-03-27 18:43+0100\n"
"PO-Revision-Date: 2019-03-15 09:03+0000\n"
"Last-Translator: Zmicer Turok <zmicerturok@gmail.com>\n"
"Language-Team: Belarusian <https://hosted.weblate.org/projects/minetest/mod-"
"storage-drawers/be/>\n"
"Language: be\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Generator: Weblate 3.6-dev\n"

#: lua/visual.lua lua/api.lua
msgid "Empty"
msgstr "Пустая"

#: lua/api.lua init.lua
msgid "Wooden"
msgstr "Драўляны"

#: lua/api.lua
msgid "@1 Drawer"
msgstr "@1 шуфляда"

#: lua/api.lua
msgid "@1 Drawers (1x2)"
msgstr "@1 шуфляды (1x2)"

#: lua/api.lua
msgid "@1 Drawers (2x2)"
msgstr "@1 шуфляды (2x2)"

#: lua/controller.lua
msgid "Drawer Controller"
msgstr "Кантролер шуфляды"

#: lua/controller.lua
msgid "Digiline Channel"
msgstr ""

#: lua/controller.lua
msgid "Save"
msgstr ""

#: lua/helpers.lua
msgid "@1 (@2% full)"
msgstr "@1 (@2% поўны)"

#: lua/helpers.lua
msgid "@1 @2 (@3% full)"
msgstr "@1 @2 (@3% поўны)"

#: init.lua
msgid "Acacia Wood"
msgstr "Драўніна акацыі"

#: init.lua
msgid "Aspen Wood"
msgstr "Асінавая драўніна"

#: init.lua
msgid "Junglewood"
msgstr "Джунглевая драўніна"

#: init.lua
msgid "Pine Wood"
msgstr "Хваёвая драўніна"

#: init.lua
msgid "Oak Wood"
msgstr "Дубовая драўніна"

#: init.lua
msgid "Birch Wood"
msgstr "Бярозавая драўніна"

#: init.lua
msgid "Dark Oak Wood"
msgstr "Цёмная дубовая драўніна"

#: init.lua
msgid "Spruce Wood"
msgstr "Ялінавая драўніна"

#: init.lua
msgid "Steel Drawer Upgrade (x2)"
msgstr "Мадэрнізацыя сталёвай шуфляды (x2)"

#: init.lua
msgid "Gold Drawer Upgrade (x3)"
msgstr "Мадэрнізацыя залатой шуфляды (x3)"

#: init.lua
#, fuzzy
msgid "Obsidian Drawer Upgrade (x4)"
msgstr "Мадэрнізацыя абсідыянавай шуфляды (x5)"

#: init.lua
msgid "Diamond Drawer Upgrade (x8)"
msgstr "Мадэрнізацыя дыяментавай шуфляды (x8)"

#: init.lua
msgid "Iron Drawer Upgrade (x2)"
msgstr "Мадэрнізацыя жалезнай шуфляды (x2)"

#: init.lua
msgid "Emerald Drawer Upgrade (x13)"
msgstr "Мадэрнізацыя смарагдавай шуфляды (x13)"

#: init.lua
#, fuzzy
msgid "Mithril Drawer Upgrade (x13)"
msgstr "Мадэрнізацыя смарагдавай шуфляды (x13)"

#: init.lua
msgid "Wooden Trim"
msgstr "Драўлянае аздабленне"

#: init.lua
msgid "Drawer Upgrade Template"
msgstr "Шаблон мадэрнізацыі шуфляды"

#~ msgid "Current State: "
#~ msgstr "Бягучы стан: "

#~ msgid "Stopped"
#~ msgstr "Спынены"

#~ msgid "Running"
#~ msgstr "Працуе"

#~ msgid "Jammed"
#~ msgstr "Затрыманы"


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-03-27 18:43+0100\n"
"PO-Revision-Date: 2020-05-10 12:32+0000\n"
"Last-Translator: Oymate <dhruboadittya96@gmail.com>\n"
"Language-Team: Bengali (Bangladesh) <https://hosted.weblate.org/projects/"
"minetest/mod-storage-drawers/bn_BD/>\n"
"Language: bn_BD\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.1-dev\n"

#: lua/visual.lua lua/api.lua
msgid "Empty"
msgstr "খালি"

#: lua/api.lua init.lua
msgid "Wooden"
msgstr "কাঠের"

#: lua/api.lua
msgid "@1 Drawer"
msgstr "@১ ড্রয়ার"

#: lua/api.lua
msgid "@1 Drawers (1x2)"
msgstr "@১ ড্রয়ার (১x২)"

#: lua/api.lua
msgid "@1 Drawers (2x2)"
msgstr "@১ ড্রয়ার (২x২)"

#: lua/controller.lua
msgid "Drawer Controller"
msgstr "ড্রয়ার কন্ট্রোলার"

#: lua/controller.lua
msgid "Digiline Channel"
msgstr ""

#: lua/controller.lua
msgid "Save"
msgstr ""

#: lua/helpers.lua
msgid "@1 (@2% full)"
msgstr "@1 (@2% পূর্ণ)"

#: lua/helpers.lua
msgid "@1 @2 (@3% full)"
msgstr "@1 @2 (@3% পূর্ণ)"

#: init.lua
msgid "Acacia Wood"
msgstr "বাবলা কাঠ"

#: init.lua
msgid "Aspen Wood"
msgstr "ভূর্জ কাঠ"

#: init.lua
msgid "Junglewood"
msgstr "জংলিকাঠ"

#: init.lua
msgid "Pine Wood"
msgstr "পাইন কাঠ"

#: init.lua
msgid "Oak Wood"
msgstr ""

#: init.lua
msgid "Birch Wood"
msgstr "ভূর্জ কাঠ"

#: init.lua
msgid "Dark Oak Wood"
msgstr ""

#: init.lua
msgid "Spruce Wood"
msgstr ""

#: init.lua
msgid "Steel Drawer Upgrade (x2)"
msgstr ""

#: init.lua
msgid "Gold Drawer Upgrade (x3)"
msgstr ""

#: init.lua
msgid "Obsidian Drawer Upgrade (x4)"
msgstr ""

#: init.lua
msgid "Diamond Drawer Upgrade (x8)"
msgstr ""

#: init.lua
msgid "Iron Drawer Upgrade (x2)"
msgstr ""

#: init.lua
msgid "Emerald Drawer Upgrade (x13)"
msgstr ""

#: init.lua
msgid "Mithril Drawer Upgrade (x13)"
msgstr ""

#: init.lua
msgid "Wooden Trim"
msgstr ""

#: init.lua
msgid "Drawer Upgrade Template"
msgstr ""

#~ msgid "Current State: "
#~ msgstr "বর্তমান অবস্থা: "

#~ msgid "Stopped"
#~ msgstr "বন্ধ"

#~ msgid "Running"
#~ msgstr "চলছে"

#~ msgid "Jammed"
#~ msgstr "জ্যামড"


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-01-11 16:49+0100\n"
"PO-Revision-Date: 2017-06-21 18:49+0000\n"
"Last-Translator: Jakub Vaněk <vanek.jakub4@seznam.cz>\n"
"Language-Team: Czech <https://hosted.weblate.org/projects/minetest/mod-"
"storage-drawers/cs/>\n"
"Language: cs\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
"X-Generator: Weblate 4.0.2\n"

#: lua/controller.lua
msgid "Current State: "
msgstr "Aktuální stav: "

#: lua/controller.lua
msgid "Stopped"
msgstr "Zastaveno"

#: lua/controller.lua
msgid "Running"
msgstr "Spuštěno"

#: lua/controller.lua
msgid "Jammed"
msgstr "Zaseknuto"

#: lua/controller.lua
msgid "Drawer Controller"
msgstr "Ovládání Zásuvky"

#: lua/visual.lua lua/api.lua
msgid "Empty"
msgstr "Prázdný"

#: lua/api.lua init.lua
msgid "Wooden"
msgstr "Dřevěný"

#: init.lua
msgid "Acacia Wood"
msgstr "ze dřeva akácie"

#: init.lua
msgid "Aspen Wood"
msgstr "ze dřeva osiky"

#: init.lua
msgid "Junglewood"
msgstr "ze dřeva džunglovníku"

#: init.lua
msgid "Pine Wood"
msgstr "ze borovicového dřeva"

#: init.lua
msgid "Oak Wood"
msgstr "ze dubového dřeva"

#: init.lua
msgid "Birch Wood"
msgstr "z bukového dřeva"

#: init.lua
msgid "Dark Oak Wood"
msgstr "z tmavého dubového dřeva"

#: init.lua
msgid "Spruce Wood"
msgstr "ze smrkového dřeva"

#: init.lua
msgid "Steel Drawer Upgrade (x2)"
msgstr "Ocelové vylepšení šuplíku (x2)"

#: init.lua
msgid "Gold Drawer Upgrade (x3)"
msgstr "Zlaté vylepšení šuplíku (x3)"

#: init.lua
#, fuzzy
msgid "Obsidian Drawer Upgrade (x4)"
msgstr "Obsidiánové vylepšení šuplíku (x5)"

#: init.lua
msgid "Diamond Drawer Upgrade (x8)"
msgstr "Diamantové vylepšení šuplíku (x8)"

#: init.lua
msgid "Iron Drawer Upgrade (x2)"
msgstr "Železné vylepšení šuplíku (x2)"

#: init.lua
msgid "Emerald Drawer Upgrade (x13)"
msgstr "Emeraldové vylepšení šuplíku (x13)"

#: init.lua
#, fuzzy
msgid "Mithril Drawer Upgrade (x13)"
msgstr "Emeraldové vylepšení šuplíku (x13)"

#: init.lua
msgid "Wooden Trim"
msgstr "Dřevěný Ořez"

#: init.lua
msgid "Drawer Upgrade Template"
msgstr "Šablona vylepšení šuplíku"

#: lua/controller.lua
msgid "Current State: "
msgstr ""

#: lua/controller.lua
msgid "Stopped"
msgstr ""

#: lua/controller.lua
msgid "Running"
msgstr ""

#: lua/controller.lua
msgid "Jammed"
msgstr ""

#: lua/controller.lua
msgid "Drawer Controller"
msgstr ""

#: lua/api.lua lua/visual.lua
msgid "Empty"
msgstr "Prázdný"

#: lua/api.lua
msgid "@1 Drawer"
msgstr "Šuplík @1"

#: lua/api.lua
msgid "@1 Drawers (1x2)"
msgstr "Šuplíky @1 (1x2)"

#: lua/api.lua
msgid "@1 Drawers (2x2)"
msgstr "Šuplíky @1 (2x2)"

#: lua/helpers.lua
msgid "@1 (@2% full)"
msgstr "@1 (z @2 % plný)"

#: lua/helpers.lua
msgid "@1 @2 (@3% full)"
msgstr "@1 @2 (z @3 % plný)"


code:
# German translations for PACKAGE package.
# Copyright (C) 2017 THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# LNJ <git@lnj.li>, 2017.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-03-27 18:43+0100\n"
"PO-Revision-Date: 2018-12-08 09:04+0000\n"
"Last-Translator: LNJ <git@lnj.li>\n"
"Language-Team: German <https://hosted.weblate.org/projects/minetest/mod-"
"storage-drawers/de/>\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 3.4-dev\n"

#: lua/visual.lua lua/api.lua
msgid "Empty"
msgstr "Leer"

#: lua/api.lua init.lua
msgid "Wooden"
msgstr "Holz"

#: lua/api.lua
msgid "@1 Drawer"
msgstr "@1schubfach"

#: lua/api.lua
msgid "@1 Drawers (1x2)"
msgstr "@1schubfächer (1×2)"

#: lua/api.lua
msgid "@1 Drawers (2x2)"
msgstr "@1schubfächer (2×2)"

#: lua/controller.lua
msgid "Drawer Controller"
msgstr "Schubfach Steuerung"

#: lua/controller.lua
msgid "Digiline Channel"
msgstr ""

#: lua/controller.lua
msgid "Save"
msgstr ""

#: lua/helpers.lua
msgid "@1 (@2% full)"
msgstr "@1 (@2% voll)"

#: lua/helpers.lua
msgid "@1 @2 (@3% full)"
msgstr "@1 @2 (@3% voll)"

#: init.lua
msgid "Acacia Wood"
msgstr "Akazienholz"

#: init.lua
msgid "Aspen Wood"
msgstr "Espenholz"

#: init.lua
msgid "Junglewood"
msgstr "Tropenholz"

#: init.lua
msgid "Pine Wood"
msgstr "Kiefernholz"

#: init.lua
msgid "Oak Wood"
msgstr "Eichenholz"

#: init.lua
msgid "Birch Wood"
msgstr "Birkenholz"

#: init.lua
msgid "Dark Oak Wood"
msgstr "Dunkeleichenholz"

#: init.lua
msgid "Spruce Wood"
msgstr "Fichtenholz"

#: init.lua
msgid "Steel Drawer Upgrade (x2)"
msgstr "Stahl-Schubfachverbesserung (×2)"

#: init.lua
msgid "Gold Drawer Upgrade (x3)"
msgstr "Gold-Schubfachverbesserung (×3)"

#: init.lua
#, fuzzy
msgid "Obsidian Drawer Upgrade (x4)"
msgstr "Obsidian-Schubfachverbesserung (×5)"

#: init.lua
msgid "Diamond Drawer Upgrade (x8)"
msgstr "Diamant-Schubfachverbesserung (×8)"

#: init.lua
msgid "Iron Drawer Upgrade (x2)"
msgstr "Eisen-Schubfachverbesserung (×2)"

#: init.lua
msgid "Emerald Drawer Upgrade (x13)"
msgstr "Smaragd-Schubfachverbesserung (×13)"

#: init.lua
#, fuzzy
msgid "Mithril Drawer Upgrade (x13)"
msgstr "Smaragd-Schubfachverbesserung (×13)"

#: init.lua
msgid "Wooden Trim"
msgstr "Holzverkleidung"

#: init.lua
msgid "Drawer Upgrade Template"
msgstr "Schubfachverbesserungsvorlage"

#~ msgid "Current State: "
#~ msgstr "Momentaner Zustand: "

#~ msgid "Stopped"
#~ msgstr "Angehalten"

#~ msgid "Running"
#~ msgstr "Läuft"

#~ msgid "Jammed"
#~ msgstr "Gestaut"


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-06-06 00:47+0200\n"
"PO-Revision-Date: 2020-09-29 13:40+0000\n"
"Last-Translator: THANOS SIOURDAKIS <siourdakisthanos@gmail.com>\n"
"Language-Team: Greek <https://hosted.weblate.org/projects/minetest/mod-"
"storage-drawers/el/>\n"
"Language: el\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.3-dev\n"

#: lua/controller.lua
msgid "Current State: "
msgstr "Τρέχουσα κατάσταση: "

#: lua/controller.lua
msgid "Stopped"
msgstr "Διακόπηκε"

#: lua/controller.lua
msgid "Running"
msgstr "Εκτέλεση"

#: lua/controller.lua
msgid "Jammed"
msgstr "Μπλοκαρισμένο"

#: lua/controller.lua
msgid "Drawer Controller"
msgstr "Ελεγκτής συρταριού"

#: lua/visual.lua lua/api.lua
msgid "Empty"
msgstr "Κενό"

#: lua/api.lua init.lua
msgid "Wooden"
msgstr "Ξύλινο"

#: init.lua
msgid "Acacia Wood"
msgstr "Ξύλο ακακίας"

#: init.lua
msgid "Aspen Wood"
msgstr ""

#: init.lua
msgid "Junglewood"
msgstr ""

#: init.lua
msgid "Pine Wood"
msgstr "Ξύλο πεύκου"

#: init.lua
msgid "Oak Wood"
msgstr "Ξύλο βελανιδιάς"

#: init.lua
msgid "Birch Wood"
msgstr "Ξύλο σημύδας"

#: init.lua
msgid "Dark Oak Wood"
msgstr "Σκούρο ξύλο βελανιδιάς"

#: init.lua
msgid "Spruce Wood"
msgstr "Ξύλο ερυθρελάτης"

#: init.lua
msgid "Steel Drawer Upgrade (x2)"
msgstr "Χαλύβδινη αναβάθμιση συρταριού (x2)"

#: init.lua
msgid "Gold Drawer Upgrade (x3)"
msgstr "Χρυσού αναβάθμιση συρταριού (x3)"

#: init.lua
msgid "Obsidian Drawer Upgrade (x5)"
msgstr "Οψιδιανή αναβάθμιση συρταριού (x5)"

#: init.lua
msgid "Diamond Drawer Upgrade (x8)"
msgstr "Διαμαντένια Αναβάθμιση συρταριού (x8)"

#: init.lua
msgid "Iron Drawer Upgrade (x2)"
msgstr "Σιδερένια αναβάθμιση συρταριού (x2)"

#: init.lua
msgid "Emerald Drawer Upgrade (x13)"
msgstr "Σμαραγδένια αναβάθμιση συρταριού (x13)"

#: init.lua
msgid "Mithril Drawer Upgrade (x13)"
msgstr ""

#: init.lua
msgid "Wooden Trim"
msgstr ""

#: init.lua
msgid "Drawer Upgrade Template"
msgstr ""

#: lua/controller.lua
msgid "Current State: "
msgstr "Τρέχουσα κατάσταση: "

#: lua/controller.lua
msgid "Digiline Channel"
msgstr ""

#: lua/controller.lua
msgid "Save"
msgstr ""

#: lua/controller.lua
msgid "Stopped"
msgstr "Σταμάτησε"

#: lua/controller.lua
msgid "Running"
msgstr "Εκτέλεση"

#: lua/controller.lua
msgid "Jammed"
msgstr "Μπλοκαρισμένο"

#: lua/controller.lua
msgid "Drawer Controller"
msgstr "Ελεγκτής συρταριού"

#: lua/api.lua lua/visual.lua
msgid "Empty"
msgstr "Κενό"

#: lua/api.lua
msgid "@1 Drawer"
msgstr "@1 συρτάρι"

#: lua/api.lua
msgid "@1 Drawers (1x2)"
msgstr "@1 συρτάρια (1x2)"

#: lua/api.lua
msgid "@1 Drawers (2x2)"
msgstr "@1 συρτάρια (2x2)"

#: lua/helpers.lua
msgid "@1 (@2% full)"
msgstr "@1 (@2% Πλήρης)"

#: lua/helpers.lua
msgid "@1 @2 (@3% full)"
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-03-27 18:43+0100\n"
"PO-Revision-Date: 2020-03-28 17:09+0000\n"
"Last-Translator: Tirifto <tirifto@posteo.cz>\n"
"Language-Team: Esperanto <https://hosted.weblate.org/projects/minetest/mod-"
"storage-drawers/eo/>\n"
"Language: eo\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.0-dev\n"

#: lua/visual.lua lua/api.lua
msgid "Empty"
msgstr "Malplena"

#: lua/api.lua init.lua
msgid "Wooden"
msgstr "Ligna"

#: lua/api.lua
msgid "@1 Drawer"
msgstr "@1 tirkesto"

#: lua/api.lua
msgid "@1 Drawers (1x2)"
msgstr "@1 tirkestoj (1×2)"

#: lua/api.lua
msgid "@1 Drawers (2x2)"
msgstr "@1 tirkestoj (2×2)"

#: lua/controller.lua
msgid "Drawer Controller"
msgstr "Regilo de tirkesto"

#: lua/controller.lua
msgid "Digiline Channel"
msgstr ""

#: lua/controller.lua
msgid "Save"
msgstr ""

#: lua/helpers.lua
msgid "@1 (@2% full)"
msgstr "@1 (plena je @2%)"

#: lua/helpers.lua
msgid "@1 @2 (@3% full)"
msgstr "@1 @2 (plena je @3%)"

#: init.lua
msgid "Acacia Wood"
msgstr "Akacia ligno"

#: init.lua
msgid "Aspen Wood"
msgstr "Tremola ligno"

#: init.lua
msgid "Junglewood"
msgstr "Ĝangala ligno"

#: init.lua
msgid "Pine Wood"
msgstr "Abia ligno"

#: init.lua
msgid "Oak Wood"
msgstr "Kverka ligno"

#: init.lua
msgid "Birch Wood"
msgstr "Betula ligno"

#: init.lua
msgid "Dark Oak Wood"
msgstr "Malhela kverka ligno"

#: init.lua
msgid "Spruce Wood"
msgstr "Picea ligno"

#: init.lua
msgid "Steel Drawer Upgrade (x2)"
msgstr "Ŝtala plibonigo de tirkesto (×2)"

#: init.lua
msgid "Gold Drawer Upgrade (x3)"
msgstr "Ora plibonigo de tirkesto (×3)"

#: init.lua
#, fuzzy
msgid "Obsidian Drawer Upgrade (x4)"
msgstr "Obsidiana plibonigo de tirkesto (×5)"

#: init.lua
msgid "Diamond Drawer Upgrade (x8)"
msgstr "Diamanta plibonigo de tirkesto (×8)"

#: init.lua
msgid "Iron Drawer Upgrade (x2)"
msgstr "Fera plibonigo de tirkesto (×2)"

#: init.lua
msgid "Emerald Drawer Upgrade (x13)"
msgstr "Smeralda plibonigo de tirkesto (×13)"

#: init.lua
#, fuzzy
msgid "Mithril Drawer Upgrade (x13)"
msgstr "Smeralda plibonigo de tirkesto (×13)"

#: init.lua
msgid "Wooden Trim"
msgstr ""

#: init.lua
msgid "Drawer Upgrade Template"
msgstr "Ŝablono por plibonigo de tirkesto"

#~ msgid "Current State: "
#~ msgstr "Nuna stato: "

#~ msgid "Stopped"
#~ msgstr "Haltinta"

#~ msgid "Running"
#~ msgstr "Funkcianta"

#~ msgid "Jammed"
#~ msgstr "Ŝtopita"


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-03-27 18:43+0100\n"
"PO-Revision-Date: 2020-09-06 00:36+0000\n"
"Last-Translator: H <joaquinfc@protonmail.com>\n"
"Language-Team: Spanish <https://hosted.weblate.org/projects/minetest/mod-"
"storage-drawers/es/>\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.3-dev\n"

#: lua/visual.lua lua/api.lua
msgid "Empty"
msgstr "Vacío"

#: lua/api.lua init.lua
msgid "Wooden"
msgstr "De Madera"

#: lua/api.lua
msgid "@1 Drawer"
msgstr ""

#: lua/api.lua
#, fuzzy
msgid "@1 Drawers (1x2)"
msgstr "Mejora para Gavetas de Hierro (x2)"

#: lua/api.lua
#, fuzzy
msgid "@1 Drawers (2x2)"
msgstr "Mejora para Gavetas de Hierro (x2)"

#: lua/controller.lua
msgid "Drawer Controller"
msgstr "Controlador de Gavetas"

#: lua/controller.lua
msgid "Digiline Channel"
msgstr ""

#: lua/controller.lua
msgid "Save"
msgstr ""

#: lua/helpers.lua
msgid "@1 (@2% full)"
msgstr ""

#: lua/helpers.lua
msgid "@1 @2 (@3% full)"
msgstr ""

#: init.lua
msgid "Acacia Wood"
msgstr "Madera de acacia"

#: init.lua
msgid "Aspen Wood"
msgstr "Madera de álamo"

#: init.lua
msgid "Junglewood"
msgstr "Madera tropical"

#: init.lua
msgid "Pine Wood"
msgstr "Madera de pino"

#: init.lua
msgid "Oak Wood"
msgstr "Madera de roble"

#: init.lua
msgid "Birch Wood"
msgstr "Madera de abedul"

#: init.lua
msgid "Dark Oak Wood"
msgstr "Madera de roble oscuro"

#: init.lua
msgid "Spruce Wood"
msgstr "Madera de pícea"

#: init.lua
msgid "Steel Drawer Upgrade (x2)"
msgstr "Mejora para Gavetas de Acero (x2)"

#: init.lua
msgid "Gold Drawer Upgrade (x3)"
msgstr "Mejora para Gavetas de Oro (x3)"

#: init.lua
#, fuzzy
msgid "Obsidian Drawer Upgrade (x4)"
msgstr "Mejora para Gavetas de Obsidiana (x5)"

#: init.lua
msgid "Diamond Drawer Upgrade (x8)"
msgstr "Mejora para Gavetas de Diamante (x8)"

#: init.lua
msgid "Iron Drawer Upgrade (x2)"
msgstr "Mejora para Gavetas de Hierro (x2)"

#: init.lua
msgid "Emerald Drawer Upgrade (x13)"
msgstr "Mejora para Gavetas de Esmeralda (x13)"

#: init.lua
#, fuzzy
msgid "Mithril Drawer Upgrade (x13)"
msgstr "Mejora para Gavetas de Esmeralda (x13)"

#: init.lua
msgid "Wooden Trim"
msgstr "Recorte De Madera"

#: init.lua
msgid "Drawer Upgrade Template"
msgstr "Plantilla de mejoras para gavetas"

#~ msgid "Current State: "
#~ msgstr "Estado actual: "

#~ msgid "Stopped"
#~ msgstr "Detenido"

#~ msgid "Running"
#~ msgstr "Ejecutándose"

#~ msgid "Jammed"
#~ msgstr "Atascado"


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-03-27 18:43+0100\n"
"PO-Revision-Date: 2020-11-07 21:26+0000\n"
"Last-Translator: Janar Leas <janarleas+ubuntuone@googlemail.com>\n"
"Language-Team: Estonian <https://hosted.weblate.org/projects/minetest/mod-"
"storage-drawers/et/>\n"
"Language: et\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.3.2\n"

#: lua/visual.lua lua/api.lua
msgid "Empty"
msgstr "Tühi"

#: lua/api.lua init.lua
msgid "Wooden"
msgstr "Puidust"

#: lua/api.lua
msgid "@1 Drawer"
msgstr "@1 salv"

#: lua/api.lua
msgid "@1 Drawers (1x2)"
msgstr "@1 salved (1x2)"

#: lua/api.lua
msgid "@1 Drawers (2x2)"
msgstr "@1 salved (2x2)"

#: lua/controller.lua
msgid "Drawer Controller"
msgstr "Salve juhtpult"

#: lua/controller.lua
msgid "Digiline Channel"
msgstr ""

#: lua/controller.lua
msgid "Save"
msgstr ""

#: lua/helpers.lua
msgid "@1 (@2% full)"
msgstr "@1 (@2% täis)"

#: lua/helpers.lua
msgid "@1 @2 (@3% full)"
msgstr "@1 @2 (@3% täis)"

#: init.lua
msgid "Acacia Wood"
msgstr "Akaatsia puidust"

#: init.lua
msgid "Aspen Wood"
msgstr "Haavast"

#: init.lua
msgid "Junglewood"
msgstr "Tihniku puidust"

#: init.lua
msgid "Pine Wood"
msgstr "Männist"

#: init.lua
msgid "Oak Wood"
msgstr "Tammest"

#: init.lua
msgid "Birch Wood"
msgstr "Kasest"

#: init.lua
msgid "Dark Oak Wood"
msgstr "Tõmmu-tammest"

#: init.lua
msgid "Spruce Wood"
msgstr "Kuusest"

#: init.lua
msgid "Steel Drawer Upgrade (x2)"
msgstr "Teras salve täiustus (x2)"

#: init.lua
msgid "Gold Drawer Upgrade (x3)"
msgstr "Kuld salve täiustus (x3)"

#: init.lua
#, fuzzy
msgid "Obsidian Drawer Upgrade (x4)"
msgstr "Vulkaanklaas salve täiustus (x5)"

#: init.lua
msgid "Diamond Drawer Upgrade (x8)"
msgstr "Teemant salve täiustus (x8)"

#: init.lua
msgid "Iron Drawer Upgrade (x2)"
msgstr "Raud salve täiustus (x2)"

#: init.lua
msgid "Emerald Drawer Upgrade (x13)"
msgstr "Smaragd salve täiustus (x13)"

#: init.lua
#, fuzzy
msgid "Mithril Drawer Upgrade (x13)"
msgstr "Smaragd salve täiustus (x13)"

#: init.lua
msgid "Wooden Trim"
msgstr "Puitliist"

#: init.lua
msgid "Drawer Upgrade Template"
msgstr "Salve täiustamise kava"

#~ msgid "Current State: "
#~ msgstr "Hetkel: "

#~ msgid "Stopped"
#~ msgstr "Seisab"

#~ msgid "Running"
#~ msgstr "Töötab"

#~ msgid "Jammed"
#~ msgstr "Umbes"


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-03-27 18:43+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
"Language: fi\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: lua/visual.lua lua/api.lua
msgid "Empty"
msgstr ""

#: lua/api.lua init.lua
msgid "Wooden"
msgstr ""

#: lua/api.lua
msgid "@1 Drawer"
msgstr ""

#: lua/api.lua
msgid "@1 Drawers (1x2)"
msgstr ""

#: lua/api.lua
msgid "@1 Drawers (2x2)"
msgstr ""

#: lua/controller.lua
msgid "Drawer Controller"
msgstr ""

#: lua/controller.lua
msgid "Digiline Channel"
msgstr ""

#: lua/controller.lua
msgid "Save"
msgstr ""

#: lua/helpers.lua
msgid "@1 (@2% full)"
msgstr ""

#: lua/helpers.lua
msgid "@1 @2 (@3% full)"
msgstr ""

#: init.lua
msgid "Acacia Wood"
msgstr ""

#: init.lua
msgid "Aspen Wood"
msgstr ""

#: init.lua
msgid "Junglewood"
msgstr ""

#: init.lua
msgid "Pine Wood"
msgstr ""

#: init.lua
msgid "Oak Wood"
msgstr ""

#: init.lua
msgid "Birch Wood"
msgstr ""

#: init.lua
msgid "Dark Oak Wood"
msgstr ""

#: init.lua
msgid "Spruce Wood"
msgstr ""

#: init.lua
msgid "Steel Drawer Upgrade (x2)"
msgstr ""

#: init.lua
msgid "Gold Drawer Upgrade (x3)"
msgstr ""

#: init.lua
msgid "Obsidian Drawer Upgrade (x4)"
msgstr ""

#: init.lua
msgid "Diamond Drawer Upgrade (x8)"
msgstr ""

#: init.lua
msgid "Iron Drawer Upgrade (x2)"
msgstr ""

#: init.lua
msgid "Emerald Drawer Upgrade (x13)"
msgstr ""

#: init.lua
msgid "Mithril Drawer Upgrade (x13)"
msgstr ""

#: init.lua
msgid "Wooden Trim"
msgstr ""

#: init.lua
msgid "Drawer Upgrade Template"
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-12-07 21:50+0100\n"
"PO-Revision-Date: 2020-03-03 03:32+0000\n"
"Last-Translator: Lucas Burlingham <lucas.burlingham@icloud.com>\n"
"Language-Team: French <https://hosted.weblate.org/projects/minetest/"
"mod-storage-drawers/fr/>\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 4.0-dev\n"

#: lua/controller.lua
msgid "Current State: "
msgstr "État Actuel : "

#: lua/controller.lua
msgid "Stopped"
msgstr "Arreté"

#: lua/controller.lua
msgid "Running"
msgstr "En cours d'exécution"

#: lua/controller.lua
msgid "Jammed"
msgstr "Bloqué"

#: lua/controller.lua
msgid "Drawer Controller"
msgstr "Contrôleur de Tiroir"

#: lua/visual.lua lua/api.lua
msgid "Empty"
msgstr "Vide"

#: lua/api.lua init.lua
msgid "Wooden"
msgstr "En bois"

#: init.lua
msgid "Acacia Wood"
msgstr "Bois d'acacia"

#: init.lua
msgid "Aspen Wood"
msgstr "Bois de tremble"

#: init.lua
msgid "Junglewood"
msgstr "Bois de jungle"

#: init.lua
msgid "Pine Wood"
msgstr "Bois de pin"

#: init.lua
msgid "Oak Wood"
msgstr "Bois de chêne"

#: init.lua
msgid "Birch Wood"
msgstr "Bois de bouleau"

#: init.lua
msgid "Dark Oak Wood"
msgstr "Bois de chêne foncé"

#: init.lua
msgid "Spruce Wood"
msgstr "Bois d'épicéa"

#: init.lua
msgid "Steel Drawer Upgrade (x2)"
msgstr "Amélioration tiroir en acier (x2)"

#: init.lua
msgid "Gold Drawer Upgrade (x3)"
msgstr "Amélioration tiroir en or (x3)"

#: init.lua
#, fuzzy
msgid "Obsidian Drawer Upgrade (x4)"
msgstr "Amélioration tiroir en obsidienne (x5)"

#: init.lua
msgid "Diamond Drawer Upgrade (x8)"
msgstr "Amélioration tiroir en diamant (x8)"

#: init.lua
msgid "Iron Drawer Upgrade (x2)"
msgstr "Amélioration tiroir en fer (x2)"

#: init.lua
msgid "Emerald Drawer Upgrade (x13)"
msgstr "Amélioration tiroir en émeraude (x13)"

#: init.lua
#, fuzzy
msgid "Mithril Drawer Upgrade (x13)"
msgstr "Amélioration tiroir en émeraude (x13)"

#: init.lua
msgid "Wooden Trim"
msgstr "Habillage en bois"

#: init.lua
msgid "Drawer Upgrade Template"
msgstr "Amélioration modèle de tiroir"

#: lua/controller.lua
msgid "Current State: "
msgstr "État Actuel : "

#: lua/controller.lua
msgid "Stopped"
msgstr "Arreté"

#: lua/controller.lua
msgid "Running"
msgstr "En cours d'exécution"

#: lua/controller.lua
msgid "Jammed"
msgstr "Bloqué"

#: lua/controller.lua
msgid "Drawer Controller"
msgstr "Contrôleur de Tiroirs"

#: lua/api.lua lua/visual.lua
msgid "Empty"
msgstr "Vide"

#: lua/api.lua
msgid "@1 Drawer"
msgstr "Tiroir @1"

#: lua/api.lua
msgid "@1 Drawers (1x2)"
msgstr "Tiroirs (1x2) @1"

#: lua/api.lua
msgid "@1 Drawers (2x2)"
msgstr "Tiroirs (2x2) @1"

#: lua/helpers.lua
msgid "@1 (@2% full)"
msgstr "@1 (@2% plein)"

#: lua/helpers.lua
msgid "@1 @2 (@3% full)"
msgstr "@1 @2 (@3% plein)"


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-03-27 18:43+0100\n"
"PO-Revision-Date: 2021-02-08 23:50+0000\n"
"Last-Translator: Omer I.S. <omeritzicschwartz@gmail.com>\n"
"Language-Team: Hebrew <https://hosted.weblate.org/projects/minetest/mod-"
"storage-drawers/he/>\n"
"Language: he\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=(n == 1) ? 0 : ((n == 2) ? 1 : ((n > 10 && "
"n % 10 == 0) ? 2 : 3));\n"
"X-Generator: Weblate 4.5-dev\n"

#: lua/visual.lua lua/api.lua
msgid "Empty"
msgstr "ריקה"

#: lua/api.lua init.lua
msgid "Wooden"
msgstr "מעץ"

#: lua/api.lua
msgid "@1 Drawer"
msgstr "מגירה @1"

#: lua/api.lua
msgid "@1 Drawers (1x2)"
msgstr "@1 מגירות (1x2)"

#: lua/api.lua
msgid "@1 Drawers (2x2)"
msgstr "@1 מגירות (2x2)"

#: lua/controller.lua
msgid "Drawer Controller"
msgstr ""

#: lua/controller.lua
msgid "Digiline Channel"
msgstr ""

#: lua/controller.lua
msgid "Save"
msgstr ""

#: lua/helpers.lua
msgid "@1 (@2% full)"
msgstr "@1 (תפוסה של @1%)"

#: lua/helpers.lua
msgid "@1 @2 (@3% full)"
msgstr "@1 @2 (תפוסה של @3%)"

#: init.lua
msgid "Acacia Wood"
msgstr "עץ שיטה"

#: init.lua
msgid "Aspen Wood"
msgstr "עץ אספן"

#: init.lua
msgid "Junglewood"
msgstr "עץ ג׳ונגל"

#: init.lua
msgid "Pine Wood"
msgstr "עץ אורן"

#: init.lua
msgid "Oak Wood"
msgstr "עץ אלון"

#: init.lua
msgid "Birch Wood"
msgstr "עץ לבנה"

#: init.lua
msgid "Dark Oak Wood"
msgstr "עץ אלון כהה"

#: init.lua
msgid "Spruce Wood"
msgstr "עץ אשוח"

#: init.lua
msgid "Steel Drawer Upgrade (x2)"
msgstr ""

#: init.lua
msgid "Gold Drawer Upgrade (x3)"
msgstr ""

#: init.lua
msgid "Obsidian Drawer Upgrade (x4)"
msgstr ""

#: init.lua
msgid "Diamond Drawer Upgrade (x8)"
msgstr ""

#: init.lua
msgid "Iron Drawer Upgrade (x2)"
msgstr ""

#: init.lua
msgid "Emerald Drawer Upgrade (x13)"
msgstr ""

#: init.lua
msgid "Mithril Drawer Upgrade (x13)"
msgstr ""

#: init.lua
msgid "Wooden Trim"
msgstr ""

#: init.lua
msgid "Drawer Upgrade Template"
msgstr ""

#~ msgid "Current State: "
#~ msgstr "המצב הנוכחי: "

#~ msgid "Stopped"
#~ msgstr "הופסקה"

#~ msgid "Running"
#~ msgstr "פעילה"

#~ msgid "Jammed"
#~ msgstr "תקועה"


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-03-27 18:43+0100\n"
"PO-Revision-Date: 2019-02-08 14:10+0000\n"
"Last-Translator: Muhammad Rifqi Priyo Susanto "
"<muhammadrifqipriyosusanto@gmail.com>\n"
"Language-Team: Indonesian <https://hosted.weblate.org/projects/minetest/mod-"
"storage-drawers/id/>\n"
"Language: id\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 3.5-dev\n"

#: lua/visual.lua lua/api.lua
msgid "Empty"
msgstr "Kosong"

#: lua/api.lua init.lua
msgid "Wooden"
msgstr "Kayu"

#: lua/api.lua
msgid "@1 Drawer"
msgstr "Laci @1"

#: lua/api.lua
msgid "@1 Drawers (1x2)"
msgstr "Laci @1 (1x2)"

#: lua/api.lua
msgid "@1 Drawers (2x2)"
msgstr "Laci @1 (2x2)"

#: lua/controller.lua
msgid "Drawer Controller"
msgstr "Pengendali Laci"

#: lua/controller.lua
msgid "Digiline Channel"
msgstr ""

#: lua/controller.lua
msgid "Save"
msgstr ""

#: lua/helpers.lua
msgid "@1 (@2% full)"
msgstr "@1 (@2% penuh)"

#: lua/helpers.lua
msgid "@1 @2 (@3% full)"
msgstr "@1 @2 (@3% penuh)"

#: init.lua
msgid "Acacia Wood"
msgstr "Kayu Akasia"

#: init.lua
msgid "Aspen Wood"
msgstr "Kayu Aspen"

#: init.lua
msgid "Junglewood"
msgstr "Kayu Rimba"

#: init.lua
msgid "Pine Wood"
msgstr "Kayu Pinus"

#: init.lua
msgid "Oak Wood"
msgstr "Kayu Ek"

#: init.lua
msgid "Birch Wood"
msgstr "Kayu Birch"

#: init.lua
msgid "Dark Oak Wood"
msgstr "Kayu Ek Gelap"

#: init.lua
msgid "Spruce Wood"
msgstr "Kayu Cemara"

#: init.lua
msgid "Steel Drawer Upgrade (x2)"
msgstr "Tingkatkan menjadi Laci Baja (x2)"

#: init.lua
msgid "Gold Drawer Upgrade (x3)"
msgstr "Tingkatkan menjadi Laci Emas (x3)"

#: init.lua
#, fuzzy
msgid "Obsidian Drawer Upgrade (x4)"
msgstr "Tingkatkan menjadi Laci Obsidian (x5)"

#: init.lua
msgid "Diamond Drawer Upgrade (x8)"
msgstr "Tingkatkan menjadi Laci Berlian (x8)"

#: init.lua
msgid "Iron Drawer Upgrade (x2)"
msgstr "Tingkatkan menjadi Laci Besi (x2)"

#: init.lua
msgid "Emerald Drawer Upgrade (x13)"
msgstr "Tingkatkan menjadi Laci Zamrud (x13)"

#: init.lua
#, fuzzy
msgid "Mithril Drawer Upgrade (x13)"
msgstr "Tingkatkan menjadi Laci Zamrud (x13)"

#: init.lua
msgid "Wooden Trim"
msgstr "Ukiran Kayu"

#: init.lua
msgid "Drawer Upgrade Template"
msgstr "Templat Peningkatan Laci"

#~ msgid "Current State: "
#~ msgstr "Keadaan Saat Ini: "

#~ msgid "Stopped"
#~ msgstr "Berhenti"

#~ msgid "Running"
#~ msgstr "Berjalan"

#~ msgid "Jammed"
#~ msgstr "Macet"


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-12-07 21:50+0100\n"
"PO-Revision-Date: 2020-01-17 19:01+0000\n"
"Last-Translator: Massimiliano Calipari <massimiliano.calipari@gmail.com>\n"
"Language-Team: Italian <https://hosted.weblate.org/projects/minetest/"
"mod-storage-drawers/it/>\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 3.10.2-dev\n"

#: lua/controller.lua
msgid "Current State: "
msgstr "Stato attuale: "

#: lua/controller.lua
msgid "Stopped"
msgstr "Fermo"

#: lua/controller.lua
msgid "Running"
msgstr "In corso di esecuzione"

#: lua/controller.lua
msgid "Jammed"
msgstr "Bloccato"

#: lua/controller.lua
msgid "Drawer Controller"
msgstr "Gestore cassetti"

#: lua/visual.lua lua/api.lua
msgid "Empty"
msgstr "Vuoto"

#: lua/api.lua init.lua
msgid "Wooden"
msgstr "Di legno"

#: init.lua
msgid "Acacia Wood"
msgstr "Legno di acacia"

#: init.lua
msgid "Aspen Wood"
msgstr "Legno di pioppo"

#: init.lua
msgid "Junglewood"
msgstr "Legno della giungla"

#: init.lua
msgid "Pine Wood"
msgstr "Legno di pino"

#: init.lua
msgid "Oak Wood"
msgstr "Legno di quercia"

#: init.lua
msgid "Birch Wood"
msgstr "Legno di betulla"

#: init.lua
msgid "Dark Oak Wood"
msgstr "Legno di quercia scura"

#: init.lua
msgid "Spruce Wood"
msgstr "Legno di abete rosso"

#: init.lua
msgid "Steel Drawer Upgrade (x2)"
msgstr "Miglioramento d'acciaio della cassettiera (x2)"

#: init.lua
msgid "Gold Drawer Upgrade (x3)"
msgstr "Miglioramento d'oro della cassettiera (x3)"

#: init.lua
#, fuzzy
msgid "Obsidian Drawer Upgrade (x4)"
msgstr "Miglioramento d'ossidiana della cassettiera (x5)"

#: init.lua
msgid "Diamond Drawer Upgrade (x8)"
msgstr "Miglioramento di diamante della cassettiera (x8)"

#: init.lua
msgid "Iron Drawer Upgrade (x2)"
msgstr "Miglioramento di ferro della cassettiera (x3)"

#: init.lua
msgid "Emerald Drawer Upgrade (x13)"
msgstr "Miglioramento di smeraldo della cassettiera (x13)"

#: init.lua
#, fuzzy
msgid "Mithril Drawer Upgrade (x13)"
msgstr "Miglioramento di smeraldo della cassettiera (x13)"

#: init.lua
msgid "Wooden Trim"
msgstr "di legno"

#: init.lua
msgid "Drawer Upgrade Template"
msgstr "Modello di miglioramento della cassettiera"

#: lua/controller.lua
msgid "Current State: "
msgstr "Stato attuale: "

#: lua/controller.lua
msgid "Stopped"
msgstr "Fermo"

#: lua/controller.lua
msgid "Running"
msgstr "In corso di esecuzione"

#: lua/controller.lua
msgid "Jammed"
msgstr "Bloccato"

#: lua/controller.lua
msgid "Drawer Controller"
msgstr ""

#: lua/api.lua lua/visual.lua
msgid "Empty"
msgstr "Vuoto"

#: lua/api.lua
msgid "@1 Drawer"
msgstr "@1 Cassetto"

#: lua/api.lua
msgid "@1 Drawers (1x2)"
msgstr "@1 Cassetti (1x2)"

#: lua/api.lua
msgid "@1 Drawers (2x2)"
msgstr "@1 Cassetti (2x2)"

#: lua/helpers.lua
msgid "@1 (@2% full)"
msgstr "@1 (@2% pieno)"

#: lua/helpers.lua
msgid "@1 @2 (@3% full)"
msgstr "@1 @2 (@3% pieno)"


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-03-27 18:43+0100\n"
"PO-Revision-Date: 2020-03-04 17:32+0000\n"
"Last-Translator: Robin Townsend <iantownsend@disroot.org>\n"
"Language-Team: Lojban <https://hosted.weblate.org/projects/minetest/mod-"
"storage-drawers/jbo/>\n"
"Language: jbo\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 4.0-dev\n"

#: lua/visual.lua lua/api.lua
msgid "Empty"
msgstr "kunti"

#: lua/api.lua init.lua
msgid "Wooden"
msgstr "mudri"

#: lua/api.lua
msgid "@1 Drawer"
msgstr ""

#: lua/api.lua
msgid "@1 Drawers (1x2)"
msgstr ""

#: lua/api.lua
msgid "@1 Drawers (2x2)"
msgstr ""

#: lua/controller.lua
msgid "Drawer Controller"
msgstr ""

#: lua/controller.lua
msgid "Digiline Channel"
msgstr ""

#: lua/controller.lua
msgid "Save"
msgstr ""

#: lua/helpers.lua
msgid "@1 (@2% full)"
msgstr ""

#: lua/helpers.lua
msgid "@1 @2 (@3% full)"
msgstr ""

#: init.lua
msgid "Acacia Wood"
msgstr ""

#: init.lua
msgid "Aspen Wood"
msgstr ""

#: init.lua
msgid "Junglewood"
msgstr ""

#: init.lua
msgid "Pine Wood"
msgstr ""

#: init.lua
msgid "Oak Wood"
msgstr ""

#: init.lua
msgid "Birch Wood"
msgstr ""

#: init.lua
msgid "Dark Oak Wood"
msgstr ""

#: init.lua
msgid "Spruce Wood"
msgstr ""

#: init.lua
msgid "Steel Drawer Upgrade (x2)"
msgstr ""

#: init.lua
msgid "Gold Drawer Upgrade (x3)"
msgstr ""

#: init.lua
msgid "Obsidian Drawer Upgrade (x4)"
msgstr ""

#: init.lua
msgid "Diamond Drawer Upgrade (x8)"
msgstr ""

#: init.lua
msgid "Iron Drawer Upgrade (x2)"
msgstr ""

#: init.lua
msgid "Emerald Drawer Upgrade (x13)"
msgstr ""

#: init.lua
msgid "Mithril Drawer Upgrade (x13)"
msgstr ""

#: init.lua
msgid "Wooden Trim"
msgstr ""

#: init.lua
msgid "Drawer Upgrade Template"
msgstr ""


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-12-07 21:50+0100\n"
"PO-Revision-Date: 2020-06-19 22:41+0000\n"
"Last-Translator: Yaya - Nurul Azeera Hidayah @ Muhammad Nur Hidayat "
"Yasuyoshi <translation@mnh48.moe>\n"
"Language-Team: Malay <https://hosted.weblate.org/projects/minetest/"
"mod-storage-drawers/ms/>\n"
"Language: ms\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 4.1.1\n"

#: init.lua lua/api.lua
msgid "Wooden"
msgstr "Kayu"

#: lua/api.lua
msgid "@1 Drawer"
msgstr "Laci @1"

#: lua/api.lua
msgid "@1 Drawers (1x2)"
msgstr "Laci @1 (1x2)"

#: lua/api.lua
msgid "@1 Drawers (2x2)"
msgstr "Laci @1 (2x2)"

#: lua/helpers.lua
msgid "@1 (@2% full)"
msgstr "@1 (@2% penuh)"

#: lua/helpers.lua
msgid "@1 @2 (@3% full)"
msgstr "@2 @1 (@3% penuh)"

#: init.lua
msgid "Acacia Wood"
msgstr "Papan Kayu Akasia"

#: init.lua
msgid "Aspen Wood"
msgstr "Papan Kayu Aspen"

#: init.lua
msgid "Junglewood"
msgstr "Papan Kayu Hutan"

#: init.lua
msgid "Pine Wood"
msgstr "Papan Kayu Pain"

#: init.lua
msgid "Oak Wood"
msgstr "Papan Kayu Oak"

#: init.lua
msgid "Birch Wood"
msgstr "Papan Kayu Birch"

#: init.lua
msgid "Dark Oak Wood"
msgstr "Papan Kayu Oak Gelap"

#: init.lua
msgid "Spruce Wood"
msgstr "Papan Kayu Fir"

#: init.lua
msgid "Steel Drawer Upgrade (x2)"
msgstr "Naik Taraf Laci - Keluli (x2)"

#: init.lua
msgid "Gold Drawer Upgrade (x3)"
msgstr "Naik Taraf Laci - Emas (x3)"

#: init.lua
#, fuzzy
msgid "Obsidian Drawer Upgrade (x4)"
msgstr "Naik Taraf Laci - Obsidia (x5)"

#: init.lua
msgid "Diamond Drawer Upgrade (x8)"
msgstr "Naik Taraf Laci - Intan (x8)"

#: init.lua
msgid "Iron Drawer Upgrade (x2)"
msgstr "Naik Taraf Laci - Besi (x2)"

#: init.lua
msgid "Emerald Drawer Upgrade (x13)"
msgstr "Naik Taraf Laci - Zamrud (x13)"

#: init.lua
#, fuzzy
msgid "Mithril Drawer Upgrade (x13)"
msgstr "Naik Taraf Laci - Zamrud (x13)"

#: init.lua
msgid "Wooden Trim"
msgstr "Hiasan Kayu"

#: init.lua
msgid "Drawer Upgrade Template"
msgstr "Templat Naik Taraf Laci"

#: lua/controller.lua
msgid "Current State: "
msgstr "Keadaan Semasa: "

#: lua/controller.lua
msgid "Digiline Channel"
msgstr ""

#: lua/controller.lua
msgid "Save"
msgstr ""

#: lua/controller.lua
msgid "Stopped"
msgstr "Berhenti"

#: lua/controller.lua
msgid "Running"
msgstr "Berjalan"

#: lua/controller.lua
msgid "Jammed"
msgstr "Tersekat"

#: lua/controller.lua
msgid "Drawer Controller"
msgstr "Pengawal Laci"

#: lua/api.lua lua/visual.lua
msgid "Empty"
msgstr "Kosong"

#: lua/api.lua
msgid "@1 Drawer"
msgstr "Laci @1"

#: lua/api.lua
msgid "@1 Drawers (1x2)"
msgstr "Laci @1 (1x2)"

#: lua/api.lua
msgid "@1 Drawers (2x2)"
msgstr "Laci @1 (2x2)"

#: lua/helpers.lua
msgid "@1 (@2% full)"
msgstr "@1 (@2% penuh)"

#: lua/helpers.lua
msgid "@1 @2 (@3% full)"
msgstr "@1 @2 (@3% penuh)"


code:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-03-27 18:43+0100\n"
"PO-Revision-Date: 2020-10-15 22:26+0000\n"
"Last-Translator: Yaya - Nurul Azeera Hidayah @ Muhammad Nur Hidayat "
"Yasuyoshi <translation@mnh48.moe>\n"
"Language-Team: Malay (Jawi) <https://hosted.weblate.org/projects/minetest/"
"mod-storage-drawers/ms_Arab/>\n"
"Language: ms_Arab\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 4.3-dev\n"

#: lua/visual.lua lua/api.lua
msgid "Empty"
msgstr "کوسوڠ"

#: lua/api.lua init.lua
msgid "Wooden"
msgstr "کايو"

#: lua/api.lua
msgid "@1 Drawer"
msgstr "لاچي @1"

#: lua/api.lua
msgid "@1 Drawers (1x2)"
msgstr "لاچي @1 جنيس 1x2"

#: lua/api.lua
msgid "@1 Drawers (2x2)"
msgstr "لاچي @1 جنيس 2x2"

#: lua/controller.lua
msgid "Drawer Controller"
msgstr "ڤڠاول لاچي"

#: lua/controller.lua
msgid "Digiline Channel"
msgstr ""

#: lua/controller.lua
msgid "Save"
msgstr ""

#: lua/helpers.lua
msgid "@1 (@2% full)"
msgstr "@1⹁ @2% ڤنوه"

#: lua/helpers.lua
msgid "@1 @2 (@3% full)"
msgstr "@2 @1⹁ @3% ڤنوه"

#: init.lua
msgid "Acacia Wood"
msgstr "ڤاڤن کايو اکاسيا"

#: init.lua
msgid "Aspen Wood"
msgstr "ڤاڤن کايو اسڤين"

#: init.lua
msgid "Junglewood"
msgstr "ڤاڤن کايو هوتن"

#: init.lua
msgid "Pine Wood"
msgstr "ڤاڤن کايو ڤاين"

#: init.lua
msgid "Oak Wood"
msgstr "ڤاڤن کايو اوک"

#: init.lua
msgid "Birch Wood"
msgstr "ڤاڤن کايو برچ"

#: init.lua
msgid "Dark Oak Wood"
msgstr "ڤاڤن کايو اوک ݢلڤ"

#: init.lua
msgid "Spruce Wood"
msgstr "ڤاڤن کايو فير"

#: init.lua
msgid "Steel Drawer Upgrade (x2)"
msgstr "ناٴيق طرف لاچي - کلولي⹁ x2"

#: init.lua
msgid "Gold Drawer Upgrade (x3)"
msgstr "ناٴيق طرف لاچي - امس⹁ x3"

#: init.lua
#, fuzzy
msgid "Obsidian Drawer Upgrade (x4)"
msgstr "ناٴيق طرف لاچي - اوبسيدي⹁ x5"

#: init.lua
msgid "Diamond Drawer Upgrade (x8)"
msgstr "ناٴيق طرف لاچي - اينتن⹁ x8"

#: init.lua
msgid "Iron Drawer Upgrade (x2)"
msgstr "ناٴيق طرف لاچي - بسي⹁ x2"

#: init.lua
msgid "Emerald Drawer Upgrade (x13)"
msgstr "ناٴيق طرف لاچي - زمرود⹁ x13"

#: init.lua
#, fuzzy
msgid "Mithril Drawer Upgrade (x13)"
msgstr "ناٴيق طرف لاچي - زمرود⹁ x13"

#: init.lua
msgid "Wooden Trim"
msgstr "هياسن کايو"

#: init.lua
msgid "Drawer Upgrade Template"
msgstr "تمڤلت ناٴيق طرف لاچي"

#~ msgid "Current State: "
#~ msgstr "کأداٴن سماس: "

#~ msgid "Stopped"
#~ msgstr "برهنتي"

#~ msgid "Running"
#~ msgstr "برجالن"

#~ msgid "Jammed"
#~ msgstr "ترسکت"