![]() |
VOOZH | about |
The module implements {{DropTable}}, {{DropLine}} and {{Drop sources}}.
locali18n={ imageSprite={ item='Invicon', mob='EntitySprite' }, headerThing={ item='Item', mob='Mob' }, headerWithoutLooting='Default', headerLooting1='Looting I', headerLooting2='Looting II', headerLooting3='Looting III', headerOverview='Quantity / Chance / Average', headerDropAmount='Amount', headerDistribution='Probability', headerAverage='Average', headerTotal={ item='Killed', mob='Drops' }, headerExpectation={ item='Expected Drops', mob='Expected Number of Kills' }, tabOverviewDecimal='Decimal', tabOverviewFraction='Fraction', tabDistribution='Distribution', tabCalculator='Expectation', titlejava="''[[Java Edition]]'':", titlebedrock="''[[Bedrock Edition]]'':", notePlayerOrPet='Only when killed by a [[player]] or a tamed [[wolf]].', notePlayerOnly='Only when killed by a [[player]].', noteBurnOrFireAspect='Only when on fire or killed with a weapon enchanted with [[Fire Aspect]].', noteBurnOnly='Only when on fire.', noteNotBurnOrFireAspect="Only when ''not'' on fire and ''not'' killed with a weapon enchanted with [[Fire Aspect]].", noteNotBurnOnly="Only when ''not'' on fire.", refgroup='FN',-- [[MediaWiki:Cite link label group-FN]] style='DropTable/styles.css',-- [[Template:DropTable/styles.css]] bucket='droptable',-- [[Bucket:droptable]] } ------------------ localFrac={} -- Defined types: -- * frac: { numerator = numerator, denominator = denominator }, used on Frac.*( ..., fraction, ... ) localfunctionGCD(x,y)-- get Greatest Common Divisor (GCD) -- Test -- gcd( 0, 0 ) = undef iftype(x)~='number'ortype(y)~='number'or(x==0andy==0)then returnnil end x=math.abs(x) y=math.abs(y) -- Improve precision localmultiplier=1 whilex%1~=0ory%1~=0do x=x*10 y=y*10 multiplier=multiplier*10 end localfunctioneuclidean(x,y) returny==0andxoreuclidean(y,x%y) end returneuclidean(x,y)/multiplier end localfunctionLCM(x,y)-- get Least Common Multiple (LCM) -- Test localGCD=GCD(x,y) ifnotGCDthen returnnil end returnx*y/GCD end -- Start of Frac: Fraction Library localfracMetatable={ __index=Frac, __add=function(fraction1,fraction2)returnFrac.add(fraction1,fraction2)end, __sub=function(fraction1,fraction2)returnFrac.sub(fraction1,fraction2)end, __mul=function(fraction1,fraction2)returnFrac.mul(fraction1,fraction2)end, __div=function(fraction1,fraction2)returnFrac.div(fraction1,fraction2)end, __pow=function(fraction,n)returnFrac.pow(fraction,n)end, __unm=function(fraction)returnFrac.neg(fraction)end, __eq=function(fraction1,fraction2)returnFrac.cmp(fraction1,fraction2)==0end, __lt=function(fraction1,fraction2)returnFrac.cmp(fraction1,fraction2)<0end, __le=function(fraction1,fraction2)returnFrac.cmp(fraction1,fraction2)<=0end, __tostring=function(fraction)returnFrac.display(fraction)end, } -- Tests functionFrac.isFrac(fraction)-- Check if it is a valid fraction returnnot(type(fraction)~='table'ornotfraction.numeratorornotfraction.denominatororfraction.denominator<=0orfraction.numerator%1~=0orfraction.denominator%1~=0) end -- Create a fraction directly functionFrac.new(numerator,denominator) iftype(numerator)~='number'ordenominatorand(type(denominator)~='number'ordenominator==0)then returnnil end localfraction=denominatorand(denominator<0and{numerator=-numerator,denominator=-denominator}or{numerator=numerator,denominator=denominator})orFrac.fromDec(numerator) ifFrac.isFrac(fraction)==falsethen returnnil end setmetatable(fraction,fracMetatable) returnfraction end functionFrac.fromDec(decimal)-- Convert decimal to fraction iftype(decimal)~='number'then returnnil end localnumerator=decimal localdenominator=1 while#tostring(numerator%1)~=1do numerator=numerator*10 denominator=denominator*10 end returnFrac.reduce(Frac.new(math.floor(numerator+0.5),denominator)) end functionFrac.toDec(fraction)-- Convert fraction to decimal ifFrac.isFrac(fraction)==falsethen returnnil end returnfraction.numerator/fraction.denominator end -- Basic calculations functionFrac.neg(fraction)-- Take the negative fraction ifFrac.isFrac(fraction)==falsethen returnnil end returnFrac.new(-fraction.numerator,fraction.denominator) end functionFrac.inv(fraction)-- Take the inversed fraction ifFrac.isFrac(fraction)==falsethen returnnil end iffraction.numerator==0then returnnil end return(fraction.numerator<0)andFrac.new(-fraction.denominator,-fraction.numerator)orFrac.new(fraction.denominator,fraction.numerator) end functionFrac.mul(fraction1,fraction2)-- Fractions multiplication fraction1=Frac.isFrac(fraction1)andfraction1orFrac.new(fraction1) fraction2=Frac.isFrac(fraction2)andfraction2orFrac.new(fraction2) ifFrac.isFrac(fraction1)==falseorFrac.isFrac(fraction2)==falsethen returnnil end returnFrac.new(fraction1.numerator*fraction2.numerator,fraction1.denominator*fraction2.denominator) end functionFrac.div(fraction1,fraction2)-- Fractions division fraction2=Frac.isFrac(fraction2)andfraction2orFrac.new(fraction2) returnFrac.mul(fraction1,Frac.inv(fraction2)) end functionFrac.pow(fraction,n)-- Fractions exponentiation ifFrac.isFrac(fraction)==falseorn%1~=0then returnnil end return(n<0)andFrac.new(fraction.denominator^(-n),fraction.numerator^(-n))orFrac.new(fraction.numerator^n,fraction.denominator^n) end -- Advanced calculation functionFrac.expand(fraction,newDenominator)-- Fractions expansion ifFrac.isFrac(fraction)==falseortype(newDenominator)~='number'or(type(newDenominator)=='number'andnewDenominator%1~=0)ornewDenominator<=0then returnnil end localnewNumerator=fraction.numerator*newDenominator/fraction.denominator ifnewNumerator%1~=0then returnnil end returnFrac.new(newNumerator,newDenominator) end functionFrac.reduce(fraction)-- Fractions reduction (to simplest) ifFrac.isFrac(fraction)==falsethen returnnil end returnFrac.expand(fraction,fraction.denominator/GCD(fraction.denominator,fraction.numerator)) end functionFrac.common(fractionList)-- Get fractions with the common denominator iftype(fractionList)~='table'then returnnil end localcandidates={} localdenominators={} for_,fractioninpairs(fractionList)do ifFrac.isFrac(fraction)==falsethen returnnil else table.insert(candidates,fraction) table.insert(denominators,fraction.denominator) end end if#candidates==1then returncandidates end locallcm=1 for_,denominatorinpairs(denominators)do lcm=LCM(denominator,lcm) end localresults={} for_,fractioninpairs(candidates)do table.insert(results,Frac.expand(fraction,lcm)) end returnresults end -- Basic calculations, with dependencies functionFrac.add(fraction1,fraction2)-- Fractions addition fraction1=Frac.isFrac(fraction1)andfraction1orFrac.new(fraction1) fraction2=Frac.isFrac(fraction2)andfraction2orFrac.new(fraction2) ifFrac.isFrac(fraction1)==falseorFrac.isFrac(fraction2)==falsethen returnnil end localfractions=Frac.common{fraction1,fraction2} returnFrac.new(fractions[1].numerator+fractions[2].numerator,fractions[1].denominator) end functionFrac.sub(fraction1,fraction2)-- Fractions subtraction fraction2=Frac.isFrac(fraction2)andfraction2orFrac.new(fraction2) returnFrac.add(fraction1,Frac.neg(fraction2)) end functionFrac.cmp(fraction1,fraction2)-- Compare fractions returnFrac.sub(fraction1,fraction2).numerator end -- Formattings to human readable functionFrac.display(fraction,isReduced,isMixed)-- Convert fractions to human-readable style ifFrac.isFrac(fraction)==falsethen return'' end iffraction.numerator==0then return'0' end localprefix='' iffraction.numerator<0then prefix=prefix..'-' fraction=Frac.neg(fraction) end ifisReducedthen fraction=Frac.reduce(fraction) end localnumerator=fraction.numerator localdenominator=fraction.denominator ifdenominator==1then returnprefix..tostring(numerator) end ifnumerator==denominatorthen returnprefix..'1' end ifisMixedandnumerator>denominatorthen prefix=prefix..math.floor(numerator/denominator) numerator=numerator%denominator ifnumerator==0then returnprefix end end returnstring.format('%s<sup>%s</sup>⁄<sub>%s</sub>',prefix,numerator,denominator) end ------------------ localDistr={} Distr.mt={} functionDistr.mt.__index(t,k) iftype(k)=='number'thenreturnFrac.new(0)end returnDistr[k] end functionDistr.mt.__newindex(t,k,v) v=Frac.isFrac(v)andvorFrac.new(v) iftype(k)~='number'orv==nilthenerror()end ifv==Frac.new(0)thenreturnend returnrawset(t,k,v) end functionDistr.new(t) t=tor{} localdistribution={} setmetatable(distribution,Distr.mt) fork,vinpairs(t)do distribution[k]=v end returndistribution end functionDistr.shift(distribution,s) localnewDistribution=Distr.new() fori,vinpairs(distribution)do newDistribution[i+s]=v end returnnewDistribution end functionDistr.limitRange(distribution,min,max) localnewDistribution=Distr.new() fori,vinpairs(distribution)do ifmaxandi>=maxthen newDistribution[max]=newDistribution[max]+v elseifminandi<=minthen newDistribution[min]=newDistribution[min]+v else newDistribution[i]=v end end returnnewDistribution end functionDistr.add(distribution1,distribution2) localnewDistribution=distribution1:new() fori,vinpairs(distribution2)do newDistribution[i]=newDistribution[i]+v end returnnewDistribution end functionDistr.multiply(distribution,x) localnewDistribution=Distr.new() fori,vinpairs(distribution)do newDistribution[i]=v*x end returnnewDistribution end functionDistr.expectation(distribution) localexpectation=Frac.new(0) fori,vinpairs(distribution)do expectation=expectation+v*i end returnexpectation end functionDistr.times(distribution,n) localnewDistribution=Distr.new({[0]=1}) fori=1,ndo newDistribution=newDistribution:addIncrease(distribution) end returnnewDistribution end functionDistr.addIncrease(distribution1,distribution2) localnewDistribution=Distr.new() fori,vinpairs(distribution2)do newDistribution=newDistribution:add(distribution1:shift(i):multiply(v)) end returnnewDistribution end functionDistr.rolls(distribution1,distribution2) localnewDistribution=Distr.new() fori,vinpairs(distribution2)do newDistribution=newDistribution:add(distribution1:times(i):multiply(v)) end returnnewDistribution end functionDistr.getUniform(min,max) localvalue=Frac.new(1,max-min+1) localdistribution=Distr.new() fori=min,maxdo distribution[i]=value end returndistribution end functionDistr.getLootingIncrease(level,min,max) min=minor0 max=maxormin+1 min=min*level max=max*level ifmax-min<2then returnDistr.getUniform(min,max) end localdistribution=Distr.new() localvalue=Frac.new(1,max-min) fori=min,maxdo distribution[i]=value end distribution[min]=value/2 distribution[max]=value/2 returndistribution end functionDistr.addLootingIncrease(distribution1,distribution2,edition) localbase=distribution1:limitRange(0,nil) localbackup=base[0] ifedition=='bedrock'then base[0]=0-- MCPE-35307: Looting doesn't work when the mob drops nothing end localnewDistribution=base:addIncrease(distribution2) ifedition=='bedrock'then newDistribution[0]=newDistribution[0]+backup end returnnewDistribution end ------------------ localp={} localfunctioncalculateDistributions(args,edition) localfunctionparseRange(str) localn=tonumber(str) ifnthenreturn{min=n,max=n}end localmin,max=str:match('^%s*(%-?%d+)%s*%-%s*(%-?%d+)%s*$') min=tonumber(min) max=tonumber(max) ifminandmaxandmin<=maxthenreturn{min=min,max=max}end error(string.format("'%s' isn't a range!",str)) end localfunctionparseProbability(str) localn=Frac.fromDec(tonumber(str))orFrac.div(tonumber(str:match('(.*)%%%s*$')),100) ifnthenreturnnend localnumerator,denominator=str:match('^%s*(%-?%d+)%s*/%s*(%-?%d+)%s*$') numerator=tonumber(numerator) denominator=tonumber(denominator) localfrac=Frac.new(numerator,denominator) iffracthenreturnfracend error(string.format("'%s' isn't a probability!",str)) end localquantity=parseRange(args.quantityor1) locallootingquantity=parseRange(args.lootingquantityor0) localdropchance=parseProbability(args.dropchanceor1) locallootingchance=parseProbability(args.lootingchanceor0) localmultiplychance=parseProbability(args.multiplychanceor1) localrolls=parseRange(args.rollsor1) locallimit=tonumber(args.limit) ifedition=='bedrock'then limit=nil end localindependent={} for_,subinipairs(args.independentor{})do table.insert(independent,calculateDistributions(sub,edition)) end localmutuallyexclusive={} for_,subinipairs(args.mutuallyexclusiveor{})do table.insert(mutuallyexclusive,calculateDistributions(sub,edition)) end localdistributions={} forlevel=0,3do locallootingIncrease=Distr.getLootingIncrease(level,lootingquantity.min,lootingquantity.max) localchance=(dropchance+lootingchance*level)*multiplychance localdistribution=Distr.getUniform(quantity.min,quantity.max) :addLootingIncrease(lootingIncrease,edition) :rolls(Distr.new{[0]=1-chance,[1]=chance}) :limitRange(0,limit) :rolls(Distr.getUniform(rolls.min,rolls.max)) for_,subinipairs(independent)do distribution=distribution:addIncrease(sub[level]) end for_,subinipairs(mutuallyexclusive)do localnodropchance1=distribution[0] localnodropchance2=sub[level][0] distribution=distribution:add(sub[level]) distribution[0]=nodropchance1+nodropchance2-Frac.new(1) end distributions[level]=distribution end returndistributions end localfunctiongetImageAndLink(args,mode) locallink=args.linkorargs.name localimage=require([[Module:SpriteFile]]).sprite{ args.imageorargs.name, name=args.spritetypeori18n.imageSprite[mode], link=link, size=32, align='middle', keepcase=mode=='item' } localdisplayname=args.displaynameorargs.name locallinktext=string.format('[[%s|%s]]',link,displayname) returnimage,linktext end localfunctiongetDropData(args,edition) localdata={} forlevel,distributioninpairs(calculateDistributions(args,edition))do localquantity={} fork,vinpairs(distribution)do ifv~=Frac.new(0)thentable.insert(quantity,k)end end table.sort(quantity) localmin=quantity[1] localmax=quantity[#quantity] localfrom=min localto localquantitytext='' localfunctionrange() quantitytext=quantitytext..(from==minand''or' / ') ..(from==toandtoor(from..'–'..to)) end for_,numinipairs(quantity)do iftoandto~=num-1then range() from=num end to=num end range() data[level]={ distribution=distribution, average=distribution:expectation():reduce(), dropchance=(1-distribution[0]):reduce(), min=min, max=max, quantitytext=quantitytext } end returndata end localfunctionlinesToDatas(lines,notes,edition) localdatas={} for_,lineinipairs(lines)do localargs=mw.text.jsonDecode(line) localdata={name=args.name} data.image,data.linktext=getImageAndLink(args,'item') ifedition~='bedrock'andargs.edition~='bedrock'then data.java=getDropData(args,'java') end ifedition~='java'andargs.edition~='java'then data.bedrock=getDropData(args,'bedrock') end localnotenames=args.notesandmw.text.split(args.notes,',')or{} data.notes={} for_,nameinipairs(notenames)do table.insert(data.notes,notes[name]) end table.insert(datas,data) end returndatas end localfunctioncreateOverviewTable(format,datas,noteTexts,mode,edition) localwikitable=mw.html.create('table'):addClass('wikitable') :tag('tr') :tag('th'):attr('colspan','2'):attr('rowspan','2'):wikitext(i18n.headerThing[mode]):done() :tag('th'):attr('colspan','12'):wikitext(i18n.headerOverview):done() :done() :tag('tr') :tag('th'):attr('colspan','3'):wikitext(i18n.headerWithoutLooting):done() :tag('th'):attr('colspan','3'):wikitext(i18n.headerLooting1):done() :tag('th'):attr('colspan','3'):wikitext(i18n.headerLooting2):done() :tag('th'):attr('colspan','3'):wikitext(i18n.headerLooting3):done() :done() fori,datainipairs(datas)do ifdata[edition]then localrow=mw.html.create('tr') :tag('td'):wikitext(data.image):done() :tag('td'):wikitext(data.linktext..noteTexts[i]):done() forlevel=0,3do localinfo=data[edition][level] row:tag('td'):css('text-wrap-mode','nowrap'):wikitext(info.quantitytext):done() ifformat=='decimal'then row:tag('td'):wikitext(string.format('%.2f%%',Frac.toDec(info.dropchance)*100)):done() row:tag('td'):wikitext(string.format('%.2f',Frac.toDec(info.average))):done() else row:tag('td'):wikitext(Frac.display(info.dropchance)):done() row:tag('td'):wikitext(Frac.display(info.average)):done() end end wikitable:node(row) end end returntostring(wikitable) end localfunctioncreateDistributionsTable(datas,noteTexts,mode,edition) localwikitable=mw.html.create('table'):addClass('wikitable') :tag('tr') :tag('th'):attr('colspan','2'):attr('rowspan','2'):wikitext(i18n.headerThing[mode]):done() :tag('th'):attr('rowspan','2'):wikitext(i18n.headerDropAmount):done() :tag('th'):attr('colspan','4'):wikitext(i18n.headerDistribution):done() :done() :tag('tr') :tag('th'):wikitext(i18n.headerWithoutLooting):done() :tag('th'):wikitext(i18n.headerLooting1):done() :tag('th'):wikitext(i18n.headerLooting2):done() :tag('th'):wikitext(i18n.headerLooting3):done() :done() fori,datainipairs(datas)do ifdata[edition]then localmin=math.huge localmax=-math.huge forlevel=0,3do min=math.min(min,data[edition][level].min) max=math.max(max,data[edition][level].max) end localrow=mw.html.create('tr') :tag('td'):attr('rowspan',max-min+2):wikitext(data.image):done() :tag('td'):attr('rowspan',max-min+2):wikitext(data.linktext..noteTexts[i]):done() fordrops=min,maxdo row:tag('td'):wikitext(tostring(drops)):done() forlevel=0,3do localprobability=data[edition][level].distribution[drops]orFrac.new(0) row:tag('td'):wikitext( probability==Frac.new(0)and'0'or string.format('%s (%.2f%%)',Frac.display(probability,true),Frac.toDec(probability)*100) ):done() end wikitable:node(row) row=mw.html.create('tr') end row:tag('th'):wikitext(i18n.headerAverage):done() forlevel=0,3do localaverage=data[edition][level].average row:tag('th'):wikitext(string.format('%s (%.2f)',Frac.display(average),Frac.toDec(average))):done() end wikitable:node(row) end end returntostring(wikitable) end localfunctioncreateCalculatorTable(datas,noteTexts,mode,edition) localwikitable=mw.html.create('table'):addClass('wikitable'):addClass('calculator-container') :tag('tr') :tag('th') :attr('colspan','2') :wikitext(mw.getCurrentFrame():expandTemplate{title='Simplecalc label',args={ label=i18n.headerTotal[mode], ['for']='count' }}) :done() :tag('td') :attr('colspan','4') :wikitext(mw.getCurrentFrame():expandTemplate{title='simplecalc',args={ type='number', id='count', min=0, step=1, default=1 }}) :done() :done() :tag('tr') :tag('th'):attr('colspan','2'):attr('rowspan','2'):wikitext(i18n.headerThing[mode]):done() :tag('th'):attr('colspan','4'):wikitext(i18n.headerExpectation[mode]):done() :done() :tag('tr') :tag('th'):wikitext(i18n.headerWithoutLooting):done() :tag('th'):wikitext(i18n.headerLooting1):done() :tag('th'):wikitext(i18n.headerLooting2):done() :tag('th'):wikitext(i18n.headerLooting3):done() :done() fori,datainipairs(datas)do ifdata[edition]then localrow=mw.html.create('tr') :tag('td'):wikitext(data.image):done() :tag('td'):wikitext(data.linktext..noteTexts[i]):done() forlevel=0,3do localaverage=data[edition][level].average ifmode=='mob'then average=Frac.inv(average) end row:tag('td') :wikitext(mw.getCurrentFrame():expandTemplate{title='simplecalc',args={ type='plain', formula=string.format('count*(%s/%s)',average.numerator,average.denominator), decimals=2, default=string.format('%.2f',Frac.toDec(average)) }}) :done() end wikitable:node(row) end end returntostring(wikitable) end localfunctioncreateTabs(datas,mode,edition) localf=mw.getCurrentFrame() localnoteTexts={} fori,datainpairs(datas)do localnoteText='' ifdata[edition]then for_,noteinipairs(data.notes)do localref=note.nameandnoteornote[edition] ifrefthen noteText=noteText..f:extensionTag{ name='ref', content=ref.content, args={name=ref.name,group=i18n.refgroup} } end end end noteTexts[i]=noteText end localtabber=f:extensionTag('tabber',string.format( '%s=%s|-|%s=%s|-|%s=%s|-|%s=%s', i18n.tabOverviewDecimal, createOverviewTable('decimal',datas,noteTexts,mode,edition), i18n.tabOverviewFraction, createOverviewTable('fraction',datas,noteTexts,mode,edition), i18n.tabDistribution, createDistributionsTable(datas,noteTexts,mode,edition), i18n.tabCalculator, createCalculatorTable(datas,noteTexts,mode,edition) )) returnrequire('Module:TSLoader').call(i18n.style) ..tostring(mw.html.create('div'):addClass('droptable-tabber'):wikitext(tabber)) ..tostring(mw.html.create('div'):addClass('droptable-references'):wikitext(f:extensionTag{ name='references', args={group=i18n.refgroup} })) end localfunctionsetBucketData(datas,args) args.name=args.nameormw.title.getCurrentTitle().text localimage,link=getImageAndLink(args,'mob') for_,datainipairs(datas)do localjsonData=mw.text.jsonEncode({ name=args.name, image=image, linktext=link, java=data.java, bedrock=data.bedrock, notes=data.notes },mw.text.JSON_PRESERVE_KEYS) localbucketObject={ item=data.name, json=jsonData } bucket(i18n.bucket).put(bucketObject) end end localfunctiongetBucketData(args) localname=args.nameorargs[1]ormw.title.getCurrentTitle().text localdata=bucket(i18n.bucket) .select('json') .where('item',name) .run() localjsons={} for_,objectinipairs(data)do localjsondata=object['json'] table.insert(jsons,mw.text.jsonDecode(jsondata,mw.text.JSON_PRESERVE_KEYS)) end returnjsons end localfunctionparseNotes(defines) localnotes={ burn_only={name='burn_only',content=i18n.noteBurnOnly}, burn_or_fire_aspect={name='burn_or_fire_aspect',content=i18n.noteBurnOrFireAspect}, not_burn_only={name='not_burn_only',content=i18n.noteNotBurnOnly}, not_burn_or_fire_aspect={name='not_burn_or_fire_aspect',content=i18n.noteNotBurnOrFireAspect}, player_only={name='player_only',content=i18n.notePlayerOnly}, player_or_pet={name='player_or_pet',content=i18n.notePlayerOrPet} } notes.player={java=notes.player_or_pet,bedrock=notes.player_only} notes.burn={java=notes.burn_or_fire_aspect,bedrock=notes.burn_only} notes.not_burn={java=notes.not_burn_or_fire_aspect,bedrock=notes.not_burn_only} for_,strinipairs(definesandmw.text.split(defines,'\n')or{})do localkey,text=str:match('^%s*([^=]-)%s*=%s*(.-)%s*$') ifkeyandtextthen localname,edition=key:match('^(.-)%.(.*)$') ifeditionthen notes[name]=notes[name]or{} localredirect=text:match('^>%s*(.-)$') ifredirectandnotes[redirect].namethen notes[name][edition]=notes[redirect] else notes[name][edition]={name=name,content=text} end else notes[key]={name=key,content=text} end end end returnnotes end functionp.line(frame) localargs=require('Module:ProcessArgs').norm(frame:getParent().args) for_,nameinpairs({'independent','mutuallyexclusive'})do ifargs[name]then args[name]=mw.text.jsonDecode('['..args[name]..']') end end returnmw.text.jsonEncode(args) end functionp.main(frame) returnp._main(frame:getParent().args) end functionp._main(args) localnotes=parseNotes(args.notes) localedition=args.editionandmw.text.trim(args.edition) localdatas=linesToDatas(args,notes,edition) ifnotargs.nosourceandmw.title.getCurrentTitle().isContentPagethen setBucketData(datas,args) end ifeditionthen returncreateTabs(datas,'item',edition) end returni18n.titlejava..createTabs(datas,'item','java') ..i18n.titlebedrock..createTabs(datas,'item','bedrock') end functionp.source(frame) returnp._source(frame:getParent().args) end functionp._source(args) localdatas=getBucketData(args) localedition=args.editionandmw.text.trim(args.edition) ifeditionthen returncreateTabs(datas,'mob',edition) end returni18n.titlejava..createTabs(datas,'mob','java') ..i18n.titlebedrock..createTabs(datas,'mob','bedrock') end returnp