<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="id">
	<id>https://wiki.javasatu.com/index.php?action=history&amp;feed=atom&amp;title=Modul%3AVal</id>
	<title>Modul:Val - Riwayat revisi</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.javasatu.com/index.php?action=history&amp;feed=atom&amp;title=Modul%3AVal"/>
	<link rel="alternate" type="text/html" href="https://wiki.javasatu.com/index.php?title=Modul:Val&amp;action=history"/>
	<updated>2026-04-06T21:51:03Z</updated>
	<subtitle>Riwayat revisi halaman ini di wiki</subtitle>
	<generator>MediaWiki 1.40.0</generator>
	<entry>
		<id>https://wiki.javasatu.com/index.php?title=Modul:Val&amp;diff=11302&amp;oldid=prev</id>
		<title>Adminjavasatu: 1 revisi diimpor</title>
		<link rel="alternate" type="text/html" href="https://wiki.javasatu.com/index.php?title=Modul:Val&amp;diff=11302&amp;oldid=prev"/>
		<updated>2023-11-04T02:51:37Z</updated>

		<summary type="html">&lt;p&gt;1 revisi diimpor&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;id&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Revisi sebelumnya&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revisi per 4 November 2023 09.51&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;id&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(Tidak ada perbedaan)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Adminjavasatu</name></author>
	</entry>
	<entry>
		<id>https://wiki.javasatu.com/index.php?title=Modul:Val&amp;diff=3669&amp;oldid=prev</id>
		<title>Adminjavasatu: ←Membuat halaman berisi '-- For Template:Val, output a number and optional unit. -- Format options include scientific and uncertainty notations.  local data_module  -- name of module defining units  local function valerror(msg, nocat, iswarning)     -- Return formatted message text for an error or warning.     -- Can append &quot;#FormattingError&quot; to URL of a page with a problem to find it.     local anchor = '&lt;span id=&quot;FormattingError&quot;&gt;&lt;/span&gt;'     local body, category     if nocat or mw.tit...'</title>
		<link rel="alternate" type="text/html" href="https://wiki.javasatu.com/index.php?title=Modul:Val&amp;diff=3669&amp;oldid=prev"/>
		<updated>2023-09-29T10:31:49Z</updated>

		<summary type="html">&lt;p&gt;←Membuat halaman berisi &amp;#039;-- For Template:Val, output a number and optional unit. -- Format options include scientific and uncertainty notations.  local data_module  -- name of module defining units  local function valerror(msg, nocat, iswarning)     -- Return formatted message text for an error or warning.     -- Can append &amp;quot;#FormattingError&amp;quot; to URL of a page with a problem to find it.     local anchor = &amp;#039;&amp;lt;span id=&amp;quot;FormattingError&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;#039;     local body, category     if nocat or mw.tit...&amp;#039;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;id&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Revisi sebelumnya&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revisi per 29 September 2023 17.31&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;id&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(Tidak ada perbedaan)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Adminjavasatu</name></author>
	</entry>
	<entry>
		<id>https://wiki.javasatu.com/index.php?title=Modul:Val&amp;diff=11301&amp;oldid=prev</id>
		<title>dw&gt;FelixJL111 pada 14 Juli 2019 08.29</title>
		<link rel="alternate" type="text/html" href="https://wiki.javasatu.com/index.php?title=Modul:Val&amp;diff=11301&amp;oldid=prev"/>
		<updated>2019-07-14T08:29:08Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Halaman baru&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- For Template:Val, output a number and optional unit.&lt;br /&gt;
