<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://wiki.onlyfulk.com/history/Modul:Vorlage:Phab?feed=atom</id>
	<title>Modul:Vorlage:Phab - Versionsgeschichte</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.onlyfulk.com/history/Modul:Vorlage:Phab?feed=atom"/>
	<link rel="alternate" type="text/html" href="https://wiki.onlyfulk.com/history/Modul:Vorlage:Phab"/>
	<updated>2026-04-25T17:36:24Z</updated>
	<subtitle>Versionsgeschichte dieser Seite in Tobinator-Wiki</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>https://wiki.onlyfulk.com/index.php?title=Modul:Vorlage:Phab&amp;diff=1925&amp;oldid=prev</id>
		<title>Wiki SysAdm: Schützte „Modul:Vorlage:Phab“ ([Bearbeiten=Nur Administratoren erlauben] (unbeschränkt) [Verschieben=Nur Administratoren erlauben] (unbeschränkt))</title>
		<link rel="alternate" type="text/html" href="https://wiki.onlyfulk.com/index.php?title=Modul:Vorlage:Phab&amp;diff=1925&amp;oldid=prev"/>
		<updated>2025-02-26T23:34:35Z</updated>

		<summary type="html">&lt;p&gt;Schützte „&lt;a href=&quot;/Modul:Vorlage:Phab&quot; title=&quot;Modul:Vorlage:Phab&quot;&gt;Modul:Vorlage:Phab&lt;/a&gt;“ ([Bearbeiten=Nur Administratoren erlauben] (unbeschränkt) [Verschieben=Nur Administratoren erlauben] (unbeschränkt))&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;de&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Nächstältere Version&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Version vom 27. Februar 2025, 01:34 Uhr&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;de&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(kein Unterschied)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Wiki SysAdm</name></author>
	</entry>
	<entry>
		<id>https://wiki.onlyfulk.com/index.php?title=Modul:Vorlage:Phab&amp;diff=1176&amp;oldid=prev</id>
		<title>UltimateG4ming: Die Seite wurde neu angelegt: „local Phab = { suite  = &quot;Phab&quot;,                serial = &quot;2021-03-30&quot;,                sick   = &quot;Category:Wikipedia:Vorlagenfehler/Vorlage:Phab&quot;,                site   = &quot;https://phabricator.wikimedia.org/&quot;,                item   = 97313076 } --[=[ {{Template:Phab}} ]=] local Failsafe = Phab    local function concatKeys( args )     -- Concatenate keys     -- Precondition:     --     args   -- table; assignments     local r     for k in pairs( args ) do…“</title>
		<link rel="alternate" type="text/html" href="https://wiki.onlyfulk.com/index.php?title=Modul:Vorlage:Phab&amp;diff=1176&amp;oldid=prev"/>
		<updated>2025-02-24T22:23:03Z</updated>

		<summary type="html">&lt;p&gt;Die Seite wurde neu angelegt: „local Phab = { suite  = &amp;quot;Phab&amp;quot;,                serial = &amp;quot;2021-03-30&amp;quot;,                sick   = &amp;quot;Category:Wikipedia:Vorlagenfehler/Vorlage:Phab&amp;quot;,                site   = &amp;quot;https://phabricator.wikimedia.org/&amp;quot;,                item   = 97313076 } --[=[ {{Template:Phab}} ]=] local Failsafe = Phab    local function concatKeys( args )     -- Concatenate keys     -- Precondition:     --     args   -- table; assignments     local r     for k in pairs( args ) do…“&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Neue Seite&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local Phab = { suite  = &amp;quot;Phab&amp;quot;,&lt;br /&gt;
               serial = &amp;quot;2021-03-30&amp;quot;,&lt;br /&gt;
               sick   = &amp;quot;Category:Wikipedia:Vorlagenfehler/Vorlage:Phab&amp;quot;,&lt;br /&gt;
               site   = &amp;quot;https://phabricator.wikimedia.org/&amp;quot;,&lt;br /&gt;
               item   = 97313076 }&lt;br /&gt;
--[=[&lt;br /&gt;
{{Template:Phab}}&lt;br /&gt;
]=]&lt;br /&gt;
local Failsafe = Phab&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function concatKeys( args )&lt;br /&gt;
    -- Concatenate keys&lt;br /&gt;
    -- Precondition:&lt;br /&gt;
    --     args   -- table; assignments&lt;br /&gt;
    local r&lt;br /&gt;
    for k in pairs( args ) do&lt;br /&gt;
        if r then&lt;br /&gt;
            r = r .. &amp;quot; &amp;quot;&lt;br /&gt;
        else&lt;br /&gt;
            r = &amp;quot;&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        r = r .. tostring( k )&lt;br /&gt;
    end -- for k&lt;br /&gt;
    return r&lt;br /&gt;
end -- concatKeys()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function file( args )&lt;br /&gt;
    -- Link to a File&lt;br /&gt;
    -- Precondition:&lt;br /&gt;
    --     args   -- table; assignments&lt;br /&gt;
    --                      .File&lt;br /&gt;
    --                      .Show&lt;br /&gt;
    --                      .style&lt;br /&gt;
    -- Postcondition:&lt;br /&gt;
    --     Returns string with bracketed external link, if fine&lt;br /&gt;
    --     Throws error on failure&lt;br /&gt;
    local r = args.File&lt;br /&gt;
    local j = r:find( &amp;quot;,&amp;quot;, 1, true )&lt;br /&gt;
    local n, params, show&lt;br /&gt;
    if j then&lt;br /&gt;
        params = r:sub( j + 1 )&lt;br /&gt;
        r      = r:sub( 1,  j - 1 )&lt;br /&gt;
        -- params = mw.text.split( split, &amp;quot;%s*,%s*&amp;quot; )&lt;br /&gt;
        -- , width=, height=, size=&lt;br /&gt;
        -- , layout, float, alt&lt;br /&gt;
    end&lt;br /&gt;
    n = r:match( &amp;quot;^[Ff]?([0-9]+)%s*$&amp;quot; )&lt;br /&gt;
    if n then&lt;br /&gt;
        n = tonumber( n )   -- discard leading zeros&lt;br /&gt;
    else&lt;br /&gt;
        r = string.format( &amp;quot;Invalid format: &amp;#039;File=%s&amp;#039;&amp;quot;, r )&lt;br /&gt;
        error( r, 0 )&lt;br /&gt;
    end&lt;br /&gt;
    if args.style then&lt;br /&gt;
        if args.Show then&lt;br /&gt;
            show = args.Show&lt;br /&gt;
        else&lt;br /&gt;
            show = string.format( &amp;quot;F%d&amp;quot;, n )&lt;br /&gt;
        end&lt;br /&gt;
        show = string.format( &amp;quot;&amp;lt;span style=&amp;#039;%s&amp;#039;&amp;gt;%s&amp;lt;/span&amp;gt;&amp;quot;,&lt;br /&gt;
                              args.style, show )&lt;br /&gt;
    end&lt;br /&gt;
    if show then&lt;br /&gt;
        r = string.format( &amp;quot;[[phab:F%d|%s]]&amp;quot;, n, show )&lt;br /&gt;
    else&lt;br /&gt;
        r = string.format( &amp;quot;[[phab:F%d]]&amp;quot;, n )&lt;br /&gt;
    end&lt;br /&gt;
    return r&lt;br /&gt;
end -- file()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function git( action, assembly, adopt, attach, anchor, against )&lt;br /&gt;
    -- Create URL for mediawiki GIT since 2013-06-06&lt;br /&gt;
    -- Precondition:&lt;br /&gt;
    --     action    -- string; kind of request&lt;br /&gt;
    --     assembly  -- string; project&lt;br /&gt;
    --     adopt     -- string; branch&lt;br /&gt;
    --     attach    -- string; file or directory (or empty)&lt;br /&gt;
    --     anchor    -- string; line number (or empty)&lt;br /&gt;
    --     against   -- string; diff ./. previous ID (or empty)&lt;br /&gt;
    -- Postcondition:&lt;br /&gt;
    --     Return URL&lt;br /&gt;
    -- Uses:&lt;br /&gt;
    --     mw.uri.encode()&lt;br /&gt;
    local r = &amp;quot;https://git.wikimedia.org/&amp;quot;&lt;br /&gt;
    if action == &amp;quot;file&amp;quot; then&lt;br /&gt;
        r = r .. &amp;quot;blob&amp;quot;&lt;br /&gt;
        if against then&lt;br /&gt;
            r = r .. &amp;quot;diff&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
    elseif action == &amp;quot;dir&amp;quot; then&lt;br /&gt;
        r = r .. &amp;quot;tree&amp;quot;&lt;br /&gt;
    elseif action == &amp;quot;plain&amp;quot; then&lt;br /&gt;
        r = r .. &amp;quot;raw&amp;quot;&lt;br /&gt;
    elseif action == &amp;quot;commit&amp;quot; or&lt;br /&gt;
           action == &amp;quot;commitdiff&amp;quot; or&lt;br /&gt;
           action == &amp;quot;history&amp;quot; then&lt;br /&gt;
        r = r .. action&lt;br /&gt;
    end&lt;br /&gt;
    r = r .. &amp;quot;/&amp;quot; .. mw.uri.encode( assembly ) .. &amp;quot;/&amp;quot; .. adopt&lt;br /&gt;
    if attach then&lt;br /&gt;
        r = r .. &amp;quot;/&amp;quot; .. mw.uri.encode( attach, &amp;quot;PATH&amp;quot; )&lt;br /&gt;
    end&lt;br /&gt;
    if anchor then&lt;br /&gt;
        r = r .. &amp;quot;#L&amp;quot; .. anchor&lt;br /&gt;
    end&lt;br /&gt;
    return r&lt;br /&gt;
end -- git()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function id40( ask )&lt;br /&gt;
    -- Check for 40 hex lowercase id&lt;br /&gt;
    -- Precondition:&lt;br /&gt;
    --     ask  -- string; project&lt;br /&gt;
    -- Postcondition:&lt;br /&gt;
    --     Throws error, if failed&lt;br /&gt;
    if #ask ~= 40 or ask:match( &amp;quot;^[0-9a-f]+$&amp;quot; ) ~= ask then&lt;br /&gt;
        local e = &amp;quot;Invalid identifier: &amp;quot; .. ask&lt;br /&gt;
        error( e,  0 )&lt;br /&gt;
    end&lt;br /&gt;
end -- id40()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function intersect( args, alone )&lt;br /&gt;
    -- Find elements occurring in both args and alone&lt;br /&gt;
    -- Precondition:&lt;br /&gt;
    --     args   -- table; assignments&lt;br /&gt;
    --     alone  -- table (sequence)&lt;br /&gt;
    -- Postcondition:&lt;br /&gt;
    --     Return table with sequence of matching elements, or false&lt;br /&gt;
    local r = { }&lt;br /&gt;
    local i&lt;br /&gt;
    for k, v in pairs( args ) do&lt;br /&gt;
        for i = 1, #alone do&lt;br /&gt;
            if k == alone[ i ] then&lt;br /&gt;
                table.insert( r, k )&lt;br /&gt;
            end&lt;br /&gt;
        end -- for i&lt;br /&gt;
    end -- for k, v&lt;br /&gt;
    if #r == 0 then&lt;br /&gt;
        r = false&lt;br /&gt;
    end&lt;br /&gt;
    return r&lt;br /&gt;
end -- intersect()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function lonely( args, alone )&lt;br /&gt;
    -- Find elements occurring in both args and alone&lt;br /&gt;
    -- Precondition:&lt;br /&gt;
    --     args   -- table; assignments&lt;br /&gt;
    --     alone  -- table (sequence)&lt;br /&gt;
    -- Postcondition:&lt;br /&gt;
    --     Throws error, if occurring in both&lt;br /&gt;
    --     Return single matching element, or false&lt;br /&gt;
    -- Uses:&lt;br /&gt;
    --     intersect()&lt;br /&gt;
    --     mw.text.listToText()&lt;br /&gt;
    local r = intersect( args, alone )&lt;br /&gt;
    if r then&lt;br /&gt;
        if #r &amp;gt; 1 then&lt;br /&gt;
            r = &amp;quot;Must not be used together: &amp;#039;&amp;#039;&amp;quot;&lt;br /&gt;
                .. mw.text.listToText( r,  &amp;quot;, &amp;quot;,  &amp;quot; &amp;quot; ) .. &amp;quot;&amp;#039;&amp;#039;&amp;quot;&lt;br /&gt;
            error( r, 0 )&lt;br /&gt;
        end&lt;br /&gt;
        r = r[ 1 ]&lt;br /&gt;
    end&lt;br /&gt;
    return r&lt;br /&gt;
end -- lonely()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function mock( args )&lt;br /&gt;
    -- Link to a Mock&lt;br /&gt;
    -- Precondition:&lt;br /&gt;
    --     args   -- table; assignments&lt;br /&gt;
    --                      .Mock&lt;br /&gt;
    --                      .Show&lt;br /&gt;
    --                      .style&lt;br /&gt;
    -- Postcondition:&lt;br /&gt;
    --     Returns string with bracketed external link, if fine&lt;br /&gt;
    --     Throws error on failure&lt;br /&gt;
    local r = args.Mock&lt;br /&gt;
    local n = r:match( &amp;quot;^[Mm]?([0-9]+)$&amp;quot; )&lt;br /&gt;
    local show&lt;br /&gt;
    if n then&lt;br /&gt;
        n = tonumber( n )   -- discard leading zeros&lt;br /&gt;
    else&lt;br /&gt;
        r = string.format( &amp;quot;Invalid format: &amp;#039;Mock=%s&amp;#039;&amp;quot;, r )&lt;br /&gt;
        error( r, 0 )&lt;br /&gt;
    end&lt;br /&gt;
    if args.style then&lt;br /&gt;
        if args.Show then&lt;br /&gt;
            show = args.Show&lt;br /&gt;
        else&lt;br /&gt;
            show = string.format( &amp;quot;M%d&amp;quot;, n )&lt;br /&gt;
        end&lt;br /&gt;
        show = string.format( &amp;quot;&amp;lt;span style=&amp;#039;%s&amp;#039;&amp;gt;%s&amp;lt;/span&amp;gt;&amp;quot;,&lt;br /&gt;
                              args.style, show )&lt;br /&gt;
    end&lt;br /&gt;
    if show then&lt;br /&gt;
        r = string.format( &amp;quot;[[phab:M%d|%s]]&amp;quot;, n, show )&lt;br /&gt;
    else&lt;br /&gt;
        r = string.format( &amp;quot;[[phab:M%d]]&amp;quot;, n )&lt;br /&gt;
    end&lt;br /&gt;
    return r&lt;br /&gt;
end -- mock()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function phabAssigned( frame )&lt;br /&gt;
    -- Retrieve table with callsign assignments&lt;br /&gt;
    -- Precondition:&lt;br /&gt;
    --     frame   -- object or nil&lt;br /&gt;
    -- Postcondition:&lt;br /&gt;
    --     Return table or nil&lt;br /&gt;
    --     Throws error on failure&lt;br /&gt;
    -- Uses:&lt;br /&gt;
    --     mw.getCurrentFrame()&lt;br /&gt;
    --     mw.loadData()&lt;br /&gt;
    local got, lucky, r, s&lt;br /&gt;
    if not frame then&lt;br /&gt;
        frame = mw.getCurrentFrame()&lt;br /&gt;
    end&lt;br /&gt;
    s = frame:getTitle() .. &amp;quot;/callsigns&amp;quot;&lt;br /&gt;
    lucky, got = pcall( mw.loadData, s )&lt;br /&gt;
    if type( got ) == &amp;quot;table&amp;quot; then&lt;br /&gt;
        r = got&lt;br /&gt;
    else&lt;br /&gt;
        error( &amp;quot;Invalid: &amp;quot; .. s,  0 )&lt;br /&gt;
    end&lt;br /&gt;
    return r&lt;br /&gt;
end -- phabAssigned()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function phabBoards( args )&lt;br /&gt;
    -- Link to a board, project, team: tag&lt;br /&gt;
    -- Precondition:&lt;br /&gt;
    --     args   -- table; assignments&lt;br /&gt;
    --                      .Engage&lt;br /&gt;
    --                      .Show&lt;br /&gt;
    --                      .style&lt;br /&gt;
    --               string; single ID&lt;br /&gt;
    -- Postcondition:&lt;br /&gt;
    --     Returns string URL, if fine&lt;br /&gt;
    local s = type( args )&lt;br /&gt;
    local n, r, show, tags&lt;br /&gt;
    if s == &amp;quot;table&amp;quot; then&lt;br /&gt;
        if type( args.Engage ) == &amp;quot;string&amp;quot; then&lt;br /&gt;
            tags = args.Engage&lt;br /&gt;
        end&lt;br /&gt;
        if args.Show and ( args.Show ~= &amp;quot;&amp;quot; ) then&lt;br /&gt;
            show = args.Show&lt;br /&gt;
        end&lt;br /&gt;
    elseif s == &amp;quot;string&amp;quot; then&lt;br /&gt;
        tags = args&lt;br /&gt;
    end&lt;br /&gt;
    if not tags  or  tags == &amp;quot;&amp;quot; then&lt;br /&gt;
        tags = &amp;quot;MediaWiki-General-or-Unknown&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    tags = mw.text.split( tags, &amp;quot;%s+&amp;quot; )&lt;br /&gt;
    n    = #tags&lt;br /&gt;
    if show  and  n &amp;gt; 1 then&lt;br /&gt;
        show = false&lt;br /&gt;
    end&lt;br /&gt;
    for i = 1, n do&lt;br /&gt;
        s = tags[ i ]&lt;br /&gt;
        if r then&lt;br /&gt;
            r = r .. &amp;quot; | &amp;quot;&lt;br /&gt;
        else&lt;br /&gt;
            r = &amp;quot;&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        if not show then&lt;br /&gt;
            show = &amp;quot;#&amp;quot; .. s&lt;br /&gt;
        end&lt;br /&gt;
        if args.style then&lt;br /&gt;
            show = string.format( &amp;quot;&amp;lt;span style=&amp;#039;%s&amp;#039;&amp;gt;%s&amp;lt;/span&amp;gt;&amp;quot;,&lt;br /&gt;
                                  args.style, show )&lt;br /&gt;
        end&lt;br /&gt;
        r = string.format( &amp;quot;%s[[phab:tag/%s|%s]]&amp;quot;,&lt;br /&gt;
                           r, s, show )&lt;br /&gt;
    end -- for i&lt;br /&gt;
    return r&lt;br /&gt;
end -- phabBoards()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function phabCallsigns( args, frame )&lt;br /&gt;
    -- Create wikitable of all callsigns&lt;br /&gt;
    -- Precondition:&lt;br /&gt;
    --     args   -- table; options&lt;br /&gt;
    --     frame  -- object or nil&lt;br /&gt;
    -- Uses:&lt;br /&gt;
    --     phabAssigned()&lt;br /&gt;
    local connect = phabAssigned( frame )&lt;br /&gt;
    local r&lt;br /&gt;
    if connect then&lt;br /&gt;
        local limit     = ( args.callsigns == &amp;quot;0&amp;quot; )&lt;br /&gt;
        local callsigns = { }&lt;br /&gt;
        local order     = { }&lt;br /&gt;
        local sub       = &amp;quot;phab:diffusion/&amp;quot;&lt;br /&gt;
        local details, pages, s, sign, support&lt;br /&gt;
        r = &amp;quot;{| class=&amp;#039;wikitable sortable&amp;#039;\n&amp;quot; ..&lt;br /&gt;
            &amp;quot;|- class=&amp;#039;hintergrundfarbe6&amp;#039;\n&amp;quot; ..&lt;br /&gt;
            &amp;quot;! Callsign !! &amp;#039;&amp;#039;repository&amp;#039;&amp;#039; !!class=&amp;#039;unsortable&amp;#039;| Infos\n&amp;quot;&lt;br /&gt;
        for k, v in pairs( connect ) do&lt;br /&gt;
            if k:find( &amp;quot;/&amp;quot;, 3, true ) then&lt;br /&gt;
                -- GIT legacy&lt;br /&gt;
                v = false&lt;br /&gt;
            elseif limit  and  type( v ) == &amp;quot;string&amp;quot; then&lt;br /&gt;
                details = connect[ v ]&lt;br /&gt;
                if type( details ) == &amp;quot;table&amp;quot;   and&lt;br /&gt;
                   type( details.list ) == &amp;quot;boolean&amp;quot;   and&lt;br /&gt;
                   not details.list then&lt;br /&gt;
                    v = false&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
            if type( v ) == &amp;quot;string&amp;quot; then&lt;br /&gt;
                s = callsigns[ v ]&lt;br /&gt;
                if s then&lt;br /&gt;
                    if #s &amp;lt; #k then&lt;br /&gt;
                        callsigns[ v ] = k&lt;br /&gt;
                    end&lt;br /&gt;
                else&lt;br /&gt;
                    callsigns[ v ] = k&lt;br /&gt;
                    table.insert( order, v )&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
        end -- for k, v&lt;br /&gt;
        table.sort( order )&lt;br /&gt;
        for i = 1, #order do&lt;br /&gt;
            sign  = order[ i ]&lt;br /&gt;
            show  = callsigns[ sign ]&lt;br /&gt;
            r     = string.format( &amp;quot;%s|- id=&amp;#039;%s&amp;#039;\n|[[%s%s|%s]]||%s\n&amp;quot;,&lt;br /&gt;
                                   r, sign, sub, sign, sign, show )&lt;br /&gt;
            pages = { }&lt;br /&gt;
            details = connect[ sign ]&lt;br /&gt;
            if type( details ) ~= &amp;quot;table&amp;quot; then&lt;br /&gt;
                details = { }&lt;br /&gt;
            end&lt;br /&gt;
            if details.say then&lt;br /&gt;
                table.insert( pages, details.say )&lt;br /&gt;
            end&lt;br /&gt;
            if details.support then&lt;br /&gt;
                table.insert( pages,&lt;br /&gt;
                              string.format( &amp;quot;[[%s]]&amp;quot;,&lt;br /&gt;
                                             details.support ) )&lt;br /&gt;
            end&lt;br /&gt;
            if type( details.tags ) == &amp;quot;table&amp;quot; then&lt;br /&gt;
                for k, v in pairs( details.tags ) do&lt;br /&gt;
                    table.insert( pages,  phabBoards( v ) )&lt;br /&gt;
                end -- for k, v&lt;br /&gt;
            end&lt;br /&gt;
            support = details.mwPage&lt;br /&gt;
            if not support then&lt;br /&gt;
                s = show:match( &amp;quot;^extension%-([%w_]+)$&amp;quot; )&lt;br /&gt;
                if s then&lt;br /&gt;
                    support = &amp;quot;Extension:&amp;quot; .. s&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
            if support  and  support ~= &amp;quot;&amp;quot; then&lt;br /&gt;
                table.insert( pages,&lt;br /&gt;
                              string.format( &amp;quot;[[mw:%s]]&amp;quot;, support ) )&lt;br /&gt;
            end&lt;br /&gt;
            if #pages &amp;gt; 0 then&lt;br /&gt;
                r = string.format( &amp;quot;%s|%s\n&amp;quot;,&lt;br /&gt;
                                   r,  table.concat( pages, &amp;quot;&amp;lt;br&amp;gt;&amp;quot; ) )&lt;br /&gt;
            end&lt;br /&gt;
        end -- for i&lt;br /&gt;
        r = string.format( &amp;quot;%s|}\n%d &amp;quot;,&lt;br /&gt;
                           r, #order )&lt;br /&gt;
    end&lt;br /&gt;
    return r&lt;br /&gt;
end -- phabCallsigns()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function phabDiffusion( action, assembly, adopt, attach,&lt;br /&gt;
                              anchor, against, as, frame )&lt;br /&gt;
    -- Create path for Phabricator Diffusion since 2015-03&lt;br /&gt;
    -- Precondition:&lt;br /&gt;
    --     action    -- string; kind of request&lt;br /&gt;
    --     assembly  -- string; project&lt;br /&gt;
    --     adopt     -- string; branch&lt;br /&gt;
    --     attach    -- string; file or directory (or empty)&lt;br /&gt;
    --     anchor    -- string; line number (or empty)&lt;br /&gt;
    --     against   -- string; diff ./. previous ID (or empty)&lt;br /&gt;
    --     as        -- string; s  = query&lt;br /&gt;
    --     frame     -- object or nil&lt;br /&gt;
    -- Postcondition:&lt;br /&gt;
    --     Return        1  -- URL, if identified, or nil&lt;br /&gt;
    --                   2  -- callsign, or nil&lt;br /&gt;
    -- Uses:&lt;br /&gt;
    --     phabAssigned()&lt;br /&gt;
    local translate = phabAssigned( frame )&lt;br /&gt;
    local r, shortcut, sub&lt;br /&gt;
    if translate then&lt;br /&gt;
        if assembly:match( &amp;quot;^%u%u%u?%u?$&amp;quot; ) then&lt;br /&gt;
            shortcut = assembly&lt;br /&gt;
        elseif assembly:match( &amp;quot;^R%d+$&amp;quot; ) then&lt;br /&gt;
            shortcut = assembly&lt;br /&gt;
            sub      = &amp;quot;source/&amp;quot; .. shortcut&lt;br /&gt;
        else&lt;br /&gt;
            shortcut = translate[ assembly ]&lt;br /&gt;
            if not shortcut  and  assembly:find( &amp;quot;/&amp;quot;, 3, true ) then&lt;br /&gt;
                -- GIT legacy&lt;br /&gt;
                local s = assembly:gsub( &amp;quot;mediawiki/extensions/&amp;quot;,&lt;br /&gt;
                                         &amp;quot;extension-&amp;quot; )&lt;br /&gt;
                shortcut = translate[ s ]&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
        if shortcut then&lt;br /&gt;
            local state, swift&lt;br /&gt;
            if adopt ~= &amp;quot;master&amp;quot;  and  adopt ~= &amp;quot;HEAD&amp;quot; then&lt;br /&gt;
                state = adopt&lt;br /&gt;
            end&lt;br /&gt;
            if attach and  not state then&lt;br /&gt;
                state = &amp;quot;master&amp;quot;&lt;br /&gt;
            end&lt;br /&gt;
            if state then&lt;br /&gt;
                if action then&lt;br /&gt;
                    if action == &amp;quot;commit&amp;quot;   or&lt;br /&gt;
                       action == &amp;quot;commitdiff&amp;quot; then&lt;br /&gt;
                        if attach then&lt;br /&gt;
                            if action == &amp;quot;commit&amp;quot; then&lt;br /&gt;
                                swift = &amp;quot;browse&amp;quot;&lt;br /&gt;
                            else&lt;br /&gt;
                                swift = &amp;quot;change&amp;quot;&lt;br /&gt;
                            end&lt;br /&gt;
                            state = &amp;quot;master&amp;quot;&lt;br /&gt;
                        else&lt;br /&gt;
                            sub = string.format( &amp;quot;r%s%s&amp;quot;,&lt;br /&gt;
                                                 shortcut, state )&lt;br /&gt;
                        end&lt;br /&gt;
                    elseif action == &amp;quot;history&amp;quot; then&lt;br /&gt;
                        swift = action&lt;br /&gt;
                    else&lt;br /&gt;
                        swift = &amp;quot;browse&amp;quot;&lt;br /&gt;
                    end&lt;br /&gt;
                else&lt;br /&gt;
                    swift = &amp;quot;browse&amp;quot;&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
            if not sub then&lt;br /&gt;
                sub = &amp;quot;diffusion/&amp;quot; .. shortcut&lt;br /&gt;
            end&lt;br /&gt;
            if swift then&lt;br /&gt;
                sub = string.format( &amp;quot;%s/%s&amp;quot;, sub, swift )&lt;br /&gt;
                if state then&lt;br /&gt;
                    local sep&lt;br /&gt;
                    if state == &amp;quot;master&amp;quot; then&lt;br /&gt;
                        sep = &amp;quot;/&amp;quot;&lt;br /&gt;
                    else&lt;br /&gt;
                        sep = &amp;quot;&amp;quot;&lt;br /&gt;
                    end&lt;br /&gt;
                    sub = string.format( &amp;quot;%s%s%s&amp;quot;, sub, sep, state )&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
            if attach then&lt;br /&gt;
                sub = string.format( &amp;quot;%s/%s&amp;quot;, sub, attach )&lt;br /&gt;
                if adopt&lt;br /&gt;
                   and  adopt ~= &amp;quot;HEAD&amp;quot;&lt;br /&gt;
                   and  state ~= adopt then&lt;br /&gt;
                    sub = string.format( &amp;quot;%s;%s&amp;quot;, sub, adopt )&lt;br /&gt;
                end&lt;br /&gt;
                if anchor then&lt;br /&gt;
                    sub = string.format( &amp;quot;%s$%s&amp;quot;, sub, anchor )&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
            if as then&lt;br /&gt;
                sub = string.format( &amp;quot;%s?%s&amp;quot;, sub, as )&lt;br /&gt;
            end&lt;br /&gt;
            r = Phab.site .. sub:gsub( &amp;quot; &amp;quot;, &amp;quot;%%20&amp;quot; )&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return r, shortcut&lt;br /&gt;
end -- phabDiffusion()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function phabUser( args, frame )&lt;br /&gt;
    -- Link to a user&lt;br /&gt;
    -- Precondition:&lt;br /&gt;
    --     args   -- table; assignments&lt;br /&gt;
    --                      .User&lt;br /&gt;
    --                      .Show&lt;br /&gt;
    --                      .style&lt;br /&gt;
    --     frame  -- object or nil&lt;br /&gt;
    -- Postcondition:&lt;br /&gt;
    --     Returns string URL, if fine&lt;br /&gt;
    -- Uses:&lt;br /&gt;
    --     mw.text.trim()&lt;br /&gt;
    local r&lt;br /&gt;
    local single = args.User&lt;br /&gt;
    if type( single ) == &amp;quot;string&amp;quot; then&lt;br /&gt;
        single = mw.text.trim( single )&lt;br /&gt;
    end&lt;br /&gt;
    if type( single ) == &amp;quot;string&amp;quot;  and  single ~= &amp;quot;&amp;quot; then&lt;br /&gt;
        local show = args.Show&lt;br /&gt;
        if not show  or  show == &amp;quot;&amp;quot; then&lt;br /&gt;
            show = &amp;quot;@&amp;quot; .. single&lt;br /&gt;
        end&lt;br /&gt;
        if not frame then&lt;br /&gt;
            frame = mw.getCurrentFrame()&lt;br /&gt;
        end&lt;br /&gt;
        if args.style then&lt;br /&gt;
            show = string.format( &amp;quot;&amp;lt;span style=&amp;#039;%s&amp;#039;&amp;gt;%s&amp;lt;/span&amp;gt;&amp;quot;,&lt;br /&gt;
                                  args.style, show )&lt;br /&gt;
        end&lt;br /&gt;
        r = string.format( &amp;quot;[[phab:p/%s|%s]]&amp;quot;,&lt;br /&gt;
                           frame:callParserFunction( &amp;quot;urlencode&amp;quot;,&lt;br /&gt;
                                                     single ),&lt;br /&gt;
                           show )&lt;br /&gt;
    else&lt;br /&gt;
        r = string.format( &amp;quot;Missing User :-(&amp;quot; )&lt;br /&gt;
        error( r, 0 )&lt;br /&gt;
    end&lt;br /&gt;
    return r&lt;br /&gt;
end -- phabUser()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function sourcing( args, frame )&lt;br /&gt;
    -- Link to a code source, directory, branch or related&lt;br /&gt;
    -- Precondition:&lt;br /&gt;
    --     args   -- table; assignments&lt;br /&gt;
    --     frame  -- object or nil&lt;br /&gt;
    -- Postcondition:&lt;br /&gt;
    --     Returns string, if fine&lt;br /&gt;
    --     Throws error on failure&lt;br /&gt;
    -- Uses:&lt;br /&gt;
    --     lonely()&lt;br /&gt;
    --     id40()&lt;br /&gt;
    --     phabDiffusion()&lt;br /&gt;
    --     git()&lt;br /&gt;
    local jump   = false&lt;br /&gt;
    local last   = false&lt;br /&gt;
    local query  = false&lt;br /&gt;
    local scope  = &amp;quot;mediawiki/core&amp;quot;&lt;br /&gt;
    local show&lt;br /&gt;
    local since  = false&lt;br /&gt;
    local slot   = &amp;quot;HEAD&amp;quot;&lt;br /&gt;
    local source = false&lt;br /&gt;
    local swift  = &amp;quot;dir&amp;quot;&lt;br /&gt;
    local lapsus, load, r&lt;br /&gt;
    r = lonely( args,&lt;br /&gt;
                { &amp;quot;branch&amp;quot;, &amp;quot;commit&amp;quot;, &amp;quot;commitdiff&amp;quot;, &amp;quot;diff&amp;quot; } )&lt;br /&gt;
    if r then&lt;br /&gt;
        slot = args[ r ]&lt;br /&gt;
    end&lt;br /&gt;
    r = lonely( args,  { &amp;quot;dir&amp;quot;, &amp;quot;file&amp;quot;, &amp;quot;plain&amp;quot; } )&lt;br /&gt;
    if r then&lt;br /&gt;
        swift  = r&lt;br /&gt;
        source = args[ swift ]&lt;br /&gt;
        if args.file then&lt;br /&gt;
            local suffix = args.file:match( &amp;quot;%.(%l+)$&amp;quot; )&lt;br /&gt;
            if suffix then&lt;br /&gt;
                if suffix == &amp;quot;svg&amp;quot; then&lt;br /&gt;
                    query = &amp;quot;as=source&amp;amp;highlight=xml&amp;amp;&amp;quot;&lt;br /&gt;
                elseif suffix == &amp;quot;json&amp;quot; or&lt;br /&gt;
                       suffix == &amp;quot;txt&amp;quot; or&lt;br /&gt;
                       suffix == &amp;quot;xml&amp;quot; then&lt;br /&gt;
                    query = &amp;quot;?&amp;quot;&lt;br /&gt;
                end&lt;br /&gt;
                if query then&lt;br /&gt;
                    query = query .. &amp;quot;blame=off&amp;quot;&lt;br /&gt;
                end&lt;br /&gt;
                if suffix == &amp;quot;md&amp;quot; then&lt;br /&gt;
                    query = &amp;quot;as=remarkup&amp;quot;&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    r = lonely( args,  { &amp;quot;commit&amp;quot;, &amp;quot;commitdiff&amp;quot; } )&lt;br /&gt;
    if r then&lt;br /&gt;
        swift = r&lt;br /&gt;
        load  = true&lt;br /&gt;
    end&lt;br /&gt;
    if args.history then&lt;br /&gt;
        last = true&lt;br /&gt;
    end&lt;br /&gt;
    if args.project then&lt;br /&gt;
        scope = args.project&lt;br /&gt;
    end&lt;br /&gt;
    if args.line or args.diff then&lt;br /&gt;
        if not args.file then&lt;br /&gt;
            r = &amp;quot; valid for &amp;#039;&amp;#039;file&amp;#039;&amp;#039; only.&amp;quot;&lt;br /&gt;
            if args.line then&lt;br /&gt;
                r = &amp;quot;Number &amp;#039;&amp;#039;line&amp;#039;&amp;#039;&amp;quot; .. r&lt;br /&gt;
                if args.diff then&lt;br /&gt;
                    r = &amp;quot; / &amp;quot; .. r&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
            if args.diff then&lt;br /&gt;
                r = &amp;quot;Version &amp;#039;&amp;#039;diff&amp;#039;&amp;#039;&amp;quot; .. r&lt;br /&gt;
            end&lt;br /&gt;
            error( r, 0 )&lt;br /&gt;
        elseif args.line then&lt;br /&gt;
            if args.diff then&lt;br /&gt;
                r = &amp;quot;No &amp;#039;&amp;#039;line&amp;#039;&amp;#039; on &amp;#039;&amp;#039;diff&amp;#039;&amp;#039; page available&amp;quot;&lt;br /&gt;
                error( r, 0 )&lt;br /&gt;
            end&lt;br /&gt;
            jump = args.line&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    if load then&lt;br /&gt;
        if scope == &amp;quot;SVN&amp;quot; then&lt;br /&gt;
            r = &amp;quot;Invalid SVN identifier: &amp;quot;&lt;br /&gt;
            if slot:match( &amp;quot;^[0-9]+$&amp;quot; ) then&lt;br /&gt;
                slot = tonumber( slot )&lt;br /&gt;
                if slot &amp;gt;= 1  and  slot &amp;lt;= 115794 then&lt;br /&gt;
                    r = false&lt;br /&gt;
                end&lt;br /&gt;
                slot = string.format( &amp;quot;%d&amp;quot;, slot )&lt;br /&gt;
            end&lt;br /&gt;
            if r then&lt;br /&gt;
                local e = r .. slot&lt;br /&gt;
                error( e,  0 )&lt;br /&gt;
            end&lt;br /&gt;
        else&lt;br /&gt;
            id40( slot )&lt;br /&gt;
        end&lt;br /&gt;
    elseif args.diff then&lt;br /&gt;
        since = args.diff&lt;br /&gt;
        id40( since )&lt;br /&gt;
    elseif last then&lt;br /&gt;
        swift = &amp;quot;history&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    r, show = phabDiffusion( swift, scope, slot, source, jump, since,&lt;br /&gt;
                             query, frame )&lt;br /&gt;
    if args.title and ( args.title ~= &amp;quot;&amp;quot; ) then&lt;br /&gt;
        show = args.title&lt;br /&gt;
    elseif last and source then&lt;br /&gt;
        show = &amp;quot;history: &amp;quot; .. source&lt;br /&gt;
    elseif source then&lt;br /&gt;
        show = source&lt;br /&gt;
        if args.diff then&lt;br /&gt;
            show = string.format( &amp;quot;%s ./.%s&amp;quot;, show, since:sub( 1, 7 ) )&lt;br /&gt;
        elseif load then&lt;br /&gt;
            show = string.format( &amp;quot;%s;%s&amp;quot;, show, slot:sub( 1, 7 ) )&lt;br /&gt;
        end&lt;br /&gt;
    elseif load then&lt;br /&gt;
        if show then&lt;br /&gt;
            show   = &amp;quot;r&amp;quot; .. show&lt;br /&gt;
        else&lt;br /&gt;
            show = &amp;quot;GIT:&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        show = show .. slot:sub( 1, 7 )&lt;br /&gt;
    else&lt;br /&gt;
        show = scope .. &amp;quot;/*&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    if r then&lt;br /&gt;
        r = string.format( &amp;quot;[%s %s]&amp;quot;, r, show )&lt;br /&gt;
    else&lt;br /&gt;
        if not scope:find( &amp;quot;/&amp;quot;, 3, true ) then&lt;br /&gt;
            error( &amp;quot;Unknown project: &amp;quot; .. scope,  0 )&lt;br /&gt;
        end&lt;br /&gt;
        lonely( args,&lt;br /&gt;
                { &amp;quot;commit&amp;quot;, &amp;quot;commitdiff&amp;quot;, &amp;quot;dir&amp;quot;, &amp;quot;file&amp;quot;, &amp;quot;plain&amp;quot; } )&lt;br /&gt;
        r = git( swift, scope, slot, source, jump, since )&lt;br /&gt;
        r = string.format( &amp;quot;[%s %s]&amp;quot;, r, show )&lt;br /&gt;
        lapsus = true&lt;br /&gt;
    end&lt;br /&gt;
    if lapsus then&lt;br /&gt;
        r = string.format( &amp;quot;%s[[%s/Diffusion]]&amp;quot;,&lt;br /&gt;
                           r, Phab.sick )&lt;br /&gt;
    end&lt;br /&gt;
    return r&lt;br /&gt;
end -- sourcing()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function task( args )&lt;br /&gt;
    -- Link to a Task&lt;br /&gt;
    -- Precondition:&lt;br /&gt;
    --     args   -- table; assignments&lt;br /&gt;
    --                      .Task&lt;br /&gt;
    --                      .Anchor&lt;br /&gt;
    --                      .Show&lt;br /&gt;
    --                      .style&lt;br /&gt;
    -- Postcondition:&lt;br /&gt;
    --     Returns string with bracketed external link, if fine&lt;br /&gt;
    --     Throws error on failure&lt;br /&gt;
    local r   = args.Task&lt;br /&gt;
    local j   = r:find( &amp;quot;#&amp;quot;, 1, true )&lt;br /&gt;
    local sub = args.Anchor&lt;br /&gt;
    local n, show&lt;br /&gt;
    if j then&lt;br /&gt;
        local scroll = r:sub( j + 1 )&lt;br /&gt;
        r      = r:sub( 1,  j - 1 )&lt;br /&gt;
        scroll = scroll:match( &amp;quot;^([0-9]+)$&amp;quot; )&lt;br /&gt;
        if scroll  and  not sub then&lt;br /&gt;
            sub = scroll&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    n = r:match( &amp;quot;^[Tt]?([0-9]+)%s*$&amp;quot; )&lt;br /&gt;
    if n then&lt;br /&gt;
        n = tonumber( n )   -- discard leading zeros&lt;br /&gt;
    else&lt;br /&gt;
        r = string.format( &amp;quot;Invalid format: &amp;#039;Task=%s&amp;#039;&amp;quot;, r )&lt;br /&gt;
        error( r, 0 )&lt;br /&gt;
    end&lt;br /&gt;
    if sub then&lt;br /&gt;
        sub = string.format( &amp;quot;#%s&amp;quot;, sub )&lt;br /&gt;
    else&lt;br /&gt;
        sub = &amp;quot;&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    if args.Show then&lt;br /&gt;
        show = args.Show&lt;br /&gt;
    else&lt;br /&gt;
        show = string.format( &amp;quot;phab:T%d&amp;quot;, n )&lt;br /&gt;
        if args.Anchor then&lt;br /&gt;
            show = string.format( &amp;quot;%s&amp;amp;#160;#%s&amp;quot;, show, args.Anchor )&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    if args.style then&lt;br /&gt;
        show = string.format( &amp;quot;&amp;lt;span style=&amp;#039;%s&amp;#039;&amp;gt;%s&amp;lt;/span&amp;gt;&amp;quot;,&lt;br /&gt;
                              args.style, show )&lt;br /&gt;
    end&lt;br /&gt;
    r = string.format( &amp;quot;[[phab:T%d%s|%s]]&amp;quot;, n, sub, show )&lt;br /&gt;
    return r&lt;br /&gt;
end -- task()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function taskBugzilla( args )&lt;br /&gt;
    -- Link to an old Bugzilla ticket&lt;br /&gt;
    -- Precondition:&lt;br /&gt;
    --     args   -- table; assignments&lt;br /&gt;
    -- Postcondition:&lt;br /&gt;
    --     Returns string, if fine&lt;br /&gt;
    --     Throws error on failure&lt;br /&gt;
    -- Uses:&lt;br /&gt;
    --     task()&lt;br /&gt;
    local r = args.Bugzilla&lt;br /&gt;
    local j = r:find( &amp;quot;#&amp;quot;, 1, true )&lt;br /&gt;
    local item, n, show&lt;br /&gt;
    if j then&lt;br /&gt;
        local scroll = r:sub( j + 1 )&lt;br /&gt;
        r      = r:sub( 1,  j - 1 )&lt;br /&gt;
        scroll = scroll:match( &amp;quot;^[cC]?([0-9]+)$&amp;quot; )&lt;br /&gt;
        if scroll then&lt;br /&gt;
            item = tonumber( scroll )&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    n = r:match( &amp;quot;^([0-9]+)%s*$&amp;quot; )&lt;br /&gt;
    if n then&lt;br /&gt;
        n = tonumber( n )   -- discard leading zeros&lt;br /&gt;
        if n &amp;lt;= 73681 then&lt;br /&gt;
            args.Task = tostring( n + 2000 )&lt;br /&gt;
        else&lt;br /&gt;
            n = false&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    if not n then&lt;br /&gt;
        r = string.format( &amp;quot;Invalid number: &amp;#039;Bugzilla=%s&amp;#039;&amp;quot;, r )&lt;br /&gt;
        error( r, 0 )&lt;br /&gt;
    end&lt;br /&gt;
    r = string.format( &amp;quot;https://old-bugzilla.wikimedia.org/%s%d&amp;quot;,&lt;br /&gt;
                       &amp;quot;show_bug.cgi?id=&amp;quot;, n )&lt;br /&gt;
    show = string.format( &amp;quot;Bugzilla:%d&amp;quot;, n )&lt;br /&gt;
    if item then&lt;br /&gt;
        r    = string.format( &amp;quot;%s#c%d&amp;quot;, r, item )&lt;br /&gt;
        show = string.format( &amp;quot;%s&amp;amp;nbsp;#c%d&amp;quot;, show, item )&lt;br /&gt;
    end&lt;br /&gt;
    r = string.format( &amp;quot;[%s %s]&amp;quot;, r, show )&lt;br /&gt;
    r = string.format( &amp;quot;%s &amp;lt;small style=\&amp;quot;font-weight:normal\&amp;quot;&amp;gt;(%s)&amp;lt;/small&amp;gt;&amp;quot;,&lt;br /&gt;
                       task( args ),  r )&lt;br /&gt;
    return r&lt;br /&gt;
end -- taskBugzilla()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function unified( args, frame )&lt;br /&gt;
    -- Link to a management issue&lt;br /&gt;
    -- Precondition:&lt;br /&gt;
    --     args   -- table; assignments&lt;br /&gt;
    -- Postcondition:&lt;br /&gt;
    --     Returns string, if fine&lt;br /&gt;
    --     Throws error on failure&lt;br /&gt;
    -- Uses:&lt;br /&gt;
    --     lonely()&lt;br /&gt;
    --     taskBugzilla()&lt;br /&gt;
    --     task()&lt;br /&gt;
    --     phabBoards()&lt;br /&gt;
    --     phabUser()&lt;br /&gt;
    local r&lt;br /&gt;
    lonely( args,&lt;br /&gt;
            { &amp;quot;Bugzilla&amp;quot;, &amp;quot;Countdown&amp;quot;, &amp;quot;Differential&amp;quot;, &amp;quot;Engage&amp;quot;,&lt;br /&gt;
              &amp;quot;File&amp;quot;, &amp;quot;Gerrit&amp;quot;, &amp;quot;Join&amp;quot;, &amp;quot;Mock&amp;quot;, &amp;quot;Paste&amp;quot;, &amp;quot;Review&amp;quot;,&lt;br /&gt;
              &amp;quot;Task&amp;quot;, &amp;quot;User&amp;quot; } )&lt;br /&gt;
    if args.Bugzilla then&lt;br /&gt;
        r = taskBugzilla( args )&lt;br /&gt;
    elseif args.Engage then&lt;br /&gt;
        r = phabBoards( args )&lt;br /&gt;
    elseif args.File then&lt;br /&gt;
        r = file( args )&lt;br /&gt;
    elseif args.Mock then&lt;br /&gt;
        r = mock( args )&lt;br /&gt;
    elseif args.Task then&lt;br /&gt;
        r = task( args )&lt;br /&gt;
    elseif args.User then&lt;br /&gt;
        r = phabUser( args, frame )&lt;br /&gt;
    else&lt;br /&gt;
        r = &amp;quot;NOT YET READY&amp;quot;&lt;br /&gt;
        error( r, 0 )&lt;br /&gt;
    end&lt;br /&gt;
    --    Countdown&lt;br /&gt;
    --    Differential&lt;br /&gt;
    --    Gerrit&lt;br /&gt;
    --    Join&lt;br /&gt;
    --    Paste&lt;br /&gt;
    --    Review&lt;br /&gt;
    --    Leerzeichen-getrennte Liste&lt;br /&gt;
    return r&lt;br /&gt;
end -- unified()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function main( args, frame )&lt;br /&gt;
    -- Do the job&lt;br /&gt;
    -- Precondition:&lt;br /&gt;
    --     args   -- table; assignments&lt;br /&gt;
    --     frame  -- object or nil&lt;br /&gt;
    -- Postcondition:&lt;br /&gt;
    --     Returns string with link, if fine&lt;br /&gt;
    --     Throws error on failure&lt;br /&gt;
    -- Uses:&lt;br /&gt;
    --     unified()&lt;br /&gt;
    --     sourcing()&lt;br /&gt;
    local defaults = { Bugzilla = &amp;quot;&amp;quot;,&lt;br /&gt;
                       Engage   = true,&lt;br /&gt;
                       User     = true }&lt;br /&gt;
    local got    = { }&lt;br /&gt;
    local mode   = 0&lt;br /&gt;
    local params = { style = 0,&lt;br /&gt;
                     Anchor       = 1,&lt;br /&gt;
                     Anchor       = 1,&lt;br /&gt;
                     Bugzilla     = 1,&lt;br /&gt;
                     Countdown    = 1,&lt;br /&gt;
                     Differential = 1,&lt;br /&gt;
                     Engage       = 1,&lt;br /&gt;
                     File         = 1,&lt;br /&gt;
          --         Gerrit       = 1,&lt;br /&gt;
                     Join         = 1,&lt;br /&gt;
                     Mock         = 1,&lt;br /&gt;
                     Paste        = 1,&lt;br /&gt;
                     Review       = 1,&lt;br /&gt;
                     Show         = 1,&lt;br /&gt;
                     Task         = 1,&lt;br /&gt;
                     User         = 1,&lt;br /&gt;
                     branch     = 2,&lt;br /&gt;
                     commit     = 2,&lt;br /&gt;
                     commitdiff = 2,&lt;br /&gt;
                     diff       = 2,&lt;br /&gt;
                     dir        = 2,&lt;br /&gt;
                     file       = 2,&lt;br /&gt;
                     history    = 2,&lt;br /&gt;
                     line       = 2,&lt;br /&gt;
                     plain      = 2,&lt;br /&gt;
                     project    = 2,&lt;br /&gt;
                     title      = 2,&lt;br /&gt;
                     callsigns = 3 }&lt;br /&gt;
    local gr, s&lt;br /&gt;
    for k, v in pairs( args ) do&lt;br /&gt;
        mode = params[ k ]&lt;br /&gt;
        if not mode then&lt;br /&gt;
            mode = -1&lt;br /&gt;
        end&lt;br /&gt;
        if not got[ mode ] then&lt;br /&gt;
            got[ mode ] = { }&lt;br /&gt;
        end&lt;br /&gt;
        got[ mode ][ k ] = v&lt;br /&gt;
    end -- for k, v&lt;br /&gt;
    r = got[ -1 ]&lt;br /&gt;
    if r then&lt;br /&gt;
        if #r == 1 then&lt;br /&gt;
            s = &amp;quot;&amp;quot;&lt;br /&gt;
        else&lt;br /&gt;
            s = &amp;quot;s&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        r = string.format( &amp;quot;Unknown parameter%s: &amp;#039;%s&amp;#039;&amp;quot;,&lt;br /&gt;
                           s,  concatKeys( r ) )&lt;br /&gt;
        error( r, 0 )&lt;br /&gt;
    elseif got[ 1 ] and got[ 2 ] then&lt;br /&gt;
        r = string.format( &amp;quot;&amp;#039;%s&amp;#039; conflicting with &amp;#039;%s&amp;#039;&amp;quot;,&lt;br /&gt;
                           concatKeys( got[ 1 ] ),&lt;br /&gt;
                           concatKeys( got[ 2 ] ) )&lt;br /&gt;
        error( r, 0 )&lt;br /&gt;
    else&lt;br /&gt;
        local procs  = { unified, sourcing, phabCallsigns }&lt;br /&gt;
        if mode == 0 then&lt;br /&gt;
            mode = 2&lt;br /&gt;
            got[ 2 ] = { }&lt;br /&gt;
        end&lt;br /&gt;
        if got[ 0 ] then&lt;br /&gt;
            for k, v in pairs( got[ 0 ] ) do&lt;br /&gt;
                got[ mode ][ k ] = v&lt;br /&gt;
            end -- for k, v&lt;br /&gt;
        end&lt;br /&gt;
        got = got[ mode ]&lt;br /&gt;
        for k, v in pairs( got ) do&lt;br /&gt;
            s = type( v )&lt;br /&gt;
            if s == &amp;quot;number&amp;quot; then&lt;br /&gt;
                v = tostring( v )&lt;br /&gt;
            elseif s == &amp;quot;string&amp;quot; then&lt;br /&gt;
                if #v == 0 then&lt;br /&gt;
                    v = defaults[ k ]&lt;br /&gt;
                end&lt;br /&gt;
            elseif v == true then&lt;br /&gt;
                v = defaults[ k ]&lt;br /&gt;
            else&lt;br /&gt;
                v = nil&lt;br /&gt;
            end&lt;br /&gt;
            if v then&lt;br /&gt;
                got[ k ] = v&lt;br /&gt;
            else&lt;br /&gt;
                got[ k ] = nil&lt;br /&gt;
            end&lt;br /&gt;
        end -- for k, v&lt;br /&gt;
        r = procs[ mode ]( got, frame )&lt;br /&gt;
    end&lt;br /&gt;
    return r&lt;br /&gt;
end -- main()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Failsafe.failsafe = function ( atleast )&lt;br /&gt;
    -- Retrieve versioning and check for compliance&lt;br /&gt;
    -- Precondition:&lt;br /&gt;
    --     atleast  -- string, with required version&lt;br /&gt;
    --                         or wikidata|item|~|@ or false&lt;br /&gt;
    -- Postcondition:&lt;br /&gt;
    --     Returns  string  -- with queried version/item, also if problem&lt;br /&gt;
    --              false   -- if appropriate&lt;br /&gt;
    -- 2020-08-17&lt;br /&gt;
    local since = atleast&lt;br /&gt;
    local last    = ( since == &amp;quot;~&amp;quot; )&lt;br /&gt;
    local linked  = ( since == &amp;quot;@&amp;quot; )&lt;br /&gt;
    local link    = ( since == &amp;quot;item&amp;quot; )&lt;br /&gt;
    local r&lt;br /&gt;
    if last  or  link  or  linked  or  since == &amp;quot;wikidata&amp;quot; then&lt;br /&gt;
        local item = Failsafe.item&lt;br /&gt;
        since = false&lt;br /&gt;
        if type( item ) == &amp;quot;number&amp;quot;  and  item &amp;gt; 0 then&lt;br /&gt;
            local suited = string.format( &amp;quot;Q%d&amp;quot;, item )&lt;br /&gt;
            if link then&lt;br /&gt;
                r = suited&lt;br /&gt;
            else&lt;br /&gt;
                local entity = mw.wikibase.getEntity( suited )&lt;br /&gt;
                if type( entity ) == &amp;quot;table&amp;quot; then&lt;br /&gt;
                    local seek = Failsafe.serialProperty or &amp;quot;P348&amp;quot;&lt;br /&gt;
                    local vsn  = entity:formatPropertyValues( seek )&lt;br /&gt;
                    if type( vsn ) == &amp;quot;table&amp;quot;  and&lt;br /&gt;
                       type( vsn.value ) == &amp;quot;string&amp;quot;  and&lt;br /&gt;
                       vsn.value ~= &amp;quot;&amp;quot; then&lt;br /&gt;
                        if last  and  vsn.value == Failsafe.serial then&lt;br /&gt;
                            r = false&lt;br /&gt;
                        elseif linked then&lt;br /&gt;
                            if mw.title.getCurrentTitle().prefixedText&lt;br /&gt;
                               ==  mw.wikibase.getSitelink( suited ) then&lt;br /&gt;
                                r = false&lt;br /&gt;
                            else&lt;br /&gt;
                                r = suited&lt;br /&gt;
                            end&lt;br /&gt;
                        else&lt;br /&gt;
                            r = vsn.value&lt;br /&gt;
                        end&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    if type( r ) == &amp;quot;nil&amp;quot; then&lt;br /&gt;
        if not since  or  since &amp;lt;= Failsafe.serial then&lt;br /&gt;
            r = Failsafe.serial&lt;br /&gt;
        else&lt;br /&gt;
            r = false&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return r&lt;br /&gt;
end -- Failsafe.failsafe()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Export&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
function p.test( a )&lt;br /&gt;
    local lucky, r = pcall( main, a )&lt;br /&gt;
    return r&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.f( frame )&lt;br /&gt;
    local lucky, r = pcall( main, frame:getParent().args, frame )&lt;br /&gt;
    if not lucky then&lt;br /&gt;
        r = string.format( &amp;quot;&amp;lt;span class=\&amp;quot;error\&amp;quot;&amp;gt;%s&amp;lt;/span&amp;gt;[[%s]]&amp;quot;,&lt;br /&gt;
                           r, Phab.sick )&lt;br /&gt;
    end&lt;br /&gt;
    return r&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.failsafe = function ( frame )&lt;br /&gt;
    -- Versioning interface&lt;br /&gt;
    local s = type( frame )&lt;br /&gt;
    local since&lt;br /&gt;
    if s == &amp;quot;table&amp;quot; then&lt;br /&gt;
        since = frame.args[ 1 ]&lt;br /&gt;
    elseif s == &amp;quot;string&amp;quot; then&lt;br /&gt;
        since = frame&lt;br /&gt;
    end&lt;br /&gt;
    if since then&lt;br /&gt;
        since = mw.text.trim( since )&lt;br /&gt;
        if since == &amp;quot;&amp;quot; then&lt;br /&gt;
            since = false&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return Failsafe.failsafe( since )  or  &amp;quot;&amp;quot;&lt;br /&gt;
end -- p.failsafe&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>UltimateG4ming</name></author>
	</entry>
</feed>