require('strict') local p = {} local sandbox-- = '/sandbox' local i18n = mw.loadData('মডিউল:ব্যানারের খোলস/কনফিগ' .. (sandbox or )) p.templatepage = function(args, raw_args, inactive_status) local wikilink = function(link, display) 	if link then 		return display and ''..display..'' or ''..link..'' 	else 		return display or  	end end  -- Initialise variables ---  local cfg = mw.loadData('মডিউল:উইকিপ্রকল্প ব্যানার/config' .. (sandbox or )) local cfg_tp = cfg.template_page -- convenient shortcut for template_page configuration settings local lang = mw.language.getContentLanguage() local current_page = mw.title.getCurrentTitle() local on_sandbox = lang:lc(current_page.subpageText)=='sandbox' -- on sandbox subpage 	or current_page.namespace==2 -- in User namespace 	or current_page.rootText=='WPBannerMeta' -- subpage of Template:WPBannerMeta local frame = mw.getCurrentFrame() local parameter_format = function(parameter, value) 	local code = parameter and mw.html.create('code') 		:addClass('tpl-para') 			:css('word-break', 'break-word') --TODO: add to css page 			:wikitext('|' .. parameter .. '=' .. (value or )) 			:done() 	return tostring(code) end local yesno = require('Module:Yesno') local messageBox = require('Module:Message box').main local project = args.PROJECT or local banner_name = mw.title.new(args.BANNER_NAME or 'Template:WikiProject ' .. project) local project_name = args.PROJECT_NAME or 'WikiProject ' .. project local notices, tracking_cats = {}, {} local add_tracking = function(tracking, show_on_sandbox) 	local category = tracking.category or cfg_tp.default_tracking -- uses Category:WikiProject banners with errors by default 	local key = tracking.sort_key or (project~= and project or '*') -- sort key defaults to name of project 	if not on_sandbox or show_on_sandbox then 		table.insert(tracking_cats, wikilink('Category:' .. category, key)) 	end end local project_link = args.PROJECT_LINK or 'Wikipedia:WikiProject ' .. project  -- Count notes/taskforces -  local task_forces, notes, taskforce_categories = {}, {}, {} for arg_name, _ in pairs(raw_args) do 	local tf_match = mw.ustring.match(arg_name,'^tf (%d+)$') 	if tf_match then 		table.insert(task_forces, tf_match) 	end 	local tf, cat = mw.ustring.match(arg_name,'^tf (%d+) cat (%d+)$') 	if tf then 		if not taskforce_categories[tf] then-- initialise table 			taskforce_categories[tf] = {} 		end 		table.insert(taskforce_categories[tf], cat) 	end 	local note_match = mw.ustring.match(arg_name,'^note (%d+)$') 	if note_match then 		table.insert(notes, note_match) 	end end table.sort(task_forces, function (x, y) return tonumber(x) < tonumber(y) end) table.sort(notes, function (x, y) return tonumber(x) < tonumber(y) end)  -- Demonstrative banner ---  args.PROJECT = args.PROJECT or args.class = i18n.en_class[raw_args.class] or raw_args.class and not inactive_status and 'C' args.importance = raw_args.importance and 'High' args.priority = raw_args.priority and 'High' args.auto = raw_args.auto and 'inherit' args.attention = raw_args.attention and 'yes' args.infobox = raw_args.infobox and 'yes' args.b1 = raw_args.b1 and 'yes' args.b2 = raw_args.b2 and 'no' args.b3 = raw_args.b3 and 'foo' args.b4 = raw_args.b4 and 'yes' args.b5 = raw_args.b5 and 'na' args.b6 = raw_args.b6 args['image-needed'] = raw_args['image-needed'] and 'yes' args['collaboration-candidate'] = raw_args['collaboration-candidate'] and 'yes' args['collaboration-current'] = raw_args['collaboration-current'] and 'yes' args['collaboration-past'] = raw_args['collaboration-past'] and 'yes' args['a class'] = raw_args['a class'] and 'current' args['peer review'] = raw_args['peer review'] and 'yes' args['old peer review'] = raw_args['old peer review'] and 'yes' for _, tf in ipairs(task_forces) do 	args['tf '..tf] = 'yes' 	if raw_args['tf '..tf..' importance'] then 		args['tf '..tf..' importance'] = 'Top' 	end end for _, note in ipairs(notes) do 	local text_arg = args['NOTE_'..note..'_TEXT'] 	if text_arg and text_arg~= then 		args['note '..note] = 'yes' 	end end local demo_banner, note_count, tf_count, assessment_link = require('Module:WikiProject banner'  .. (sandbox or ))._main(args, args, true, banner_name) if not assessment_link then --temporary code until main module updated 	assessment_link = args.ASSESSMENT_LINK end if not assessment_link then 	local project_link = mw.title.new(args.PROJECT_LINK or 'Wikipedia:' .. project_name) 	local fallback = mw.title.new(project_link.prefixedText .. '/Assessment') 	assessment_link = fallback.exists and fallback.prefixedText elseif assessment_link=='no' then 	assessment_link = nil end  -- Project status ---------  if inactive_status then 	table.insert(notices, cfg_tp.inactive:format(inactive_status)) end  -- Quality criteria -------  local custom_mask = banner_name:subPageTitle('class') if args.QUALITY_CRITERIA=='custom' then 	add_tracking(cfg_tp.quality_criteria.custom_tracking) 	if custom_mask.exists and #custom_mask:getContent()>1 then 		table.insert(notices, cfg_tp.quality_criteria.custom:format( 			custom_mask.prefixedText 		)) 	else 		table.insert(notices, string.format( 			cfg_tp.quality_criteria.missing, 			parameter_format('QUALITY_CRITERIA'), 			custom_mask.prefixedText 		)) 	end end  -- Custom importance mask -  local custom_mask = banner_name:subPageTitle('importance') if args.IMPORTANCE_SCALE=='subpage' then 	if custom_mask.exists and #custom_mask:getContent()>1 then 		table.insert(notices, string.format( 			cfg_tp.custom_importance_mask.in_use, 			custom_mask.prefixedText 		)) 	else 		table.insert(notices, string.format( 			cfg_tp.custom_importance_mask.missing, 			parameter_format('IMPORTANCE_SCALE'), 			custom_mask.prefixedText 		)) 	end elseif custom_mask.exists and #custom_mask:getContent()>1 then 	table.insert(notices, string.format( 		cfg_tp.custom_importance_mask.unused, 		custom_mask.prefixedText, 		parameter_format('IMPORTANCE_SCALE','subpage') 	)) end  -- Collapsed sections -----  local more_than = function(n) 	return n>=2 and string.format(cfg_tp.more_than.more, tostring(n)) 		or n==1 and cfg_tp.more_than.one 		or n==0 and cfg_tp.more_than.zero end local tf_threshold = tonumber(args.TF_COLLAPSE) or (args.TF_HEADER and cfg.task_force.lower_threshold) or cfg.task_force.upper_threshold if tf_count > tf_threshold then 	table.insert(notices, string.format( 		cfg_tp.task_force.collapsing, 		tf_count, 		more_than(tf_threshold), 		parameter_format('TF_COLLAPSE') 	)) end local note_threshold = tonumber(args.COLLAPSED) or 2 local hook_collapsed if args.HOOK_COLLAPSED then 	local success, result = pcall(mw.ext.ParserFunctions.expr, args.HOOK_COLLAPSED) 	hook_collapsed = success and tonumber(result) or nil 	if args.HOOK_COLLAPSED=='auto' then 		hook_collapsed = args.HOOK_NOTE and 1 or 0 -- default assumption is that HOOK_NOTE produces max one note 	end end if note_count > note_threshold then 	table.insert(notices, string.format( 		cfg_tp.note.collapsing, 		note_count, 		more_than(note_threshold), 		parameter_format('COLLAPSED') 	)) end if args.HOOK_NOTE then 	if not hook_collapsed then 		table.insert(notices, string.format( 			cfg_tp.note.counter, 			parameter_format('HOOK_NOTE'), 			parameter_format('HOOK_COLLAPSED') 		)) 		add_tracking(cfg_tp.note.tracking) 	end end  -- Assessment link --------  if raw_args.class or raw_args.importance then 	local url = mw.uri.fullUrl(banner_name.prefixedText,{ 		action = 'edit', 		summary = cfg_tp.assessment_link.edit_summary 	}) 	if args.ASSESSMENT_LINK then 		if not mw.title.new(args.ASSESSMENT_LINK).exists then 			table.insert(notices, string.format( 				cfg_tp.assessment_link.missing, 				wikilink(args.ASSESSMENT_LINK), 				tostring(url), 				parameter_format('ASSESSMENT_LINK') 			)) 		end 	end end  -- Project parameter ------  if args.PROJECT== then 	table.insert(notices, cfg_tp.project.text) 	add_tracking(cfg_tp.project.tracking) end  -- Subst check ------------  if not raw_args.substcheck then 	table.insert(notices, string.format( 		cfg_tp.substcheck.text, 		parameter_format('substcheck') 	)) 	add_tracking(cfg_tp.substcheck.tracking) end  -- Portal link ------------  if args.PORTAL then 	local portal_image = require('Module:প্রবেশদ্বার')._image(args.PORTAL) 	local portal_link = mw.title.new('Portal:' .. args.PORTAL) 	local explain 	if portal_link and portal_link.exists then 		if portal_image=='Portal-puzzle.svg' then 			explain = string.format(cfg_tp.portal.no_image, cfg_tp.portal.instructions) 		else 			explain = string.format( 				cfg_tp.portal.image_link, 				wikilink(':File:' .. portal_image), 				cfg_tp.portal.instructions 			) 		end 	else 		explain = string.format(cfg_tp.portal.missing, parameter_format('PORTAL')) 		add_tracking(cfg_tp.portal.tracking) 	end 	local text = string.format( 		cfg_tp.portal.text, 		portal_link.prefixedText, 		explain 	) 	table.insert(notices, text) end  -- Task forces ------------  for _, k in ipairs(task_forces) do 	local name_parameter = 'TF_'..k..'_NAME' 	if raw_args['tf '..k] and not args['TF_'..k..'_NAME'] then 		table.insert(notices, string.format( 			cfg_tp.task_force.text, 			parameter_format('TF_'..k..'_NAME') 		)) 		add_tracking(cfg_tp.task_force.tracking) 	end end  -- Parameter checking -----  if not inactive_status then 	local category = mw.title.new(cfg.unknown_parameters.tracking:format(project_name)) 	local text = string.format( 		category.exists and cfg_tp.parameters.tracking or cfg_tp.parameters.create, 		':' .. category.fullText 	) 	table.insert(notices, text) end  -- Assessment categories --  local importance_name = args.IMPN or (raw_args.priority and 'priority' or cfg.importance.default_name) local check_assessment_categories = function(project, assessment_cat, quality, importance_scale, prefix, tf_name) 	assessment_cat = assessment_cat or ((project or ) .. ' articles') 	local missing_cats = {} 	local red_cats_in_use = false 	local check_cat = function(cat_name, preload) 		local category = mw.title.new('Category:' .. cat_name) 		if not category.exists then 			local url = mw.uri.fullUrl('Category:' .. cat_name, { 				action = 'edit', 				preload = preload, 				editintro = cfg_tp.check_assessment.editintro, 				preview = 'no', 				summary = cfg_tp.check_assessment.create_summary, 				['preloadparams[1]'] = project, 				['preloadparams[2]'] = mw.ustring.gsub(assessment_cat, ' articles', ) 			}) 			local pages_in_category = mw.site.stats.pagesInCategory(cat_name, 'pages') 			if pages_in_category>0 then 				red_cats_in_use = true 			end 			local label = pages_in_category>0 and 'তৈরি করুন' or ' তৈরি করুন' 			local create_link = wikilink(':' .. category.prefixedText) .. ' – ([' .. tostring(url) .. ' ' .. label .. '])' 			table.insert(missing_cats, create_link) 		end 	end 	if quality then 		check_cat('মান অনুযায়ী ' .. lang:ucfirst(assessment_cat), cfg_tp.check_assessment.meta_preload) 		for _, class in ipairs(cfg_tp.check_assessment.classes) do 			local cat_name = (class=='অপর্যালোচিত' and 'অপর্যালোচিত' or i18n.class[class]..'-শ্রেনীর') .. ' ' .. assessment_cat 			check_cat(cat_name, cfg_tp.check_assessment.quality_preload) 		end 	end 	if importance_scale and importance_scale~='inline' and importance_scale~='subpage' then 		check_cat('গুরুত্ব অনুযায়ী '.. lang:ucfirst(assessment_cat) , cfg_tp.check_assessment.meta_preload) 		for _, importance in ipairs(cfg_tp.check_assessment.importances) do 			local cat_name = importance .. '-' .. importance_name .. ' ' .. assessment_cat 			check_cat(cat_name, cfg_tp.check_assessment.importance_preload) 		end 	end 	if #missing_cats>0 then 		local intro = string.format( 			cfg_tp.check_assessment.text, 			tf_name or project or , 			parameter_format((prefix or ) .. cfg_tp.check_assessment.parameter_suffix) 		) 		local list = mw.html.create('ul') 		for _, missing in ipairs(missing_cats) do 			list:tag('li') 				:wikitext(missing) 				:done() 		end 		list:done() 		if red_cats_in_use then 			add_tracking(cfg_tp.check_assessment.tracking) 		end 		return messageBox('ombox', { 			type = 'content', 			image = '50px', 			text = intro .. tostring(list) 		}) 	end 	return end local missing_cats, warnings = {}, {} local red_other_cats_in_use = false local check_other_category = function(cat_name) 	if cat_name and cat_name~='none' then 		local category = mw.title.new('Category:' .. (cat_name or )) 		if category and not category.exists then 			local pages_in_category = mw.site.stats.pagesInCategory(cat_name, 'pages') 			if pages_in_category>0 then 				red_other_cats_in_use = true 			end 			table.insert(missing_cats, wikilink(':' .. category.prefixedText)) 		end 	end end table.insert(warnings, check_assessment_categories( 	project, 	args.ASSESSMENT_CAT, 	raw_args.class and args.QUALITY_CRITERIA~='custom', 	(raw_args.importance or raw_args.priority) and (args.IMPORTANCE_SCALE or ) )) local ntf, check_task_forces = #task_forces, {} if ntf>10 then -- too many task forces to check all, so check a selection instead 	local used = {} 	math.randomseed(os.time()) 	for i = 1, 10 do 		local new 		repeat 			new = math.random(ntf) 		until not used[new] 		table.insert(check_task_forces, task_forces[new]) 		used[new] = true 	end 	table.sort(check_task_forces, function (x, y) return tonumber(x) < tonumber(y) end) 	table.insert(notices, string.format(cfg_tp.check_assessment.too_many, table.concat(check_task_forces,', '))) else 	check_task_forces = task_forces end for _, k in ipairs(check_task_forces) do 	local tf_prefix = 'TF_' .. k .. '_' 	table.insert(warnings, check_assessment_categories( 		project, 		args[tf_prefix..'ASSESSMENT_CAT'] or (args[tf_prefix..'NAME'] or )..' articles', 		raw_args.class and yesno(args[tf_prefix..'QUALITY']) and args.QUALITY_CRITERIA~='custom', 		raw_args['tf '..k..' importance'] and (args.IMPORTANCE_SCALE or ), 		tf_prefix, 		args[tf_prefix..'NAME'] 	)) 	check_other_category(args[tf_prefix .. 'MAIN_CAT']) 	for _, p in ipairs(taskforce_categories[k] or {}) do 		check_other_category(args[tf_prefix .. 'CAT_' .. p]) 	end end  -- Template categories ----  local pagetype_module = require('Module:পাতার ধরন')._main local pagetype = function(title) 	return pagetype_module{page = title.fullText} end  if on_sandbox then 	add_tracking(cfg_tp.template_categories.sandbox, true) elseif inactive_status then 	add_tracking(cfg_tp.template_categories.inactive) else 	if raw_args.class then 		add_tracking(cfg_tp.template_categories.with_quality) 	else 		add_tracking(cfg_tp.template_categories.without_quality) 	end 	if (args.PROJECT_NAME=='WikiProject '..project or not args.PROJECT_NAME) and current_page.rootPageTitle.prefixedText~='Template:WikiProject ' .. project then 		add_tracking(cfg_tp.template_categories.non_standard) 	end  	-- List of categories to check. Should probably have a one consistent style. 	local category_suffixes = { 		project_name .. "-related templates", 		'Wikipedia-' .. project_name .. ' collaboration templates', 		'Wikipedia-' .. project_name .. ' collaboration', 		project_name .. ' templates', 		project_name, 	}  	-- Check each category 	local found = false 	for _, suffix in ipairs(category_suffixes) do 		local category_title = mw.title.new('Category:' .. suffix) 		if category_title.exists and pagetype(category_title) ~= 'redirect' then 			table.insert(tracking_cats, wikilink(category_title.fullText, '*')) 			found = true 			break 		end 	end end  -- Check parameters -------  local parameters = {} local append_table = function(source) 	for _, v in ipairs(source) do 		table.insert(parameters, v) 	end end append_table(cfg_tp.parameters.parameters) for _, k in ipairs(task_forces) do 	local task_force_parameters = {'tf '..k, 'tf '..k..' importance'} 	local prefix = string.format(cfg_tp.parameters.taskforce.prefix, k)  	for _, p in ipairs(cfg_tp.parameters.taskforce.suffix) do 		table.insert(task_force_parameters, prefix .. p) 	end 	for _, p in ipairs(taskforce_categories[k] or {}) do 		table.insert(task_force_parameters, 'tf ' .. k .. ' cat ' .. p) 		table.insert(task_force_parameters, prefix .. 'CAT_' .. p) 	end 	append_table(task_force_parameters) end for _, k in ipairs(notes) do 	local note_parameters = {'note '..k} 	local prefix = string.format(cfg_tp.parameters.note.prefix, k) 	for _, p in ipairs(cfg_tp.parameters.note.suffix) do 		table.insert(note_parameters, prefix .. p) 	end 	append_table(note_parameters) 	check_other_category(args[prefix .. 'CAT']) end for _, set in ipairs(cfg_tp.parameters.extra) do 	local allow_parameters = false 	if set.trigger then 		table.insert(parameters, set.trigger) 		allow_parameters = raw_args[set.trigger] and true 	elseif set.triggers then 		append_table(set.triggers) 		for _, trig in ipairs(set.triggers) do 			if raw_args[trig] then 				allow_parameters = true 			end 		end 	end 	if allow_parameters then 		append_table(set.parameters) 		if set.categories then 			append_table(set.categories) 			for _, cat in ipairs(set.categories) do 				check_other_category(args[cat]) 			end 		end 	end end parameters.preview = cfg_tp.parameters.preview parameters.unknown = on_sandbox and  or cfg_tp.parameters.category local parameter_check = current_page.rootPageTitle.text=='WikiProject Military history' and 	or require('Module:Check for unknown parameters')._check(parameters, raw_args)  -- Other categories -------  if raw_args.attention then 	local attention_cat = args.ATTENTION_CAT or string.format(cfg.attention.default_cat, project) 	check_other_category(attention_cat) end if raw_args.infobox then 	local infobox_cat = args.INFOBOX_CAT or string.format(cfg.infobox.default_cat, project) 	check_other_category(infobox_cat) end if raw_args.auto then 	local auto_cat = args.AUTO_ASSESS_CAT or string.format(cfg.auto.default_cat, project) 	check_other_category(auto_cat) end check_other_category(args.MAIN_CAT) if #missing_cats>0 then 	local list = mw.html.create('ul') 	for _, missing in ipairs(missing_cats) do 		list:tag('li') 			:wikitext(missing) 			:done() 	end 	list:done() 	table.insert(warnings, messageBox('ombox', { 		type = 'content', 		image = '50px', 		text = cfg_tp.check_other.text .. tostring(list) 	})) 	if red_other_cats_in_use then 		add_tracking(cfg_tp.check_other.tracking) 	end end  -- Produce notices --------  local notice_html, notice_list if #notices>=1 then 	notice_html = mw.html.create('ul') 	for _, notice in ipairs(notices) do 		notice_html:tag('li') 			:wikitext(notice) 			:done() 	end 	notice_list = ' ' .. cfg_tp.notice_text .. tostring(notice_html) end local info =  messageBox('ombox', { 	type = 'notice', 	image = '50px', 	text = cfg_tp.info .. (notice_list or ) })  -- Auto documentation -----  local td_params, auto_doc, parameter_name = {}, {}, {} local basic, full, parameter_used, param = {}, {}, {}, {} local class_module = require('Module:Class') local template_code = mw.title.getCurrentTitle():getContent() for _, parameter in pairs(parameters) do 	parameter_name[parameter] = string.match( 		template_code, 		'%|%s*' .. parameter:gsub('%-','%%%-') .. '%s*=%s*{{{([^|}]*)' 	) end local addTitle = function(title, level, section) 	local hl = 'h' .. tostring(level or 2) 	local _table = section or auto_doc 	table.insert(_table, tostring(mw.html.create(hl):wikitext(title)) .. '\n') end local showSection = function(list, title) 	if param[list] then 		if title then 			addTitle(title, 3) 		end 		local out = mw.html.create('ul') 		for _, v in ipairs(param[list]) do 			out:node(v) 		end 		table.insert(auto_doc, tostring(out:done())) 	end end local parameter_description = function(parameter, text, list, option, isBasic) 	local p_name = parameter_name[parameter] 	if p_name then 		if not parameter_used[p_name] then 			local syntax = '|' .. p_name .. '= ' 			if isBasic then 				table.insert(basic, syntax) 			end 			table.insert(full, syntax) 			parameter_used[p_name] = true 		end 		local parsed_text = text 			:gsub('_PARAMETER_', parameter_format(p_name)) 			:gsub('_PARAMETER%|?(%a*)_', parameter_format(p_name, '%1')) 			:gsub('_PAGETYPE_', 'article') 		local desc = '' .. p_name .. ' – ' .. parsed_text 		local new_item = mw.html.create('li'):wikitext(desc) 		if param[list] then 			table.insert(param[list], new_item) 		else 			param[list] = {new_item} 		end 		if not option then option = {} end 		if not option.label then 			option.label = p_name 		end 		if not option.type then 			option.type = 'line' --use line type unless specified 		end 		--if not option.description then 		--	option.description = parsed_text --use text as description unless specified 		--end 		td_params[p_name] = option 	end end parameter_description('category', cfg.auto_doc.category, 'general', { 	description = 'Set to no to display the banner without any categories. For testing or demo purposes; should not be used in articles.', 	suggestedvalues = {'no'} }) parameter_description('listas', cfg.auto_doc.listas:format( 	'John Smith', parameter_format('listas', 'Smith, John'), 'Smith', 'John', 	'The Matrix', parameter_format('listas', 'Matrix, The'), 'Matrix' ), 'general', { 	description = 'Define a sort key, mainly for biographical articles, so that the page is sorted under the surname rather than the first name.', 	example = 'Smith, John' }) parameter_description('class', cfg.auto_doc.quality.see_below, 'general', { 	description = 'Assess the quality of the article. Please add this parameter to the banner shell instead.', 	example = 'C', 	deprecated = true, 	suggestedvalues = {'Stub', 'Start', 'C', 'B', 'A', 'List', 'GA', 'FA', 'FL'} }, true) parameter_description('importance', cfg.auto_doc.importance.see_below, 'general', { 	description = 'Assess the importance or priority of the article to the WikiProject', 	example = 'low', 	suggested = true, 	suggestedvalues = {'Low', 'Mid', 'High', 'Top', 'NA'} }, true) parameter_description('auto', cfg.auto_doc.auto:format(args.AUTO_ASSESS_CAT or cfg.auto.default_cat:format(project)), 'notes', { 	description = 'Indicates that the article has been automatically assessed by a bot or other tool.', 	example = 'yes' }) parameter_description('attention', cfg.auto_doc.attention:format(args.ATTENTION_CAT or cfg.attention.default_cat:format(project)), 'notes', { 	description = 'Indicates that the article needs immediate attention from experienced editors.', 	example = 'yes' }) parameter_description('infobox', cfg.auto_doc.infobox:format(args.INFOBOX_CAT or cfg.infobox.default_cat:format(project)), 'notes', { 	description = 'Indicates that the article needs an infobox.', 	example = 'yes' }) if raw_args['image-needed'] then 	parameter_description('image-needed', cfg.auto_doc.image_needed.text:format(args['image-type'] or cfg.image_needed.default_type), 'notes') 	parameter_description('image-type', cfg.auto_doc.image_needed._type:format(cfg.image_needed.default_type), 'notes') 	parameter_description('image-details', cfg.auto_doc.image_needed.details, 'notes') 	local loc_cat = args.IM_LOCATION_CATEGORY 		and (' ' .. cfg.auto_doc.image_needed.default:format('location', args.IM_LOCATION_CATEGORY)) 		or 	parameter_description('image-location', cfg.auto_doc.image_needed.location:format(args['image-type'] or 'photograph') .. loc_cat, 'notes') 	local topic_cat = args.IM_TOPIC_CATEGORY 		and (' ' .. cfg.auto_doc.image_needed.default:format('topic', args.IM_TOPIC_CATEGORY)) 		or  	parameter_description('image-topic', cfg.auto_doc.image_needed.topic:format(args['image-type'] or 'photograph') .. topic_cat, 'notes') end for _, k in ipairs(notes) do 	local text = cfg.auto_doc.note.yes_no 	if args['NOTE_'..k..'_TEXT'] then 		text = text ..  cfg.auto_doc.note.text:format(args['NOTE_'..k..'_TEXT']) 	end 	if args['NOTE_'..k..'_CAT'] then 		text = text ..  ' ' .. cfg.auto_doc.note.category:format(args['NOTE_'..k..'_CAT']) 	end 	parameter_description('note '..k, text, 'notes', { 		description = 'Triggers a custom note in the banner.', 		example = 'yes', 		suggestedvalues = {'yes', 'no'} 	}) end for _, k in ipairs(task_forces) do 	local tf_imp_name = raw_args['tf ' .. k .. ' importance'] and parameter_name['tf ' .. k .. ' importance'] 	local prefix = 'TF_' .. k .. '_' 	local text = cfg.auto_doc.task_force.yes_no:format( 		args[prefix..'LINK'] or , 		args[prefix..'NAME'] or  	) 	if args[prefix..'MAIN_CAT'] then 		text = text .. ' ' .. cfg.auto_doc.task_force.category:format(args[prefix..'MAIN_CAT']) 	end 	if yesno(args[prefix..'QUALITY']) and args[prefix..'ASSESSMENT_CAT'] then 		text = text .. ' ' .. cfg.auto_doc.task_force.class:format( 			args[prefix..'ASSESSMENT_CAT'], 			'class' 		) 	end 	if tf_imp_name and args[prefix..'ASSESSMENT_CAT'] then 		text = text .. ' ' .. cfg.auto_doc.task_force.importance:format( 			parameter_format(tf_imp_name), 			args[prefix..'ASSESSMENT_CAT'] 		) 	end 	parameter_description('tf '..k, text, 'task_forces', { 		description = 'Triggers ' .. (args[prefix..'NAME'] or 'a custom task force') .. ' in the banner.', 		example = 'yes', 		suggestedvalues = {'yes', 'no'} 	}) end  -- Quality documentation --  	 local quality local assessment_cat = args.ASSESSMENT_CAT or project .. ' articles' if raw_args.class then 	quality = {} 	local text 	if args.QUALITY_CRITERIA=='custom' and assessment_link then 		local scale = cfg.quality.project_scale:format(wikilink(assessment_link..'#'..lang:ucfirst(cfg.quality.name), cfg.quality.name)) 		text = cfg.auto_doc.quality.custom:format(scale) 	else 		text = cfg.auto_doc.quality.default:format(cfg.quality.default_scale) 	end 	table.insert(quality, text) 	local exists = {} 	addTitle(cfg.auto_doc.quality.class_parameter, 3, quality) 	local add_row = function(class, input, rowspan) 		local cat = i18n.class[class]..'-শ্রেনীর '..assessment_cat 		return mw.html.create('tr') 			:tag('th') 				:wikitext(input or class) 				:done() 			:tag('td') 				:attr('rowspan', rowspan or 1) 				:css('text-align', 'center') --TODO: add to css page 				:wikitext(class_module.icon{class}) 				:done() 			:node(class_module._class{class, category=assessment_cat, image='no', rowspan=rowspan or 1}) 			:tag('td') 				:attr('rowspan', rowspan or 1) 				:wikitext(wikilink(':Category:'..cat)) 				:done() 			:tag('td') 				:attr('rowspan', rowspan or 1) 				:css('text-align', 'right') --TODO: add to css page 				:wikitext(lang:formatNum(mw.site.stats.pagesInCategory(cat))) 			:done() 	end 	local class_table = mw.html.create('table') 		:addClass('wikitable') 		:tag('tr') 			:tag('th') 				:wikitext(cfg.auto_doc.quality._table._input) 				:done() 			:tag('th') 				:wikitext(cfg.auto_doc.quality._table.icon) 				:done() 			:tag('th') 				:wikitext(cfg.auto_doc.quality._table.class) 				:done() 			:tag('th') 				:wikitext(cfg.auto_doc.quality._table.category) 				:done() 			:tag('th') 				:wikitext(cfg.auto_doc.quality._table.population) 				:done() 		:done() 	for _, class in ipairs{'FA', 'A', 'GA'} do 		class_table:node(add_row(class)) 	end 	class_table:node(add_row('B')) 	class_table:node(add_row('C')) 	for _, class in ipairs{'Start', 'Stub', 'FL', 'List', 'NA'} do 		class_table:node(add_row(class)) 	end 	for _, class in ipairs(cfg.auto_doc.quality.extended) do 		local cat = mw.title.new('Category:' .. class .. '-শ্রেনীর ' .. assessment_cat) 		if cat.exists and #cat:getContent()>1 then 			exists[class] = true 			class_table:node(add_row(class)) 		end 	end 	table.insert(quality, tostring(class_table)) 	addTitle(cfg.auto_doc.quality.redirect, 3, quality) 	local redirects = cfg.auto_doc.quality.redirects:format( 		exists.Redirect and 'Redirect' or 'NA', 		wikilink(':Category:' .. (exists.Redirect and 'Redirect' or 'NA') .. '-Class ' ..assessment_cat) 	) 	local dabs = cfg.auto_doc.quality.dabs:format( 		exists.Disambig and 'Disambig' or 'NA', 		wikilink(':Category:' .. (exists.Disambig and 'Disambig' or 'NA') .. '-Class ' ..assessment_cat) 	) 	table.insert(quality, cfg.auto_doc.quality.not_defined) 	local list = mw.html.create('ul') 		:tag('li') 			:wikitext(redirects) 			:done() 		:tag('li') 			:wikitext(dabs) 			:done() 	:done() 	table.insert(quality, tostring(list)) 	addTitle(cfg.auto_doc.quality.namespace, 3, quality) 	table.insert(quality, cfg.auto_doc.quality.deduced) 	local first_col = function(text) 		return mw.html.create('tr'):tag('th') 			:wikitext(text) 			:allDone() 	end 	local namespace_table = mw.html.create('table') 		:addClass('wikitable') 		:tag('tr') 			:tag('th') 				:wikitext(cfg.auto_doc.quality._table.namespace) 				:done() 			:tag('th') 				:wikitext(cfg.auto_doc.quality._table.icon) 				:done() 			:tag('th') 				:wikitext(cfg.auto_doc.quality._table.class) 				:done() 			:tag('th') 				:wikitext(cfg.auto_doc.quality._table.category) 				:done() 			:tag('th') 				:wikitext(cfg.auto_doc.quality._table.population) 				:done() 		:done() 	local na_rowspan = 3 		+ (exists.File and 0 or 2) 		+ (exists.Category and 0 or 1) 		+ (exists.Portal and 0 or 1) 		+ (exists.Template and 0 or 2) 		+ (exists.Project and 0 or 1) 		+ (exists.Draft and 0 or 1) 	namespace_table:node(add_row('NA', 'User talk', na_rowspan)) 	:node(not exists.File and first_col('File talk')) 	:node(not exists.File and first_col('TimedText talk')) 	:node(not exists.Category and first_col('Category talk')) 	:node(not exists.Portal and first_col('Portal talk')) 	:node(not exists.Template and first_col('Template talk')) 	:node(not exists.Template and first_col('Module talk')) 	:node(not exists.Project and first_col('Project talk')) 	:node(not exists.Draft and first_col('Draft talk')) 	:node(first_col('Help talk')) 	:node(first_col('MediaWiki talk')) 	:node(exists.File and add_row('File', 'File talk', 2)) 	:node(exists.File and first_col('TimedText talk')) 	:node(exists.Category and add_row('Category', 'Category talk')) 	:node(exists.Portal and add_row('Portal', 'Portal talk')) 	:node(exists.Template and add_row('Template', 'Template talk', 2)) 	:node(exists.Template and first_col('Module talk')) 	:node(exists.Project and add_row('Project', 'Project talk')) 	:node(exists.Draft and add_row('Draft', 'Draft talk')) 	table.insert(quality, tostring(namespace_table)) 	table.insert(quality, cfg.auto_doc.quality.other:format(assessment_cat)) end  -- Importance doc ---------  local importance_doc if raw_args.importance and args.IMPORTANCE_SCALE~='inline' and args.IMPORTANCE_SCALE~='subpage' then 	importance_doc = {} 	local imp_doc = cfg.auto_doc.importance 	addTitle(imp_doc.heading, 2, importance_doc) 	table.insert(importance_doc, imp_doc.standard) 	local add_row = function(importance) 		local cat = importance..'-' .. 'importance ' .. assessment_cat 		return mw.html.create('tr') 			:tag('th') 				:wikitext(importance) 				:done() 			:node(frame:expandTemplate{title='Template:Importance', args={importance, category=assessment_cat}}) 			:tag('td') 				:wikitext(wikilink(':Category:'..cat)) 				:done() 			:tag('td') 				:css('text-align', 'right') --TODO: add to css page 				:wikitext(lang:formatNum(mw.site.stats.pagesInCategory(cat))) 				:done() 	end 	local imp_table = mw.html.create('table') 		:addClass('wikitable') 		:tag('tr') 			:tag('th') 				:wikitext(imp_doc._table._input) 				:done() 			:tag('th') 				:wikitext(imp_doc._table.importance) 				:done() 			:tag('th') 				:wikitext(imp_doc._table.category) 				:done() 			:tag('th') 				:wikitext(imp_doc._table.population) 				:done() 		:done() 	for _, importance in ipairs(imp_doc.classes) do 		imp_table:node(add_row(importance)) 	end 	table.insert(importance_doc, tostring(imp_table)) end  -- Build documentation ----  table.insert(auto_doc, string.format(cfg.auto_doc.lead, wikilink(project_link, project_name)))  if args.MAIN_CAT then 	table.insert(auto_doc, 'All articles are categorised into :Category:' .. args.MAIN_CAT .. '.') end addTitle('Basic usage', 3) table.insert(auto_doc, cfg.auto_doc.usage_basic 	.. frame:extensionTag{ 		name = 'syntaxhighlight', 		content = '', 		args = {lang = 'wikitext'} 	} ) addTitle('Full usage', 3) table.insert(auto_doc, cfg.auto_doc.usage_full 	.. frame:extensionTag{ 		name = 'syntaxhighlight', 		content = '', 		args = {lang = 'wikitext'} 	} ) addTitle('Parameters') showSection('general') showSection('notes', 'Notes and alerts') showSection('task_forces', 'Task forces') if quality then 	addTitle(cfg.auto_doc.quality.heading) 	table.insert(auto_doc, table.concat(quality)) end if importance_doc then 	table.insert(auto_doc, table.concat(importance_doc)) end  -- Template data ----------  local template_data = { 	description = 'This template identifies the article as being within scope of ' .. project_name .. '.', 	format = 'inline', 	params = td_params } if args.DOC=='auto' then 	addTitle('TemplateData', 3) 	table.insert( 		auto_doc, 		frame:extensionTag{ 			name = 'templatedata', 			content = mw.text.jsonEncode(template_data) 		} 	) end  local doc = if args.DOC=='auto' or args.DOC=='auto+custom' then 	local not_documented = {'INHERIT_IMPORTANCE', 'priority', 'IMPN', 'QII_FORMAT', 'collaboration-candidate', 'collaboration-current', 'collaboration-past', 'a class', 'peer review', 'old peer review'} 	local doc_missing = false 	for _, p in ipairs(not_documented) do 		if raw_args[p] then 			doc_missing = p 		end 	end 	if doc_missing then 		add_tracking{ 			category = 'WikiProject banner templates using undocumented features', 			sort_key = doc_missing 		} 	end 	doc = require('Module:Documentation').main{content = table.concat(auto_doc)} end if args.DOC=='custom' or args.DOC=='auto+custom' then 	doc = doc .. require('Module:Documentation').main() end  return parameter_check .. demo_banner .. info .. (inactive_status and  or table.concat(warnings)) .. table.concat(tracking_cats) .. doc end  return p