-- Format options include scientific and uncertainty notations.&lt;br /&gt;
&lt;br /&gt;
local data_module  -- name of module defining units&lt;br /&gt;
&lt;br /&gt;
local function valerror(msg, nocat, iswarning)&lt;br /&gt;
    -- Return formatted message text for an error or warning.&lt;br /&gt;
    -- Can append &amp;quot;#FormattingError&amp;quot; to URL of a page with a problem to find it.&lt;br /&gt;
    local anchor = '&amp;lt;span id=&amp;quot;FormattingError&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;'&lt;br /&gt;
    local body, category&lt;br /&gt;
    if nocat or mw.title.getCurrentTitle():inNamespaces(1, 2, 3, 5) then&lt;br /&gt;
        -- No category in Talk, User, User_talk, or Wikipedia_talk.&lt;br /&gt;
        category = ''&lt;br /&gt;
    else&lt;br /&gt;
        category = '[[Kategori:Halaman dengan penggunaan templat format yang salah]]'&lt;br /&gt;
    end&lt;br /&gt;
    iswarning = false  -- problems are infrequent so try showing large error so editor will notice&lt;br /&gt;
    if iswarning then&lt;br /&gt;
        body = '&amp;lt;sup class=&amp;quot;noprint Inline-Template&amp;quot; style=&amp;quot;white-space:nowrap;&amp;quot;&amp;gt;' ..&lt;br /&gt;
            '[[Template:Val|&amp;lt;span title=&amp;quot;' ..&lt;br /&gt;
            msg:gsub('&amp;quot;', '&amp;amp;quot;') ..&lt;br /&gt;
            '&amp;quot;&amp;gt;warning&amp;lt;/span&amp;gt;]]&amp;lt;/sup&amp;gt;'&lt;br /&gt;
    else&lt;br /&gt;
        body = '&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;' ..&lt;br /&gt;
            'Error in &amp;amp;#123;&amp;amp;#123;[[Templat:val|val]]&amp;amp;#125;&amp;amp;#125;: ' ..&lt;br /&gt;
            msg ..&lt;br /&gt;
            '&amp;lt;/strong&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    return anchor .. body .. category&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local range_types = {&lt;br /&gt;
    -- No need for '&amp;amp;nbsp;' because nowrap applies to all output.&lt;br /&gt;
    [&amp;quot;,&amp;quot;]   = &amp;quot;, &amp;quot;,&lt;br /&gt;
    [&amp;quot;by&amp;quot;]  = &amp;quot; by &amp;quot;,&lt;br /&gt;
    [&amp;quot;-&amp;quot;]   = &amp;quot;–&amp;quot;,&lt;br /&gt;
    [&amp;quot;–&amp;quot;]   = &amp;quot;–&amp;quot;,&lt;br /&gt;
    [&amp;quot;and&amp;quot;] = &amp;quot; and &amp;quot;,&lt;br /&gt;
    [&amp;quot;or&amp;quot;]  = &amp;quot; or &amp;quot; ,&lt;br /&gt;
    [&amp;quot;to&amp;quot;]  = &amp;quot; to &amp;quot; ,&lt;br /&gt;
    [&amp;quot;x&amp;quot;]   = &amp;quot; × &amp;quot;,&lt;br /&gt;
    [&amp;quot;×&amp;quot;]   = &amp;quot; × &amp;quot;,&lt;br /&gt;
    [&amp;quot;/&amp;quot;]   = &amp;quot;/&amp;quot;,&lt;br /&gt;
}&lt;br /&gt;
local range_repeat_unit = {&lt;br /&gt;
    -- WP:UNIT wants unit repeated when a &amp;quot;multiply&amp;quot; range is used.&lt;br /&gt;
    [&amp;quot;x&amp;quot;]   = true,&lt;br /&gt;
    [&amp;quot;×&amp;quot;]   = true,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function extract_item(index, numbers, arg)&lt;br /&gt;
    -- Extract an item from arg and store the result in numbers[index].&lt;br /&gt;
    -- If no argument or if argument is valid, return nil (no error);&lt;br /&gt;
    -- otherwise, return an error message.&lt;br /&gt;
    -- The stored result is:&lt;br /&gt;
    -- * a table for a number (empty if there was no specified number); or&lt;br /&gt;
    -- * a string for range text&lt;br /&gt;
    -- Input like 1e3 is regarded as invalid for all except argument 1&lt;br /&gt;
    -- which accepts e notation as an alternative to the 'e' argument.&lt;br /&gt;
    -- Input commas are removed so 1,234 is the same as 1234.&lt;br /&gt;
    local which = index&lt;br /&gt;
    local function fail(msg)&lt;br /&gt;
        local description&lt;br /&gt;
        if which == 'e' then&lt;br /&gt;
            description = 'exponent parameter (&amp;lt;b&amp;gt;e&amp;lt;/b&amp;gt;)'&lt;br /&gt;
        else&lt;br /&gt;
            description = 'parameter ' .. which&lt;br /&gt;
        end&lt;br /&gt;
        return description .. ' ' .. (msg or 'is not a valid number') .. '.'&lt;br /&gt;
    end&lt;br /&gt;
    local result = {}&lt;br /&gt;
    local range = range_types[arg]&lt;br /&gt;
    if range then&lt;br /&gt;
        if type(index) == 'number' and (index % 2 == 0) then&lt;br /&gt;
            if index == 2 then&lt;br /&gt;
                if numbers[1] and numbers[1].exp then&lt;br /&gt;
                    return fail('cannot use a range if the first parameter includes &amp;quot;e&amp;quot;')&lt;br /&gt;
                end&lt;br /&gt;
                numbers.has_ranges = true&lt;br /&gt;
            else&lt;br /&gt;
                if not numbers.has_ranges then&lt;br /&gt;
                    return fail('needs a range in parameter 2')&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
            numbers[index] = range&lt;br /&gt;
            if range_repeat_unit[arg] then&lt;br /&gt;
                -- Any &amp;quot;repeat&amp;quot; range forces unit (if any) to be repeated for all items.&lt;br /&gt;
                numbers.isrepeat = true&lt;br /&gt;
            end&lt;br /&gt;
            return nil&lt;br /&gt;
        end&lt;br /&gt;
        return fail('does not accept a range')&lt;br /&gt;
    end&lt;br /&gt;
    if numbers.has_ranges and type(index) == 'number' and (index % 2 == 0) then&lt;br /&gt;
        return fail('should be a range')&lt;br /&gt;
    end&lt;br /&gt;
    if index == 'e' then&lt;br /&gt;
        local e = numbers[1] and numbers[1].exp&lt;br /&gt;
        if e then&lt;br /&gt;
            if arg then&lt;br /&gt;
                return fail('cannot be used if the first parameter includes &amp;quot;e&amp;quot;')&lt;br /&gt;
            end&lt;br /&gt;
            arg = e&lt;br /&gt;
            which = 1&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    if arg and arg ~= '' then&lt;br /&gt;
        arg = arg:gsub(',', '')&lt;br /&gt;
        if arg:sub(1, 1) == '(' and arg:sub(-1) == ')' then&lt;br /&gt;
            result.parens = true&lt;br /&gt;
            arg = arg:sub(2, -2)&lt;br /&gt;
        end&lt;br /&gt;
        local a, b = arg:match('^(.+)[Ee](.+)$')&lt;br /&gt;
        if a then&lt;br /&gt;
            if index == 1 then&lt;br /&gt;
                arg = a&lt;br /&gt;
                result.exp = b&lt;br /&gt;
            else&lt;br /&gt;
                return fail('cannot use e notation')&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
        local isnegative, propersign, prefix&lt;br /&gt;
        local minus = '−'&lt;br /&gt;
        prefix, arg = arg:match('^(.-)([%d.]+)$')&lt;br /&gt;
        local value = tonumber(arg)&lt;br /&gt;
        if not value then&lt;br /&gt;
            return fail()&lt;br /&gt;
        end&lt;br /&gt;
        if arg:sub(1, 1) == '.' then&lt;br /&gt;
            arg = '0' .. arg&lt;br /&gt;
        end&lt;br /&gt;
        if prefix == '' then&lt;br /&gt;
            -- Ignore.&lt;br /&gt;
        elseif prefix == '±' then&lt;br /&gt;
            -- Display for first number, ignore for others.&lt;br /&gt;
            if index == 1 then&lt;br /&gt;
                propersign = '±'&lt;br /&gt;
            end&lt;br /&gt;
        elseif prefix == '+' then&lt;br /&gt;
            propersign = '+'&lt;br /&gt;
        elseif prefix == '-' or prefix == minus then&lt;br /&gt;
            propersign = minus&lt;br /&gt;
            isnegative = true&lt;br /&gt;
        else&lt;br /&gt;
            return fail()&lt;br /&gt;
        end&lt;br /&gt;
        result.clean = arg&lt;br /&gt;
        result.sign = propersign or ''&lt;br /&gt;
        result.value = isnegative and -value or value&lt;br /&gt;
    end&lt;br /&gt;
    numbers[index] = result&lt;br /&gt;
    return nil  -- no error&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function get_args(numbers, args)&lt;br /&gt;
    -- Extract arguments and store the results in numbers.&lt;br /&gt;
    -- Return nothing (no error) if ok; otherwise, return an error message.&lt;br /&gt;
    for index = 1, 99 do&lt;br /&gt;
        local which = index&lt;br /&gt;
        local arg = args[which]  -- has been trimmed&lt;br /&gt;
        if not arg then&lt;br /&gt;
            which = 'e'&lt;br /&gt;
            arg = args[which]&lt;br /&gt;
        end&lt;br /&gt;
        local msg = extract_item(which, numbers, arg)&lt;br /&gt;
        if msg then&lt;br /&gt;
            return msg&lt;br /&gt;
        end&lt;br /&gt;
        if which == 'e' then&lt;br /&gt;
            break&lt;br /&gt;
        end&lt;br /&gt;
        if index &amp;gt; 19 then&lt;br /&gt;
            return 'too many parameters'&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    if numbers.has_ranges and (#numbers % 2 == 0) then&lt;br /&gt;
        return 'need a number after the last parameter because it is a range.'&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function get_scale(text, ucode)&lt;br /&gt;
    -- Return the value of text as a number, or throw an error.&lt;br /&gt;
    -- This supports extremely basic expressions of the form:&lt;br /&gt;
    --   a / b&lt;br /&gt;
    --   a ^ b&lt;br /&gt;
    -- where a and b are numbers or 'pi'.&lt;br /&gt;
    local n = tonumber(text)&lt;br /&gt;
    if n then&lt;br /&gt;
        return n&lt;br /&gt;
    end&lt;br /&gt;
    n = text:gsub('pi', math.pi)&lt;br /&gt;
    for _, op in ipairs({ '/', '^' }) do&lt;br /&gt;
        local a, b = n:match('^(.-)' .. op .. '(.*)$')&lt;br /&gt;
        if a then&lt;br /&gt;
            a = tonumber(a)&lt;br /&gt;
            b = tonumber(b)&lt;br /&gt;
            if a and b then&lt;br /&gt;
                if op == '/' then&lt;br /&gt;
                    return a / b&lt;br /&gt;
                elseif op == '^' then&lt;br /&gt;
                    return a ^ b&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
            break&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    error('Unit &amp;quot;' .. ucode .. '&amp;quot; has invalid scale &amp;quot;' .. text .. '&amp;quot;')&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function get_builtin_unit(ucode, definitions)&lt;br /&gt;
    -- Return table of information for the specified built-in unit, or nil if not known.&lt;br /&gt;
    -- Each defined unit code must be followed by two spaces (not tab characters).&lt;br /&gt;
    local _, pos = definitions:find('\n' .. ucode .. '  ', 1, true)&lt;br /&gt;
    if pos then&lt;br /&gt;
        local endline = definitions:find('%s*\n', pos)&lt;br /&gt;
        if endline then&lt;br /&gt;
            local result = {}&lt;br /&gt;
            local n = 0&lt;br /&gt;
            local text = definitions:sub(pos + 1, endline - 1):gsub('%s%s+', '\t')&lt;br /&gt;
            for item in (text .. '\t'):gmatch('(%S.-)\t') do&lt;br /&gt;
                if item == 'ALIAS' then&lt;br /&gt;
                    result.alias = true&lt;br /&gt;
                elseif item == 'ANGLE' then&lt;br /&gt;
                    result.isangle = true&lt;br /&gt;
                    result.nospace = true&lt;br /&gt;
                elseif item == 'NOSPACE' then&lt;br /&gt;
                    result.nospace = true&lt;br /&gt;
                elseif item == 'SI' then&lt;br /&gt;
                    result.si = true&lt;br /&gt;
                else&lt;br /&gt;
                    n = n + 1&lt;br /&gt;
                    if n == 1 then&lt;br /&gt;
                        local link, symbol = item:match('^%[%[([^|]+)|(.+)%]%]$')&lt;br /&gt;
                        if link then&lt;br /&gt;
                            result.symbol = symbol&lt;br /&gt;
                            result.link = link&lt;br /&gt;
                            n = 2&lt;br /&gt;
                        else&lt;br /&gt;
                            result.symbol = item&lt;br /&gt;
                        end&lt;br /&gt;
                    elseif n == 2 then&lt;br /&gt;
                        result.link = item&lt;br /&gt;
                    elseif n == 3 then&lt;br /&gt;
                        result.scale_text = item&lt;br /&gt;
                        result.scale = get_scale(item, ucode)&lt;br /&gt;
                    else&lt;br /&gt;
                        result.more_ignored = item&lt;br /&gt;
                        break&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
            if result.si then&lt;br /&gt;
                local s = result.symbol&lt;br /&gt;
                if ucode == 'mc' .. s or ucode == 'mu' .. s then&lt;br /&gt;
                    result.ucode = 'µ' .. s  -- unit code for convert should be this&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
            if n &amp;gt;= 2 or (n &amp;gt;= 1 and result.alias) then&lt;br /&gt;
                return result&lt;br /&gt;
            end&lt;br /&gt;
            -- Ignore invalid definition, treating it as a comment.&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function convert_lookup(ucode, value, scaled_top, want_link, si, options)&lt;br /&gt;
    local lookup = require('Module:Convert')._unit&lt;br /&gt;
    return lookup(ucode, {&lt;br /&gt;
            value = value,&lt;br /&gt;
            scaled_top = scaled_top,&lt;br /&gt;
            link = want_link,&lt;br /&gt;
            si = si,&lt;br /&gt;
            sort = options.sortable,&lt;br /&gt;
        })&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function get_unit(ucode, value, scaled_top, options)&lt;br /&gt;
    local want_link = options.want_link&lt;br /&gt;
    if scaled_top then&lt;br /&gt;
        want_link = options.want_per_link&lt;br /&gt;
    end&lt;br /&gt;
    local data = mw.loadData(data_module)&lt;br /&gt;
    local result = options.want_longscale and&lt;br /&gt;
        get_builtin_unit(ucode, data.builtin_units_long_scale) or&lt;br /&gt;
        get_builtin_unit(ucode, data.builtin_units)&lt;br /&gt;
    local si, use_convert&lt;br /&gt;
    if result then&lt;br /&gt;
        if result.alias then&lt;br /&gt;
            ucode = result.symbol&lt;br /&gt;
            use_convert = true&lt;br /&gt;
        end&lt;br /&gt;
        if result.scale then&lt;br /&gt;
            -- Setting si means convert will use the unit as given, and the sort key&lt;br /&gt;
            -- will be calculated from the value without any extra scaling that may&lt;br /&gt;
            -- occur if convert found the unit code. For example, if val defines the&lt;br /&gt;
            -- unit 'year' with a scale and if si were not set, convert would also apply&lt;br /&gt;
            -- its own scale because convert knows that a year is 31,557,600 seconds.&lt;br /&gt;
            si = { result.symbol, result.link }&lt;br /&gt;
            value = value * result.scale&lt;br /&gt;
        end&lt;br /&gt;
        if result.si then&lt;br /&gt;
            ucode = result.ucode or ucode&lt;br /&gt;
            si = { result.symbol, result.link }&lt;br /&gt;
            use_convert = true&lt;br /&gt;
        end&lt;br /&gt;
    else&lt;br /&gt;
        result = {}&lt;br /&gt;
        use_convert = true&lt;br /&gt;
    end&lt;br /&gt;
    local convert_unit = convert_lookup(ucode, value, scaled_top, want_link, si, options)&lt;br /&gt;
    result.sortkey = convert_unit.sortspan&lt;br /&gt;
    if use_convert then&lt;br /&gt;
        result.text = convert_unit.text&lt;br /&gt;
        result.scaled_top = convert_unit.scaled_value&lt;br /&gt;
    else&lt;br /&gt;
        if want_link then&lt;br /&gt;
            result.text = '[[' .. result.link .. '|' .. result.symbol .. ']]'&lt;br /&gt;
        else&lt;br /&gt;
            result.text = result.symbol&lt;br /&gt;
        end&lt;br /&gt;
        result.scaled_top = value&lt;br /&gt;
    end&lt;br /&gt;
    return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function makeunit(value, options)&lt;br /&gt;
    -- Return table of information for the requested unit and options, or&lt;br /&gt;
    -- return nil if no unit.&lt;br /&gt;
    options = options or {}&lt;br /&gt;
    local unit&lt;br /&gt;
    local ucode = options.u&lt;br /&gt;
    local percode = options.per&lt;br /&gt;
    if ucode then&lt;br /&gt;
        unit = get_unit(ucode, value, nil, options)&lt;br /&gt;
    elseif percode then&lt;br /&gt;
        unit = { nospace = true, scaled_top = value }&lt;br /&gt;
    else&lt;br /&gt;
        return nil&lt;br /&gt;
    end&lt;br /&gt;
    local text = unit.text or ''&lt;br /&gt;
    local sortkey = unit.sortkey&lt;br /&gt;
    if percode then&lt;br /&gt;
        local function bracketed(code, text)&lt;br /&gt;
            return code:find('[*./]') and '(' .. text .. ')' or text&lt;br /&gt;
        end&lt;br /&gt;
        local perunit = get_unit(percode, 1, unit.scaled_top, options)&lt;br /&gt;
        text = (ucode and bracketed(ucode, text) or '') ..&lt;br /&gt;
                '/' .. bracketed(percode, perunit.text)&lt;br /&gt;
        sortkey = perunit.sortkey&lt;br /&gt;
    end&lt;br /&gt;
    if not (unit.nospace or options.nospace) then&lt;br /&gt;
        text = '&amp;amp;nbsp;' .. text&lt;br /&gt;
    end&lt;br /&gt;
    return { text = text, isangle = unit.isangle, sortkey = sortkey }&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function list_units(mode)&lt;br /&gt;
    -- Return wikitext to list the built-in units.&lt;br /&gt;
    -- A unit code should not contain wikimarkup so don't bother escaping.&lt;br /&gt;
    local data = mw.loadData(data_module)&lt;br /&gt;
    local definitions = data.builtin_units .. data.builtin_units_long_scale&lt;br /&gt;
    local last_was_blank = true&lt;br /&gt;
    local n = 0&lt;br /&gt;
    local result = {}&lt;br /&gt;
    local function add(line)&lt;br /&gt;
        if line == '' then&lt;br /&gt;
            last_was_blank = true&lt;br /&gt;
        else&lt;br /&gt;
            if last_was_blank and n &amp;gt; 0 then&lt;br /&gt;
                n = n + 1&lt;br /&gt;
                result[n] = ''&lt;br /&gt;
            end&lt;br /&gt;
            last_was_blank = false&lt;br /&gt;
            n = n + 1&lt;br /&gt;
            result[n] = line&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    local si_prefixes = {&lt;br /&gt;
        -- These are the prefixes recognized by convert; u is accepted for micro.&lt;br /&gt;
        y = 'y',&lt;br /&gt;
        z = 'z',&lt;br /&gt;
        a = 'a',&lt;br /&gt;
        f = 'f',&lt;br /&gt;
        p = 'p',&lt;br /&gt;
        n = 'n',&lt;br /&gt;
        u = 'µ',&lt;br /&gt;
        ['µ'] = 'µ',&lt;br /&gt;
        m = 'm',&lt;br /&gt;
        c = 'c',&lt;br /&gt;
        d = 'd',&lt;br /&gt;
        da = 'da',&lt;br /&gt;
        h = 'h',&lt;br /&gt;
        k = 'k',&lt;br /&gt;
        M = 'M',&lt;br /&gt;
        G = 'G',&lt;br /&gt;
        T = 'T',&lt;br /&gt;
        P = 'P',&lt;br /&gt;
        E = 'E',&lt;br /&gt;
        Z = 'Z',&lt;br /&gt;
        Y = 'Y',&lt;br /&gt;
    }&lt;br /&gt;
    local function is_valid(ucode, unit)&lt;br /&gt;
        if unit and not unit.more_ignored then&lt;br /&gt;
            assert(type(unit.symbol) == 'string' and unit.symbol ~= '')&lt;br /&gt;
            if unit.alias then&lt;br /&gt;
                if unit.link or unit.scale_text or unit.si then&lt;br /&gt;
                    return false&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
            if unit.si then&lt;br /&gt;
                if unit.scale_text then&lt;br /&gt;
                    return false&lt;br /&gt;
                end&lt;br /&gt;
                ucode = unit.ucode or ucode&lt;br /&gt;
                local base = unit.symbol&lt;br /&gt;
                if ucode == base then&lt;br /&gt;
                    unit.display = base&lt;br /&gt;
                    return true&lt;br /&gt;
                end&lt;br /&gt;
                local plen = #ucode - #base&lt;br /&gt;
                if plen &amp;gt; 0 then&lt;br /&gt;
                    local prefix = si_prefixes[ucode:sub(1, plen)]&lt;br /&gt;
                    if prefix and ucode:sub(plen + 1) == base then&lt;br /&gt;
                        unit.display = prefix .. base&lt;br /&gt;
                        return true&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
            else&lt;br /&gt;
                unit.display = unit.symbol&lt;br /&gt;
                return true&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
        return false&lt;br /&gt;
    end&lt;br /&gt;
    local lookup = require('Module:Convert')._unit&lt;br /&gt;
    local function show_convert(ucode, unit)&lt;br /&gt;
        -- If a built-in unit defines a scale or sets the SI flag, any unit defined in&lt;br /&gt;
        -- convert is not used (the scale or SI prefix's scale is used for a sort key).&lt;br /&gt;
        -- If there is no scale or SI flag, and the unit is not defined in convert,&lt;br /&gt;
        -- the sort key may not be correct; this allows such units to be identified.&lt;br /&gt;
        if not (unit.si or unit.scale_text) then&lt;br /&gt;
            if mode == 'convert' then&lt;br /&gt;
                unit.show = not lookup(unit.alias and unit.symbol or ucode).unknown&lt;br /&gt;
                unit.show_text = 'CONVERT'&lt;br /&gt;
            elseif mode == 'unknown' then&lt;br /&gt;
                unit.show = lookup(unit.alias and unit.symbol or ucode).unknown&lt;br /&gt;
                unit.show_text = 'UNKNOWN'&lt;br /&gt;
            elseif not unit.alias then&lt;br /&gt;
                -- Show convert's scale in square brackets ('[1]' for an unknown unit).&lt;br /&gt;
                -- Don't show scale for an alias because it's misleading for temperature&lt;br /&gt;
                -- and an alias is probably not useful for anything else.&lt;br /&gt;
                local scale = lookup(ucode, {value=1, sort='on'}).scaled_value&lt;br /&gt;
                if type(scale) == 'number' then&lt;br /&gt;
                    scale = string.format('%.5g', scale):gsub('e%+?(%-?)0*(%d+)', 'e%1%2')&lt;br /&gt;
                else&lt;br /&gt;
                    scale = '?'&lt;br /&gt;
                end&lt;br /&gt;
                unit.show = true&lt;br /&gt;
                unit.show_text = '[' .. scale .. ']'&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    for line in definitions:gmatch('([^\n]*)\n') do&lt;br /&gt;
        local pos, _ = line:find('  ', 1, true)&lt;br /&gt;
        if pos then&lt;br /&gt;
            local ucode = line:sub(1, pos - 1)&lt;br /&gt;
            local unit = get_builtin_unit(ucode, '\n' .. line .. '\n')&lt;br /&gt;
            if is_valid(ucode, unit) then&lt;br /&gt;
                show_convert(ucode, unit)&lt;br /&gt;
                local flags, text&lt;br /&gt;
                if unit.alias then&lt;br /&gt;
                    text = unit.symbol&lt;br /&gt;
                else&lt;br /&gt;
                    text = '[[' .. unit.link .. '|' .. unit.display .. ']]'&lt;br /&gt;
                end&lt;br /&gt;
                if unit.isangle then&lt;br /&gt;
                    unit.nospace = nil  -- don't show redundant flag&lt;br /&gt;
                end&lt;br /&gt;
                for _, f in ipairs({&lt;br /&gt;
                        { 'alias', 'ALIAS' },&lt;br /&gt;
                        { 'isangle', 'ANGLE' },&lt;br /&gt;
                        { 'nospace', 'NOSPACE' },&lt;br /&gt;
                        { 'si', 'SI' },&lt;br /&gt;
                        { 'scale_text', unit.scale_text },&lt;br /&gt;
                        { 'show', unit.show_text },&lt;br /&gt;
                    }) do&lt;br /&gt;
                    if unit[f[1]] then&lt;br /&gt;
                        local t = f[2]&lt;br /&gt;
                        if t:match('^%u+$') then&lt;br /&gt;
                            t = '&amp;lt;small&amp;gt;' .. t .. '&amp;lt;/small&amp;gt;'&lt;br /&gt;
                        end&lt;br /&gt;
                        if flags then&lt;br /&gt;
                            flags = flags .. ' ' .. t&lt;br /&gt;
                        else&lt;br /&gt;
                            flags = t&lt;br /&gt;
                        end&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
                if flags then&lt;br /&gt;
                    text = text .. ' • ' .. flags&lt;br /&gt;
                end&lt;br /&gt;
                add(ucode .. ' = ' .. text .. '&amp;lt;br /&amp;gt;')&lt;br /&gt;
            else&lt;br /&gt;
                add(line .. ' ◆ &amp;lt;b&amp;gt;invalid definition&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;')&lt;br /&gt;
            end&lt;br /&gt;
        else&lt;br /&gt;
            add(line)&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return table.concat(result, '\n')&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local delimit_groups = require('Module:Gapnum').groups&lt;br /&gt;
local function delimit(sign, numstr, fmt)&lt;br /&gt;
    -- Return sign and numstr (unsigned digits or '.' only) after formatting.&lt;br /&gt;
    -- Four-digit integers are not formatted with gaps.&lt;br /&gt;
    fmt = (fmt or ''):lower()&lt;br /&gt;
    if fmt == 'none' or (fmt == '' and #numstr == 4 and numstr:match('^%d+$')) then&lt;br /&gt;
        return sign .. numstr&lt;br /&gt;
    end&lt;br /&gt;
    -- Group number by integer and decimal parts.&lt;br /&gt;
    -- If there is no decimal part, delimit_groups returns only one table.&lt;br /&gt;
    local ipart, dpart = delimit_groups(numstr)&lt;br /&gt;
    local result&lt;br /&gt;
    if fmt == 'commas' then&lt;br /&gt;
        result = sign .. table.concat(ipart, ',')&lt;br /&gt;
        if dpart then&lt;br /&gt;
            result = result .. '.' .. table.concat(dpart)&lt;br /&gt;
        end&lt;br /&gt;
    else&lt;br /&gt;
    	if fmt == 'points' then&lt;br /&gt;
        	result = sign .. table.concat(ipart, '.')&lt;br /&gt;
        	if dpart then&lt;br /&gt;
            	result = result .. ',' .. table.concat(dpart)&lt;br /&gt;
        	end&lt;br /&gt;
        else&lt;br /&gt;
        	if fmt == 'gaps' then&lt;br /&gt;
        		local groups = {}&lt;br /&gt;
				groups[1] = table.remove(ipart, 1)&lt;br /&gt;
				for _, v in ipairs(ipart) do&lt;br /&gt;
					table.insert(groups, '&amp;lt;span style=&amp;quot;margin-left:.25em;&amp;quot;&amp;gt;' .. v .. '&amp;lt;/span&amp;gt;')&lt;br /&gt;
				end&lt;br /&gt;
				if dpart then&lt;br /&gt;
					table.insert(groups, '.' .. (table.remove(dpart, 1) or ''))&lt;br /&gt;
					for _, v in ipairs(dpart) do&lt;br /&gt;
						table.insert(groups, '&amp;lt;span style=&amp;quot;margin-left:.25em;&amp;quot;&amp;gt;' .. v .. '&amp;lt;/span&amp;gt;')&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				result = sign .. table.concat(groups)&lt;br /&gt;
        	else&lt;br /&gt;
        		-- Delimit with a point by default.&lt;br /&gt;
        		local groups = {}&lt;br /&gt;
        		groups[1] = table.remove(ipart, 1)&lt;br /&gt;
        		for _, v in ipairs(ipart) do&lt;br /&gt;
            		table.insert(groups, '.' .. v .. '&amp;lt;/span&amp;gt;')&lt;br /&gt;
        		end&lt;br /&gt;
        		if dpart then&lt;br /&gt;
            		table.insert(groups, ',' .. (table.remove(dpart, 1) or ''))&lt;br /&gt;
            		for _, v in ipairs(dpart) do&lt;br /&gt;
                		table.insert(groups,  v .. '&amp;lt;/span&amp;gt;')&lt;br /&gt;
                	end&lt;br /&gt;
            	end&lt;br /&gt;
            	result = sign .. table.concat(groups)&lt;br /&gt;
	        end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function sup_sub(sup, sub, align)&lt;br /&gt;
    -- Return the same result as Module:Su except val defaults to align=right.&lt;br /&gt;
    if align == 'l' or align == 'left' then&lt;br /&gt;
        align = 'left'&lt;br /&gt;
    elseif align == 'c' or align == 'center' then&lt;br /&gt;
        align = 'center'&lt;br /&gt;
    else&lt;br /&gt;
        align = 'right'&lt;br /&gt;
    end&lt;br /&gt;
    return '&amp;lt;span style=&amp;quot;display:inline-block;margin-bottom:-0.3em;vertical-align:-0.4em;line-height:1.2em;font-size:85%;text-align:' ..&lt;br /&gt;
        align .. ';&amp;quot;&amp;gt;' .. sup .. '&amp;lt;br /&amp;gt;' .. sub .. '&amp;lt;/span&amp;gt;'&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function range_text(items, unit_table, options)&lt;br /&gt;
    local fmt = options.fmt&lt;br /&gt;
    local nend = items.nend or ''&lt;br /&gt;
    if items.isrepeat or unit_table.isangle then&lt;br /&gt;
        nend = nend .. unit_table.text&lt;br /&gt;
    end&lt;br /&gt;
    local text = ''&lt;br /&gt;
    for i = 1, #items do&lt;br /&gt;
        if i % 2 == 0 then&lt;br /&gt;
            text = text .. items[i]&lt;br /&gt;
        else&lt;br /&gt;
            text = text .. delimit(items[i].sign, items[i].clean, fmt) .. nend&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function uncertainty_text(uncertainty, unit_table, options)&lt;br /&gt;
    local angle, text, need_parens&lt;br /&gt;
    if unit_table.isangle then&lt;br /&gt;
        angle = unit_table.text&lt;br /&gt;
    end&lt;br /&gt;
    local upper = uncertainty.upper or {}&lt;br /&gt;
    local lower = uncertainty.lower or {}&lt;br /&gt;
    local uncU = upper.clean&lt;br /&gt;
    if uncU then&lt;br /&gt;
        local fmt = options.fmt&lt;br /&gt;
        local uncL = lower.clean&lt;br /&gt;
        if uncL then&lt;br /&gt;
            uncU = delimit('+', uncU, fmt) .. (upper.errend or '')&lt;br /&gt;
            uncL = delimit('−', uncL, fmt) .. (lower.errend or '')&lt;br /&gt;
            if angle then&lt;br /&gt;
                uncU = uncU .. angle&lt;br /&gt;
                uncL = uncL .. angle&lt;br /&gt;
            end&lt;br /&gt;
            text = (angle or '') ..&lt;br /&gt;
                '&amp;lt;span style=&amp;quot;margin-left:0.3em;&amp;quot;&amp;gt;' ..&lt;br /&gt;
                sup_sub(uncU, uncL, options.align) ..&lt;br /&gt;
                '&amp;lt;/span&amp;gt;'&lt;br /&gt;
        else&lt;br /&gt;
            if upper.parens then&lt;br /&gt;
                text = '(' .. uncU .. ')'  -- old template did not delimit&lt;br /&gt;
            else&lt;br /&gt;
                text = (angle or '') ..&lt;br /&gt;
                    '&amp;lt;span style=&amp;quot;margin-left:0.3em;margin-right:0.15em;&amp;quot;&amp;gt;±&amp;lt;/span&amp;gt;' ..&lt;br /&gt;
                    delimit('', uncU, fmt)&lt;br /&gt;
                need_parens = true&lt;br /&gt;
            end&lt;br /&gt;
            if uncertainty.errend then&lt;br /&gt;
                text = text .. uncertainty.errend&lt;br /&gt;
            end&lt;br /&gt;
            if angle then&lt;br /&gt;
                text = text .. angle&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    else&lt;br /&gt;
        if angle then&lt;br /&gt;
            text = angle&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return text, need_parens&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function _main(values, unit_spec, options)&lt;br /&gt;
    data_module = 'Module:Val/units' .. (options.sandbox and '/sandbox' or '')&lt;br /&gt;
    local action = options.action&lt;br /&gt;
    if action then&lt;br /&gt;
        if action == 'list' then&lt;br /&gt;
            -- Kludge: am using the align parameter (a=xxx) for type of list.&lt;br /&gt;
            return list_units(options.align)&lt;br /&gt;
        end&lt;br /&gt;
        return valerror('invalid action &amp;quot;' .. action .. '&amp;quot;.', options.nocat)&lt;br /&gt;
    end&lt;br /&gt;
    local number = values.number or (values.numbers and values.numbers[1]) or {}&lt;br /&gt;
    local e_10 = options.e or {}&lt;br /&gt;
    local novalue = (number.value == nil and e_10.clean == nil)&lt;br /&gt;
    local fmt = options.fmt&lt;br /&gt;
    local want_sort = true&lt;br /&gt;
    local sortable = options.sortable&lt;br /&gt;
    if sortable == 'off' or (sortable == nil and novalue) then&lt;br /&gt;
        want_sort = false&lt;br /&gt;
    elseif sortable == 'debug' then&lt;br /&gt;
        -- Same as sortable = 'on' but the sort key is displayed.&lt;br /&gt;
    else&lt;br /&gt;
        sortable = 'on'&lt;br /&gt;
    end&lt;br /&gt;
    local sort_value = 1&lt;br /&gt;
    if want_sort then&lt;br /&gt;
        sort_value = number.value or 1&lt;br /&gt;
        if e_10.value and sort_value ~= 0 then&lt;br /&gt;
            -- The 'if' avoids {{val|0|e=1234}} giving an invalid sort_value due to overflow.&lt;br /&gt;
            sort_value = sort_value * 10^e_10.value&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    local unit_table = makeunit(sort_value, {&lt;br /&gt;
                        u = unit_spec.u,&lt;br /&gt;
                        want_link = unit_spec.want_link,&lt;br /&gt;
                        per = unit_spec.per,&lt;br /&gt;
                        want_per_link = unit_spec.want_per_link,&lt;br /&gt;
                        nospace = novalue,&lt;br /&gt;
                        want_longscale = unit_spec.want_longscale,&lt;br /&gt;
                        sortable = sortable,&lt;br /&gt;
                    })&lt;br /&gt;
    local sortkey&lt;br /&gt;
    if unit_table then&lt;br /&gt;
        if want_sort then&lt;br /&gt;
            sortkey = unit_table.sortkey&lt;br /&gt;
        end&lt;br /&gt;
    else&lt;br /&gt;
        unit_table = { text = '' }&lt;br /&gt;
        if want_sort then&lt;br /&gt;
            sortkey = convert_lookup('dummy', sort_value, nil, nil, nil, { sortable = sortable }).sortspan&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    local final_unit = unit_table.isangle and '' or unit_table.text&lt;br /&gt;
    local e_text, n_text, need_parens&lt;br /&gt;
    local uncertainty = values.uncertainty&lt;br /&gt;
    if uncertainty then&lt;br /&gt;
        if number.clean then&lt;br /&gt;
            n_text = delimit(number.sign, number.clean, fmt) .. (number.nend or '')&lt;br /&gt;
            local text&lt;br /&gt;
            text, need_parens = uncertainty_text(uncertainty, unit_table, options)&lt;br /&gt;
            if text then&lt;br /&gt;
                n_text = n_text .. text&lt;br /&gt;
            end&lt;br /&gt;
        else&lt;br /&gt;
            n_text = ''&lt;br /&gt;
        end&lt;br /&gt;
    else&lt;br /&gt;
        if values.numbers.isrepeat then&lt;br /&gt;
            final_unit = ''&lt;br /&gt;
        end&lt;br /&gt;
        n_text = range_text(values.numbers, unit_table, options)&lt;br /&gt;
        need_parens = true&lt;br /&gt;
    end&lt;br /&gt;
    if e_10.clean then&lt;br /&gt;
        if need_parens then&lt;br /&gt;
            n_text = '(' .. n_text .. ')'&lt;br /&gt;
        end&lt;br /&gt;
        e_text = '10&amp;lt;sup&amp;gt;' .. delimit(e_10.sign, e_10.clean, fmt) .. '&amp;lt;/sup&amp;gt;'&lt;br /&gt;
        if number.clean then&lt;br /&gt;
            e_text = '&amp;lt;span style=&amp;quot;margin-left:0.25em;margin-right:0.15em;&amp;quot;&amp;gt;×&amp;lt;/span&amp;gt;' .. e_text&lt;br /&gt;
        end&lt;br /&gt;
    else&lt;br /&gt;
        e_text = ''&lt;br /&gt;
    end&lt;br /&gt;
    local result =&lt;br /&gt;
        (sortkey or '') ..&lt;br /&gt;
        (options.prefix or '') ..&lt;br /&gt;
        n_text ..&lt;br /&gt;
        e_text ..&lt;br /&gt;
        final_unit ..&lt;br /&gt;
        (options.suffix or '')&lt;br /&gt;
    if result ~= '' then&lt;br /&gt;
        result = '&amp;lt;span class=&amp;quot;nowrap&amp;quot;&amp;gt;' .. result .. '&amp;lt;/span&amp;gt;'&lt;br /&gt;
    end&lt;br /&gt;
    return result .. (options.warning or '')&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function check_parameters(args, has_ranges, nocat)&lt;br /&gt;
    -- Return warning text for the first problem parameter found, or nothing if ok.&lt;br /&gt;
    local whitelist = {&lt;br /&gt;
        a = true,&lt;br /&gt;
        action = true,&lt;br /&gt;
        debug = true,&lt;br /&gt;
        e = true,&lt;br /&gt;
        ['end'] = true,&lt;br /&gt;
        errend = true,&lt;br /&gt;
        ['+errend'] = true,&lt;br /&gt;
        ['-errend'] = true,&lt;br /&gt;
        fmt = true,&lt;br /&gt;
        ['long scale'] = true,&lt;br /&gt;
        long_scale = true,&lt;br /&gt;
        longscale = true,&lt;br /&gt;
        nocategory = true,&lt;br /&gt;
        p = true,&lt;br /&gt;
        s = true,&lt;br /&gt;
        sortable = true,&lt;br /&gt;
        u = true,&lt;br /&gt;
        ul = true,&lt;br /&gt;
        up = true,&lt;br /&gt;
        upl = true,&lt;br /&gt;
    }&lt;br /&gt;
    for k, v in pairs(args) do&lt;br /&gt;
        if type(k) == 'string' and not whitelist[k] then&lt;br /&gt;
            local warning = 'Val parameter &amp;quot;' .. k .. '=' .. v .. '&amp;quot; is not supported'&lt;br /&gt;
            return valerror(warning, nocat, true)&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    if not has_ranges and args[4] then&lt;br /&gt;
        return valerror('Val parameter 4 ignored', nocat, true)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function main(frame)&lt;br /&gt;
    local getArgs = require('Module:Arguments').getArgs&lt;br /&gt;
    local args = getArgs(frame, {wrappers = { 'Template:Val', 'Template:Val/sandboxlua' }})&lt;br /&gt;
    local nocat = args.nocategory&lt;br /&gt;
    local numbers = {}  -- table of number tables, perhaps with range text&lt;br /&gt;
    local msg = get_args(numbers, args)&lt;br /&gt;
    if msg then&lt;br /&gt;
        return valerror(msg, nocat)&lt;br /&gt;
    end&lt;br /&gt;
    if args.u and args.ul then&lt;br /&gt;
        return valerror('unit (&amp;lt;b&amp;gt;u&amp;lt;/b&amp;gt;) and unit with link (&amp;lt;b&amp;gt;ul&amp;lt;/b&amp;gt;) are both specified, only one is allowed.', nocat)&lt;br /&gt;
    end&lt;br /&gt;
    if args.up and args.upl then&lt;br /&gt;
        return valerror('unit per (&amp;lt;b&amp;gt;up&amp;lt;/b&amp;gt;) and unit per with link (&amp;lt;b&amp;gt;upl&amp;lt;/b&amp;gt;) are both specified, only one is allowed.', nocat)&lt;br /&gt;
    end&lt;br /&gt;
    local values&lt;br /&gt;
    if numbers.has_ranges then&lt;br /&gt;
        -- Multiple values with range separators but no uncertainty.&lt;br /&gt;
        numbers.nend = args['end']&lt;br /&gt;
        values = {&lt;br /&gt;
            numbers = numbers,&lt;br /&gt;
        }&lt;br /&gt;
    else&lt;br /&gt;
        -- A single value with optional uncertainty.&lt;br /&gt;
        local function setfield(i, dst, src)&lt;br /&gt;
            local v = args[src]&lt;br /&gt;
            if v then&lt;br /&gt;
                if numbers[i] then&lt;br /&gt;
                    numbers[i][dst] = v&lt;br /&gt;
                else&lt;br /&gt;
                    numbers[i] = { [dst] = v }&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
        setfield(1, 'nend', 'end')&lt;br /&gt;
        setfield(2, 'errend', '+errend')&lt;br /&gt;
        setfield(3, 'errend', '-errend')&lt;br /&gt;
        values = {&lt;br /&gt;
            number = numbers[1],&lt;br /&gt;
            uncertainty = {&lt;br /&gt;
                upper = numbers[2],&lt;br /&gt;
                lower = numbers[3],&lt;br /&gt;
                errend = args.errend,&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    end&lt;br /&gt;
    local unit_spec = {&lt;br /&gt;
            u = args.ul or args.u,&lt;br /&gt;
            want_link = args.ul ~= nil,&lt;br /&gt;
            per = args.upl or args.up,&lt;br /&gt;
            want_per_link = args.upl ~= nil,&lt;br /&gt;
            want_longscale = (args.longscale or args.long_scale or args['long scale']) == 'on',&lt;br /&gt;
        }&lt;br /&gt;
    local options = {&lt;br /&gt;
            action = args.action,&lt;br /&gt;
            align = args.a,&lt;br /&gt;
            e = numbers.e,&lt;br /&gt;
            fmt = args.fmt,&lt;br /&gt;
            nocat = nocat,&lt;br /&gt;
            prefix = args.p,&lt;br /&gt;
            sandbox = string.find(frame:getTitle(), 'sandbox', 1, true) ~= nil,&lt;br /&gt;
            sortable = args.sortable or (args.debug == 'yes' and 'debug' or nil),&lt;br /&gt;
            suffix = args.s,&lt;br /&gt;
            warning = check_parameters(args, numbers.has_ranges, nocat),&lt;br /&gt;
        }&lt;br /&gt;
    return _main(values, unit_spec, options)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return { main = main, _main = _main }&lt;/div&gt;</summary>
		<author><name>dw&gt;FelixJL111</name></author>
	</entry>
</feed>