<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://wiki.steelbeasts.org/index.php?action=history&amp;feed=atom&amp;title=Modul%3ADependencyList</id>
	<title>Modul:DependencyList - Versionsgeschichte</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.steelbeasts.org/index.php?action=history&amp;feed=atom&amp;title=Modul%3ADependencyList"/>
	<link rel="alternate" type="text/html" href="https://wiki.steelbeasts.org/index.php?title=Modul:DependencyList&amp;action=history"/>
	<updated>2026-06-24T11:34:21Z</updated>
	<subtitle>Versionsgeschichte dieser Seite in Steel Beasts Wiki</subtitle>
	<generator>MediaWiki 1.39.5</generator>
	<entry>
		<id>https://wiki.steelbeasts.org/index.php?title=Modul:DependencyList&amp;diff=81&amp;oldid=prev</id>
		<title>Dr.Thodt: 1 Version importiert</title>
		<link rel="alternate" type="text/html" href="https://wiki.steelbeasts.org/index.php?title=Modul:DependencyList&amp;diff=81&amp;oldid=prev"/>
		<updated>2023-09-03T05:52:39Z</updated>

		<summary type="html">&lt;p&gt;1 Version importiert&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;de&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Nächstältere Version&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Version vom 3. September 2023, 07:52 Uhr&lt;/td&gt;
				&lt;/tr&gt;
