Module:Biota infobox/core
Documentation for this module may be created at Module:Biota infobox/core/doc
require('Module:No globals')
local p = {}
local templateArgs = {}
local info = {}
local paramData = require( 'Module:Biota infobox/data' ) -- contains the taxon ranks in order
local autotaxa = require("Module:Autotaxobox")
local parameters = require( 'Module:Biota infobox/param' )
--[[ ##################### CORE FUNCTIONS ###################################
this core function emulates Template:Taxobox/core
it is followed by functions handling the different type of entry
]]
p.main = function(frame)
-- this function emulates Template:Taxobox/core when called from taxobox feeder templates
-- i.e. Taxobox, Automatic taxobox, Speciesbox, etc
parameters.getArgs(frame)
templateArgs['image_upright'] = templateArgs['upright'] or 1
templateArgs['image2_upright'] = templateArgs['upright2'] or 1
info.headerColor = templateArgs['colour']
return p._core
--TODO check it works
end
-- this is the core function, called either from main() or auto()
p.core = function(frame, args, localinfo)
templateArgs = args
info = localinfo
return p._core(frame)
end
p._core = function(frame)
-- TODO use mw.title.getCurrentTitle().basePageTitle
info.name = templateArgs['name'] or tostring( mw.title.getCurrentTitle() ) --.rootPageTitle )
info.headerColor = p.getTaxoboxColor(frame) -- so only transverse taxobox heirarchy once
--[[ create table (two versions)
1. use mwhtml library to build table in taxoboxTable
2. use wikitest to build table in wikitextTable
]]
local taxoboxTable = mw.html.create('table'):addClass('infobox'):addClass('biota')
:addClass('biota-infobox')
local wikitextTable = '\n{| class="infobox biota biota-infobox" '
info.subheader = ''
if templateArgs['subheader'] and templateArgs['subheader'] ~= '' then
info.subheader='<div style="font-weight:normal;font-size:smaller;">'..templateArgs['subheader']..'</div>'
end
--TODO do we need additional handling to check {{geological range}} templete
-- or handle oldest_fossil and youngest_fossil (these don't seem to be used now)
-- Note: taxobox/core uses temporal_range
local temporalRange = ''
if templateArgs['temporal_range'] then
temporalRange = '<div><small>Temporal range: ' .. templateArgs['temporal_range'] .. '</small></div>' -- use <div> rather than <br/>
end
local rowHeader = taxoboxTable:tag('tr'):tag('th'):attr('colspan', '2'):addClass('section-header')
:cssText('background:' .. info.headerColor .. ';')
:wikitext(info.name .. info.subheader .. temporalRange)
wikitextTable = wikitextTable .. '\n|-\n! colspan="2" class="section-header" style="background:' .. info.headerColor .. ';" '
.. '|' .. info.name .. info.subheader .. temporalRange
-- add images
wikitextTable = wikitextTable .. p.addImageSection(frame, taxoboxTable, 'image')
.. p.addImageSection(frame, taxoboxTable, 'image2')
--add conservation status
wikitextTable = wikitextTable .. p.addStatusSection(frame, taxoboxTable, 'status')
.. p.addStatusSection(frame, taxoboxTable, 'status2')
-- add taxonomy table (uses entered parameters or automatic taxonomy system)
wikitextTable = wikitextTable .. p.addTaxonomySection(frame, taxoboxTable)
-- add sections with binomial, trinomial, type species/genus (with authorities)
wikitextTable = wikitextTable
.. p.addTaxonSection(frame, taxoboxTable, 'binomial', 'Bionomial name')
.. p.addTaxonSection(frame, taxoboxTable, 'trinomial', 'Trionomial name')
.. p.addTaxonSection(frame, taxoboxTable, 'type_genus', 'Type genus')
--TODO type_ichnogenus, type_oogenus
.. p.addTaxonSection(frame, taxoboxTable, 'type_species', 'Type species')
--TODO type_ichnospecies, type_oospecies
.. p.addTaxonSection(frame, taxoboxTable, 'type_strain', 'Type strain')
-- add sections showing subdivisions (i.e. child taxa)
wikitextTable = wikitextTable
.. p.addListSection(frame, taxoboxTable, 'subdivision', templateArgs['subdivision_ranks'] or 'Subdivisions')
.. p.addListSection(frame, taxoboxTable, 'possible_subdivision', templateArgs['possible_subdivision_ranks'] or 'Possible subdivisions')
-- diversity section (TODO consider how best to handle)
wikitextTable = wikitextTable .. p.addTaxonSection(frame, taxoboxTable, 'diversity', 'Diversity')
-- show included groups (accepts 'included' or 'includes') [used for paraphyletic taxa]
wikitextTable = wikitextTable .. p.addListSection(frame, taxoboxTable, 'includes', 'Groups included')
--p.addListSection(frame, taxoboxTable, 'included', 'Groups included') -- use alias
--add range map (should this be below binomial/trinomial?)
wikitextTable = wikitextTable .. p.addImageSection(frame, taxoboxTable, 'range_map')
-- show excluded groups (accepts 'excluded' or 'excludes') [used for paraphyletic taxa]
local excludedHeaderText = '[[Cladistics|Cladistically]] included but traditionally excluded taxa'
wikitextTable = wikitextTable .. p.addListSection(frame, taxoboxTable, 'excludes', excludedHeaderText)
-- add addition binomials, trinomial and range maps
wikitextTable = wikitextTable
.. p.addTaxonSection(frame, taxoboxTable, 'binomial2', 'Bionomial name (2)')
--p.addTaxonSection(frame, taxoboxTable, 'trinomial2', 'Trionomial name (2)')
.. p.addImageSection(frame, taxoboxTable, 'range_map2')
.. p.addTaxonSection(frame, taxoboxTable, 'binomial3', 'Bionomial name (3)')
--p.addTaxonSection(frame, taxoboxTable, 'trinomial3', 'Trionomial name (3)')
.. p.addImageSection(frame, taxoboxTable, 'range_map3')
.. p.addTaxonSection(frame, taxoboxTable, 'binomial4', 'Bionomial name (4)')
--p.addTaxonSection(frame, taxoboxTable, 'trinomial4', 'Trionomial name (4)')
.. p.addImageSection(frame, taxoboxTable, 'range_map4')
-- add synonyms section
wikitextTable = wikitextTable .. p.addListSection(frame, taxoboxTable, 'synonyms', '[[Synonym (taxonomy)|Synonyms]]')
-- add debug/tracking info section
if info.debug then
wikitextTable = wikitextTable ..p.addListSection(frame, taxoboxTable, 'debug', 'Debug/tracking info')
end
------------------add templateSyles and return taxobox table---------------------------
local src = "Template:Biota infobox/styles.css" -- TemplateStyles file
wikitextTable = wikitextTable .. '\n|}'
local output = wikitextTable -- output the wikitext table
--local output = tostring(taxoboxTable) -- output the mw.html table
return p.templateStyle( frame, src ) .. output .. info.parameterCategory
-- .. (info.parameterCategory or "")
end -- End the main function.
--[[ ====================================================================================
function to add conservation sections
uses template {{taxobox/species|{{{status_system|}}}|{{{status|}}}|{{{status_ref|}}}|extinct={{{extinct|}}} }} }}
--]]
function p.addStatusSection(frame, taxoboxTable, status)
-- must use table container to handle template output
-- don't use header or content cells; the 'taxobox/species' template handles it
-- just need to add background colour on the row
local wikiText = ""
if templateArgs[status] and templateArgs[status] ~= "" then
local status = frame:expandTemplate{ title = 'taxobox/species',
args = {templateArgs[status..'_system'] or '',
templateArgs[status] or '',
templateArgs[status..'_ref'] or '',
extinct=templateArgs['extinct'] or ''
}
}
local row = taxoboxTable:tag('tr')
--:cssText('background:' .. p.getTaxoboxColor(frame) .. ';')
local cell = row:tag('td'):attr('colspan', '2')
:wikitext('\n{|\n|- style="background:' .. info.headerColor .. ';"')
:wikitext('\n'..tostring(status))
:wikitext('\n|}')
wikiText = '\n|- colspan="2" style="background:' .. info.headerColor .. ';" '
.. '\n' ..tostring(status)
end
return wikiText
end
--[[ ==============================================================================
function to add sections for taxonomic information with authorities ('_authority' suffix)
e.g. binomial, trinomial, type_species, type_genus;
diversity also handled here
--]]
function p.addTaxonSection(frame, taxoboxTable, target, headerText)
local wikiText = ""
-- return if we don't have value
if not templateArgs[target] or templateArgs[target] == '' then return "" end
local bold = "" -- variable for bolding binomial and trinomial (type genus/species etc are not bolded)
local showHeader = true
-- custom processing section
--if target == 'binomial' or target == 'binomial2' or target == 'binomial3' or target == 'binomial4' then
if target == 'binomial' then
headerText = '[[Binomial nomenclature|' .. headerText .. ']]'
bold ="'''"
--elseif target == 'trinomial' or target == 'trinomial2' or target == 'trinomial3' or target == 'trinomial4' then
elseif target == 'trinomial' then
local trinomenLink = "Trinomen" -- for zoological or default
if info.auto == "infraspeciesbox" then trinomenLink = "Infraspecific name (botany)" end -- regnum contains plant/fung/Archaeplastida"
headerText = '[['.. trinomenLink .. '|' .. headerText .. ']]'
bold ="'''"
elseif target == 'binomial2' or target == 'binomial3' or target == 'binomial4'
or target == 'trinomial2' or target == 'trinomial3' or target == 'trinomial4' then
showHeader = false
bold ="'''"
else
--TODO is any handling needed for diversity etc
headerText = '[[' .. headerText .. ']]'
end
if templateArgs[target..'_ref'] then
headerText = headerText .. templateArgs[target..'_ref'] .. '\n'
end
local contentString = '' -- content for the content cell
if target == 'diversity' and templateArgs['diversity'] ~= "" then
if templateArgs[target..'_link'] and templateArgs[target..'_link'] ~= "" then
contentString = '\n[[' .. templateArgs[target..'_link'] .. '|' .. templateArgs[target] .. ']]\n'
else
contentString = '\n' .. templateArgs[target] .. '\n'
end
else
-- taxon name and authority (binomial, type species, etc)
local authorityString = ''
if templateArgs[target..'_authority'] then
authorityString = '<br/><small>' .. templateArgs[target..'_authority'] .. '</small>' -- \n'
end
contentString = bold .. templateArgs[target] .. bold .. authorityString .. '\n'
--contentString = '\n' .. bold .. templateArgs[target] .. bold .. authorityString .. '\n' -- extra <p> inserted
end
-- add table rows
if templateArgs[target] and templateArgs[target] ~= '' then
if showHeader then
local rowHeader = taxoboxTable:tag('tr')
rowHeader :tag('th')
:attr('colspan', '2')
:addClass('section-header')
:cssText('background:' .. info.headerColor .. ';')
:wikitext( headerText )
wikiText = wikiText .. '\n|- \n! colspan="2" class="section-header" style="background:' .. info.headerColor .. ';" '
.. '|' .. headerText
end
local rowList = taxoboxTable:tag('tr')
rowList :tag('td')
:attr('colspan', '2')
--:addClass('section-content')
:addClass('taxon-section')
--:cssText('text-align:center;') --font-weight:bold;')
:wikitext( contentString )
wikiText = wikiText .. '\n|- \n| colspan="2" class="taxon-section" |' .. contentString
end
return wikiText
end
--[[ ====================================================================================
function to produce sections for included taxa (subdivisions), synonyms, etc
- each consists of two rows containing a header and the content
- for paraphyletic groups it has include(d|s) and exclude(d|s) groups
- for general taxobox it has subdivision and possible subdivision (disabled here)
- any can be modified for other purposes (e.g. sisters) by changing the header taxt with a -text parameter
]]
function p.addListSection(frame, taxoboxTable, target, headerText)
if not templateArgs[target] or templateArgs[target] == "" then return "" end -- redundant for now
local wikiText = ""
local refString = ''
if templateArgs[target..'_ref'] then
--add '_ref' option for 'synonym_ref' (the rest get it as a bonus) TODO check example
refString = templateArgs[target..'_ref'] --.. '\n'
end
local listHeader = (templateArgs[target..'_text'] or headerText) .. refString
-- add table rows
if templateArgs[target] and templateArgs[target] ~= ''then
local rowHeader = taxoboxTable:tag('tr')
rowHeader :tag('th')
:attr('colspan', '2')
:addClass('section-header')
:cssText('background:' .. info.headerColor .. ';')
:wikitext(listHeader)
wikiText = wikiText .. '\n|- \n! colspan="2" class="section-header" style="background:' .. info.headerColor .. ';" '
.. '|' .. listHeader
local rowList = taxoboxTable:tag('tr')
rowList :tag('td')
:attr('colspan', '2')
:addClass('section-content')
:wikitext('\n' .. templateArgs[target] .. '\n' )
wikiText = wikiText .. '\n|- \n| colspan="2" class="section-content" '
.. '|' .. '\n' .. templateArgs[target] .. '\n'
end
return wikiText
end
-----------------------------------------------------------------------------------------------
--[[ ============================================================================
function to add image sections
- used for illustrative images at top and for range maps
--]]
function p.addImageSection(frame, taxoboxTable, target)
local wikiText = ""
if templateArgs[target] and templateArgs[target] ~= '' then
local imageWidth = ''
local imageCaptionString = ''
if templateArgs[target..'_caption'] then
--imageCaptionString = '<br /><small><div style="text-align:center">' .. templateArgs[target .. '_caption'] .. '</div></small>'
--imageCaptionString = '<br /><div>' .. templateArgs[target .. '_caption'] .. '</div>'
imageCaptionString = templateArgs[target .. '_caption']
end
local imageAltString = ''
if templateArgs[target..'_alt'] then
imageAltString = templateArgs[target..'_alt']
elseif templateArgs[target..'_caption'] then
imageAltString = templateArgs[target..'_caption'] -- use caption for alt text if none provided
end
local upright = templateArgs['image_upright'] or 1
local InfoboxImage = require( 'Module:InfoboxImage' ) --, parent.args[target] )
local params = { args = { image = templateArgs[target],
size = templateArgs[target..'_width'],
sizedefault = 'frameless',
alt = imageAltString,
upright = templateArgs[target..'_upright'] or upright
}
}
local image = InfoboxImage.InfoboxImage( params )
--local rowImage = taxoboxTable:tag('tr')
local rowImage = mw.html.create('tr')
rowImage:tag('td')
:attr('colspan', '2')
:addClass("image-section")
:wikitext(image)
--:wikitext(imageCaptionString)
taxoboxTable:node(rowImage)
wikiText= wikiText .. '\n|- \n|colspan="2" class="image-section" |' .. image
if imageCaptionString ~= "" then -- only insert row if caption string
local rowImageCaption = mw.html.create('tr')
rowImageCaption:tag('td')
:attr('colspan', '2')
:addClass("image-section")
--:wikitext(image)
:wikitext(imageCaptionString)
taxoboxTable:node(rowImageCaption)
wikiText = wikiText .. '\n|- \n|colspan="2" class="image-section" |' .. imageCaptionString
end
end
-- TODO handle upright
return wikiText
end
--[[ ============================ TAXONOMY SECTION =======================================
adds a table showing the taxonomy
- uses either manual parameters or the automatic taxonomy system
- currently adds a table inside a cell (like paraphyletic group) rather than just adding rows (core taxobox system)
--]]
function p.addTaxonomySection(frame, taxoboxTable)
local wikiText = ""
local taxonomyHeader = "[[Taxonomy_(biology)|Scientific classification]]"
if templateArgs['virus_group'] then
taxonomyHeader = "[[Virus classification]]"
elseif templateArgs['ichnos'] then
taxonomyHeader = "[[Trace fossil classification]]"
elseif templateArgs['veterovata'] then
taxonomyHeader = "[[Veterovata|Eggshell classification]]"
else
-- TODO add other options (DONE but not verified ichnos or veterovata)
-- ! colspan=2 style="min-width:15em; text-align: center{{#if:{{{colour|}}}|{{;}} background-color{{COLON}} {{{colour}}} }}" |
-- {{#if:{{{virus_group|{{{virus|}}}}}}|[[Virus classification]]
-- |{{#if:{{{ichnos|}}}|[[Trace fossil classification]]
-- |{{#if:{{{veterovata|}}}|[[Veterovata|Eggshell classification]]
-- |[[Taxonomy (biology)|Scientific classification]]}} }} }}
-- {{#if:{{{edit link|}}}|{{edit taxonomy|{{{parent|}}} | {{{edit link}}} }}
-- {{#if: {{{classification_status|}}} | <br>({{{classification_status}}}) | }} }}
-- handle |classification_status=disputed (add ref)
end
-- add symbol and link to taxonomy editor
local editLink = ''
if info.auto then
local tooltip = templateArgs['edit link'] or "Edit this classification"
editLink = '<span class="plainlinks" style="font-size:smaller; float:right; padding-right:0.4em; margin-left:-3em;">'
.. '[[File:Red Pencil Icon.png|link=Template:Taxonomy/' .. templateArgs['parent']
.. '|' .. tooltip .. ']]</span>'
end
local status = ""
if templateArgs['classification_status'] then
status = '<div style="font-weight:normal;" >(' .. templateArgs['classification_status'] .. ')'
if templateArgs['classification_ref'] then status = status .. templateArgs['classification_ref'] end
status = status .. '</div>'
end
local rowTaxonomyHeader = taxoboxTable:tag('tr')
rowTaxonomyHeader:tag('th')
:attr('colspan', '2')
:addClass('section-header')
:cssText('background:' .. info.headerColor .. ';')
:wikitext(taxonomyHeader)
:wikitext(editLink)
:wikitext(status)
wikiText = wikiText .. '\n|- \n! colspan="2" class="section-header" style="background:' .. info.headerColor .. ';" '
.. '|' .. taxonomyHeader .. editLink .. status
-- get taxonomy list, either using automatic taxobox system or manual system
if info.auto then
--[[ get automatic taxonomy hierarchy (three different variants)
1) direct call to taxoboxList() - preferred if issues with setting frame arguments can be resolved
2) experimental version of taxoboxList()
3) [ET] using Template:Ttaxobox/taxonomy
]]
wikiText = wikiText ..'\n|-|\n|' .. p.addAutomaticTaxonomy(frame, taxoboxTable) -- use #invoke of module
-- use manual taxobox for genus, subgenus,species, subspecies, variety
local taxonRanks = { 'subgenus', 'species', 'hybrid', 'subspecies', 'variety' }
wikiText = wikiText .. p.addManualTaxonomy(frame, taxoboxTable, taxonRanks)
else
wikiText = wikiText .. p.addManualTaxonomy(frame, taxoboxTable, paramData.taxonRanks) -- just add rows
end
return wikiText
end
-------------------------------------------------AUTOMATIC TAXONOMY (using invoke of module function) -----------
function p.addAutomaticTaxonomy(frame, taxoboxTable) -- use invoke of module function
--emulate template: {{taxobox/taxonomy}}
--which uses {{#invoke:Autotaxobox|taxoboxList
local bold_first = 'bold'
if templateArgs['species'] or templateArgs['hybrid'] then bold_first = 'link' end
if templateArgs['link_parent'] then bold_first = 'link' end
local args = { templateArgs['parent'], -- or tostring( mw.title.getCurrentTitle() ),
display_taxa = templateArgs['display_taxa'] or 1,
offset = templateArgs['offset'] or 0,
authority = templateArgs['authority'],
parent_authority = templateArgs['parent_authority'],
gparent_authority = templateArgs['grandparent_authority'],
ggparent_authority = templateArgs['greatgrandparent_authority'],
gggparent_authority = templateArgs['greatgreatgrandparent_authority'],
virus=templateArgs['virus'],
bold_first = bold_first
}
frame.args = args
-- templateArgs['debug'] = mw.dumpObject(frame)
local autoTaxonomy = autotaxa.taxoboxList(frame)
if (1==1) then return autoTaxonomy end
local row = taxoboxTable:tag('tr') -- incompatible with the templates called
:wikitext('\n|rank ||taxon name ')
:wikitext('\n'.. autoTaxonomy ) -- autoTaxonomy ends with a new row (|-)at end
:wikitext('\n|x ||y ') -- so add blank cells to complete extra row
-- this and affects spacing in taxonomy rows
--:wikitext('\n') -- spacing fine, newline for table wikitext
--[[ note: the output of {{taxobox/showtaxon}} [used by invoke:Autotaxobox|taxoboxList] ends with a newline token
this and affects spacing in taxonomy rows
leaving the empty row results in spurious paragraphs above the table
]]
return
end
----------------------------------------MANUAL TAXONOMY--------------------------------
function p.addManualTaxonomy(frame,taxoboxTable, taxonRanks)
--local parent = mw.getCurrentFrame():getParent()
--local taxonRanks = data.taxonRanks
-- following {{Paraphyletic group, a table is add to the cell in the classification row
--local taxonomyTable = mw.html.create('table'):addClass('taxonomy')
-- an alternative is to dispense with the extra table and just add the rows (like taxobox/core),
-- which would need colspan=2 on other rows (DONE)
local taxonomyTable = taxoboxTable
local wikiText = ""
for k,v in pairs(taxonRanks) do
if templateArgs[v] then
local taxonName = templateArgs[v]
local taxonRank = frame:expandTemplate{ title = "anglicise rank", args = {taxonRanks[k]} }
if taxonRanks[k] == "virus_group" then
taxonName = frame:expandTemplate{ title = "Virus group", args = {templateArgs[v]} }
-- taxonRank = "Group" -- handled by anglicise rank template
end
local authorityString = ''
if templateArgs[taxonRanks[k]..'_authority'] then
authorityString = '<br /><small>'..templateArgs[taxonRanks[k]..'_authority']..'</small>'
end
local taxonString = '<span class="'.. taxonRanks[k] ..'">'..taxonName..'</span>'..authorityString
local row = taxonomyTable:tag('tr')
row:tag('td'):wikitext(taxonRank..':')
row:tag('td'):wikitext(taxonString)
--:wikitext('<br /><small>'..parent.args[taxonRanks[k]..'_authority']..'</small>')
wikiText = wikiText .. '\n|- \n|' .. taxonRank..': \n|' .. taxonString
end
end -- end for loop
--return tostring(taxonomyTable)
return wikiText
end
--[[ ########################### UTILITY FUNCTIONS ###############################################
-----------------------------------------TAXOBOX COLOUR--------------------------------------
-- gets colour for headers using manual or automatic taxobox schemes
]]
function p.getTaxoboxColor(frame)
local colorAs = templateArgs['color_as'] or nil
if info.auto and not templateArgs['virus_group'] then
--[[(1) if color_as|colour_as|color as|colour as set, use template {{Taxobox colour|color_as}}
(2) else use the auto taxonnomy tree to find colour: {{#invoke:Autotaxobox|taxoboxColour| }}
{{#invoke:Autotaxobox|taxoboxColour|{{{parent|{{{genus|{{first word|{{{taxon|{{PAGENAME}} }}
--]]
--[[if (templateArgs['color_as'] and templateArgs['color_as'] ~= "") or
(templateArgs['colour_as'] and templateArgs['colour_as'] ~= "") or
(templateArgs['color as'] and templateArgs['color as'] ~= "") or
(templateArgs['colour as'] and templateArgs['colour as'] ~= "") then
local colorAs = ""
if templateArgs['color_as'] then colorAs = templateArgs['color_as'] end
if templateArgs['colour_as'] then colorAs = templateArgs['colour_as'] end
if templateArgs['color as'] then colorAs = templateArgs['color as'] end
if templateArgs['colour as'] then colorAs = templateArgs['colour as'] end]]
if colorAs then -- templateArgs['color_as'] and templateArgs['color_as'] ~= "" then
return frame:expandTemplate{ title = 'Taxobox colour', args = {colorAs} }
else
-- us #invoke:Autotaxobox|taxoboxColour|{{{parent}}} [parent should be set]
frame.args[1] = templateArgs['parent']
return autotaxa.taxoboxColour(frame)
--return "palegreen"
end
else -- use manual taxobox colours
--{{Taxobox colour|{{{regnum|{{{virus_group|{{{unranked_phylum|{{{phylum|''[[Incertae sedis]]''}}}}}}}}}}}}}}
if not colorAs then --templateArgs['color_as'] then
local group =''
if templateArgs['regnum'] then
group = templateArgs['regnum']
elseif templateArgs['virus_group'] then
group = templateArgs['virus_group']
elseif templateArgs['unranked_phylum'] then
group = templateArgs['unranked_phylum']
elseif templateArgs['phylum'] then
group = templateArgs['phylum']
else
group = "''[[Incertae sedis]]''" -- TODO check if this is what was desired
end
colorAs = group
end
return frame:expandTemplate{ title = 'Taxobox colour', args = {colorAs} }
end
end
-------------------------------------------------------------------
function p.templateStyle( frame, src )
return frame:extensionTag( 'templatestyles', '', { src = src } );
end
function p.test(frame)
return info.auto
end
return p