Mô đun:WikiProject banner/templatepage

require('strict')
local p = {}
local sandbox-- = '/sandbox'
local template_page_cfg = {
	info = 'Bản mẫu biểu ngữ WikiProject sử dụng Mô đun:WikiProject banner, một siêu bản mẫu để tạo và duy trì biểu ngữ dự án dễ dàng. Hãy báo cáo lỗi hoặc yêu cầu tính năng tại Thảo luận Mô đun:WikiProject banner.',
	notice_text = 'Thông tin hoặc cảnh báo về bản mẫu nằm dưới đây:',
	quality_criteria = {
		custom = 'Dự án này đã chọn không tham gia đánh giá chất lượng độc lập và đang sử dụng mặt nạ chất lượng tùy chỉnh.',
		custom_tracking = {category = 'Dự án sử dụng thang chất lượng không tiêu chuẩn'},
		missing = 'Tham số %s được đặt thành tùy chỉnh nhưng không có mặt nạ chất lượng tùy chỉnh được lưu tại %s. Do đó, thang đo chất lượng đã bị tắt.',
	},
	custom_importance_mask = {
		in_use = 'Một mặt nạ độ quan trọng tùy chỉnh đang được sử dụng.',
		missing = 'Tham số %s được đặt thành trang con nhưng không có mặt nạ tầm quan trọng tùy chỉnh được lưu tại %s. Do đó, thang đo độ quan trọng đã bị tắt.',
		unused = '/trang con độ quan trọng hiện không được sử dụng. Để sử dụng, hãy đặt %s. Để xóa cảnh báo này, hãy xóa hoặc làm trống trang con đó..'
	},
	more_than = {
		zero = 'bất kỳ trong số đó',
		one = 'hơn một trong số đó',
		more = 'hơn %s trong số đó'
	},
	note = {
		collapsing = 'Ghi chú %s trong bản mẫu này sẽ tự động thu gọn nếu %s được kích hoạt. Để thay đổi cài đặt này, hãy đặt hoặc cập nhật tham số %s.',
		counter = 'Một móc đã được gắn vào tham số %s nhưng không có bộ đếm hợp lệ được gắn vào %s.',
		tracking = {sort_key = 'Hook collapsed'},
	},
	assessment_link = {
		missing = 'This project banner specifies a non-existent assessment page %s. Please %s update or remove the %s parameter to fix this problem.',
		edit_summary = 'set ASSESSMENT_LINK parameter',
	},
	project = {
		text = 'The required PROJECT parameter has not been defined.',
		banner = 'The page name of the banner template does not exist. Please check the PROJECT or BANNER_NAME parameters.',
		tracking = {sort_key = 'Missing PROJECT parameter'},
	},
	substcheck = {
		text = 'A feature for detecting incorrectly substituted project banners has not yet been implemented on this template. Please see the documentation for how to set the %s parameter.',
		tracking = {sort_key = 'Check'},
	},
	portal = {
		text = 'Bản mẫu biểu ngữ này bao gồm một liên kết đến %s, %s',
		no_image = 'nhưng vẫn chưa có hình ảnh tùy chỉnh nào. Hãy đọc %s.',
		image_link = 'và hình ảnh đi kèm là %s. Hãy xem %s để biết cách thay đổi hình ảnh này.',
		instructions = 'hướng dẫn',
		missing = 'nhưng cổng thông tin này không tồn tại - bạn có thể đã định nghĩa %s không đúng hoặc cổng thông tin có thể đã bị xóa.',
		tracking = {sort_key = 'O'},
	},
	task_force = {
		text = 'A task force does not have a defined name, which is needed for proper classification of these articles. Please add the %s parameter.',
		tracking = {sort_key = 'N'},
		collapsing = 'The %s task forces and/or work groups will automatically collapse if %s displayed. To change this setting, set or update the %s parameter.',
	},
	check_assessment = {
		classes = {'Bài viết chọn lọc', 'Danh sách chọn lọc', 'Bài viết chất lượng A', 'Bài viết tốt', 'Bài viết chất lượng B', 'Bài viết chất lượng C', 'Sơ khởi', 'Sơ khai', 'Danh sách', 'Chưa đánh giá chất lượng', 'Trang ngoài bài viết'},
		importances = {'Đặc biệt', 'Rất', 'Khá', 'Ít', 'Không áp dụng độ', 'Không rõ độ'},
		text = 'Some of the assessment categories required for %s do not currently exist, and should to be created to avoid redlinks appearing on talk pages. Alternatively, you may need to set or update the %s parameter in this template.',
		icon = 'Nuvola apps kfig.svg',
		create_summary = 'Creating category for 1.0 Assessment scheme',
		_preload = {
			root = 'Template:WikiProject banner preload template',
			quality = 'quality',
			importance = 'importance',
			meta = 'meta'
		},
		parameter_suffix = 'ASSESSMENT_CAT',
		tracking = {sort_key = 'Assessment categories missing'},
		too_many = 'There are too many task forces to check the assessment categories for each one, so the following selection have been checked: %s.',
	},
	check_other = {
		text = 'The following categories are required for the banner to work correctly. Please either create these categories or adjust the banner so that they are not required.',
		icon = 'Nuvola apps kfig.svg',
		tracking = {sort_key = 'Z'},
	},
	default_tracking = 'WikiProject banners with errors',
	template_categories = {
		non_standard = {category = 'WikiProject banners with non-standard names'},
		sandbox = {category = 'WikiProject banner template sandboxes'},
		with_quality = {category = 'WikiProject banners with quality assessment'},
		without_quality = {category = 'WikiProject banners without quality assessment'},
		inactive = {category = 'Inactive WikiProject banners'}
	},
	parameters = {
		preview = 'Unexpected or deprecated parameter _VALUE_',
		category = ,
		parameters = {'PROJECT', 'BANNER_NAME', 'PROJECT_NAME', 'PROJECT_LINK', 'demo_page', 'substcheck', 'category', 'listas', 'MAIN_TEXT', 'MAIN_ARTICLE', 'PORTAL', 'TF_TEXT', 'TF_SIZE', 'TF_COLLAPSE', 'TF_HEADER', 'INHERIT_IMPORTANCE', 'NOTE_SIZE', 'COLLAPSED', 'COLLAPSED_HEAD', 'MAIN_CAT', 'BOTTOM_TEXT', 'HOOK_NESTED', 'HOOK_NESTED_ASSESS', 'HOOK_ASSESS', 'HOOK_TF', 'HOOK_NOTE', 'HOOK_BOTTOM', 'HOOK_COLLAPSED', 'HOOK_IMPORTANCE', 'PROJECT_STATUS', 'DOC'},
		extra = {
			{
				trigger = 'IMAGE_LEFT',
				parameters = {'IMAGE_LEFT_SIZE'}
			},
			{
				trigger = 'IMAGE_RIGHT',
				parameters = {'IMAGE_RIGHT_SIZE'}
			},
			{
				trigger = 'class',
				parameters = {'QUALITY_SCALE', 'QUALITY_CRITERIA', 'ASSESSMENT_CAT', 'ASSESSMENT_LINK'}
			},
			{
				triggers = {'b1', 'b2', 'b3', 'b4', 'b5', 'b6'},
				parameters = {'B_DISPLAY_ON_START'},
				categories = {'B1_CAT', 'B2_CAT', 'B3_CAT', 'B4_CAT', 'B5_CAT', 'B6_CAT', 'B_MAIN_CAT'}
			},
			{
				triggers = {'importance', 'priority'},
				parameters = {'IMPORTANCE_SCALE', 'ASSESSMENT_CAT', 'ASSESSMENT_LINK', 'IMPN'}
			},
			{
				trigger = 'auto',
				parameters = {'AUTO_ASSESS_CAT'}
			},
			{
				trigger = 'attention',
				parameters = {'ATTENTION_CAT'}
			},
			{
				trigger = 'infobox',
				parameters = {'INFOBOX_CAT'}
			},
			{
				triggers = {'TODO_TEXT', 'TODO_LINK'},
				parameters = {'TODO_TITLE', 'TODO_EDITLINKS'}
			},
			{
				trigger = 'QII_FORMAT',
				parameters = {'QII_SUPPRESS_NA', 'QII_SUPPRESS_NA_CLASS', 'QII_SUPPRESS_NA_IMPORTANCE', 'QII_UNASSESSED_APPENDIX'}
			},
			{
				trigger = 'image-needed',
				parameters = {'IM_IMAGE', 'image-location', 'image-details', 'image-topic', 'image-type'},
				categories = {'IM_LOCATION_CATEGORY', 'IM_TOPIC_CATEGORY'}
			},
			{
				triggers = {'collaboration-candidate', 'collaboration-current', 'collaboration-past'},
				parameters = {'COLL_LINK', 'COLL_TEXT', 'COLL_IMAGE'},
				categories = {'COLL_CANDIDATE_CAT', 'COLL_CURRENT_CAT', 'COLL_PAST_CAT'}
			},
			{
				trigger = 'a class',
				parameters = {'ACR_SUBPAGE_LINK', 'ACR_REVIEW_LINK', 'ACR_IMAGE', 'ACR_SIZE', 'ACR_PRELOAD'},
				categories = {'ACR_PASS_CAT', 'ACR_FAIL_CAT', 'ACR_CURRENT_CAT', 'ACR_INVALID_CAT'}
			},
			{
				triggers = {'peer review', 'old peer review'},
				parameters = {'PR_LINK', 'peer review title', 'PR_IMAGE', 'PR_SIZE'},
				categories = {'PR_CAT', 'PR_OLD_CAT', 'PR_INVALID_CAT'}
			}
		},
		taskforce = {
			prefix = 'TF_%s_',
			suffix = {'LINK', 'NAME', 'NESTED', 'IMAGE', 'TEXT', 'QUALITY', 'ASSESSMENT_CAT', 'MAIN_CAT', 'PORTAL', 'HOOK', 'SIZE', 'QII_FORMAT', 'QII_SUPPRESS_NA', 'QII_SUPPRESS_NA_CLASS', 'QII_SUPPRESS_NA_IMPORTANCE', 'QII_UNASSESSED_APPENDIX'},
		},
		note = {
			prefix = 'NOTE_%s_',
			suffix = {'TEXT', 'IMAGE', 'CAT', 'SIZE'},
		},
		tracking = 'Automatic parameter checking is enabled and pages with invalid parameters can be found in the tracking category.',
		create = 'Automatic parameter checking is enabled. Create the tracking category to track invalid parameters.',
	},
	inactive = 'This project has been identified as %s. Please see WP:INACTIVEWP for more information. To reactivate this project, change inactive on the first line to main.'
}
local auto_doc_cfg = {
	lead = 'This is the WikiProject banner template used by %s to keep track of articles within its scope.',
	main_cat = 'All articles are categorised into :Category:%s.',
	attention = 'set _PARAMETER|yes_ if the article needs immediate attention from experienced editors. Use only if another parameter does not cover the need for attention; this should be used sparingly. It is strongly encouraged to also add a section to the talk page explaining what needs attention. This parameter populates :Category:%s.',
	auto = 'this parameter is for the use of bots and indicates that the article has been automatically rated:\n'
		.. '*length – based on the length of the article;\n'
		.. '*inherit – because one or more other projects use this class;\n'
		.. '*yes or stub (in conjunction with |class=stub) – as Stub-Class because it uses a stub template.\n'
		.. 'Use of the above values with this parameter populates :Category:%s.',
	category = {
		list = 'general',
		text = 'set _PARAMETER|no_ if, and only if, a banner is being used for demonstration or testing purposes, to prevent unnecessary or undesirable categorization. Otherwise, omit this parameter.',
		description = 'Set to no to display the banner without any categories. For testing or demo purposes; should not be used in articles.',
		suggestedvalues = {'no'},
		alwaysShow = true
	},
	image_needed = {
		text = 'to request that %s be added to the page.',
		location = 'specify the location of the requested image. Will be categorised into Category:Wikipedia requested %ss in LOCATION, where LOCATION is the value of the _PARAMETER_ paramater.',
		details = 'additional text to insert before the words \"be added to this article\" to describe the subject or type of image that is requested.',
		topic = 'specify the topic of the requested image. Will be categorised into Category:Wikipedia requested %ss of TOPIC, where TOPIC is the value of the _PARAMETER_ parameter.',
		_type = 'overrides the default text (%s); also used to categorise the request.',
		default = 'If no %s is specified then :Category:%s is used by default.'
	},
	importance = {
		list = 'general',
		text = 'see #Importance assessment below.',
		description = 'Assess the importance or priority of the article to the WikiProject',
		example = 'low',
		suggested = true,
		suggestedvalues = {'Low', 'Mid', 'High', 'Top', 'NA'},
		isBasic = true,
		heading = 'Importance assessment',
		standard = 'This project uses the standard importance scale. Valid values are shown below.',
		_table = {
			_input = 'Input(not case sensitive)',
			importance = 'Importance',
			category = 'Category',
			population = 'Population',
		},
		classes = {'Top', 'High', 'Mid', 'Low', 'NA'}
	},
	infobox = 'set _PARAMETER|yes_ if the article needs an infobox. Remember that infoboxes are not suitable for all articles, and can overwhelm short articles. This parameter populates :Category:%s.',
	listas = {
		list = 'deprecated',
		text = 'this parameter should be used with the banner shell template, not on individual project banners. Please see Template:WikiProject banner shell for details.',
		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',
		isFull = false
	},
	note = {
		yes_no = 'set _PARAMETER|yes_ or any non-blank value other than "no", "n" or "0". ',
		text = 'The following message will be displayed: "%s"',
		category = 'This will populate :Category:%s.'
	},
	portal_selected = {
		-- 'selected' can be replaced with a link in the format of selected if a link is given
		text = 'This article has been selected for use on the Cổng thông tin %s.',
		image = 'Portal-puzzle.svg',
	},
	class = {
		list =  'deprecated',
		text = 'this parameter should be used with the banner shell template, not on individual project banners. See #Quality assessment below.',
		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'},
		isFull = false
	},
	quality = {
		heading = 'Quality assessment',
		custom = 'This project has opted to use custom quality criteria. See the %s for details.',
		default = 'This project uses %s.',
		class_parameter = 'Classification based on class parameter',
		class_text = 'Classification of articles is made by adding the %s parameter to the banner shell template. Valid values are shown below.',
		_table = {
			_input = 'Input(not case sensitive)',
			icon = 'Icon',
			class = 'Class',
			category = 'Category',
			population = 'Population',
			namespace = 'Namespace'
		},
		classes = {'FA', 'A', 'GA', 'B', 'C', 'Start', 'Stub', 'FL', 'List'},
		extended = {'File', 'Draft', 'Category', 'Disambig', 'Cổng thông tin', 'Redirect', 'Template', 'FM'},
		redirect = 'Classification of redirects and disambiguation pages',
		not_defined = 'If the WikiProject banner is placed on the talk page of a redirect (in any namespace) or disambigation page then it will automatically be classified as follows:',
		redirects = 'Redirects will automatically be classified as %s-class and placed in :Category:%s-Class %s pages.',
		dabs = 'Disambiguation pages will automatically be classified as %s-class and placed in :Category:%s-Class %s pages.',
		namespace = 'Classification based on namespace',
		deduced = 'When placed on non-articles, the class will be deduced from the namespace of the page.',
		all_na = 'All non-articles are classified as NA-class and will populate :Category:NA-Class %s pages.\n',
		other = 'In all other circumstances, articles will be classed as Unassessed and placed in :Category:Unassessed %s.'
	},	
	task_force = {
		yes_no = 'set _PARAMETER|yes_ if the article is supported by %s. ',
		category = 'This parameter populates :Category:%s. ',
		class = 'This parameter populates the relevant subcategory of :Category:%s by quality based on the |%s= parameter. ',
		importance = 'This parameter sets the importance of the article according to %s. It populates the relevant subcategory of :Category:%s by importance. See #Importance assessment for valid values.'
	},
	usage_basic = 'Place this on the talk page of relevant articles:',
	usage_full = 'It is usual to remove any unused parameters from the template call.',
}
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('Module:WikiProject banner/config' .. (sandbox or ))
local cfg_tp = template_page_cfg -- 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  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_categoriestf then-- initialise table
			taskforce_categoriestf = {}
		end
		table.insert(taskforce_categoriestf, 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) 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:Portal')._image(args.PORTAL)
	local portal_link = mw.title.new('Cổng thông tin:' .. 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(':Tập tin:' .. 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)
	local cat = (assessment_cat and assessment_cat:gsub(' articles', ) or project or ) -- strip "articles" from assessment category
	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 = cfg_tp.check_assessment._preload.root .. '/' .. _preload,
				preview = 'no',
				summary = cfg_tp.check_assessment.create_summary,
				'preloadparams1' = project
			})
			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 'create' or 'create'
			local create_link = wikilink(':' .. category.prefixedText) .. ' – (' .. tostring(url) .. ' ' .. label .. ')'
			table.insert(missing_cats, create_link)
		end
	end
	if quality then
		check_cat('Bài viết' .. ' ' .. lang:ucfirst(cat) .. ' theo chất lượng', cfg_tp.check_assessment._preload.meta)
		for _, class in ipairs(cfg_tp.check_assessment.classes) do
			local cat_name = (class=='Chưa đánh giá chất lượng' and 'Chưa đánh giá chất lượng' or class) ..  ' về ' .. cat
			check_cat(cat_name, cfg_tp.check_assessment._preload.quality)
		end
	end
	if importance_scale and importance_scale~='inline' and importance_scale~='subpage' then
		check_cat(lang:ucfirst(cat) .. ' articles by ' .. importance_name, cfg_tp.check_assessment._preload.meta)
		for _, importance in ipairs(cfg_tp.check_assessment.importances) do
			local cat_name = importance ..  ' quan trọng về ' .. cat
			check_cat(cat_name, cfg_tp.check_assessment._preload.importance)
		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 usednew
		table.insert(check_task_forces, task_forcesnew)
		usednew = true
	end
	table.sort(check_task_forces, function (x, y) return tonumber(x) 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 ad_cfg = auto_doc_cfg
local class_module = require('Module:Class')
local template_code = mw.title.getCurrentTitle():getContent()
local transclusion_count = require('Module:Transclusion count').fetch{args={}}
if transclusion_count and transclusion_count~= then
	local high_use = frame:expandTemplate{title='Template:High-use'}
	table.insert(auto_doc, high_use)
end
for _, parameter in pairs(parameters) do
	parameter_nameparameter = string.match(
		template_code,
		'%|%s*' .. parameter:gsub('%-','%%%-') .. '%s*=%s*