FANDOM


local Item = {}
----------------------------
-- Libraries of functions --
----------------------------
-- Loads high frequency functions
local HF = require('Module:HF')
 
-- Parses invocation and template parameters, trims whitespace, and removes blanks.
local getArgs = require('Dev:Arguments').getArgs
 
-- Language functions for the default language
local lang = mw.language.getContentLanguage()
 
-- Smarter boolean logic
local yesno = require( 'Dev:Yesno' )
 
-- Wikitext lists
local L = require( 'Dev:List' )
 
-- Grand Exchange data
local EX = require('Module:Exchange')
local EXD = require('Module:ExchangeData')
 
-----------------------
-- Libraries of data --
-----------------------
 
------------------------------------------------
-- Local functions (used only in this Module) --
------------------------------------------------
local pagetitle, namespace, content = 
    mw.title.getCurrentTitle().fullText,
    mw.title.getCurrentTitle().namespace,
    mw.title.getCurrentTitle().isContentPage
local testcase = (mw.title.getCurrentTitle():inNamespace( 10 ) 
    and mw.title.getCurrentTitle().text:lower():match('testcases$'))
        and true
local documentation = (mw.title.getCurrentTitle():inNamespace( 10 ) 
    and mw.title.getCurrentTitle().text:lower():match('doc$'))
        and true
 
local function rawnumber(value)
    if value then
        -- in case it's a number in comma-grouped form,
        -- or (more likely) a string
        -- make it a pure number
        value = lang:parseFormattedNumber( value )
        value = tonumber( value ) and tonumber( value ) or value
        return value
    else
        return nil
    end
end
local function groupednumber(value)
    if value then
        -- in case it's a number in comma-grouped form,
        -- or (more likely) a string
        -- make it a pure number
        value = rawnumber(value)
        -- if it's a pure number,
        -- put it in comma-grouped form
        value = type(value) == 'number'
            and lang:formatNum( value )
            or value
        return value
    else
        return nil
    end
end
local function getParam( parameters, version, args )
  if type(parameters) == 'string' and type(args) == 'table' then
    if version -- We're on tab 'version'
      and args[parameters..version] -- and it has a value
      then
          local backref = args[parameters..version]:match('^%$%d+$') -- checks if the value is '$1'
          backref = backref and backref:gsub('%$','')
          return args[parameters..(backref or version)] or args[parameters..version]
    elseif
      version -- We're on tab 'version'
      and args['version'..version] -- That version actually exists
      and not args[parameters..version] -- There's no specialized value
      and args[parameters] -- There is a generic value
      then
      return args[parameters]
    elseif 
      not version -- We're on generic tab
      and not args['version'..1] -- No specialized version exists
      and not args[parameters..1] -- There's no specialized value
      and args[parameters] -- There is a generic value
      then
      return args[parameters]
    else
      return nil
    end
  elseif type(parameters) == 'table' and type(args) == 'table' then
    local out = {}
    for _,parameter in ipairs(parameters) do
      out.parameter = getParam( parameter, version, args)
    end
    return out
  else
    return nil
  end
end
local function default(parameter, version, args, category)
    -- Default, if used, is the word "Unknown"
    -- Adds a category in content namespaces
    local default = content 
        and ('%s%s'):format('Unknown', HF.Category(category))
        or 'Unknown'
    -- Only uses default under certain conditions
    default = (content or testcase or documentation) and default or nil
    -- Only use default if on the generic page
    default = (version == nil) and default or nil
    -- Only use default if there's no generic or specialized value
    default = (not args[parameter] and not args[parameter..1])
        and default or nil
    return default
