Module:Infobox/Item

--Get Required Modules local loadLib = require('Module:LoadLib')

loadLib(_G, {	infobox = 'Infobox',	mRarity = 'RarityTier',	mLink = 'Link',	mOdds = 'Odds',	{'Bazaar', values = {		bazaarLastUpdatedIcon='lastUpdatedIcon',		getBazaarPriceChange='_getPriceChange',		getBazaarPriceSpred='_getPriceSpread',	}},	templates = 'String/Templates',	list = 'List',	ability = 'Ability',	{'Currency', values = {		'currency',	}},	animate = 'Animate',	infoboxdata = 'Infobox/Data',	pet = 'Pet', })

mw.html.create = require('Module:Html').create local curTitle = mw.title.getCurrentTitle local allstats = infoboxdata.allstats --D1+ local rarityList = infoboxdata.rarityList --M4-21 local armorAliases = infoboxdata.armorAliases local MAX_INDEX = infoboxdata.MAX_INDEX local MAX_TAB = infoboxdata.MAX_TAB local sacksSuffix = { {'_s', 'Small', '640'}, {'_m', 'Medium', '2,240'}, {'_l', 'Large', '20,160'} }

--Begin Exports local p = {} local yesIcon, noIcon, unknownIcon = templates.yes(1), templates.no(1), templates.unknown(1)

local function yesnodefault(val, yes, no, def) if tostring(val):sub(1, 1):lower == 'u' then return unknownIcon end local bool = yesno(val); if bool == nil then return def or val elseif bool then return yes else return no	end end

local function yesnoIcon(val, def) return yesnodefault(val, yesIcon, noIcon, def) end

local function addBazaarGroup(id, parent) if id then parent :addGroup{ header = { 'Bazaar', string.wrapTag({ bazaarLastUpdatedIcon, '', }, 'sup') }, layout = 'horizontal', ['row-items']=2 } :addData{ label = 'Buy', (''):format(1, id, 'buy', 'true') } :addData{ label = 'Sell', (''):format(1, id, 'sell', 'true') } :addData{ label = 'Buy (stack)', (''):format(64, id, 'buy', 'true') } :addData{ label = 'Sell (stack)', (''):format(64, id, 'sell', 'true') } :addGroup{ ['row-items']=1 } :addData{ label = string.wrapTag('Price Spread', 'center'), string.wrapTag(getBazaarPriceSpred(id, nil, true), 'center') } :done :addData{ getBazaarPriceChange(id, 'buy', true), label = { 'Buy Price Change', string.wrapTag(bazaarLastUpdatedIcon, 'sup') } } :addData{ getBazaarPriceChange(id, 'sell', true), label = { 'Sell Price Change', string.wrapTag(bazaarLastUpdatedIcon, 'sup') } } :done end end