&lt;!-- diff cache key User_sbwiki:diff::1.12:old-80:rev-81 --&gt;
&lt;/table&gt;</summary>
		<author><name>Dr.Thodt</name></author>
	</entry>
	<entry>
		<id>https://wiki.steelbeasts.org/index.php?title=Modul:DependencyList&amp;diff=80&amp;oldid=prev</id>
		<title>sc&gt;FoXFTW am 25. Juni 2023 um 09:55 Uhr</title>
		<link rel="alternate" type="text/html" href="https://wiki.steelbeasts.org/index.php?title=Modul:DependencyList&amp;diff=80&amp;oldid=prev"/>
		<updated>2023-06-25T09:55:43Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Neue Seite&lt;/b&gt;&lt;/p&gt;&lt;div&gt;require(&amp;quot;strict&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
local libraryUtil = require( &amp;#039;libraryUtil&amp;#039; )&lt;br /&gt;
local arr = require( &amp;#039;Module:Array&amp;#039; )&lt;br /&gt;
local yn = require( &amp;#039;Module:Yesno&amp;#039; )&lt;br /&gt;
local param = require( &amp;#039;Module:Paramtest&amp;#039; )&lt;br /&gt;
local userError = require(&amp;quot;Module:User error&amp;quot;)&lt;br /&gt;
local mHatnote = require(&amp;#039;Module:Hatnote&amp;#039;)&lt;br /&gt;
local mHatlist = require(&amp;#039;Module:Hatnote list&amp;#039;)&lt;br /&gt;
local TNT = require( &amp;#039;Module:Translate&amp;#039; ):new()&lt;br /&gt;
&lt;br /&gt;
local moduleIsUsed = false&lt;br /&gt;
local COLLAPSE_LIST_LENGTH_THRESHOLD = 1&lt;br /&gt;
local dynamicRequireListQueryCache = {}&lt;br /&gt;
&lt;br /&gt;
local moduleNSName =  mw.site.namespaces[ 828 ].name&lt;br /&gt;
local templateNSName = mw.site.namespaces[ 10 ].name&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- FIXME: This should go to somewhere else, like Module:Common&lt;br /&gt;
--- Calls TNT with the given key&lt;br /&gt;
---&lt;br /&gt;
--- @param key string The translation key&lt;br /&gt;
--- @return string If the key was not found in the .tab page, the key is returned&lt;br /&gt;
local function translate( key, ... )&lt;br /&gt;
    local success, translation = pcall( TNT.format, &amp;#039;Module:DependencyList/i18n.json&amp;#039;, key or &amp;#039;&amp;#039;, ... )&lt;br /&gt;
&lt;br /&gt;
    if not success or translation == nil then&lt;br /&gt;
        return key&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return translation&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local builtins = {&lt;br /&gt;
	[ &amp;quot;strict&amp;quot; ] = {&lt;br /&gt;
		link = &amp;quot;mw:Special:MyLanguage/Extension:Scribunto/Lua reference manual#strict&amp;quot;,&lt;br /&gt;
		categories = { translate( &amp;#039;category_strict_mode_modules&amp;#039; ) },&lt;br /&gt;
	},&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Used in case &amp;#039;require( varName )&amp;#039; is found. Attempts to find a string value stored in &amp;#039;varName&amp;#039;.&lt;br /&gt;
---@param content string    The content of the module to search in&lt;br /&gt;
---@param varName string&lt;br /&gt;
---@return string&lt;br /&gt;
local function substVarValue( content, varName )&lt;br /&gt;
    local res = content:match( varName .. &amp;#039;%s*=%s*(%b&amp;quot;&amp;quot;%s-%.*)&amp;#039; ) or content:match( varName .. &amp;quot;%s*=%s*(%b&amp;#039;&amp;#039;%s-%.*)&amp;quot; ) or &amp;#039;&amp;#039;&lt;br /&gt;
    if res:find( &amp;#039;^([&amp;quot;\&amp;#039;])[Mm]odule?:[%S]+%1&amp;#039; ) and not res:find( &amp;#039;%.%.&amp;#039; ) and not res:find( &amp;#039;%%%a&amp;#039; ) then&lt;br /&gt;
        return mw.text.trim( res )&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;#039;&amp;#039;&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---@param capture string&lt;br /&gt;
---@param content string    The content of the module to search in&lt;br /&gt;
---@return string&lt;br /&gt;
local function extractModuleName( capture, content )&lt;br /&gt;
    capture = capture:gsub( &amp;#039;^%(%s*(.-)%s*%)$&amp;#039;, &amp;#039;%1&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
    if capture:find( &amp;#039;^([&amp;quot;\&amp;#039;]).-%1$&amp;#039; ) then -- Check if it is already a pure string&lt;br /&gt;
        return capture&lt;br /&gt;
    elseif capture:find( &amp;#039;^[%a_][%w_]*$&amp;#039; ) then -- Check if if is a single variable&lt;br /&gt;
        return substVarValue( content, capture )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return capture&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---@param str string&lt;br /&gt;
---@return string&lt;br /&gt;
local function formatPageName( str )&lt;br /&gt;
    local name = mw.text.trim( str )&lt;br /&gt;
        :gsub( &amp;#039;^([\&amp;#039;\&amp;quot;])(.-)%1$&amp;#039;, function( _, x ) return x end ) -- Only remove quotes at start and end of string if both are the same type&lt;br /&gt;
        :gsub( &amp;#039;_&amp;#039;, &amp;#039; &amp;#039; )&lt;br /&gt;
        :gsub( &amp;#039;^.&amp;#039;, string.upper )&lt;br /&gt;
        :gsub( &amp;#039;:.&amp;#039;, string.upper )&lt;br /&gt;
&lt;br /&gt;
    return name&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---@param str string&lt;br /&gt;
---@return string&lt;br /&gt;
local function formatModuleName( str, allowBuiltins )&lt;br /&gt;
	if allowBuiltins then&lt;br /&gt;
		local name = mw.text.trim( str )&lt;br /&gt;
			-- Only remove quotes at start and end of string if both are the same type&lt;br /&gt;
			:gsub( [[^([&amp;#039;&amp;quot;])(.-)%1$]], function( _, x ) return x end );&lt;br /&gt;
&lt;br /&gt;
		local builtin = builtins[ name ];&lt;br /&gt;
		if builtin then&lt;br /&gt;
			return builtin.link .. &amp;quot;|&amp;quot; .. name, builtin;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
    local module = formatPageName( str )&lt;br /&gt;
&lt;br /&gt;
    if not string.find( module, &amp;#039;^[Mm]odule?:&amp;#039; ) then&lt;br /&gt;
        module = moduleNSName .. &amp;#039;:&amp;#039; .. module&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return module&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function dualGmatch( str, pat1, pat2 )&lt;br /&gt;
    local f1 = string.gmatch( str, pat1 )&lt;br /&gt;
    local f2 = string.gmatch( str, pat2 )&lt;br /&gt;
    return function()&lt;br /&gt;
        return f1() or f2()&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Used in case a construct like &amp;#039;require( &amp;quot;Module:wowee/&amp;quot; .. isTheBest )&amp;#039; is found.&lt;br /&gt;
--- Will return a list of pages which satisfy this pattern where &amp;#039;isTheBest&amp;#039; can take any value.&lt;br /&gt;
---@param query string&lt;br /&gt;
---@return string[]     Sequence of strings&lt;br /&gt;
local function getDynamicRequireList( query )&lt;br /&gt;
	local isDynamic = true;&lt;br /&gt;
&lt;br /&gt;
    if query:find( &amp;#039;%.%.&amp;#039; ) then&lt;br /&gt;
        query = mw.text.split( query, &amp;#039;..&amp;#039;, true )&lt;br /&gt;
        query = arr.map( query, function( x ) return mw.text.trim( x ) end )&lt;br /&gt;
        query = arr.map( query, function( x ) return ( x:match(&amp;#039;^[\&amp;#039;\&amp;quot;](.-)[\&amp;#039;\&amp;quot;]$&amp;#039;) or &amp;#039;%&amp;#039;) end )&lt;br /&gt;
        query = table.concat( query )&lt;br /&gt;
    else&lt;br /&gt;
        local _; _, query = query:match( &amp;#039;([&amp;quot;\&amp;#039;])(.-)%1&amp;#039; )&lt;br /&gt;
        local replacements;&lt;br /&gt;
        query, replacements = query:gsub( &amp;#039;%%%a&amp;#039;, &amp;#039;%%&amp;#039; )&lt;br /&gt;
		if replacements == 0 then&lt;br /&gt;
			isDynamic = false;&lt;br /&gt;
		end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    query = query:gsub( &amp;#039;^[Mm]odule?:&amp;#039;, &amp;#039;&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
    if dynamicRequireListQueryCache[ query ] then&lt;br /&gt;
        return dynamicRequireListQueryCache[ query ], isDynamic;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return {}, isDynamic;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Returns a list of modules loaded and required by module &amp;#039;moduleName&amp;#039;.&lt;br /&gt;
---@param moduleName string&lt;br /&gt;
---@param searchForUsedTemplates boolean&lt;br /&gt;
---@return string[], string[], string[], string[]&lt;br /&gt;
local function getRequireList( moduleName, searchForUsedTemplates )&lt;br /&gt;
    local content = mw.title.new( moduleName ):getContent()&lt;br /&gt;
    local requireList = arr{}&lt;br /&gt;
    local loadDataList = arr{}&lt;br /&gt;
    local usedTemplateList = arr{}&lt;br /&gt;
    local dynamicRequirelist = arr{}&lt;br /&gt;
    local dynamicLoadDataList = arr{}&lt;br /&gt;
    local extraCategories = arr{}&lt;br /&gt;
&lt;br /&gt;
    assert( content ~= nil, translate( &amp;#039;message_not_exists&amp;#039;, moduleName ) )&lt;br /&gt;
&lt;br /&gt;
    content = content:gsub( &amp;#039;%-%-%[(=-)%[.-%]%1%]&amp;#039;, &amp;#039;&amp;#039; ):gsub( &amp;#039;%-%-[^\n]*&amp;#039;, &amp;#039;&amp;#039; ) -- Strip comments&lt;br /&gt;
&lt;br /&gt;
    for match in dualGmatch( content, &amp;#039;require%s*(%b())&amp;#039;, &amp;#039;require%s*(([&amp;quot;\&amp;#039;])%s*[Mm]odule?:.-%2)&amp;#039; ) do&lt;br /&gt;
        match = mw.text.trim( match )&lt;br /&gt;
        match = extractModuleName( match, content )&lt;br /&gt;
&lt;br /&gt;
        if match:find( &amp;#039;%.%.&amp;#039; ) or match:find( &amp;#039;%%%a&amp;#039; ) then&lt;br /&gt;
            for _, x in ipairs( getDynamicRequireList( match ) ) do&lt;br /&gt;
                table.insert( dynamicRequirelist, x )&lt;br /&gt;
            end&lt;br /&gt;
        elseif match ~= &amp;#039;&amp;#039; then&lt;br /&gt;
        	local builtin;&lt;br /&gt;
            match, builtin = formatModuleName( match, true )&lt;br /&gt;
            table.insert( requireList, match )&lt;br /&gt;
&lt;br /&gt;
			if builtin then&lt;br /&gt;
				local builtinCategories = builtin.categories;&lt;br /&gt;
				if type( builtinCategories ) == &amp;#039;table&amp;#039; then&lt;br /&gt;
					for _, x in ipairs( builtinCategories ) do&lt;br /&gt;
						table.insert( extraCategories, x );&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    for match in dualGmatch( content, &amp;#039;mw%.loadData%s*(%b())&amp;#039;, &amp;#039;mw%.loadData%s*(([&amp;quot;\&amp;#039;])%s*[Mm]odule?:.-%2)&amp;#039; ) do&lt;br /&gt;
        match = mw.text.trim( match )&lt;br /&gt;
        match = extractModuleName( match, content )&lt;br /&gt;
&lt;br /&gt;
        if match:find( &amp;#039;%.%.&amp;#039; ) or match:find( &amp;#039;%%%a&amp;#039; ) then&lt;br /&gt;
            for _, x in ipairs( getDynamicRequireList( match ) ) do&lt;br /&gt;
                table.insert( dynamicLoadDataList, x )&lt;br /&gt;
            end&lt;br /&gt;
        elseif match ~= &amp;#039;&amp;#039; then&lt;br /&gt;
            match = formatModuleName( match, true )&lt;br /&gt;
            table.insert( loadDataList, match )&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    for match in dualGmatch( content, &amp;#039;mw%.loadJsonData%s*(%b())&amp;#039;, &amp;#039;mw%.loadJsonData%s*(([&amp;quot;\&amp;#039;])%s*[Mm]odule?:.-%2)&amp;#039; ) do&lt;br /&gt;
        match = mw.text.trim( match )&lt;br /&gt;
        match = extractModuleName( match, content )&lt;br /&gt;
&lt;br /&gt;
        if match:find( &amp;#039;%.%.&amp;#039; ) or match:find( &amp;#039;%%%a&amp;#039; ) then&lt;br /&gt;
            for _, x in ipairs( getDynamicRequireList( match ) ) do&lt;br /&gt;
                table.insert( dynamicLoadDataList, x )&lt;br /&gt;
            end&lt;br /&gt;
        elseif match ~= &amp;#039;&amp;#039; then&lt;br /&gt;
            match = formatModuleName( match, true )&lt;br /&gt;
            table.insert( loadDataList, match )&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    for func, match in string.gmatch( content, &amp;#039;pcall%s*%(([^,]+),([^%),]+)&amp;#039; ) do&lt;br /&gt;
        func = mw.text.trim( func )&lt;br /&gt;
        match = mw.text.trim( match )&lt;br /&gt;
&lt;br /&gt;
		local dynList, isDynamic;&lt;br /&gt;
        if func == &amp;#039;require&amp;#039; then&lt;br /&gt;
			dynList, isDynamic = getDynamicRequireList( match );&lt;br /&gt;
&lt;br /&gt;
			if ( isDynamic == false and #dynList == 1 ) then&lt;br /&gt;
				table.insert( requireList, dynList[ 1 ] );&lt;br /&gt;
			else&lt;br /&gt;
                for _, x in ipairs( dynList ) do&lt;br /&gt;
                    table.insert( dynamicRequirelist, x )&lt;br /&gt;
			    end&lt;br /&gt;
            end&lt;br /&gt;
        elseif func == &amp;#039;mw.loadData&amp;#039; then&lt;br /&gt;
			dynList, isDynamic = getDynamicRequireList( match );&lt;br /&gt;
&lt;br /&gt;
			if ( isDynamic == false and #dynList == 1 ) then&lt;br /&gt;
				table.insert( loadDataList, dynList[ 1 ] );&lt;br /&gt;
			else&lt;br /&gt;
                for _, x in ipairs( dynList ) do&lt;br /&gt;
                    table.insert( dynamicLoadDataList, x )&lt;br /&gt;
			    end&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if searchForUsedTemplates then&lt;br /&gt;
        for preprocess in string.gmatch( content, &amp;#039;:preprocess%s*(%b())&amp;#039; ) do&lt;br /&gt;
            local function recursiveGMatch( str, pat )&lt;br /&gt;
                local list = {}&lt;br /&gt;
                local i = 0&lt;br /&gt;
&lt;br /&gt;
                repeat&lt;br /&gt;
                    for match in string.gmatch( list[ i ] or str, pat ) do&lt;br /&gt;
                        table.insert( list, match )&lt;br /&gt;
                    end&lt;br /&gt;
                    i =  i + 1&lt;br /&gt;
                until i &amp;gt; #list or i &amp;gt; 100&lt;br /&gt;
&lt;br /&gt;
                i = 0&lt;br /&gt;
                return function()&lt;br /&gt;
                    i = i + 1&lt;br /&gt;
                    return list[ i ]&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
&lt;br /&gt;
            for template in recursiveGMatch( preprocess, &amp;#039;{(%b{})}&amp;#039; ) do&lt;br /&gt;
                local name = string.match( template, &amp;#039;{(.-)[|{}]&amp;#039; )&lt;br /&gt;
                if name ~= &amp;#039;&amp;#039; then&lt;br /&gt;
                    if name:find( &amp;#039;:&amp;#039; ) then&lt;br /&gt;
                        local ns = name:match( &amp;#039;^(.-):&amp;#039; )&lt;br /&gt;
                        if arr.contains( { &amp;#039;&amp;#039;, &amp;#039;template&amp;#039;, &amp;#039;user&amp;#039; }, ns:lower() ) then&lt;br /&gt;
                            table.insert( usedTemplateList, name )&lt;br /&gt;
                        elseif ns == ns:upper() then&lt;br /&gt;
                            table.insert( usedTemplateList, ns ) -- Probably a magic word&lt;br /&gt;
                        end&lt;br /&gt;
                    else&lt;br /&gt;
                        if name:match( &amp;#039;^%u+$&amp;#039; ) or name == &amp;#039;!&amp;#039; then&lt;br /&gt;
                            table.insert( usedTemplateList, name ) -- Probably a magic word&lt;br /&gt;
                        else&lt;br /&gt;
                            table.insert( usedTemplateList, &amp;#039;Template:&amp;#039;..name )&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;
&lt;br /&gt;
    requireList = requireList .. dynamicRequirelist:reject( loadDataList )&lt;br /&gt;
    requireList = requireList:unique()&lt;br /&gt;
    loadDataList = loadDataList .. dynamicLoadDataList:reject( requireList )&lt;br /&gt;
    loadDataList = loadDataList:unique()&lt;br /&gt;
    usedTemplateList = usedTemplateList:unique()&lt;br /&gt;
    extraCategories = extraCategories:unique()&lt;br /&gt;
    table.sort( requireList )&lt;br /&gt;
    table.sort( loadDataList )&lt;br /&gt;
    table.sort( usedTemplateList )&lt;br /&gt;
    table.sort( extraCategories )&lt;br /&gt;
&lt;br /&gt;
    return requireList, loadDataList, usedTemplateList, extraCategories&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Returns a list with module and function names used in all &amp;#039;{{#Invoke:moduleName|funcName}}&amp;#039; found on page &amp;#039;templateName&amp;#039;.&lt;br /&gt;
---@param templateName string&lt;br /&gt;
---@return table&amp;lt;string, string&amp;gt;[]&lt;br /&gt;
local function getInvokeCallList( templateName )&lt;br /&gt;
    local content = mw.title.new( templateName ):getContent()&lt;br /&gt;
    local invokeList = {}&lt;br /&gt;
&lt;br /&gt;
    assert( content ~= nil, translate( &amp;#039;message_not_exists&amp;#039;, templateName ) )&lt;br /&gt;
&lt;br /&gt;
    for moduleName, funcName in string.gmatch( content, &amp;#039;{{[{|safeubt:}]-#[Ii]nvoke:([^|]+)|([^}|]+)[^}]*}}&amp;#039; ) do&lt;br /&gt;
        moduleName = formatModuleName( moduleName )&lt;br /&gt;
        funcName = mw.text.trim( funcName )&lt;br /&gt;
        if string.find( funcName, &amp;#039;^{{{&amp;#039; ) then&lt;br /&gt;
        	funcName = funcName ..  &amp;#039;}}}&amp;#039;&lt;br /&gt;
        end&lt;br /&gt;
        table.insert( invokeList, { moduleName = moduleName, funcName = funcName } )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    invokeList = arr.unique( invokeList, function( x ) return x.moduleName..x.funcName end )&lt;br /&gt;
    table.sort( invokeList, function( x, y ) return x.moduleName..x.funcName &amp;lt; y.moduleName..y.funcName end )&lt;br /&gt;
&lt;br /&gt;
    return invokeList&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
---@param pageName string&lt;br /&gt;
---@param addCategories boolean&lt;br /&gt;
---@return string&lt;br /&gt;
local function messageBoxUnused( pageName, addCategories )&lt;br /&gt;
	local mbox = require( &amp;#039;Module:Mbox&amp;#039; )._mbox&lt;br /&gt;
&lt;br /&gt;
	local category = addCategories and &amp;#039;[[Category:&amp;#039; .. translate( &amp;#039;category_unused_module&amp;#039; ) .. &amp;#039;]]&amp;#039; or &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
	return mbox(&lt;br /&gt;
		translate( &amp;#039;message_unused_module_title&amp;#039; ),&lt;br /&gt;
		translate( &amp;#039;message_unused_module_desc&amp;#039; ),&lt;br /&gt;
		{ icon = &amp;#039;WikimediaUI-Alert.svg&amp;#039; }&lt;br /&gt;
	) .. category&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function collapseList( list, id, listType )&lt;br /&gt;
    local text = string.format( &amp;#039;%d %s&amp;#039;, #list, listType )&lt;br /&gt;
    local button = &amp;#039;&amp;lt;span&amp;gt;&amp;#039; .. text .. &amp;#039;:&amp;lt;/span&amp;gt;&amp;amp;nbsp;&amp;#039;&lt;br /&gt;
    local content = mHatlist.andList( list, false )&lt;br /&gt;
&lt;br /&gt;
    return { tostring( button ) .. tostring( content ) }&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--- Creates a link to [[Special:Search]] showing all pages found by getDynamicRequireList() in case it found more than MAX_DYNAMIC_REQUIRE_LIST_LENGTH pages.&lt;br /&gt;
---@param query string      @This will be in a format like &amp;#039;Module:Wowee/%&amp;#039; or &amp;#039;Module:Wowee/%/data&amp;#039;&lt;br /&gt;
---@return string&lt;br /&gt;
local function formatDynamicQueryLink( query )&lt;br /&gt;
    local prefix = query:match( &amp;#039;^([^/]+)&amp;#039; )&lt;br /&gt;
    local linkText = query:gsub( &amp;#039;%%&amp;#039;, &amp;#039;&amp;amp;lt; ... &amp;amp;gt;&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
    query = query:gsub( &amp;#039;^Module?:&amp;#039;,  &amp;#039;&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
    query = query:gsub( &amp;#039;([^/]+)/?&amp;#039;, function ( match )&lt;br /&gt;
        if match == &amp;#039;%&amp;#039; then&lt;br /&gt;
            return &amp;#039;\\/[^\\/]+&amp;#039;&lt;br /&gt;
        else&lt;br /&gt;
            return &amp;#039;\\/&amp;quot;&amp;#039; .. match .. &amp;#039;&amp;quot;&amp;#039;&lt;br /&gt;
        end&lt;br /&gt;
    end )&lt;br /&gt;
&lt;br /&gt;
    query = query:gsub( &amp;#039;^\\/&amp;#039;, &amp;#039;&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
    query = string.format(&lt;br /&gt;
        &amp;#039;intitle:/%s%s/i -intitle:/%s\\/&amp;quot;&amp;quot;/i -intitle:doc prefix:&amp;quot;%s&amp;quot;&amp;#039;,&lt;br /&gt;
        query,&lt;br /&gt;
        query:find( &amp;#039;&amp;quot;$&amp;#039; ) and &amp;#039;&amp;#039; or &amp;#039;&amp;quot;&amp;quot;&amp;#039;,&lt;br /&gt;
        query,&lt;br /&gt;
        prefix&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
    return string.format( &amp;#039;&amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[%s %s]&amp;lt;/span&amp;gt;&amp;#039;, tostring( mw.uri.fullUrl( &amp;#039;Special:Search&amp;#039;, { search = query } ) ), linkText )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---@param templateName string&lt;br /&gt;
---@param addCategories boolean&lt;br /&gt;
---@param invokeList table&amp;lt;string, string&amp;gt;[]    @This is the list returned by getInvokeCallList()&lt;br /&gt;
---@return string&lt;br /&gt;
local function formatInvokeCallList( templateName, addCategories, invokeList )&lt;br /&gt;
    local category = addCategories and &amp;#039;[[Category:&amp;#039; .. translate( &amp;#039;category_lua_based_template&amp;#039; ) .. &amp;#039;]]&amp;#039; or &amp;#039;&amp;#039;&lt;br /&gt;
    local res = {}&lt;br /&gt;
&lt;br /&gt;
    for _, item in ipairs( invokeList ) do&lt;br /&gt;
        local msg = translate(&lt;br /&gt;
                &amp;#039;message_invokes_function&amp;#039;,&lt;br /&gt;
    		templateName,&lt;br /&gt;
    		item.funcName,&lt;br /&gt;
    		item.moduleName&lt;br /&gt;
    	)&lt;br /&gt;
        table.insert( res, mHatnote._hatnote( msg, { icon = &amp;#039;WikimediaUI-Code.svg&amp;#039; } ) )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if #invokeList &amp;gt; 0 then&lt;br /&gt;
        table.insert( res, category )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return table.concat( res )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---@param moduleName string&lt;br /&gt;
---@param addCategories boolean&lt;br /&gt;
---@param whatLinksHere string    @A list generated by a dpl of pages in the Template namespace which link to moduleName.&lt;br /&gt;
---@return string&lt;br /&gt;
local function formatInvokedByList( moduleName, addCategories, whatLinksHere )&lt;br /&gt;
    local function lcfirst( str )&lt;br /&gt;
		return string.gsub( str, &amp;#039;^[Mm]odule?:.&amp;#039;, string.lower )&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
    local templateData = arr.map( whatLinksHere, function( x ) return { templateName = x, invokeList = getInvokeCallList( x ) } end )&lt;br /&gt;
    templateData = arr.filter( templateData, function( x )&lt;br /&gt;
        return arr.any( x.invokeList, function( y )&lt;br /&gt;
            return lcfirst( y.moduleName ) == lcfirst( moduleName )&lt;br /&gt;
        end )&lt;br /&gt;
    end )&lt;br /&gt;
&lt;br /&gt;
    local invokedByList = {}&lt;br /&gt;
&lt;br /&gt;
    for _, template in ipairs( templateData ) do&lt;br /&gt;
        for _, invoke in ipairs( template.invokeList ) do&lt;br /&gt;
            table.insert( invokedByList, translate( &amp;#039;message_function_invoked_by&amp;#039;, invoke.funcName, template.templateName ) )&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    table.sort( invokedByList)&lt;br /&gt;
&lt;br /&gt;
    local res = {}&lt;br /&gt;
&lt;br /&gt;
    if #invokedByList &amp;gt; COLLAPSE_LIST_LENGTH_THRESHOLD then&lt;br /&gt;
    	local msg = translate(&lt;br /&gt;
        &amp;#039;message_function_invoked_by&amp;#039;,&lt;br /&gt;
            moduleName,&lt;br /&gt;
    		collapseList( invokedByList, &amp;#039;invokedBy&amp;#039;, translate( &amp;#039;list_type_templates&amp;#039; ) )[ 1 ]&lt;br /&gt;
    	)&lt;br /&gt;
&lt;br /&gt;
        table.insert( res, mHatnote._hatnote( msg, { icon=&amp;#039;WikimediaUI-Code.svg&amp;#039; } ) )&lt;br /&gt;
    else&lt;br /&gt;
	    for _, item in ipairs( invokedByList ) do&lt;br /&gt;
	    	local msg = string.format(&lt;br /&gt;
	    		&amp;quot;&amp;#039;&amp;#039;&amp;#039;%s&amp;#039;s&amp;#039;&amp;#039;&amp;#039; %s.&amp;quot;,&lt;br /&gt;
	    		moduleName,&lt;br /&gt;
	    		item&lt;br /&gt;
	    	)&lt;br /&gt;
        	table.insert( res, mHatnote._hatnote( msg, { icon=&amp;#039;WikimediaUI-Code.svg&amp;#039; } ) )&lt;br /&gt;
	    end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if #templateData &amp;gt; 0 then&lt;br /&gt;
        moduleIsUsed = true&lt;br /&gt;
        table.insert( res, ( addCategories and &amp;#039;[[Category:&amp;#039; .. translate( &amp;#039;category_template_invoked_modules&amp;#039; ) .. &amp;#039;]]&amp;#039; or &amp;#039;&amp;#039; ) )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return table.concat( res )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---@param moduleName string&lt;br /&gt;
---@param addCategories boolean&lt;br /&gt;
---@param whatLinksHere string      @A list generated by a dpl of pages in the Module namespace which link to moduleName.&lt;br /&gt;
---@return string&lt;br /&gt;
local function formatRequiredByList( moduleName, addCategories, whatLinksHere )&lt;br /&gt;
    local childModuleData = arr.map( whatLinksHere, function ( title )&lt;br /&gt;
        local requireList, loadDataList = getRequireList( title )&lt;br /&gt;
        return { name = title, requireList = requireList, loadDataList = loadDataList }&lt;br /&gt;
    end )&lt;br /&gt;
&lt;br /&gt;
    local requiredByList = arr.map( childModuleData, function ( item )&lt;br /&gt;
        if arr.any( item.requireList, function( x )&lt;br /&gt;
            return x:lower():gsub( &amp;#039;^module?:&amp;#039;, &amp;#039;module&amp;#039; ) == moduleName:lower():gsub( &amp;#039;^module?:&amp;#039;, &amp;#039;module&amp;#039; )&lt;br /&gt;
        end ) then&lt;br /&gt;
            if item.name:find( &amp;#039;%%&amp;#039; ) then&lt;br /&gt;
                return formatDynamicQueryLink( item.name )&lt;br /&gt;
            else&lt;br /&gt;
                return &amp;#039;[[&amp;#039; .. item.name .. &amp;#039;]]&amp;#039;&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end )&lt;br /&gt;
&lt;br /&gt;
    local loadedByList = arr.map( childModuleData, function ( item )&lt;br /&gt;
        if arr.any( item.loadDataList, function( x )&lt;br /&gt;
            return x:lower():gsub( &amp;#039;^module?:&amp;#039;, &amp;#039;module&amp;#039; ) == moduleName:lower():gsub( &amp;#039;^module?:&amp;#039;, &amp;#039;module&amp;#039; )&lt;br /&gt;
        end ) then&lt;br /&gt;
            if item.name:find( &amp;#039;%%&amp;#039; ) then&lt;br /&gt;
                return formatDynamicQueryLink( item.name )&lt;br /&gt;
            else&lt;br /&gt;
                return &amp;#039;[[&amp;#039; .. item.name .. &amp;#039;]]&amp;#039;&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end )&lt;br /&gt;
&lt;br /&gt;
    if #requiredByList &amp;gt; 0 or #loadedByList &amp;gt; 0 then&lt;br /&gt;
        moduleIsUsed  = true&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if #requiredByList &amp;gt; COLLAPSE_LIST_LENGTH_THRESHOLD then&lt;br /&gt;
        requiredByList = collapseList( requiredByList, &amp;#039;requiredBy&amp;#039;, translate( &amp;#039;list_type_modules&amp;#039; ) )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if #loadedByList &amp;gt; COLLAPSE_LIST_LENGTH_THRESHOLD then&lt;br /&gt;
        loadedByList = collapseList( loadedByList, &amp;#039;loadedBy&amp;#039;, translate( &amp;#039;list_type_modules&amp;#039; ) )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local res = {}&lt;br /&gt;
&lt;br /&gt;
    for _, requiredByModuleName in ipairs( requiredByList ) do&lt;br /&gt;
    	local msg = translate(&lt;br /&gt;
    		&amp;#039;message_required_by&amp;#039;,&lt;br /&gt;
    		moduleName,&lt;br /&gt;
    		requiredByModuleName&lt;br /&gt;
    	)&lt;br /&gt;
        table.insert( res, mHatnote._hatnote( msg, { icon = &amp;#039;WikimediaUI-Code.svg&amp;#039; } ) )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if #requiredByList &amp;gt; 0 then&lt;br /&gt;
        table.insert( res, ( addCategories and &amp;#039;[[Category:&amp;#039; .. translate( &amp;#039;category_modules_required_by_modules&amp;#039; ) .. &amp;#039;]]&amp;#039; or &amp;#039;&amp;#039; ) )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    for _, loadedByModuleName in ipairs( loadedByList ) do&lt;br /&gt;
    	local msg = translate(&lt;br /&gt;
    		&amp;#039;message_loaded_by&amp;#039;,&lt;br /&gt;
    		moduleName,&lt;br /&gt;
            loadedByModuleName&lt;br /&gt;
    	)&lt;br /&gt;
        table.insert( res, mHatnote._hatnote( msg, { icon=&amp;#039;WikimediaUI-Code.svg&amp;#039; } ) )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if #loadedByList &amp;gt; 0 then&lt;br /&gt;
        table.insert( res, ( addCategories and &amp;#039;[[Category:&amp;#039; .. translate( &amp;#039;category_module_data&amp;#039; ) .. &amp;#039;]]&amp;#039; or &amp;#039;&amp;#039; ) )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return table.concat( res )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function formatRequireList( currentPageName, addCategories, requireList )&lt;br /&gt;
    local res = {}&lt;br /&gt;
&lt;br /&gt;
    if #requireList &amp;gt; COLLAPSE_LIST_LENGTH_THRESHOLD then&lt;br /&gt;
        requireList = collapseList( requireList, &amp;#039;require&amp;#039;, translate( &amp;#039;list_type_modules&amp;#039; ) )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    for _, requiredModuleName in ipairs( requireList ) do&lt;br /&gt;
    	local msg = translate(&lt;br /&gt;
    		&amp;#039;message_requires&amp;#039;,&lt;br /&gt;
    		currentPageName,&lt;br /&gt;
    		requiredModuleName&lt;br /&gt;
    	)&lt;br /&gt;
        table.insert( res, mHatnote._hatnote( msg, { icon = &amp;#039;WikimediaUI-Code.svg&amp;#039; } ) )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if #requireList &amp;gt; 0 then&lt;br /&gt;
        table.insert( res, (addCategories and &amp;#039;[[Category:&amp;#039; .. translate( &amp;#039;category_modules_required_by_modules&amp;#039; ) .. &amp;#039;]]&amp;#039; or &amp;#039;&amp;#039;) )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return table.concat( res )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function formatLoadDataList( currentPageName, addCategories, loadDataList )&lt;br /&gt;
    local res = {}&lt;br /&gt;
&lt;br /&gt;
    if #loadDataList &amp;gt; COLLAPSE_LIST_LENGTH_THRESHOLD then&lt;br /&gt;
        loadDataList = collapseList( loadDataList, &amp;#039;loadData&amp;#039;, translate( &amp;#039;list_type_modules&amp;#039; ) )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    for _, loadedModuleName in ipairs( loadDataList ) do&lt;br /&gt;
    	local msg = translate(&lt;br /&gt;
    		&amp;#039;message_loads_data_from&amp;#039;,&lt;br /&gt;
    		currentPageName,&lt;br /&gt;
    		loadedModuleName&lt;br /&gt;
    	)&lt;br /&gt;
        table.insert( res, mHatnote._hatnote( msg, { icon = &amp;#039;WikimediaUI-Code.svg&amp;#039; } ) )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if #loadDataList &amp;gt; 0 then&lt;br /&gt;
        table.insert( res, ( addCategories and &amp;#039;[[Category:&amp;#039; .. translate( &amp;#039;category_modules_using_data&amp;#039; ) .. &amp;#039;]]&amp;#039; or &amp;#039;&amp;#039; ) )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return table.concat( res )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function formatUsedTemplatesList( currentPageName, addCategories, usedTemplateList )&lt;br /&gt;
    local res = {}&lt;br /&gt;
&lt;br /&gt;
    if #usedTemplateList &amp;gt; COLLAPSE_LIST_LENGTH_THRESHOLD then&lt;br /&gt;
        usedTemplateList = collapseList( usedTemplateList, &amp;#039;usedTemplates&amp;#039;, translate( &amp;#039;list_type_templates&amp;#039; ) )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    for _, templateName in ipairs( usedTemplateList ) do&lt;br /&gt;
    	local msg = translate(&lt;br /&gt;
    		&amp;#039;message_transcludes&amp;#039;,&lt;br /&gt;
    		currentPageName,&lt;br /&gt;
    		templateName&lt;br /&gt;
    	)&lt;br /&gt;
        table.insert( res, mHatnote._hatnote( msg, { icon = &amp;#039;WikimediaUI-Code.svg&amp;#039; } ) )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return table.concat( res )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function p.main( frame )&lt;br /&gt;
    local args = frame:getParent().args&lt;br /&gt;
    return p._main( args[ 1 ], args.category, args.isUsed )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
---@param currentPageName string|nil&lt;br /&gt;
---@param addCategories boolean|string|nil&lt;br /&gt;
---@return string&lt;br /&gt;
function p._main( currentPageName, addCategories, isUsed )&lt;br /&gt;
    libraryUtil.checkType( &amp;#039;Module:RequireList._main&amp;#039;, 1, currentPageName, &amp;#039;string&amp;#039;, true )&lt;br /&gt;
    libraryUtil.checkTypeMulti( &amp;#039;Module:RequireList._main&amp;#039;, 2, addCategories, { &amp;#039;boolean&amp;#039;, &amp;#039;string&amp;#039;, &amp;#039;nil&amp;#039; } )&lt;br /&gt;
    libraryUtil.checkTypeMulti( &amp;#039;Module:RequireList._main&amp;#039;, 3, isUsed, { &amp;#039;boolean&amp;#039;, &amp;#039;string&amp;#039;, &amp;#039;nil&amp;#039; } )&lt;br /&gt;
&lt;br /&gt;
    local title = mw.title.getCurrentTitle()&lt;br /&gt;
&lt;br /&gt;
    -- Leave early if not in module or template namespace&lt;br /&gt;
    if param.is_empty( currentPageName ) and&lt;br /&gt;
        ( not arr.contains( { moduleNSName, templateNSName }, title.nsText ) ) then&lt;br /&gt;
        return &amp;#039;&amp;#039;&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    currentPageName = param.default_to( currentPageName, title.fullText )&lt;br /&gt;
    currentPageName = string.gsub( currentPageName, &amp;#039;/[Dd]o[ck]u?$&amp;#039;, &amp;#039;&amp;#039; )&lt;br /&gt;
    currentPageName = formatPageName( currentPageName )&lt;br /&gt;
    addCategories = yn( param.default_to( addCategories, title.subpageText~=&amp;#039;doc&amp;#039; ) )&lt;br /&gt;
    moduleIsUsed = yn( param.default_to( isUsed, false ) )&lt;br /&gt;
&lt;br /&gt;
    if title.text:lower():find( &amp;#039;sandbox&amp;#039; ) then&lt;br /&gt;
    	moduleIsUsed = true -- Don&amp;#039;t show sandbox modules as unused&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if currentPageName:find( &amp;#039;^&amp;#039; .. templateNSName .. &amp;#039;:&amp;#039; ) then&lt;br /&gt;
        local ok, invokeList = pcall( getInvokeCallList, currentPageName )&lt;br /&gt;
		if ok then&lt;br /&gt;
        	return formatInvokeCallList( currentPageName, addCategories, invokeList )&lt;br /&gt;
        else&lt;br /&gt;
			return userError( invokeList )&lt;br /&gt;
		end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local whatTemplatesLinkHere = {}&lt;br /&gt;
    local whatModulesLinkHere = {}&lt;br /&gt;
&lt;br /&gt;
    local function cleanFrom( from )&lt;br /&gt;
        from = from or &amp;#039;&amp;#039;&lt;br /&gt;
        local parts = mw.text.split( from, &amp;#039;|&amp;#039;, true )&lt;br /&gt;
&lt;br /&gt;
        if #parts == 2 then&lt;br /&gt;
            local name = string.gsub( parts[ 1 ], &amp;#039;%[%[:&amp;#039;, &amp;#039;&amp;#039; )&lt;br /&gt;
            name = string.gsub( name, &amp;#039;/[Dd]o[ck]u?&amp;#039;, &amp;#039;&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
            return name&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        return nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local templatesRes = mw.smw.ask({&lt;br /&gt;
        &amp;#039;[[Links to::&amp;#039; .. currentPageName .. &amp;#039;]]&amp;#039;,&lt;br /&gt;
        &amp;#039;[[Template:+]]&amp;#039;,&lt;br /&gt;
        &amp;#039;sort=Links to&amp;#039;,&lt;br /&gt;
        &amp;#039;order=asc&amp;#039;,&lt;br /&gt;
        &amp;#039;mainlabel=from&amp;#039;&lt;br /&gt;
    }) or {}&lt;br /&gt;
&lt;br /&gt;
    whatTemplatesLinkHere = arr.new( arr.condenseSparse( arr.map( templatesRes, function ( link )&lt;br /&gt;
        return cleanFrom( link[ &amp;#039;from&amp;#039; ] )&lt;br /&gt;
    end ) ) ):unique()&lt;br /&gt;
&lt;br /&gt;
    local moduleRes = mw.smw.ask( {&lt;br /&gt;
        &amp;#039;[[Links to::&amp;#039; .. currentPageName .. &amp;#039;]]&amp;#039;,&lt;br /&gt;
        &amp;#039;[[Module:+]]&amp;#039;,&lt;br /&gt;
        &amp;#039;sort=Links to&amp;#039;,&lt;br /&gt;
        &amp;#039;order=asc&amp;#039;,&lt;br /&gt;
        &amp;#039;mainlabel=from&amp;#039;&lt;br /&gt;
    } ) or {}&lt;br /&gt;
&lt;br /&gt;
    whatModulesLinkHere = arr.new( arr.condenseSparse( arr.map( moduleRes, function ( link )&lt;br /&gt;
        return cleanFrom( link[ &amp;#039;from&amp;#039; ] )&lt;br /&gt;
    end ) ) ):unique():reject( { currentPageName } )&lt;br /&gt;
&lt;br /&gt;
    local requireList, loadDataList, usedTemplateList, extraCategories;&lt;br /&gt;
    do&lt;br /&gt;
        local ok;&lt;br /&gt;
        ok, requireList, loadDataList, usedTemplateList, extraCategories = pcall( getRequireList, currentPageName, true );&lt;br /&gt;
        if not ok then&lt;br /&gt;
            return userError( requireList );&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    requireList = arr.map( requireList, function ( moduleName )&lt;br /&gt;
        if moduleName:find( &amp;#039;%%&amp;#039; ) then&lt;br /&gt;
            return formatDynamicQueryLink( moduleName )&lt;br /&gt;
        else&lt;br /&gt;
            return &amp;#039;[[&amp;#039; .. moduleName .. &amp;#039;]]&amp;#039;&lt;br /&gt;
        end&lt;br /&gt;
    end )&lt;br /&gt;
&lt;br /&gt;
    loadDataList = arr.map( loadDataList, function ( moduleName )&lt;br /&gt;
        if moduleName:find( &amp;#039;%%&amp;#039; ) then&lt;br /&gt;
            return formatDynamicQueryLink( moduleName )&lt;br /&gt;
        else&lt;br /&gt;
            return &amp;#039;[[&amp;#039; .. moduleName .. &amp;#039;]]&amp;#039;&lt;br /&gt;
        end&lt;br /&gt;
    end )&lt;br /&gt;
&lt;br /&gt;
    usedTemplateList = arr.map( usedTemplateList, function( templateName )&lt;br /&gt;
        if string.find( templateName, &amp;#039;:&amp;#039; ) then -- Real templates are prefixed by a namespace, magic words are not&lt;br /&gt;
            return &amp;#039;[[&amp;#039;..templateName..&amp;#039;]]&amp;#039;&lt;br /&gt;
        else&lt;br /&gt;
            return &amp;quot;&amp;#039;&amp;#039;&amp;#039;&amp;amp;#123;&amp;amp;#123;&amp;quot;..templateName..&amp;quot;&amp;amp;#125;&amp;amp;#125;&amp;#039;&amp;#039;&amp;#039;&amp;quot; -- Magic words don&amp;#039;t have a page so make them bold instead&lt;br /&gt;
        end&lt;br /&gt;
    end )&lt;br /&gt;
&lt;br /&gt;
    local res = {}&lt;br /&gt;
&lt;br /&gt;
    table.insert( res, formatInvokedByList( currentPageName, addCategories, whatTemplatesLinkHere ) )&lt;br /&gt;
    table.insert( res, formatRequireList( currentPageName, addCategories, requireList ) )&lt;br /&gt;
    table.insert( res, formatLoadDataList( currentPageName, addCategories, loadDataList ) )&lt;br /&gt;
    table.insert( res, formatUsedTemplatesList( currentPageName, addCategories, usedTemplateList ) )&lt;br /&gt;
    table.insert( res, formatRequiredByList( currentPageName, addCategories, whatModulesLinkHere ) )&lt;br /&gt;
&lt;br /&gt;
	if addCategories then&lt;br /&gt;
		extraCategories = arr.map( extraCategories, function( categoryName )&lt;br /&gt;
			return &amp;quot;[[Category:&amp;quot; .. categoryName .. &amp;quot;]]&amp;quot;;&lt;br /&gt;
		end )&lt;br /&gt;
&lt;br /&gt;
		table.insert( res, table.concat( extraCategories ) );&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
    if not moduleIsUsed then&lt;br /&gt;
        table.insert( res, 1, messageBoxUnused( currentPageName:gsub( &amp;#039;Module:&amp;#039;, &amp;#039;&amp;#039; ), addCategories ) )&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return table.concat( res )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
return p&lt;br /&gt;
-- &amp;lt;/nowiki&amp;gt;&lt;/div&gt;</summary>
		<author><name>sc&gt;FoXFTW</name></author>
	</entry>
</feed>