end
local function ge(version, args)
    local exch = {}
    local name = getParam( 'name', version, args )
    local exchange = getParam( 'exchange', version, args )
    local override_name = getParam( 'gemwname', version, args )
    if exchange and exchange:lower() == 'gemw' then exch.exchange = true end
    if yesno(getParam( 'tradeable', version, args )) == true and exch.exchange then exch.gemw = true end
 
	if override_name and override_name:find('%S') then
		exch.name = override_name:gsub('</?span>','')
	elseif name and name:find('%S') then
		exch.name = name:gsub('</?span>','')
	else
		exch.name = mw.title.getCurrentTitle().fullText
	end
 
	if exch.gemw == true and EX._exists(exch.name) then
	    exch.price = tonumber(EX._price(exch.name),10) or -1
	    if exch.price > 0 then
	        local wrapper = mw.html.create('span')
	        :addClass('infobox-quantity')
	        :attr('data-val-each', exch.price)
	        :wikitext(
	            ('<span class="infobox-quantity-replace">%s</span> %s %s')
	                :format(
	                    groupednumber(exch.price),
	                    lang:plural(exch.price, ' coin', ' coins'),
	                    (' (%s)'):format(HF.Link('Exchange:'..exch.name, 'info'))
                    )
            )
            :allDone()
	        exch.exchange = tostring(wrapper)
            exch.graph = EXD._chart{exch.name, ['size'] = 'small'}
            exch.buylimit = EX._limit(exch.name) 
                and groupednumber(EX._limit(exch.name)) 
                or nil
            exch.display = 'infobox-cell-shown'
        end
 
    elseif exch.gemw == true then
        exch.price = -1
        exch.exchange = mw.smw.info('The parameter «exchange» was set to «gemw» but no page was found for «'..exch.name..'».','warning')
        exch.graph = 'No data to display'
        exch.buylimit = nil
        exch.display = 'infobox-cell-shown'
    else
        exch.price = 0
        exch.exchange = '<span class="infobox-quantity" data-val-each="0">Not sold</span>'
        exch.graph = nil
        exch.buylimit = nil
        exch.display = ''
    end
    return exch
end
local function kept(version, args)
 
    local k = {
        _kept = getParam('kept', version, args),
        ikod = getParam('ikod', version, args),
        _reclaim = getParam('reclaim', version, args),
        _sacrifice = getParam('sacrifice', version, args),
        _value = rawnumber(getParam('value', version, args))
    }
    local display = {
        ['never'] = 'Always lost',
        ['always'] = 'Always kept outside ' .. HF.Link('Wilderness','Wild'),
        ['alwaysinclwild'] = 'Always kept',
        ['dropped'] = 'Dropped on death',
        ['safe'] = 'Always a safe death',
        ['gemwdegrade'] = nil,
        ['reclaimable'] = 'Reclaimable'
    }
    local cats = {
        ['never'] = HF.Category('Items that are never kept on death'),
        ['always'] = HF.Category('Items that are always kept outside the Wilderness on death'),
        ['reclaimable'] = HF.Category('Items that are reclaimable on death'),
        ['alwaysinclwild'] = HF.Category('Items that are always kept on death')
    }
    k.kept = type(k._kept) == 'string' and display[k._kept:lower()]
    k.category = type(k._kept) == 'string' and cats[k._kept:lower()]
 
    -- Stop there if it's not reclaimable
    if k.kept ~= 'Reclaimable' then return k end
 
    local i = (k.ikod and rawnumber(k.ikod)) 
        or (((tonumber(g,10) or 0) > 0) and ge(version, args).price)
        or (k._value and rawnumber(k._value))
        or nil
    k.value = i and groupednumber(i)
    k.reclaim = k._reclaim and rawnumber(k._reclaim) or nil
    k.sacrifice = k._sacrifice and rawnumber(k._sacrifice) or nil
 
    if i and not k.reclaim then
        local r
		-- less than 10,000: .15x
		if i < 10000 then
			r = math.floor(i * .15)
			-- all items cost at least 1 coin, so round back up if 0
			if r == 0 then
				r = 1
			end
 
		--Death formula
		-- 10,000 to 49,999: 500 + 0.1x
		elseif i >= 10000 and i < 50000 then
			r = 500 + i * 0.1
 
		-- 50,000 to 249,999: 3000 + 0.05x
		elseif i >= 50000 and i < 250000 then
			r = 3000 + i * 0.05
 
		-- 250,000 to 999,999: 10500 + 0.02x
		elseif i >= 250000 and i < 1000000 then
			r = 10500 + i * 0.02
 
		-- 1,000,000 to 9,999,999: 20500 + 0.01x
		elseif i >= 1000000 and i < 10000000 then
			r = 20500 + i * 0.01
 
		-- 10,000,000 and greater: 70,500 + 0.005x
		elseif i >= 10000000 then
			r = 70500 + i * 0.005
 
		-- this shouldn't happen, but fallback to 1
		else
			r = 1
		end
	    k.reclaim = r and math.floor(math.floor(r*1000+0.0000099)/1000)
	end
	k.sacrifice = k.sacrifice or (k.reclaim and k.reclaim * 4) or nil
 
    return k