function p.infoboxCreate(frame) local args = getArgs(frame) local deftype = args.default_type -- All checkings; Need to check if reforge stone due to naming conflict with 'reforge' and a 'reforgeable' alt name local isReforgeStone, isArmorSet, isSack, isPet do local function check(v) return (deftype or ''):lower:match(v) and true or false end isReforgeStone = check('reforge stone') isArmorSet = check('armor') and check('set') isSack = check('sack') isPet = check('pet') end local pagename = curTitle.text or 'Diamond' local title = args.title or pagename local category_to_add = args.category_to_add or '' local onmain = curTitle.namespace == 0 local sections = {} local idsExistForAllTabs = true local propertiesExistForAllTabs = true local idRequirementDisabled = isPet or false -- Sack Handler if isSack then local onetier = yesno(args.only_one_tier or args.is_ench_sack, false) for i, v in ipairs(sacksSuffix) do			local sf, fl, cap = v[1], v[2], v[3] local function argS(name) return args[name..i] or args[name..sf] end args['tab'..i] = argS('tab') or not onetier and fl or nil args['tab'..sf] = args['tab'..i]			args['image'..sf] = argS('image') or onetier and ('%s.png'):format(pagename) or ('%s %s.png'):format(fl, pagename) args['slot'..sf] = argS('slot') or onetier and pagename or ('%s %s'):format(fl, pagename) args['sack_capacity'..sf] = argS('sack_capacity') or ('%s for each item'):format(onetier and sacksSuffix[3][3] or cap) end end for j = 1,MAX_TAB,1 do		local function argJ(name, default) return args[name..j] or default end local sectionExists = j==1 or argJ('tab') if sectionExists then local i, _i if isSack then -- Support custom syntax i = sacksSuffix[j][1] or ( j==1 and '' or j ) _i = sacksSuffix[j][1] or ( j==1 and '' or '_'..j ) else -- section one does have numbers after params; on 2+ do that i = j==1 and  or j				_i = j==1 and  or '_'..j -- needed for when a param ends in a number naturally end local function argI(name, default) return args[name..(name:match('%d$') and _i or i)] or default end local function sumStat(attr) local ret = 0 for _, piece in ipairs{'helmet_', 'chest_', 'legs_', 'boots_'} do					ret = ret + (tonumber(argI(piece..attr)) or 0) end return ret > 0 and ret or nil end local function processStat(long, short) return argI(long) or argI(short) or sumStat(short) end if isArmorSet then if not (argI('chest_id') and argI('legs_id') and argI('boots_id')) then idsExistForAllTabs = false end else if not argI('id') then idsExistForAllTabs = false end end -- table of all params for this section local s = {} -- Top level infobox values --0			s.tab = argJ('tab') or argI('tab') -- purposefully use 'j' here since default section does actually use 'tab1' --1|2			s.caption = argI('caption') or argI('imagecaption') s.image_gallery = (argI('image') and argI('image'):match('UNIQ%-%-gallery')) and argI('image') or nil s.image = not s.image_gallery and string.wrapTag(animate.animate({ argI('image') or pagename..'.png', class='pi-image-thumbnail', caption = s.caption }), 'center') or nil --[3]]			if isArmorSet then for _,v in ipairs{'helmet','chest','legs','boots'} do					s['slot_'..v] = argI('slot_'..v)					s['slot_'..v] = yesno(s['slot_'..v], true) and (s['slot_'..v] or pagename:gsub('%s*Armor$',' '..armorAliases[v])) or nil end s.slot_item = string.wrapHtml(					table.concat(table.map({'helmet','chest','legs','boots'}, function(v)						-- expandTemplate is needed here!! This is because if a slot value contains `&`, the infobox will convert it to unicode (&amp;), which mess it - using expandTemplate we parse the text -before- sending it to the infobox						return s['slot_'..v] and mw.getCurrentFrame:expandTemplate{ title='Slot', args={							s['slot_'..v], link = (not onmain and 'none' or nil)						} }					end)),					'center') else s.slot_item = argI('slot_item') or argI('slot') if isPet then local _slot = pet.inquireslots(s.slot_item or pagename) s.slot_item = string.wrapHtml((_slot == '') and s.slot_item or _slot, 'center') else -- If a value is passed in, set to value; if no value is passed in set to page name; if the value passed in is a 'no' type value, set to nil s.slot_item = yesno(s.slot_item, true) and (s.slot_item or pagename) or nil -- Unless a 'false' value is set, show ; if a value that isn't 'false' is given, uses that instead. 'true' values being passed in break this -- Since slot{} has newlines that messes up formatting here for some reason, remove the newlines -- expandTemplate is needed here!! This is because if a slot value contains `&`, the infobox will convert it to unicode (&amp;), which mess it - using expandTemplate we parse the text -before- sending it to the infobox s.slot_item = s.slot_item and string.wrapHtml(mw.getCurrentFrame:expandTemplate{ title='Slot', args={						s.slot_item,						text = argI('slot_text') or nil,						title = argI('slot_title') or nil,						link = argI('slot_link') or (not onmain and 'none' or nil),					} }, 'center') end end --4			s.aka = argI('aka') --5			s.type = argI('type') or deftype or 'Item' --6			s.rarity = argI('rarity') and mRarity.link{ argI('rarity'), addcategory = true } --7			s.collection = argI('collection') and mLink.collectionLink{ argI('collection'), showIcon = true } --8			s.combat_level_requirement = argI('combat_level_requirement') --9			s.slayer_level_requirement = argI('slayer_level_requirement') and mLink.collectionLink{ argI('slayer_level_requirement'), showIcon = true } --10			s.dungeon_level_requirement = argI('dungeon_level_requirement') --11			s.dungeon_floor_clearing_requirement = argI('dungeon_floor_clearing_requirement') --12			s.hotm_requirement = argI('hotm_requirement') --13			s.other_level_requirement = argI('other_level_requirement') --14			s.reforge_name = (isReforgeStone and argI('reforge')) or argI('reforge_name') --15			s.source = argI('source') --16			s.obtained = argI('obtained') or argI('obtain') or argI('obtaining') --17			s.drop_chance = argI('drop_chance') or argI('odds') if s.drop_chance then if s.drop_chance:sub(1,1):lower == 'u' then s.drop_chance = templates.unknown(1) else s.drop_chance = mOdds.odds{ s.drop_chance, big = true } end end --18			s.uses = argI('uses') or argI('usage') --19			s.minion_xp = argI('minion_xp') and (''):format(argI('minion_xp')) --20			s.lore = argI('lore') --21			s.mob = argI('mob') --22			s.rarities = argI('rarities') -- Sack Stats group -- since all sacks share same items, no reason to pass it in multiple times --A0 s.sack_capacity = argI('sack_capacity') --A1 s.sack_items = argI('sack_items') or args['sack_items'] if s.sack_items then -- If the list of items is to large to easily fit, collapse it				local _, count = string.gsub(s.sack_items, '%*', '') s.sack_items = (''):format(s.sack_items) if count > 4 then s.sack_items = string.wrapHtml(s.sack_items,'div',{						class = 'mw-collapsible mw-collapsed'					}) end end -- Block Details group --B0 s.location = argI('location') and (''):format(argI('location')) --B1 s.tool = argI('tool') and (''):format(argI('tool')) --B2 s.breaking_power_required = argI('breaking_power_required') --B3 s.skill_xp_given = argI('skill_xp_given') and (''):format(argI('skill_xp_given')) --B4 -- Block Drops s.experience_given = argI('experience_given') --B5 s.normal_drop = argI('normal_drop') --B6 s.silk_touch_drop = argI('silk_touch_drop') --B7 s.smelting_touch_drop = argI('smelting_touch_drop') -- Function group --C0 s['function']= argI('function') -- Stats group if isArmorSet then --D0 s.stats = argI('stats') --D1+ for _,v in pairs(allstats) do					local ln, sh = v[1], v[2] s[ln] = processStat(ln,sh) end table.each( {'helmet_','chest_','legs_','boots_'}, function(a)					--D0(-H/-C/-L/-B)s[a..'stats'] = argI(a..'stats')					table.each( table.values(allstats), function (v) local b = v[2] -- stat short name --D1+(-H/-C/-L/-B)s[a..b] = argI(a..b)					end)				end) else --D0 s.stats = argI('stats') --D1+ table.each(table.values(allstats), function(v)					local ln = v[1]					s[ln] = argI(ln)				end) end -- Special Effects --E0 s.effects = argI('effects') or argI('effect') or argI('special_effect') or argI('additional_effects') --E1 s.duration = argI('duration') --E2 s.speed_boost = argI('speed_boost') -- used by minion fuel --E3 s.full_set_bonus = argI('full_set_bonus') --E4 s.piece_bonus = argI('piece_bonus') --E5 s.full_set_bonus2 = argI('full_set_bonus2') --E6 s.piece_bonus2 = argI('piece_bonus2') -- Abilities (up to 4) for k = 1, 4, 1 do				local counter = k > 1 and k or '' local function arg(name) return args[name..counter.._i] end --F0 s['ability_name'..counter] = arg('ability_name') or arg('ability') or arg('ia_name') or arg('abilityname') s['ability_desc'..counter] = arg('ability_desc') or arg('item_ability') or arg('ia_desc') or arg('abilitydesc') s['ability_activation'..counter] = arg('ability_activation') or arg('ia_activation') if s['ability_name'..counter] or s['ability_desc'..counter] then local abnmdc = {} -- ability_name_desc abnmdc[#abnmdc+1] = '\'\'\'' if s['ability_name'..counter] then abnmdc[#abnmdc+1] = ability.ability{ s['ability_name'..counter] } else abnmdc[#abnmdc+1] = colorText('Gray', '\'\'\'\'') end if s['ability_activation'..counter] then abnmdc[#abnmdc+1] = ' '..colorText('Yellow', s['ability_activation'..counter]:upper) end abnmdc[#abnmdc+1] = '\'\'\'' abnmdc[#abnmdc+1] = ' '					abnmdc[#abnmdc+1] = s['ability_desc'..counter] or '\'\'description missing\'\'' -- Combine final product s['ability_name_desc'..counter] = table.concat(abnmdc) end --F1 s['soulflow_cost'..counter] = arg('soulflow cost') or arg('soulflow.cost') or arg('soulflow') or arg('sfcost') or arg('ia_soulflow') --F2 s['mana_cost'..counter] = arg('mana_cost') or arg('mana.cost') or arg('mana') or arg('manacost') or arg('ia_mana_cost') --F3 s['cooldown'..counter] = arg('cooldown') or arg('ia_cooldown') --F4 s['int_scaling'..counter] = arg('int_scaling') end -- Material Tiers group --G0 s.prev_material = argI('prev_material') and list.imageList{ argI('prev_material') } or (argI('next_material') and 'None (lowest tier material)') --G1 s.next_material = argI('next_material') and list.imageList{ argI('next_material') } or (argI('prev_material') and 'None (top tier material)') -- Upgrades group --H0 s.upgrades_from = argI('upgrades_from') and itemDisplay(argI('upgrades_from')) or (argI('upgrades_to') and 'None (lowest tier item)') --H1 s.upgrades_to = argI('upgrades_to') and itemDisplay(argI('upgrades_to')) or (argI('upgrades_from') and 'None (top tier item)') -- Tiers group --I0 s.lower_tier = argI('lower_tier') and itemDisplay(argI('lower_tier')) or (argI('higher_tier') and 'None (lowest tier item)') --I1 s.higher_tier = argI('higher_tier') and itemDisplay(argI('higher_tier')) or (argI('lower_tier') and 'None (top tier item)') -- Gemstone Upgrades --R0 s.gemstone_slots = argI('gemstone_upgrades') or argI('gemstone_slots') if s.gemstone_slots then s.gemstone_slots = list.gemstoneSlots{ s.gemstone_slots }..(onmain and  or ) end --R1 s.gemstone_slots_fragged = argI('gemstone_slots_fragged') and list.gemstoneSlots{ argI('gemstone_slots_fragged') } -- Reforge Requirements --J0 s.req_item_rarity = argI('req_item_rarity') --J1 s.apply_cost = argI('apply_cost') --J2 s.req_skill_level = argI('req_skill_level') and '' -- Properties group --K0 s.upgradeable = yesnoIcon(argI('upgradeable')) --K1 s.enchantable = yesnoIcon(argI('enchant') or argI('enchantable')) --K2 s.reforgeable = yesnoIcon((not isReforgeStone and argI('reforge')) or argI('reforgeable')) --K3 s.salable = yesnoIcon(argI('salable') or argI('sellable') or not (isPet or isSack)) --K4 s.tradeable = yesnoIcon(argI('tradeable') or argI('trade') or (not isSack and true or false)) --K5 s.auctionable = yesnoIcon(argI('auctionable') or (not isSack and true or false)) --K6 if isPet then s.rideable = yesnoIcon(argI('rideable') or false) elseif isReforgeStone then s.salable = yesnoIcon(argI('salable') or true) end -- Property value (Group K) checks if isPet then if (argI('rideable') or ''):sub(1,1):lower == 'u' then propertiesExistForAllTabs = false end end for _,v in ipairs{'upgradeable', {'enchant', 'enchantable'}, {'reforge', 'reforgeable'}, {'salable', 'sellable'}, {'tradeable', 'trade'}, 'auctionable'} do				local okay = true for _,a in ipairs(type(v) == 'table' and v or {v}) do if (argI(a) or ''):sub(1,1):lower == 'u' then okay = false end end if not okay then propertiesExistForAllTabs = false end end -- Color Group --L0 s.color = argI('color') and ():format(				argI('color'),				( not isArmorSet or yesno(argI('all_colors_the_same')) )					and '|all = true' or 			) -- Shop --M0 s.merchant = argI('merchant') and list.npcList{ argI('merchant'), noErr=true, liststyle='text-align:center;' } --M1 s.daily_limit = argI('daily_limit') --M2 s.buy = argI('buy') and currency{ argI('buy') } --M3 s.sell = argI('sell') and currency{ argI('sell') } --M4-21 if isPet then for _,v in ipairs(rarityList) do					s['buy'..v[1]] = argI('buy'..v[1]) s['sell'..v[1]] = argI('sell'..v[1]) and ('US$%s'):format(argI('sell'..v[1])) end end -- Bazaar --N0 s.bazaar = argI('bazaar') -- Materials --O0 s.raw_materials = argI('raw_materials') and list.resourceList{ image=1, argI('raw_materials') } --O1 s.material_cost = argI('material_cost') and coins{ argI('material_cost') } --O2 s.mat_cost_bazaar = argI('mat_cost_bazaar') and ():format(				argI('mat_cost_bazaar') or argI('raw_materials'),				argI('bazaar_not_including') and '|not_including='..argI('bazaar_not_including') or 				):gsub('\n', '') --O3 s.raw_materials_upgr = argI('raw_materials_upgr') and list.resourceList{ image=1, argI('raw_materials_upgr') } --O4 s.material_cost_upgr = argI('material_cost_upgr') and coins{ argI('material_cost_upgr') } --O5 s.mat_cost_bazaar_upgr = argI('mat_cost_bazaar_upgr') and ():format(				argI('mat_cost_bazaar_upgr') or argI('raw_materials_upgr'),				argI('bazaar_not_including_upgr') and '|not_including='..argI('bazaar_not_including_upgr') or 				):gsub('\n', '') -- Trade --P0 s.trade_requirement = argI('trade_requirement') or argI('trade.requirement') if s.trade_requirement then s.trade_requirement = link._collectionLink(s.trade_requirement, nil, true) end --P1 s.trade_from = argI('trade_from') or argI('trade.from') --P2 s.trade_to = argI('trade_to') or argI('trade.to') -- Item Metadata s.id = argI('item_id') or (isPet and pet.inquirerarities(argI('tab') or title) or nil) for _,v in ipairs{ --Q0 'id', --Q1 'head_id','helmet_id', --Q2 'chest_id', --Q3 'legs_id', --Q4 'boots_id' } do				s[v] = s[v] or argI(v) if s[v] then -- Always show ID in all caps s[v] = string.wrapTag(s[v]:upper, 'code') -- If array syntax, make a list s[v] = s[v]:gsub(' ', '') -- lazy trim for array; ids never naturally have spaces s[v] = table.concat(mw.text.split(s[v], ','), ' ') end end s.head_id = s.head_id or s.helmet_id --Q5 s.head_texture = argI('head_texture') or argI('head_tex') or argI('helmet_texture') or argI('helmet_tex') s.head_texture = s.head_texture and string.wrapTag(s.head_texture, 'code') for _,v in ipairs{ --Q6 'nbt', --Q7 'head_nbt','helmet_nbt', --Q8 'chest_nbt', --Q9 'legs_nbt', --Q10 'boots_nbt', } do				s[v] = argI(v) and argI(v):gsub('(   +)', ' %1') -- Since newlines are being deleted, can't be used; and since escape br tags, need to make own fake pre tag s[v] = s[v] and string.wrapHtml(s[v],'div',{					style = {						['background-color'] = 'rgba(0,0,0,0.35)',						border = '1px solid #9b8d8e',						overflow = 'auto',						['word-wrap'] = 'normal',						['white-space'] = 'pre',					}				}):gsub('} ', ' } ') end s.head_nbt = s.head_nbt or s.helmet_nbt -- Push section data into array sections[#sections+1] = s		end end -- Make infobox local ibox = infobox.create ibox:addTitle{ title } local panel = ibox:addPanel for i,sdata in ipairs(sections) do		local section = --0panel:addSection{ label = sdata.tab } --1|2		if sdata.image_gallery then section:addImage{ sdata.image_gallery, caption = { sdata.caption }, source='image'..(i==1 and '' or i) } else section:addData{ sdata.image } end section --3 :addData{ sdata.slot_item } --4 :addData{ sdata.aka, label = 'Also known as' } --5 :addData{ sdata.type, label = 'Type' } --6 :addData{ sdata.rarity, label = 'Rarity' } --7 :addData{ sdata.collection, label = string.makeLink('Collections', 'Collection') } --8 :addData{ sdata.combat_level_requirement, label = 'Combat Level Requirement' } --9 :addData{ sdata.slayer_level_requirement, label = 'Slayer Level Requirement' } --10 :addData{ sdata.dungeon_level_requirement, label = 'Dungeon Level Requirement' } --11 :addData{ sdata.dungeon_floor_clearing_requirement, label = 'Requires Dungeon Floor Cleared' } --12 :addData{ sdata.hotm_requirement, label = 'Heart of the Mountain Level Requirement' } --13 :addData{ sdata.other_level_requirement, label = 'Skill Level Requirement' } --14 :addData{ sdata.reforge_name, label = 'Reforge' } --15 :addData{ sdata.source, label = 'Source' } --16 :addData{ sdata.obtained, label = 'Obtained via' } --17 :addData{ sdata.drop_chance, label = 'Drop Chance' } --18 :addData{ sdata.uses, label = 'Uses' } --19 :addData{ sdata.minion_xp, label = string.makeTitle('Minion XP', 'The amount of xp a player receives when taking this material from a minion inventory.') } --20 :addData{ sdata.lore, label = 'Lore' } --21 :addData{ sdata.mob, label = 'Mob' } --22 :addData{ sdata.rarities, label = 'Rarities' } :addGroup{ header = 'Sack Stats' } --A0 :addData{ sdata.sack_capacity, label = 'Max Capacity' } --A1 :addData{ sdata.sack_items, label = 'Items' } :done :addGroup{ header = 'Block Details' } --B0 :addData{ sdata.location, label = 'Location' } --B1 :addData{ sdata.tool, label = string.makeLink('Tool') } --B2 :addData{ sdata.breaking_power_required, label = ' Required' } --B3 :addData{ sdata.skill_xp_given, label = 'Skill XP Given' } --B4 :addData{ sdata.experience_given, label = 'Experience Given' } :addGroup{ header = 'Block Drops', layout = 'horizontal', ['row-items']=3 } --B5 :addData{ sdata.normal_drop, label = 'Normal drop' } --B6 :addData{ sdata.silk_touch_drop, label = 'Silk Touch drop' } --B7 :addData{ sdata.smelting_touch_drop, label = 'Smelting Touch Drop' } :done :done :addGroup{ header = 'Function' } --C0 :addData{ sdata['function'] } :done do -- define first group local panel_, group_ if isArmorSet then panel_ = section:addPanel{ header = 'Stats', collapse = 'open' } group_ = panel_:addSection{ label = 'Total' }:addGroup{ name = 'infobox-stats-list' } else group_ = section:addGroup{ header = 'Stats', name = 'infobox-stats-list' } end -- process first group --D0 group_:addData{ sdata.stats } for _, v in pairs(allstats) do				local ln = v[1] --D1+group_:addData{ sdata[ln], label = makeStat(ln, nil, true) } end -- process all armor groups if isArmorSet then for _, v in ipairs{ {'Head', 'helmet_'}, {'Chest', 'chest_'}, {'Legs', 'legs_'}, {'Boots', 'boots_'}, } do					local lbl, pc = v[1], v[2] group_ = panel_:addSection{ label = lbl }:addGroup{ name = 'infobox-stats-list' } --D0 (-H/-C/-L/-B)group_:addData{ sdata[pc..'stats'] } for _, val in pairs(allstats) do						local ln, sh = val[1], val[2] --D1+(-H/-C/-L/-B)group_:addData{ sdata[pc..sh], label = makeStat(ln, nil, true) } end end end end section:addGroup{ header = 'Special Effects' } --E0 :addData{ sdata.effects } --E1 :addData{ sdata.duration, label = 'Duration' } --E2 :addData{ sdata.speed_boost, label = 'Speed Boost' } --E3 :addData{ sdata.full_set_bonus, label = ability.fullSetBonus } --E4 :addData{ sdata.piece_bonus, label = ability.pieceBonus } --E5 :addData{ sdata.full_set_bonus2, label = ability.fullSetBonus } --E6 :addData{ sdata.piece_bonus2, label = ability.pieceBonus } :done local ability_places = { '', 'Second', 'Third', 'Fourth' } for k = 1, 4, 1 do			local counter = k > 1 and k or '' section:addGroup{ header = ability_places[k]..' Ability', name='infobox-stats-list' } --F0 :addData{ sdata['ability_name_desc'..counter] } --F1 :addData{ sdata['soulflow_cost'..counter], label = makeStat('Soulflow Cost') } --F2 :addData{ sdata['mana_cost'..counter], label = makeStat('Manacost') } --F3 :addData{ sdata['cooldown'..counter], label = 'Cooldown' } --F4 :addData{ sdata['int_scaling'..counter], label = { '%s Scaling', makeStat('int', nil, true) } } :done end section:addGroup{ header = 'Material Tiers', layout = 'horizontal' } --G0 :addData{ sdata.prev_material, label = '← Previous' } --G1 :addData{ sdata.next_material, label = 'Next →' } :done :addGroup{ header = 'Upgrades', layout = 'horizontal' } --H0 :addData{ sdata.upgrades_from, label = '← Previous' } --H1 :addData{ sdata.upgrades_to, label = 'Next →' } :done :addGroup{ header = 'Tiers', layout = 'horizontal' } --I0 :addData{ sdata.lower_tier, label = '← Previous' } --I1 :addData{ sdata.higher_tier, label = 'Next →' } :done section:addGroup{ header = isArmorSet and string.makeTitle('Gemstone Slots', 'These are the gemtone slots available to each armor piece.') or 'Gemstone Slots' } --R0 :addData{ sdata.gemstone_slots } --R1 :addData{ sdata.gemstone_slots_fragged, label = 'Fragged Slots' } :done :addGroup{ header = 'Reforge Requirements', collapse='open' } --J0 :addData{ sdata.req_item_rarity, label = 'Req. Item Rarity' } --J1 :addData{ sdata.apply_cost, label = 'Apply Cost' } --J2 :addData{ sdata.req_skill_level, label = 'Req. Skill Level' } :done :addGroup{ header = 'Properties', layout = 'horizontal', ['row-items']=2 } --K0 :addData{ sdata.upgradeable, label = 'Upgradeable' } --K1 :addData{ sdata.enchantable, label = 'Enchantable' } --K2 :addData{ sdata.reforgeable, label = 'Reforgeable' } --K3 :addData{ sdata.salable, label = 'Salable' } --K4 :addData{ sdata.tradeable, label = 'Tradeable' } --K5 :addData{ sdata.auctionable, label = 'Auctionable' } --K6 :addData{ sdata.rideable, label = 'Rideable' } :done :addGroup --L0 :addData{ sdata.color, label = 'Color' } :done local shop_group = section :addGroup{ header = 'Shop', layout = 'horizontal', ['row-items']=2 } if isPet then local merchant_panel = shop_group --M0 :addData{ sdata.merchant, label = 'Merchant'..(sdata.merchant and sdata.merchant:find('%s*%*%s*') and 's' or '') } :addPanel{ ['row-items']=1 } for _, v in ipairs(rarityList) do				merchant_panel:addSection{ label = v[2] } --M4-21 :addData{ sdata['buy'..v[1]], label = 'Buy' } :addData{ sdata['sell'..v[1]], label = 'Sell' } end else shop_group:addGroup{ ['row-items']=1 } --M0 :addData{ sdata.merchant, label = 'Merchant'..(sdata.merchant and sdata.merchant:find('%s*%*%s*') and 's' or '') } :done --M1 :addData{ sdata.daily_limit, label = string.makeTitle('Daily Limit', 'A limit on how much items of this type a player can buy in one day.') } --M2 :addData{ sdata.buy, label = 'Buy' } --M3 :addData{ sdata.sell, label = 'Sell' } end addBazaarGroup(--N0 sdata.bazaar, section) section:addGroup{ header = 'Materials' } --O0 :addData{ sdata.raw_materials, label=string.makeTitle('Raw Materials', 'All materials in their most basic form needed to obtain the item.') } --O1 :addData{ sdata.material_cost, label=string.makeTitle('Material cost', 'Cost to buy all necessary materials from merchants.') } --O2 :addData{ sdata.mat_cost_bazaar, label=string.makeTitle('Bazaar Material cost', 'Cost to buy all necessary materials from the Bazaar.') } --O3 :addData{ sdata.raw_materials_upgr, label=string.makeTitle('Raw Materials to upgrade', 'All materials in their most basic form needed to obtain the item.') } --O4 :addData{ sdata.material_cost_upgr, label=string.makeTitle('Material cost to upgrade', 'Cost to buy all necessary materials from merchants.') } --O5 :addData{ sdata.mat_cost_bazaar_upgr, label=string.makeTitle('Bazaar Material cost to upgrade', 'Cost to buy all necessary materials from the Bazaar.') } :done :addGroup{ header = 'Trade', layout = 'horizontal' } --P0 :addData{ sdata.trade_requirement, label = 'Requires' } --P1 :addData{ sdata.trade_from, label = 'From' } --P2 :addData{ sdata.trade_to, label = 'To' } :done :addGroup{ header = 'Item Metadata', ['row-items']=1, collapse='closed' } --Q0 :addData{ sdata.id, label = 'Item ID' } --Q1 :addData{ sdata.head_id, label = 'Helmet Item ID' } --Q2 :addData{ sdata.chest_id, label = 'Chestplate Item ID' } --Q3 :addData{ sdata.legs_id, label = 'Leggings Item ID' } --Q4 :addData{ sdata.boots_id, label = 'Boots Item ID' } --Q5 :addData{ sdata.head_texture, label = 'Head Texture' } --Q6 :addData{ sdata.nbt, label = 'NBT Data' } --Q7 :addData{ sdata.head_nbt, label = 'Helmet NBT Data' } --Q8 :addData{ sdata.chest_nbt, label = 'Chestplate NBT Data' } --Q9 :addData{ sdata.legs_nbt, label = 'Leggings NBT Data' } --Q10 :addData{ sdata.boots_nbt, label = 'Boots NBT Data' } :done end return table.concat{ frame:getParent:preprocess(ibox:tostring), curTitle.namespace == 0 and category_to_add or '', curTitle.namespace == 0 and not idsExistForAllTabs and not idRequirementDisabled and  or , curTitle.namespace == 0 and not propertiesExistForAllTabs and  or , } end

--Finish Module/Exports return p