end
 
---------------------------------------------------------
-- Internal functions (used in this and other Modules) --
---------------------------------------------------------
function Item.PageHandler(frame)
    local args = getArgs(frame, { parentOnly = true })
    if not content and not testcase and not documentation then
        return nil
    end
    local categories = {
        HF.Category('Items')
    }
    if id then
        mw.smw.set{
            ['Item ID'] = args['id'],
            ['All Item ID'] = args['id']
        }
    elseif args['id'..1] then
      for i=1,100,1 do
        if args['id'..i] then
        local set = { ['All Item ID'] = args['id'..i] }
        set[tostring('Item ID'..i)] = args[tostring('id'..i)] 
        mw.smw.set(set)
        mw.smw.subobject(
            { ['Item ID'] = args['id'..i],
              ['Name'] = args['name'..i],
              ['Version'] = args['version'..i] },
            args['name'..i] or args['version'..i] or 'Version'..i
        )
        end
      end
    else
        table.insert(categories, HF.Category('Needs ID'))
    end
    return content and table.concat(categories)
end
 
function Item.GalleryItems(frame)
    local args = getArgs(frame, { parentOnly = true })
    local out = {}
    local name = args['name'] or pagetitle
    table.insert(out, 
        (args['image/detail'] or name..' detail.png') ..
        '|Detailed'
    )
    if args['image/detail_alternative_label'] and args['image/detail_alternative'] then
        table.insert(out, args['image/detail_alternative']..'|'..args['image/detail_alternative_label'])
    end
    table.insert(out, 
        (args['image/equipped'] or name..' equipped.png') ..
        '|Equipped'
    )
    if args['image/equipped_alternative_label'] and args['image/equipped_alternative'] then
        table.insert(out, args['image/equipped_alternative']..'|'..args['image/equipped_alternative_label'])
    end
    table.insert(out, 
        (args['image/chathead'] or name..' chathead.png') ..
        '|Chathead'
    )
    return table.concat(out,'\n')
end
function Item.image_icon(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local icon = getParam('image',version,args)
    if icon and content then
        if version then
            local vI = tostring('Icon'..version)
            mw.smw.set{
                ['All Icons'] = icon,
                [vI] = icon
            }
            mw.smw.subobject(
                { ['Icon'] = icon },
                (args['name'..version] or args['version'..version] or 'Version'..version)
            )
        elseif not version then
            mw.smw.set{ ['Icon'] = icon }
        end
    end
    return icon or nil
end
function Item.version_label(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local name = version and args['name'..version]
    local name_backref = name and name:match('^%$%d+$')
          name_backref = name_backref and name_backref:gsub('%$','')
    name = name_backref and 
        (args['name'..name_backref] or args['name'..(version or '')])
    local ver = version and args['version'..version]
    return name or ver or 'Typical'
end
function Item.release(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local release = getParam('release', version, args)
    local update = getParam('update', version, args)
 
    if release and content then
        release_plaintext = release:gsub('%[%[',''):gsub('%]%]','')
        if version then
            local vRD = tostring('Release date'..version)
            mw.smw.set{
                ['All Release date'] = release_plaintext,
                [vRD] = release_plaintext
            }
            mw.smw.subobject(
                { ['Release date'] = release_plaintext },
                (args['name'..version] or args['version'..version] or 'Version'..version)
            )
        elseif not version then
            mw.smw.set{ ['Release date'] = release_plaintext }
        end
        -- Does not produce a singleton 'Release date' property if there are any versions 
    end
 
    release = release and ('%s (%s)'):format( 
        release,
        update 
            and HF.Link('Update:'..update, 'Update')
            or 'Update unknown'
    )
    return release or default('release', version, args, 'Needs release date')
end
function Item.removal(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local removal = getParam('removal', version, args)
    local removalupdate = getParam('removalupdate', version, args)
 
    removal = removal and ('%s (%s)'):format( 
        removal,
        removalupdate 
            and HF.Link('Update:'..removalupdate, 'Update')
            or 'Update unknown'
    )
    return removal
end
function Item.aka(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local aka = getParam('aka', version, args)
 
    aka = (aka and content) 
        and ('%s%s'):format(aka, HF.Category('Pages with AKA'))
    return aka
end
function Item.members(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local members = getParam( 'members', version, args )
 
    local categories = {}
    if members and content then
        if yesno(members) == true then
            table.insert(categories, HF.Category("Members' items"))
            if version then
                local vMO = tostring('Is members only'..version)
                mw.smw.set{
                    ['All Is members only'] = 'true',
                    [vMO] = 'true'
                }
                mw.smw.subobject(
                    { ['Is members only'] = 'true',
                      ['@category'] = "Members' items" },
                    (args['name'..version] or args['version'..version] or 'Version'..version)
                )
            elseif not version then
                mw.smw.set{ ['Is members only'] = 'true' }
            end
        elseif yesno(members) == false then
            table.insert(categories, HF.Category('Free-to-play items'))
            if version then
                local vMO = tostring('Is members only'..version)
                mw.smw.set{
                    ['All Is members only'] = 'false',
                    [vMO] = 'false'
                }
                mw.smw.subobject(
                    { ['Is members only'] = 'false',
                      ['@category'] = "Free-to-play items" },
                    (args['name'..version] or args['version'..version] or 'Version'..version)
                )
            elseif not version then
                mw.smw.set{ ['Is members only'] = 'false' }
            end
        end
        members = members .. table.concat(categories)
    end
    return members or default('members', version, args, 'Needs members status')
end
function Item.quest(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local quest = getParam('quest', version, args)
 
    quest = (quest and content and quest:match('%[%[')) 
            and quest..HF.Category('Quest items')
            or quest
    return quest or default('quest', version, args, 'Items missing quest')
end
function Item.tradeable(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local tradeable = getParam('tradeable', version, args)
    local categories = {}
 
    if (tradeable and yesno(tradeable) == true) then
        tradeable = 'Yes'
        table.insert(categories, HF.Category('Tradeable items'))
    elseif (tradeable and yesno(tradeable) == false) then
        tradeable = 'No'
        table.insert(categories, HF.Category('Untradeable items'))
    elseif (tradeable and tradeable:lower() == 'restricted') then
        tradeable = HF.Link('Restricted trade items','Restricted')
        table.insert(categories, HF.Category('Restricted trade items'))
    else tradeable = tradeable 
            and tradeable .. 
                mw.smw.info('Invalid value for "bankable"','warning')
            or nil
    end
 
    tradeable = (tradeable and content) 
        and tradeable..table.concat(categories)
        or tradeable
    return tradeable or nil
end
function Item.equipable(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local equipable = getParam( 'equipable', version, args )
    equipable = (equipable and yesno(equipable) == true and content) 
        and equipable..HF.Category('Equipable items')
        or equipable
    return equipable or nil   
end
function Item.bankable(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local bankable = getParam( 'bankable', version, args )
 
    if yesno(bankable) == true then
        return nil
    elseif yesno(bankable) == false then
        return (content or testcase or documentation) and 'No'
    else
        return bankable
            and bankable .. 
                mw.smw.info('Invalid value for "bankable"','warning')
            or nil
    end
end
function Item.stacksinbank(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local stacksinbank = getParam( 'stacksinbank', version, args )
 
    if yesno(stacksinbank) == true then
        return nil
    elseif yesno(stacksinbank) == false then
        return (content or testcase or documentation) and 'No'
    else
        return stacksinbank 
            and stacksinbank .. 
                mw.smw.info('Invalid value for "stacksinbank"','warning')
            or nil
    end
end
function Item.lendable(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local lendable = getParam( 'lendable', version, args )
 
    if yesno(lendable) == false then
        return nil
    elseif yesno(lendable) == true then
        lendable = content 
            and 'Yes' .. HF.Category('Lendable items')
            or 'Yes'
        return (content or testcase or documentation) and lendable
    else
        return lendable
            and lendable .. 
                mw.smw.info('Invalid value for "lendable"','warning')
            or nil
    end
end
function Item.stackable(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local stackable = getParam( 'stackable', version, args )
 
    stackable = (stackable and yesno(stackable) == true and content) 
        and stackable..HF.Category('Stackable items')
        or stackable
    return stackable or nil   
end
function Item.disassembly(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local disassembly = getParam('disassembly', version, args)
    local categories = {}
    local notapplicable = {
        ['na'] = true,
        ['n/a'] = true,
        ['discontinued'] = true,
        ['irrelevant'] = true
    }
 
    if (disassembly and yesno(disassembly) == true) then
        disassembly = HF.Link('#DisassemblyT','Yes')
        table.insert(categories, HF.Category('Items that can be disassembled'))
    elseif (disassembly and yesno(disassembly) == false) then
        disassembly = 'No'
        table.insert(categories, HF.Category('Items that cannot be disassembled'))
    elseif (disassembly and disassembly:lower() == 'restricted') then
        disassembly = HF.Link(':Category:Location restricted disassembly','Restricted')
        table.insert(categories, HF.Category('Location restricted disassembly'))
    elseif (disassembly and notapplicable[disassembly:lower()]) then
        disassembly = 'N/A'
        table.insert(categories, HF.Category('Items with N/A disassembly'))
    else
        disassembly = disassembly 
            and disassembly .. 
                mw.smw.info('Invalid value for "disassembly"','warning')
            or nil
    end
 
    disassembly = (disassembly and content) 
        and disassembly..table.concat(categories)
        or disassembly
    return disassembly or default( 'disassembly', version, args, 'Items missing disassembly info')
end
function Item.noteable(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local noteable = getParam( 'noteable', version, args )
 
    if yesno(noteable) == false then
        return nil
    elseif yesno(noteable) == true then
        return (content or testcase or documentation) and noteable
    else
        return noteable
            and noteable .. 
                mw.smw.info('Invalid value for "noteable"','warning')
            or nil
    end
end
function Item.edible(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local edible = getParam( 'edible', version, args )
 
    if yesno(edible) == false then
        return nil
    elseif yesno(edible) == true then
        return (content or testcase or documentation) and edible
    else
        return edible
            and edible .. 
                mw.smw.info('Invalid value for "edible"','warning')
            or nil
    end
end
function Item.value(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local value = getParam('value', version, args)
 
    local unit = value 
        and lang:plural( rawnumber(value), ' coin', ' coins' )
    if value then
        if version then
            local vV = tostring('Value'..version)
            mw.smw.set{
                ['All Value'] = rawnumber(value),
                [vV] = rawnumber(value)
            }
            mw.smw.subobject(
                { ['Value'] = rawnumber(value) },
                (args['name'..version] or args['version'..version] or 'Version'..version)
            )
        elseif not version then
            mw.smw.set{ ['Value'] = rawnumber(value) }
        end
    end
 
    return value and groupednumber(value)..unit or default('value', version, args, 'Items missing value')
end
function Item.value_cashout(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local convert = getParam( 'convert', version, args )
    convert = (convert and not tonumber(convert))
        and rawnumber(convert:gsub(' coins',''):gsub(' coin',''))
 
    local unit = type(convert) == 'number'
        and lang:plural( rawnumber(convert), ' coin', ' coins' )
        or nil
    return type(convert) == 'number' 
        and groupednumber(convert)..(unit or '') 
        or convert or nil
end
function Item.alchable(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local alchable = getParam( 'alchable', version, args )
    local high = getParam( 'high', version, args )
    local low = getParam( 'low', version, args )
 
    if yesno(alchable) == false 
        or (yesno(high) == false and yesno(low) == false)
        then
        alchable = content 
            and 'Not alchemisable' ..
                HF.Category('Items that cannot be alchemised')
            or 'Not alchemisable'
    end
    return alchable or nil
end
function Item.highalchemy(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local alchable = getParam( 'alchable', version, args )
    local high = rawnumber(getParam( 'high', version, args ))
    local value = rawnumber(getParam( 'value', version, args ))
    local multiplier = rawnumber(getParam( 'alchmultiplier', version, args )) or .6
    if high and yesno(high) == false or yesno(alchable) == false then
        return nil    
    elseif type(high) == 'number' then
        return high .. lang:plural( high, ' coin', ' coins' )
    else
        local X = value and math.floor(math.floor(value * multiplier*1000+0.0000099)/1000)
		return X and groupednumber(X) .. lang:plural( X, ' coin', ' coins' ) or nil
    end
end
function Item.lowalchemy(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local alchable = getParam( 'alchable', version, args )
    local low = rawnumber(getParam( 'low', version, args ))
    local value = rawnumber(getParam( 'value', version, args ))
    local multiplier = rawnumber(getParam( 'alchmultiplier', version, args )) or .6
    if low and yesno(low) == false or yesno(alchable) == false then
        return nil    
    elseif type(low) == 'number' then
        return low .. lang:plural( low, ' coin', ' coins' )
    else
        local X = value and math.floor(math.floor(value * (2/3) * multiplier*1000+0.0000099)/1000)
		return X and groupednumber(X) .. lang:plural( X, ' coin', ' coins' ) or nil
    end
end
function Item.destroy(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local destroy = getParam( 'destroy', version, args )
    return destroy or default( 'destroy', version, args, 'Missing destroy text')
end
function Item.kept_death(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local position = getArgs(frame, { frameOnly = true })[2] or nil
    local args = getArgs(frame, { parentOnly = true })
    local k = kept(version, args)
 
    k.kept = (content and k.category)
        and k.kept .. k.category
        or k.kept
 
    if k.kept 
      and (k.reclaim or k.sacrifice)
      and position == 'vertical' then
          k.kept = nil
    elseif k.kept 
      and not (k.reclaim or k.sacrifice)
      and position == 'horizontal' then
          k.kept = nil
    end
 
    return content and k.kept or default('kept',version,args,'Items missing death info')
end
function Item.kept_reclaim(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local k = kept(version, args)
    return k.reclaim or nil
end
function Item.kept_sacrifice(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local k = kept(version, args)
    return k.sacrifice or nil
end
function Item.weight(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
        mw.log(version)
    local args = getArgs(frame, { parentOnly = true })
    local weight = getParam( 'weight', version, args )
 
    local unit = weight and ' kg'
 
    if weight then
        if version then
            local vW = tostring('Weight'..version)
            mw.smw.set{
                ['All Weight'] = rawnumber(weight:gsub('[kg ]','')),
                [vW] = rawnumber(weight:gsub('[kg ]',''))
            }
            mw.smw.subobject(
                { ['Weight'] = rawnumber(weight:gsub('[kg ]','')) },
                (args['name'..version] or args['version'..version] or 'Version'..version)
            )
        elseif not version then
            mw.smw.set{ ['Weight'] = rawnumber(weight:gsub('[kg ]','')) }
        end
    end
 
	weight = weight and weight:gsub('-','&minus;')
    return weight and weight..unit or default( 'weight', version, args, 'Needs weight added' )
end
function Item.tooltip(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local tooltip = getParam( 'tooltip', version, args )
 
    if (not tooltip) or yesno(tooltip) == 'no' then return nil end
    local tooltips = tooltip and mw.text.split(tooltip, ',')
    local t = {
        ['passive'] = HF.Link('Passive effect'),
        ['set'] = HF.Link('Set bonus'),
        ['time'] = 'Time remaining',
        ['degrade'] = HF.Link('Degradation'),
        ['items'] = 'Items consumed',
        ['urn'] = 'Percentage filled'
    }
    local out = {}
    for _,v in ipairs(tooltips) do
        v = mw.text.trim(v):gsub("^%s*(.-)%s*$", "%1")
        x = v:lower()
        if x ~= '' and t[x] then
            table.insert(out, t[x])
        elseif v~= '' then
            table.insert(out, v)
        end
    end
    return out[1] 
        and L.makeList('bulleted', out) ..
            (content and HF.Category('Items that have a tooltip') or '')
        or nil
end
function Item.examine(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local examine = getParam( 'examine', version, args )
    return examine or default('examine', version, args, 'Needs examine added')
end
 
function Item.ExchangePrice(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local exch = ge(version, args)
    local tradeable = getParam( 'tradeable', version, args )
    local categories = {}
 
    if exch.gemw ~= true and yesno(tradeable) == true then
        table.insert(categories, HF.Category('Non-GE items'))
    elseif exch.gemw == true then
        table.insert(categories, HF.Category('Grand Exchange items'))
    end
 
    if (version and not args['version'..version])
        or (not version and args['version1'])then
        return nil
    end
    return content and exch.exchange..table.concat(categories) or nil
end
function Item.BuyLimit(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local exch = ge(version, args)
    return content and exch.buylimit or nil
end
function Item.graph(frame)
    local version = getArgs(frame, { frameOnly = true })[1] or nil
    local args = getArgs(frame, { parentOnly = true })
    local exch = ge(version, args)return content and exch.graph or nil
end
-------------------------------------------------
-- Output (send it back to whatever called it) --
-------------------------------------------------
return Item
Community content is available under CC-BY-SA unless otherwise noted.