सूचना: यह पृष्ठ सुरक्षित करने बाद, परिवर्तनों को देखने लिए ब्राउज़र का कैश ख़ाली करने की आवश्यकता हो सकती है।

  • मोज़िला / फ़ायरफ़ॉक्स / सफ़ारी: shift hold करें जब आप reload क्लिक करते है, या Ctrl-Shift-R (अपल मैक में Cmd-Shift-R) दबाएँ;
  • गूगल क्रोम: Ctrl-shift-R (मैक में Cmd-Shift-R) दबाएँ
  • इंटरनेट एक्सप्लोरर: Ctrl hold करें जब आप refresh क्लिक करते हैं, या Ctrl-F5 क्लिक करते हैं;
  • कॉङ्करर: सिर्फ़ Reload बटन पर क्लिक करें, या F5 क्लिक करें;
  • ऑपरा सदस्य को Tools→Preferences में सम्पूर्ण कैश ख़ाली करने की ज़रूरत हो सकती है।
//<nowiki>
/******/ (() => { // webpackBootstrap
/******/ 	"use strict";
var __webpack_exports__ = {};

;// CONCATENATED MODULE: ./src/modules/utils.js
const currentPageName = mw.config.get('wgPageName');
const currentPageNameWithoutUnderscores = currentPageName.replaceAll('_', ' ');
const currentUser = mw.config.get('wgUserName');
const currentNamespace = mw.config.get('wgNamespaceNumber');

//Creates the window that holds the status messages
function createStatusWindow() {
    let Window = new Morebits.simpleWindow(400, 350);
    Window.setTitle('Processing actions');
    let statusdiv = document.createElement('div');
    statusdiv.style.padding = '15px';
    Window.setContent(statusdiv);
    Morebits.status.init(statusdiv);
    Window.display();
}

// Returns a promise with the name of the user who created the page
function getCreator() {
    let params = {
        action: 'query',
        prop: 'revisions',
        titles: currentPageName,
        rvprop: 'user',
        rvdir: 'newer',
        format: 'json',
        rvlimit: 1,
    }
    let apiPromise = new mw.Api().get(params);
    let userPromise = apiPromise.then(function (data) {
        let pages = data.query.pages;
        for (let p in pages) {
            return pages[p].revisions[0].user;
        }
    });

    return userPromise;
}

// Returns a boolean stating whether there's a spot available to create the page (true) or whether it already exists (false)
function isPageMissing(title) {
    let params = {
        action: 'query',
        titles: title,
        prop: 'pageprops',
        format: 'json'
    };
    let apiPromise = new mw.Api().get(params);
    return apiPromise.then(function (data) {
        let result = data.query.pages
        return result.hasOwnProperty("-1")
    });
}


;// CONCATENATED MODULE: ./src/modules/deletionrequestmaker.js


let listOptions = [
    { code: 'B', name: 'जीवनी' },
    { code: 'CAT', name: 'श्रेणियाँ' },
    { code: 'D', name: 'Sports and games' },
    { code: 'F', name: 'कथा और कला' },
    { code: 'I', name: 'अवर्गीकृत' },
    { code: 'L', name: 'स्थान और परिवहन' },
    { code: 'M', name: 'संगीत और मीडिया' },
    { code: 'N', name: 'Consultas sin clasificar todavía' },
    { code: 'O', name: 'संगठन, कंपनियाँ और उत्पाद' },
    { code: 'P', name: 'साँचा और उपयोक्ताबॉक्स' },
    { code: 'S', name: 'समाज' },
    { code: 'T', name: 'विज्ञान और प्रौद्योगिकी' },
    { code: 'W', name: 'वेब और इंटरनेट' }
];

//Returns a boolean that states whether a spot for the creation of the DR page is available
function canCreateDeletionRequestPage() {
    return isPageMissing(`Wikipedia:Deletion_queries/${currentPageName}`)
}

function getCategoryOptions() {
    let categoryOptions = [];
    for (let category of listOptions) {
        let option = { type: 'option', value: category.code, label: category.name };
        categoryOptions.push(option);
    }
    return categoryOptions;
}

//Creates the window for the form that will later be filled with the pertinent info
function createFormWindow() {
    let Window = new Morebits.simpleWindow(620, 530);
    Window.setScriptName('ट्विंकल लाइट');
    Window.setTitle('Delete query');
    Window.addFooterLink('Deletion policy', 'Wikipedia:Deletion policy');
    let form = new Morebits.quickForm(submitMessage);
    form.append({
        type: 'textarea',
        name: 'reason',
        label: 'Describe the reason:',
        tooltip: 'आप अपने विवरण में विकिकोड का उपयोग कर सकते हैं, आपका हस्ताक्षर स्वचालित रूप से जुड़ जाएगा।'
    });
    form.append({
        type: 'submit',
        label: 'Accept'
    });

    let categoryField = form.append({
        type: 'field',
        label: 'Categories:',
    })

    categoryField.append({
        type: 'select',
        name: 'category',
        label: 'Select the page category:',
        list: getCategoryOptions()
    });

    form.append({
        type: 'checkbox',
        list:
            [{
                name: "notify",
                value: "notify",
                label: "Notify the page creator",
                checked: true,
                tooltip: "ट्विंकल लाइट द्वारा रचनाकार के वार्ता पृष्ठ पर उनके लेख के संभावित विलोपन की चेतावनी देते हुए एक स्वचालित संदेश छोड़ने के लिए इस बॉक्स को चेक करें।"
            }],
        style: "padding-left: 1em; padding-bottom:0.5em;"
    })

    let result = form.render();
    Window.setContent(result);
    Window.display();
}

function submitMessage(e) {
    let form = e.target;
    let input = Morebits.quickForm.getInputData(form);
    if (input.reason === ``) {
        alert("No se ha establecido un motivo.");
    } else {
        if (window.confirm(`This will create a delete query for the item ${currentPageNameWithoutUnderscores}, ¿estás seguro?`)) {
            canCreateDeletionRequestPage()
                .then(function (canMakeNewDeletionRequest) {
                    if (!canMakeNewDeletionRequest) {
                        throw new Error('La página no puede crearse. Ya existe una candidatura en curso o esta se cerró en el pasado.')
                    } else {
                        createStatusWindow()
                        new Morebits.status("Paso 1", "colocando plantilla en la página nominada...", "info");
                        return new mw.Api().edit(
                            currentPageName,
                            buildEditOnNominatedPage
                        );
                    }
                })
                .then(function () {
                    new Morebits.status("Paso 2", "creando la página de discusión de la consulta de borrado...", "info");
                    return createDeletionRequestPage(input.category, input.reason);
                })
                .then(function () {
                    if (!input.notify) return;
                    new Morebits.status("Paso 3", "publicando un mensaje en la página de discusión del creador...", "info");
                    return getCreator().then(postsMessage);
                })
                .then(function () {
                    new Morebits.status("Finalizado", "actualizando página...", "status");
                    setTimeout(() => { location.reload() }, 2000);
                })
                .catch(function () {
                    new Morebits.status("Se ha producido un error", "Comprueba las ediciones realizadas", "error")
                    setTimeout(() => { location.reload() }, 4000);
                })
        }

    }
}

// function that builds the text to be inserted in the new DR page.
function buildDeletionTemplate(category, reason) {
    return `{{sust:cdb2|pg={{sust:SUBPAGENAME}}|cat=${category}|texto=${reason}|{{sust:CURRENTDAY}}|{{sust:CURRENTMONTHNAME}}}} ~~~~`
}

//function that fetches the two functions above and actually adds the text to the article to be submitted to DR.
function buildEditOnNominatedPage(revision) {
    return {
        text: '{{sust:cdb}}\n' + revision.content,
        summary: `Nominated for deletion, see [[Wikipedia:Deletion queries/${currentPageName}]] mediante [[WP:Twinkle Lite|Twinkle Lite]].`,
        minor: false
    };
}

//function that creates the page hosting the deletion request
function createDeletionRequestPage(category, reason) {
    return new mw.Api().create(`Wikipedia:Deletion queries/${currentPageName}`,
        { summary: `Creating discussion page for the deletion of[[${currentPageNameWithoutUnderscores}]] mediante [[WP:Twinkle Lite|Twinkle Lite]]` },
        buildDeletionTemplate(category, reason)
    );
}

// Leaves a message on the creator's talk page
function postsMessage(creator) {
    return isPageMissing(`Usuario_discusión:${creator}`)
        .then(function (mustCreateNewTalkPage) {
            if (mustCreateNewTalkPage) {
                return new mw.Api().create(
                    `Usuario_discusión:${creator}`,
                    { summary: 'Notice to the user of the opening of a CBD through [[WP:Twinkle Lite|Twinkle Lite]]' },
                    `{{sust:Aviso cdb|${currentPageNameWithoutUnderscores}}} ~~~~`
                );
            } else {
                return new mw.Api().edit(
                    `Usuario_discusión:${creator}`,
                    function (revision) {
                        return {
                            text: revision.content + `\n{{sust:Aviso cdb|${currentPageNameWithoutUnderscores}}} ~~~~`,
                            summary: 'Notice to the user of the opening of a CBD through[[WP:Twinkle Lite|Twinkle Lite]]',
                            minor: false
                        }
                    }
                )
            }
        })
}


;// CONCATENATED MODULE: ./src/modules/pageprotection.js


let listProtectionOptions = [
	{ code: "protection", name: "Request protection", default: true },
	{ code: "deprotection", name: "Request checkout" }
]

function getProtectionTypeOptions() {
	let dropDownOptions = [];
	for (let chosenType of listProtectionOptions) {
		let option = { type: 'option', value: chosenType.code, label: chosenType.name, checked: chosenType.default };
		dropDownOptions.push(option);
	}
	return dropDownOptions;
}

let listMotiveOptions = [
	{ name: "बर्बरता" },
	{ name: "स्पैमिंग" },
	{ name: "ग़लत या काल्पनिक जानकारी" },
	{ name: "संस्करण युद्ध" },
	{ name: "अन्य" }
]

function getMotiveOptions() {
	let dropDownOptions = [];
	for (let motive of listMotiveOptions) {
		let option = { type: 'option', value: motive.name, label: motive.name, checked: motive.default };
		dropDownOptions.push(option);
	}
	return dropDownOptions
}

function protectionFromGetReply(data) {
	let pages = data.query.pages;
	for (let p in pages) {
		let protectionLevel = pages[p].protection[0]?.level
		switch (protectionLevel) {
			case 'प्रबन्धक':
				return 'solo bibliotecarios';
			case 'स्वतः_स्थापित_सदस्य':
				return 'solo usuarios autoconfirmados';
			case 'साँचा संपादक':
				return 'solo editores de plantillas'
			default:
				return 'without protection';
		}
	}
}

// Returns the protection status of the page as a string through a query to the mw API
function getProtectionStatus() {
	let params = {
		action: 'query',
		prop: 'info',
		inprop: 'protection',
		titles: currentPageName,
		format: 'json',
	}
	let apiPromise = new mw.Api().get(params);
	let protectionPromise = apiPromise.then(protectionFromGetReply);

	return protectionPromise;
}

function pageprotection_createFormWindow() {
	let Window = new Morebits.simpleWindow(620, 530);
	Window.setScriptName('ट्विंकल लाइट');
	Window.setTitle('Request page protection');
	Window.addFooterLink('Protection policy', 'Wikipedia:Protection policy');
	let form = new Morebits.quickForm(pageprotection_submitMessage);

	let radioField = form.append({
		type: 'field',
		label: 'Tipo:',
	});

	radioField.append({
		type: 'radio',
		name: 'protection',
		id: 'protect',
		event:
			function (e) {
				let nameToModify = document.querySelector("select[name='motive']")
				if (e.target.value !== "protección") {
					nameToModify.setAttribute('disabled', "")
				} else {
					nameToModify.removeAttribute('disabled', "")
				}
			},
		list: getProtectionTypeOptions()
	})

	form.append({
		type: 'div',
		name: 'currentProtection',
		label: `Nivel actual de protección: `
	})

	let textAreaAndReasonField = form.append({
		type: 'field',
		label: 'Opciones:',
	});

	textAreaAndReasonField.append({
		type: 'select',
		name: 'motive',
		label: 'Select the reason:',
		list: getMotiveOptions(),
		disabled: false
	});

	textAreaAndReasonField.append({
		type: 'textarea',
		name: 'reason',
		label: 'Develop reason:',
		tooltip: 'आप अपने विवरण में विकिकोड का उपयोग कर सकते हैं, आपका हस्ताक्षर स्वचालित रूप से जुड़ जाएगा।'
	});
	form.append({
		type: 'submit',
		label: 'Accept'
	});

	let result = form.render();
	Window.setContent(result);
	Window.display();

	getProtectionStatus().then(function (protectionLevel) {
		// Displays protection level on page
		let showProtection = document.querySelector("div[name='currentProtection'] > span.quickformDescription");
		showProtection.innerHTML = `Nivel actual de protección:<span style="color:royalblue; font-weight: bold;"> ${protectionLevel} <span>`
		// Disables "unprotect" option if not applicable
		if (protectionLevel == 'without protection') {
			let unprotectDiv = document.getElementById('protect').childNodes[1]
			unprotectDiv.firstChild.setAttribute('disabled', '');
		}

	})
}

function pageprotection_submitMessage(e) {
	let form = e.target;
	let input = Morebits.quickForm.getInputData(form);
	if (input.reason === ``) {
		alert("No se ha establecido un motivo.");
	} else {
		if (window.confirm(`¿Do you want to request the ${input.protection} of the article ${currentPageNameWithoutUnderscores}?`)) {
			createStatusWindow();
			new Morebits.status("Paso 1", `solicitando la ${input.protection} de la página...`, "info");
			new mw.Api().edit(
				"Wikipedia:Tablón_de_anuncios_de_los_bibliotecarios/Portal/Archivo/Protección_de_artículos/Actual",
				buildEditOnNoticeboard(input)
			)
				.then(function () {
					new Morebits.status("Finalizado", "actualizando página...", "status");
					setTimeout(() => { location.reload() }, 1500);
				})
				.catch(function () {
					new Morebits.status("Se ha producido un error", "Comprueba las ediciones realizadas", "error")
					setTimeout(() => { location.reload() }, 4000);
				})
		}

	}
}

function buildEditOnNoticeboard(input) {
	let title = `== Solicitud de ${input.protection} de [[${currentPageNameWithoutUnderscores}]] ==`;
	if (input.protection === 'protección') {
		if (input.motive !== 'Otro') {
			title = `== Solicitud de ${input.protection} de [[${currentPageNameWithoutUnderscores}]] por ${input.motive.toLowerCase()} ==`;
		}
	};
	return (revision) => {
		return {
			text: revision.content + `\n
${title} 
;Artículo(s) 
* {{a|${currentPageNameWithoutUnderscores}}}
;Causa 
${input.reason}
; Usuario que lo solicita
* ~~~~ 
;Respuesta
(a rellenar por un bibliotecario)`,
			summary: `Solicitando ${input.protection} de [[${currentPageNameWithoutUnderscores}]] mediante [[WP:Twinkle Lite|Twinkle Lite]]`,
			minor: false
		}
	}
}



;// CONCATENATED MODULE: ./src/modules/speedydeletion.js


let criteriaLists = {
    general: [
        { code: "g1", name: "G1. बर्बरता" },
        { code: "g2", name: "G2. Label faults" },
        { code: "g3", name: "G3. प्रचारात्मक पृष्ठ" },
        { code: "g4", name: "G4. परीक्षण पृष्ठ" },
        { code: "g5", name: "G5. धोखा, धोखाधड़ी" },
        { code: "g6", name: "G6. कॉपीराइट उल्लंघन" },
        { code: "g7", name: "G7. Orphan talk pages" },
        { code: "g8", name: "G8. Deleting a page to make room" },
        { code: "g9", name: "G9. हटाई गई सामग्री का पुनः निर्माण" },
        { code: "g10", name: "G10. मूलभूत रखरखाव के लिए" },
        { code: "g11", name: "G11.  सदस्य अनुरोध " }
    ], articles: [
        {
            code: "a1", name: "A1. Violates “what Wikipedia is not”", subgroup: {
                type: 'checkbox',
                name: 'subA',
                list: [
                    { value: "a1.1", label: "A1.1 Articles that only include links" },
                    { value: "a1.2", label: "A1.2 Dictionary definitions or recipes" },
                    { value: "a1.3", label: "A1.3 Primary source" },
                    { value: "a1.4", label: "A1.4 opinion essays" }
                ]
            },
        },
        { code: "a2", name: "A2. Infraesbozo" },
        { code: "a3", name: "A3. Pages without translation or automatic translations" },
        { code: "a4", name: "A4. Non-encyclopedic or irrelevant content" },
        {
            code: "a5", name: "A5. Duplicate article", subgroup: {
                type: "input",
                name: "originalArticleName",
                label: "Original article name: ",
                tooltip: "विकिकोड का उपयोग किए बिना लेख का नाम टाइप करें। उदाहरण के लिए: «ग्रेनाडा (फ्रूटा)», «एन्सलाडा» या «प्लांटिला:एटाजोस»",
                required: true
            }
        }
    ], redirects: [
        { code: "r1", name: "R1. Redirects to non-existent pages" },
        { code: "r2", name: "R2. Redirects from one namespace to another" },
        { code: "r3", name: "R3. Unnecessary automatic redirects" },
        { code: "r4", name: "R4. Incorrect or unnecessary redirects" },
    ], categories: [
        { code: "c1", name: "C1. Empty categories" },
        { code: "c2", name: "C2. Moved or renamed categories" },
        { code: "c3", name: "C3. Categories that violate the categories policy" }
    ], userpages: [
        { code: "u1", name: "U1. सदस्य के स्वयं के अनुरोध पर" },
        { code: "u2", name: "U2. अस्तित्वहीन सदस्यों के सदस्य पृष्ठ अथवा उपपृष्ठ" },
        { code: "u3", name: "U3. सदस्य पृष्ठ नीति का उल्लंघन" }
    ], templates: [
        { code: "p1", name: "P1. Navigation Template Policy Violation" },
        { code: "p2", name: "P2. Orphan Documentation Subpage" },
        { code: "p3", name: "P3. Single use templates" }
    ], other: [
        {
            code: "other", name: "Otra razón", subgroup: {
                type: "input",
                name: "otherreason",
                label: "Establece la razón: ",
                tooltip: "आप अपने उत्तर में विकिकोड का उपयोग कर सकते हैं",
                required: true
            }
        }
    ]
}

function getOptions(criteriaType) {
    let options = [];
    for (let chosenType of criteriaLists[criteriaType]) {
        let option = { value: chosenType.code, label: chosenType.name, checked: chosenType.default, subgroup: chosenType.subgroup };
        options.push(option);
    }
    return options;
}

function speedydeletion_createFormWindow() {
    let Window = new Morebits.simpleWindow(620, 530);
    Window.setScriptName('ट्विंकल लाइट');
    Window.setTitle('Request quick delete');
    Window.addFooterLink('Criterios para el borrado rápido', 'Wikipedia:Criterios para el borrado rápido');
    let form = new Morebits.quickForm(speedydeletion_submitMessage);

    form.append({
        type: 'checkbox',
        list:
            [{
                name: "notify",
                value: "notify",
                label: "Notificar al creador de la página",
                checked: true,
                tooltip: "ट्विंकल लाइट द्वारा रचनाकार के वार्ता पृष्ठ पर उनके लेख के संभावित विलोपन की चेतावनी देते हुए एक स्वचालित संदेश छोड़ने के लिए इस बॉक्स को चेक करें।"
            }],
        style: "padding-left: 1em; padding-top:0.5em;"
    })

    let gField = form.append({
        type: 'field',
        label: 'Criterios generales:',
    });
    gField.append({
        type: 'checkbox',
        name: 'general',
        list: getOptions("general")
    })

    if (currentNamespace == 0 && !mw.config.get('wgIsRedirect')) {
        let aField = form.append({
            type: 'field',
            label: 'Article Criteria:',
        })

        aField.append({
            type: 'checkbox',
            name: 'article',
            list: getOptions("articles")
        })
    }

    if (mw.config.get('wgIsRedirect')) {
        let rField = form.append({
            type: 'field',
            label: 'Criteria for redirect pages:',
        })
        rField.append({
            type: 'checkbox',
            name: 'redirect',
            list: getOptions("redirects")
        })
    }

    if (currentNamespace == 14) {
        let cField = form.append({
            type: 'field',
            label: 'Criteria for categories:',
        })
        cField.append({
            type: 'checkbox',
            name: 'categories',
            list: getOptions("categories")
        })
    }

    if (currentNamespace == 2) {
        let uField = form.append({
            type: 'field',
            label: 'Criteria for user pages:',
        })
        uField.append({
            type: 'checkbox',
            name: 'userpages',
            list: getOptions("userpages")
        })
    }

    if (currentNamespace == 10) {
        let tField = form.append({
            type: 'field',
            label: 'Template Criteria:',
        })
        tField.append({
            type: 'checkbox',
            name: 'templates',
            list: getOptions("templates")
        })
    }

    form.append({
        type: 'checkbox',
        name: 'other',
        list: getOptions("other"),
        style: "padding-left: 1em; padding-bottom: 0.5em"
    })

    form.append({
        type: 'submit',
        label: 'Accept'
    });

    let result = form.render();
    Window.setContent(result);
    Window.display();
}

function speedydeletion_submitMessage(e) {
    let form = e.target;
    let input = Morebits.quickForm.getInputData(form);
    if (window.confirm(`¿You want to request the deletion of the article ${currentPageNameWithoutUnderscores}?`)) {
        createStatusWindow();
        new Morebits.status("Paso 1", `generando plantilla de borrado...`, "info");
        new mw.Api().edit(
            currentPageName,
            speedyTemplateBuilder(input)
        )
            .then(function () {
                return getCreator().then(speedydeletion_postsMessage(input));
            })
            .then(function () {
                new Morebits.status("Finalizado", "actualizando página...", "status");
                setTimeout(() => { location.reload() }, 2000);
            })
            .catch(function () {
                new Morebits.status("Se ha producido un error", "Comprueba las ediciones realizadas", "error")
                setTimeout(() => { location.reload() }, 4000);
            })
    }
}

function speedyTemplateBuilder(data) {
    return (revision) => {
        return {
            text: `{{destruir|${allCriteria(data)}}} \n` + revision.content,
            summary: `Adding deletion template using [[WP:Twinkle Lite|Twinkle Lite]]${data?.originalArticleName ? `. Higher quality existing item: [[${data.originalArticleName}]]` : ''}`,
            minor: false
        }
    }
}

function allCriteria(data) {
    let fields = [];
    for (let criteriaType in data) {
        if (criteriaType !== "other" && Array.isArray(data[criteriaType])) {
            fields.push(...data[criteriaType]);
        }
    }

    let reasonString = data?.otherreason ?? '';
    if (reasonString != '') {
        fields.push(reasonString);
    }
    return fields.join('|');
}

function speedydeletion_postsMessage(input) {
    if (!input.notify) return;
    return (creator) => {
        if (creator == currentUser) {
            return;
        } else {
            new Morebits.status("Paso 2", "publicando un mensaje en la página de discusión del creador...", "info");
            return isPageMissing(`Usuario_discusión:${creator}`)
                .then(function (mustCreateNewTalkPage) {
                    if (mustCreateNewTalkPage) {
                        return new mw.Api().create(
                            `Usuario_discusión:${creator}`,
                            { summary: `Aviso al usuario del posible borrado de [[${currentPageNameWithoutUnderscores}]] mediante [[WP:Twinkle Lite|Twinkle Lite]]` },
                            `{{subst:Aviso destruir|${currentPageNameWithoutUnderscores}|${allCriteria(input)}}} ~~~~`
                        );
                    } else {
                        return new mw.Api().edit(
                            `Usuario_discusión:${creator}`,
                            function (revision) {
                                return {
                                    text: revision.content + `\n{{subst:Aviso destruir|${currentPageNameWithoutUnderscores}|${allCriteria(input)}}} ~~~~`,
                                    summary: `Aviso al usuario del posible borrado de [[${currentPageNameWithoutUnderscores}]] mediante [[WP:Twinkle Lite|Twinkle Lite]]`,
                                    minor: false
                                }
                            }
                        )
                    }
                })
        }
    }
}


;// CONCATENATED MODULE: ./src/modules/reports.js


let reportedUser = mw.config.get("wgRelevantUserName")

let reports_listMotiveOptions = [
    { value: "Account created to vandalize" },
    { value: "Lockout Evasion" },
    { value: "Edition war" },
    { value: "inappropriate name" },
    { value: "Etiquette violation" },
    { value: "Vandalism in progress" },
    { value: "Persistent vandalism" },
    { value: "Other" },
]

let motiveOptionsDict = {
    "Cuenta creada para vandalizar":
    {
        "link": "Wikipedia:Tablón_de_anuncios_de_los_bibliotecarios/Portal/Archivo/Nombres_inapropiados_y_vandalismo_persistente/Actual",
        "usersSubtitle": 'Lista de usuarios'
    },
    "Evasión de bloqueo":
    {
        "link": "Wikipedia:Tablón_de_anuncios_de_los_bibliotecarios/Portal/Archivo/Nombres_inapropiados_y_vandalismo_persistente/Actual",
        "usersSubtitle": 'Lista de usuarios'
    },
    "Guerra de ediciones":
    {
        "link": "Wikipedia:Tablón_de_anuncios_de_los_bibliotecarios/Portal/Archivo/3RR/Actual",
        "usersSubtitle": 'Usuarios implicados'
    },
    "Nombre inapropiado":
    {
        "link": "Wikipedia:Tablón_de_anuncios_de_los_bibliotecarios/Portal/Archivo/Nombres_inapropiados_y_vandalismo_persistente/Actual",
        "usersSubtitle": 'Lista de usuarios'
    },
    "Violación de etiqueta":
    {
        "link": "Wikipedia:Tablón_de_anuncios_de_los_bibliotecarios/Portal/Archivo/Violaciones_de_etiqueta/Actual",
        "usersSubtitle": 'Usuarios implicados'
    },
    "Vandalismo en curso":
        { "link": "Wikipedia:Vandalismo_en_curso" },
    "Vandalismo persistente":
    {
        "link": "Wikipedia:Tablón_de_anuncios_de_los_bibliotecarios/Portal/Archivo/Nombres_inapropiados_y_vandalismo_persistente/Actual",
        "usersSubtitle": 'Lista de usuarios'
    },
    "Otro":
    {
        "link": "Wikipedia:Tablón_de_anuncios_de_los_bibliotecarios/Portal/Archivo/Miscelánea/Actual",
        "usersSubtitle": 'Usuarios implicados'
    }
}

function reports_getMotiveOptions() {
    let dropDownOptions = [];
    for (let motive of reports_listMotiveOptions) {
        let option = { value: motive.value, label: motive.value, subgroup: motive.subgroup };
        dropDownOptions.push(option);
    }
    return dropDownOptions;
}

function reports_createFormWindow() {
    let Window = new Morebits.simpleWindow(620, 530);
    Window.setScriptName('ट्विंकल लाइट');
    Window.setTitle('Report user');
    Window.addFooterLink('Tablón de anuncios de los bibliotecarios', 'Wikipedia:Tablón de anuncios de los bibliotecarios');
    let form = new Morebits.quickForm(reports_submitMessage);

    let reportTypeField = form.append({
        type: 'field',
        label: 'Opciones:',
    })
    reportTypeField.append({
        type: 'select',
        label: 'Selecciona el motivo:',
        name: 'motive',
        list: reports_getMotiveOptions(),
        event:
            function (e) {
                let selectedOption = e.target.value
                document.querySelector("label[for='reasontextareanode']").innerText = 'Desarrolla la razón:'
                document.getElementById('articlefieldnode').setAttribute('style', 'display:none');
                document.getElementById('otherreasonnode').setAttribute('style', 'display:none');
                switch (selectedOption) {
                    case 'Guerra de ediciones':
                        document.getElementById('articlefieldnode').removeAttribute('style')
                        break;
                    case 'Violación de etiqueta':
                        document.querySelector("label[for='reasontextareanode']").innerText = 'Ediciones que constituyen una violación de etiqueta:'
                        break;
                    case 'Otro':
                        document.getElementById('otherreasonnode').removeAttribute('style')
                        break;
                }
            }
    })

    form.append({
        type: 'checkbox',
        list: [{
            name: "notify",
            value: "notify",
            label: "Notificar al usuario denunciado",
            checked: false,
            tooltip: "ट्विंकल लाइट द्वारा रिपोर्ट किए गए उपयोगकर्ता के वार्ता पृष्ठ पर उन्हें रिपोर्ट के बारे में सूचित करने के लिए एक स्वचालित संदेश छोड़ने के लिए इस बॉक्स को चेक करें"
        }],
        style: "padding-left: 1em;"
    })

    let reportInfoField = form.append({
        type: 'field',
        label: 'Información:'
    })
    reportInfoField.append({
        type: 'dyninput',
        label: 'Usuarios denunciados:',
        sublabel: 'Usuario:',
        name: 'usernamefield',
        value: "",
        tooltip: 'Escribe el nombre del usuario denunciado sin ningún tipo de wikicódigo'
    })
    reportInfoField.append({
        type: 'dyninput',
        label: 'Artículos involucrados:',
        sublabel: 'Artículo:',
        name: 'articlefieldbox',
        style: "display: none;",
        id: 'articlefieldnode',
        tooltip: 'Escribe el nombre del artículo sin ningún tipo de wikicódigo'
    })
    reportInfoField.append({
        type: "input",
        name: "otherreason",
        id: "otherreasonnode",
        style: "display: none;",
        placeholder: "Título de la denuncia",
    })

    reportInfoField.append({
        type: 'textarea',
        label: 'Desarrolla la razón:',
        name: 'reason',
        tooltip: 'Incluye diffs si es necesario. Puedes usar wikicódigo. La firma se añadirá de forma automática.',
        id: 'reasontextareanode'
    })

    form.append({
        type: 'submit',
        label: 'Aceptar'
    });

    let result = form.render();
    Window.setContent(result);
    Window.display();

    // Changes names of add/remove user buttons to Spanish
    function changeButtonNames() {
        let moreBox = document.querySelector('input[value="more"]')
        moreBox.value = "añadir"
        moreBox.style.marginTop = '0.3em' // To separate it slightly from the rest of the elements
        moreBox.addEventListener("click", () => {
            let removeBox = document.querySelector('input[value="remove"]')
            removeBox.value = "eliminar"
            removeBox.style.marginLeft = '0.3em' // Idem as four code lines above
        })
    }
    // Automatically adds the name of the reported user to the form
    document.querySelector('input[name="usernamefield"]').value = reportedUser
    changeButtonNames()
}

function reports_submitMessage(e) {
    let form = e.target;
    let input = Morebits.quickForm.getInputData(form);
    if (input.reason === `` && input.motive != 'NI') {
        alert("No se ha establecido un motivo.");
    } else if (input.motive == 'Otro' && input.otherreason == '') {
        alert("No se ha establecido un título para la denuncia");
    } else if (input.usernamefield == '') {
        alert("No se ha establecido un usuario");
    } else {
        createStatusWindow()
        new Morebits.status("Paso 1", `obteniendo datos del formulario...`, "info");
        let usernames = Array.from(document.querySelectorAll('input[name=usernamefield]')).map((o) => o.value)
        let articles = Array.from(document.querySelectorAll('input[name=articlefieldbox]')).map((o) => o.value)
        new Morebits.status("Paso 2", `creando denuncia en el tablón...`, "info");
        new mw.Api().edit(
            motiveOptionsDict[input.motive].link,
            reports_buildEditOnNoticeboard(input, usernames, articles)
        )
            .then(function () {
                return reports_postsMessage(input)
            })
            .then(function () {
                new Morebits.status("Finalizado", "actualizando página...", "status");
                setTimeout(() => { location.reload() }, 1500);
            })
            .catch(function () {
                new Morebits.status("Se ha producido un error", "Comprueba las ediciones realizadas", "error")
                setTimeout(() => { location.reload() }, 4000);
            })

    }
}

function listWords(array, templateLetter) {
    let bulletedWords = ''
    for (let word of array) {
        bulletedWords += `* {{${templateLetter}|${word}}} \n`
    }
    return bulletedWords
}

function VECReportBuilder(usernames, input) {
    let finalText = ''
    for (let user of usernames) {
        let templateWord = mw.util.isIPAddress(user, true) ? 'VándaloIP' : 'Vándalo';
        finalText += `=== ${user} ===` + '\n' + '\n' +
            `* Posible vándalo: {{${templateWord}|${user}}}` + '\n' +
            `* Motivo del reporte: ${input.reason}` + '\n' +
            '* Usuario que reporta: ~~~~' + '\n' +
            '* Acción administrativa: (a rellenar por un bibliotecario)' + '\n'
    }
    return finalText
}

function reports_buildEditOnNoticeboard(input, usernames, articles) {
    if (input.motive == "Vandalismo en curso") {
        return (revision) => {
            return {
                text: revision.content + '\n' + '\n' + VECReportBuilder(usernames, input),
                summary: `Creando denuncia de usuario mediante [[WP:Twinkle Lite|Twinkle Lite]]`,
                minor: false
            }
        }
    } else {
        let title = input.motive == "Otro" ? input.otherreason : input.motive;
        let bulletedUserList = listWords(usernames, 'u')
        let bulletedArticleList = listWords(articles, 'a')
        let reasonTitle = input.motive == "Guerra de ediciones" ? `; Comentario` : `; Motivo`;
        let articleListIfEditWar = input.motive == "Guerra de ediciones" ? `\n; Artículos en los que se lleva a cabo \n${bulletedArticleList} \n` : '\n';
        return (revision) => {
            return {
                text: revision.content + '\n' + '\n' +
                    `== ${title} ==` + '\n' +
                    `; ${motiveOptionsDict[input.motive].usersSubtitle}` + '\n' +
                    `${bulletedUserList}` +
                    articleListIfEditWar +
                    reasonTitle + '\n' +
                    `${input.reason}` + '\n' +
                    '; Usuario que lo solicita' + '\n' +
                    '* ~~~~' + '\n' +
                    '; Respuesta' + '\n' +
                    '(a rellenar por un bibliotecario)',
                summary: `Creando denuncia de usuario mediante [[WP:Twinkle Lite|Twinkle Lite]]`,
                minor: false
            }
        }
    }
}

function reports_postsMessage(input) {
    if (!input.notify) return;
    new Morebits.status("Paso 3", `avisando al usuario reportado...`, "info");
    return isPageMissing(`Usuario_discusión:${input.usernamefield}`)
        .then(function (mustCreateNewTalkPage) {
            let title = input.motive == "Otro" ? input.otherreason : input.motive;
            if (mustCreateNewTalkPage) {
                return new mw.Api().create(
                    `Usuario_discusión:${input.usernamefield}`,
                    { summary: `Aviso al usuario de su denuncia por [[${motiveOptionsDict[input.motive].link}|${title.toLowerCase()}]] mediante [[WP:Twinkle Lite|Twinkle Lite]]` },
                    `\n== ${title} ==\n` +
                    `Hola. Te informo de que he creado una denuncia —por la razón mencionada en el título— que te concierne. Puedes consultarla en el tablón correspondiente a través de '''[[${motiveOptionsDict[input.motive].link}#${title}|este enlace]]'''. Un [[WP:B|bibliotecario]] se encargará de analizar el caso y emitirá una resolución al respecto próximamente. Un saludo. ~~~~`
                );
            } else {
                return new mw.Api().edit(
                    `Usuario_discusión:${input.usernamefield}`,
                    function (revision) {
                        return {
                            text: revision.content + `\n== ${title} ==\n` + `Hola. Te informo de que he creado una denuncia —por la razón mencionada en el título— que te concierne. Puedes consultarla en el tablón correspondiente a través de '''[[${motiveOptionsDict[input.motive].link}#${title}|este enlace]]'''. Un [[WP:B|bibliotecario]] se encargará de analizar el caso y emitirá una resolución al respecto próximamente. Un saludo. ~~~~`,
                            summary: `Aviso al usuario de su denuncia por [[${motiveOptionsDict[input.motive].link}|${title.toLowerCase()}]] mediante [[WP:Twinkle Lite|Twinkle Lite]]`,
                            minor: false
                        }
                    }
                )
            }
        })
}


;// CONCATENATED MODULE: ./src/modules/tags.js
// ** Tags module **
// Allows users to add a tag in articles. The tag can be selected as part of a series of options of a checkbox list



// Dictionary that stores the templates, the description, as well as the parameter and the name of the warning template if any of them is applicable
// Template parameters are set in the subgroup, specifically in the 'name' key, their syntax is as follows:
// `_param-parent template name-parameter identifier`
// If the parameter doesn't have an identifier, then just type a «1»

const templateDict = {
	"autotrad": {
		warning: "aviso autotrad",
		description: "use of automation in translations of zero quality"
	},
	"categorize": {
		warning: "aviso categorizar",
		description: "Uncategorized articles"
	},
	"CDI": {
		warning: "aviso conflicto de interés",
		description: "written under conflict of interest"
	},
	"categorizar": {
		warning: "aviso categorizar",
		description: "articles that do not have categories"
	},
	"contextualizar": {
		warning: "aviso contextualizar",
		description: "the topic or scope is not clearly worded. 30 day template."
	},
	"complejo": {
		description: "difficult to understand texts"
	},
	"copyedit": {
		warning: "aviso copyedit",
		description: "needs a spelling and grammar check"
	},
	"curiosities": {
		description: "texts with curiosities section"
	},
	"outdated": {
		description: "page with outdated information"
	},
	"Developing": {
		description: "pages under construction or actively being edited",
		subgroup: [
			{
				type: 'input',
				name: '_param-en desarrollo-1',
				label: 'Publisher name',
				tooltip: 'Enter the name of the user who is developing the article, do not use any type of Wikicode'
			}
		]
	},
	"evento actual": {
		description: "current articles whose information is susceptible to change"
	},
	"excesivamente detallado": {
		description: "too much information on trivial topics"
	},
	"experto": {
		description: "very technical articles with content deficiencies that can only be corrected by an expert"
	},
	"ficticio": {
		description: "no focus from a real point of view"
	},
	"formato de referencias": {
		warning: "aviso formato de referencias",
		description: "incorrect or poorly constructed references"
	},
	"fuente primaria": {
		warning: "aviso fuente primaria",
		description: "unverifiable information. 30 day template."
	},
	"fuentes no fiables": {
		description: "references that do not follow the reliable sources policy"
	},
	"fusionar": {
		description: "suggest a merger",
		subgroup: [
			{
				type: 'input',
				name: '_param-fusionar-1',
				label: 'Objective article',
				tooltip: 'Enter the name of the item you want to merge this page with. Do not use Wikicode.'
			}
		]
	},
	"globalizar": {
		warning: "aviso globalizar",
		description: "existe sesgo territorial",
		subgroup: [
			{
				type: 'input',
				name: '_param-globalizar-1',
				label: 'Cultura o territorio del sesgo'
			}
		]
	},
	"infraesbozo": {
		warning: "aviso infraesbozo",
		description: "contenido insuficiente como para constituir un esbozo de artículo o anexo válido. Plantilla de 30 días",
	},
	"largo": {
		description: "artículos excesivamente largos que deberían subdividirse en varios"
	},
	"mal traducido": {
		warning: "aviso mal traducido",
		description: "escasa calidad de una traducción de otro idioma"
	},
	"mejorar redacción": {
		description: "redacciones que no siguen el manual de estilo"
	},
	"no neutralidad": {
		warning: "aviso no neutralidad",
		description: "artículos sesgados o claramente decantados en una dirección",
		subgroup: [
			{
				type: 'input',
				name: `_param-no neutralidad-motivo`,
				label: 'Razón del sesgo',
				tooltip: 'Describe brevemente la razón del sesgo. Es importante, también, desarrollarla más exhaustivamente en la PD',
				required: true
			}
		]
	},
	"plagio": {
		warning: "aviso destruir|2=plagio",
		description: "artículos copiados, que violan derechos de autor",
		subgroup: [
			{
				type: 'input',
				name: '_param-plagio-1',
				label: 'URL origen del plagio',
				tooltip: 'Copia y pega aquí la URL de la página externa en la que se halla el texto original',
				required: true
			}
		]
	},
	"polémico": {
		description: "temas susceptibles a guerras de edición o vandalismo"
	},
	// "pr": {
	// 	description: "para atribuir el artículo a un wikiproyecto",
	// 	subgroup: [
	// 		{
	// 			type: 'input',
	// 			name: '_param-pr-1',
	// 			label: 'Nombre del wikiproyecto',
	// 			tooltip: 'Escribe aquí el nombre del Wikiproyecto (esta plantilla se coloca en la PD automáticamente)',
	//			required: true
	// 		}
	// 	]
	// },
	"promocional": {
		warning: "aviso promocional",
		description: "texto con marcado carácter publicitario, no neutral. Plantilla de 30 días"
	},
	"publicidad": {
		description: "contenido comercial que defiende proselitismos o propaganda"
	},
	"pvfan": {
		warning: "aviso no neutralidad|2=PVfan",
		description: "escritos poco neutrales, con punto de vista fanático"
	},
	"referencias": {
		warning: "aviso referencias",
		description: "artículos sin una sola referencia"
	},
	"referencias adicionales": {
		warning: "aviso referencias",
		description: "artículos con falta de referencias"
	},
	"renombrar": {
		description: "Para proponer un renombrado de una página",
		subgroup: [
			{
				type: 'input',
				name: '_param-renombrar-1',
				label: 'Nuevo nombre sugerido',
				required: true
			}
		]
	},
	"revisar traducción": {
		description: "texto traducido legible pero necesita un repaso lingüístico"
	},
	"sin relevancia": {
		warning: "aviso sin relevancia",
		description: "artículos que no superan umbral de relevancia. Plantilla de 30 días"
	},
	"traducción incompleta": {
		warning: "aviso traducción incompleta",
		description: "artículos que han sido traducidos solo parcialmente"
	},
	"wikificar": {
		warning: "aviso wikificar",
		description: "textos con mal formato o que no cumplen el manual de estilo"
	}
}

// Builds the link to be displayed in each checkbox description
function linkBuilder(link) {
	let fullLink = `https://es.wikipedia.org/wiki/Plantilla:${link}`
	return `<a href="${fullLink}" target="_blank">(+)</a>`
}

// Builds the list to be passed as parameter to the Morebits function that creates the box holding all the options
// The data is gathered from the dictionary
function listBuilder(list) {
	let finalList = [];
	for (let item in list) {
		let template = {};
		template.name = item
		template.value = item
		template.label = `{{${item}}} · ${list[item].description} ${linkBuilder(item)}`
		template.subgroup = list[item]?.subgroup ? list[item].subgroup : '';
		finalList.push(template)
	}
	return finalList;
}

// Creates the Morebits window holding the form
function tags_createFormWindow() {
	let Window = new Morebits.simpleWindow(620, 530);
	Window.setScriptName('ट्विंकल लाइट');
	Window.setTitle('Add template');
	Window.addFooterLink('Portal de mantenimiento', 'Portal:Mantenimiento');
	let form = new Morebits.quickForm(tags_submitMessage);

	form.append({
		type: 'input',
		value: '',
		name: 'search',
		label: 'Búsqueda:',
		id: 'search',
		size: '30',
		event: function quickFilter() {
			const searchInput = document.getElementById("search");
			const allCheckboxDivs = document.querySelectorAll("#checkboxContainer > div");
			if (this.value) {
				// Flushes the list before calling the search query function, then does it as a callback so that it happens in the right order
				function flushList(callback) {
					for (let i = 0; i < allCheckboxDivs.length; i++) {
						const div = allCheckboxDivs[i];
						div.style.display = 'none';
					}
					callback();
				}
				// Finds matches for the search query within the checkbox list
				function updateList(searchString) {
					for (let i = 0; i < allCheckboxDivs.length; i++) {
						let checkboxText = allCheckboxDivs[i].childNodes[1].innerText
						if (checkboxText.includes(searchString.toLowerCase()) || checkboxText.includes(searchString.toUpperCase())) {
							const div = allCheckboxDivs[i];
							div.style.display = '';
						}
					}
				}
				flushList(() => updateList(searchInput.value));
			}
			// Retrieves the full list if nothing is on the search input box
			if (this.value.length == 0) {
				for (let i = 0; i < allCheckboxDivs.length; i++) {
					const div = allCheckboxDivs[i];
					div.style.display = '';
				}
			}
		}
	})

	let optionBox = form.append({
		type: 'div',
		id: 'tagWorkArea',
		className: 'morebits-scrollbox',
		style: 'max-height: 28em; min-height: 0.5em;'
	})

	optionBox.append({
		type: 'checkbox',
		id: 'checkboxContainer',
		list: listBuilder(templateDict),
		label: 'checkOption'
	})

	let optionsField = form.append({
		type: 'field',
		label: 'Opciones:'
	})

	optionsField.append({
		type: 'checkbox',
		list:
			[{
				name: "notify",
				value: "notify",
				label: "Notificar al creador de la página si es posible",
				checked: false,
				tooltip: "Marca esta casilla para que Twinkle Lite deje un mensaje automático en la página de discusión del creador del artículo advertiéndole de la colocación de la plantilla"
			}],
	})

	optionsField.append({
		type: 'input',
		name: 'reason',
		label: 'Razón:',
		tooltip: '(Opcional) Escribe aquí el resumen de edición explicando la razón por la que se ha añadido la plantilla',
		style: 'width: 80%; margin-top: 0.5em;'
	})

	form.append({
		type: 'submit',
		label: 'Aceptar'
	});

	let result = form.render();
	Window.setContent(result);
	Window.display();
}

function tags_submitMessage(e) {
	let form = e.target;
	let input = Morebits.quickForm.getInputData(form);
	let templateList = [];

	// First let's tidy up Morebit's array
	for (const [key, value] of Object.entries(input)) {
		if (value && !key.includes('_param') && key != 'notify' && key != 'reason' && key != 'search') {
			templateList.push([key])
		}
	}

	// Then we will assign each parameter to their corresponding value and make it accessible
	for (const element of templateList) {
		for (const [key, value] of Object.entries(input)) {
			if (key.includes('_param') && key.includes(element)) {
				templateList[element] = {
					"param": key.split('-').pop(),
					"paramValue": value
				}
			}
		}
	}

	createStatusWindow();
	new Morebits.status("Paso 1", `generando plantilla...`, "info");
	new mw.Api().edit(
		currentPageName,
		function (revision) {
			return {
				text: templateBuilder(templateList) + revision.content,
				summary: `Añadiendo plantilla mediante [[WP:TL|Twinkle Lite]]` + `${input.reason ? `. ${input.reason}` : ''}`,
				minor: false
			}
		})
		.then(function () {
			if (!input.notify) return;
			return getCreator().then(tags_postsMessage(templateList));
		})
		.then(function () {
			new Morebits.status("Finalizado", "actualizando página...", "status");
			setTimeout(() => { location.reload() }, 2000);
		})
		.catch(function () {
			new Morebits.status("Se ha producido un error", "Comprueba las ediciones realizadas", "error")
			setTimeout(() => { location.reload() }, 4000);
		})



}

function templateBuilder(list) {
	let finalString = '';
	for (const element of list) {
		let parameter = list[element]?.param ? `|${list[element].param}=` : '';
		let parameterValue = list[element]?.paramValue || '';
		finalString += `{{sust:${element}${parameter}${parameterValue}}}\n`;
	}
	return finalString;
}

function allWarnings(list) {
	let finalString = ''
	for (let template of list) {
		if (templateDict[template]?.warning) {
			finalString += `{{sust:${templateDict[template].warning}|${currentPageNameWithoutUnderscores}}} ~~~~\n`
		}
	}
	return finalString
}

function tags_postsMessage(templateList) {
	return (creator) => {
		if (creator == currentUser) {
			return;
		} else {
			new Morebits.status("Paso 2", "publicando un mensaje de aviso en la página de discusión del creador (si es posible)...", "info");
			return isPageMissing(`Usuario_discusión:${creator}`)
				.then(function (mustCreateNewTalkPage) {
					if (mustCreateNewTalkPage) {
						return new mw.Api().create(
							`Usuario_discusión:${creator}`,
							{ summary: `Aviso al usuario de la colocación de una plantilla en [[${currentPageNameWithoutUnderscores}]] mediante [[WP:Twinkle Lite|Twinkle Lite]]` },
							`${allWarnings(templateList)}`
						);
					} else {
						return new mw.Api().edit(
							`Usuario_discusión:${creator}`,
							function (revision) {
								return {
									text: revision.content + `\n${allWarnings(templateList)}`,
									summary: `Aviso al usuario de la colocación de una plantilla en [[${currentPageNameWithoutUnderscores}]] mediante [[WP:Twinkle Lite|Twinkle Lite]]`,
									minor: false
								}
							}
						)
					}
				})
		}
	}
}


;// CONCATENATED MODULE: ./src/modules/warnings.js
// ** Warn module **
// Posts a warning message on a user discussion page that can be selected as part of a series of options of a checkbox list



const warnedUser = mw.config.get('wgRelevantUserName');

const warnings_templateDict = {
    "aviso autopromoción": {
        description: "usuarios creadores de páginas promocionales o de publicidad",
        subgroup: [
            {
                type: 'input',
                name: '_param-aviso autopromoción-1',
                label: 'Artículo promocional en cuestión',
                tooltip: 'Escribe el nombre del artículo considerado promocional o publicitario. No uses corchetes, el enlace se añadirá automáticamente'
            }
        ]
    },
    "aviso blanqueo": {
        description: "usuarios que han blanqueado total o parcialmente páginas en general o de discusión asociada",
        subgroup: [
            {
                type: 'input',
                name: '_param-aviso blanqueo-1',
                label: 'Artículo en el que se realizó el blanqueo',
                tooltip: 'Escribe el nombre del artículo en el que se realizó el blanqueo parcial o total. No uses corchetes, el enlace se añadirá automáticamente'
            }
        ]
    },
    "aviso blanqueo discusión": {
        description: "usuarios que han blanqueado total o parcialmente su página de discusión o la de otros usuarios",
    },
    "aviso categorizar": {
        description: "usuarios que han olvidado categorizar artículos",
        subgroup: [
            {
                type: 'input',
                name: '_param-aviso categorizar-1',
                label: 'Artículo en cuestión',
                tooltip: 'Escribe el nombre del artículo que no ha sido categorizado por el usuario. No uses corchetes, el enlace se añadirá automáticamente'
            }
        ]
    },
    "aviso conflicto de interés": {
        description: "usuarios que editan bajo conflicto de interés o que constituyen CPP y no respetan PVN"
    },
    "aviso copyvio": {
        description: "usuarios que han creado artículos que vulneran derechos de autor",
        subgroup: [
            {
                type: 'input',
                name: '_param-aviso copyvio-1',
                label: 'Artículo en el que hay copyvio',
                tooltip: 'Escribe el nombre del artículo en el que se han vulnerado derechos de autor. No uses corchetes, el enlace se añadirá automáticamente'
            }
        ]
    },
    "aviso etiqueta": {
        description: "usuarios que han faltado a la etiqueta, realizando ediciones o creando comentarios o páginas que pueden resultar ofensivas",
        subgroup: [
            {
                type: 'input',
                name: '_param-aviso etiqueta-1',
                label: 'Nombre del artículo donde se ha producido la falta de etiqueta',
                tooltip: 'Escribe el nombre de la página donde se ha producido la falta de etiqueta. No uses corchetes, el enlace se añadirá automáticamente'
            }
        ]
    },
    "aviso firma": {
        description: "usuarios que han firmado artículos",
        subgroup: [
            {
                type: 'input',
                name: '_param-aviso firma-1',
                label: 'Nombre del artículo donde se ha firmado erróneamente',
                tooltip: 'Escribe el nombre del artículo donde se ha añadido una firma. No uses corchetes, el enlace se añadirá automáticamente'
            }
        ]
    },
    "aviso guerra de ediciones": {
        description: "autores que han subido imágenes que no deberían estar en Commons",
        subgroup: [
            {
                type: 'input',
                name: '_param-aviso guerra de ediciones-1',
                label: 'Nombre de la página en la que se ha dado la guerra de ediciones',
                tooltip: 'Escribe el nombre de la página en la que el usuario avisado ha participado en una guerra de ediciones. No uses corchetes, el enlace se añadirá automáticamente'
            }
        ]
    },
    "aviso imagen": {
        description: "autores que han subido imágenes que no deberían estar en Commons",
        subgroup: [
            {
                type: 'input',
                name: '_param-aviso imagen-1',
                label: 'Nombre del archivo en Commons',
                tooltip: 'Escribe el nombre del archivo en Commons, incluyendo su extensión. No uses corchetes, el enlace se añadirá automáticamente'
            }
        ]
    },
    "aviso noesunforo2": {
        description: "usuarios que forean en páginas de discusión",
        subgroup: [
            {
                type: 'input',
                name: '_param-aviso noesunforo2-1',
                label: 'Artículo en el que se realizó la edición',
                tooltip: 'Escribe el nombre del artículo en el que se cometió la prueba de edición. No uses corchetes, el enlace se añadirá automáticamente'
            }
        ]
    },
    "aviso nombre inapropiado": {
        description: "nombres de usuario que van contra la política de nombres de usuario"
    },
    "aviso prueba1": {
        description: "usuarios que han realizado ediciones no apropiadas",
        subgroup: [
            {
                type: 'input',
                name: '_param-aviso prueba1-1',
                label: 'Artículo en el que se realizó la edición',
                tooltip: 'Escribe el nombre del artículo en el que se cometió la prueba de edición. No uses corchetes, el enlace se añadirá automáticamente'
            }
        ]
    },
    "aviso prueba2": {
        description: "usuarios que han realizado ediciones vandálicas",
        subgroup: [
            {
                type: 'input',
                name: '_param-aviso prueba2-1',
                label: 'Artículo en el que se realizó el vandalismo',
                tooltip: 'Escribe el nombre del artículo en el que se cometió el vandalismo. No uses corchetes, el enlace se añadirá automáticamente'
            }
        ]
    },
    "aviso prueba3": {
        description: "usuarios que han realizado más de una edición vandálica",
        subgroup: [
            {
                type: 'input',
                name: '_param-aviso prueba3-1',
                label: 'Artículo en el que se llevó a cabo el vandalismo',
                tooltip: 'Escribe el nombre del artículo en elviso noesunforo1 que se cometió el vandalismo. No uses corchetes, el enlace se añadirá automáticamente'
            }
        ]
    },
    "aviso prueba4": {
        description: "ultimo aviso a usuarios vandálicos antes de denunciarlo en TAB",
        subgroup: [
            {
                type: 'input',
                name: '_param-aviso prueba4-1',
                label: 'Artículo en el que se llevó a cabo el vandalismo',
                tooltip: 'Escribe el nombre del artículo en el que se cometió el vandalismo. No uses corchetes, el enlace se añadirá automáticamente'
            }
        ]
    },
    "aviso sin sentido": {
        description: "usuarios que crean páginas sin sentido o bulos",
        subgroup: [
            {
                type: 'input',
                name: '_param-aviso sin sentido-1',
                label: 'Artículo en el que se llevó a cabo la edición',
                tooltip: 'Escribe el nombre del artículo en el que se llevó a cabo la edición sin sentido o bulo. No uses corchetes, el enlace se añadirá automáticamente',
                required: true
            }
        ]
    },
    "aviso topónimos de España": {
        description: "usuarios que no han tenido en cuenta WP:TOES",
        subgroup: [
            {
                type: 'input',
                name: '_param-aviso topónimos de España-1',
                label: 'Artículo en cuestión',
                tooltip: 'Escribe el nombre de la página en la que se ha violado la política de WP:TOES. No uses corchetes, el enlace se añadirá automáticamente',
            }
        ]
    },
    "aviso traslado al taller": {
        description: "usuarios que han creado una página no apta para el espacio principal",
        subgroup: [
            {
                type: 'input',
                name: '_param-aviso traslado al taller-1',
                label: 'Página (del taller) en la que se encuentra el artículo trasladado',
                tooltip: 'Escribe el nombre de la página en la que se encuentra ahora el artículo (Ej.: si pones «EjemploDePágina», el enlace llevará a «Usuario:Ejemplo/Taller/EjemploDePágina»). No uses corchetes, el enlace se añadirá automáticamente',
            }
        ]
    },
    "aviso votonulo": {
        description: "usuarios que han intentado votar sin cumplir los requisitos"
    },
    "no amenaces con acciones legales": {
        description: "usuarios que han amenazado con denunciar o llevar a juicio a Wikipedia/otros usuarios",
        subgroup: [
            {
                type: 'input',
                name: '_param-no amenaces con acciones legales-1',
                label: 'Página en la que se llevó a cabo la amenaza',
                tooltip: '(Opcional) Escribe el nombre de la página en la que se llevó a cabo la amenaza. No uses corchetes, el enlace se añadirá automáticamente'
            }
        ]
    },
    "no retires plantillas de mantenimiento crítico": {
        description: "usuarios que han retirado plantillas de mantenimiento crítico sin consenso en PD",
        subgroup: [
            {
                type: 'input',
                name: '_param-no retires plantillas de mantenimiento crítico-1',
                label: 'Artículo en el que se retiró la plantilla',
                tooltip: 'Escribe el nombre del artículo en el que se encontraba la plantilla retirada. No uses corchetes, el enlace se añadirá automáticamente'
            }
        ]
    },
    "planvand": {
        description: "usuarios que han realizado ediciones perjudiciales o que van más allá del vandalismo",
        subgroup: [
            {
                type: 'input',
                name: '_param-planvand-1',
                label: 'Artículo en el que se llevó a cabo el vandalismo',
                tooltip: 'Escribe el nombre del artículo en el que se cometió el vandalismo. No uses corchetes, el enlace se añadirá automáticamente'
            }
        ]
    },
    "ten precaución en la retirada de plantillas de mantenimiento no crítico": {
        description: "usuarios que han retirado plantillas de mantenimiento no crítico sin explicaciones",
        subgroup: [
            {
                type: 'input',
                name: '_param-ten precaución en la retirada de plantillas de mantenimiento no crítico-1',
                label: 'Artículo del que se retiró la plantilla',
                tooltip: 'Escribe el nombre del artículo en el que se produjo la retirada indebida de la plantilla de mantenimiento no crítico. No uses corchetes, el enlace se añadirá automáticamente'
            }
        ]
    }

}

function warnings_linkBuilder(link) {
    let fullLink = `https://es.wikipedia.org/wiki/Plantilla:${link}`
    return `<a href="${fullLink}" target="_blank">(+)</a>`
}

function warnings_listBuilder(list) {
    let finalList = [];
    for (let item in list) {
        let template = {};
        template.name = item
        template.value = item
        template.label = `{{${item}}} · ${list[item].description} ${warnings_linkBuilder(item)}`
        template.subgroup = list[item]?.subgroup ? list[item].subgroup : '';
        finalList.push(template)
    }
    return finalList;
}

function warnings_templateBuilder(list) {
    let finalString = '';
    for (const element of list) {
        let parameter = list[element]?.param ? `|${list[element].param}=` : '';
        let parameterValue = list[element]?.paramValue || '';
        finalString += `{{sust:${element}${parameter}${parameterValue}}}\n`;
    }
    return finalString;
}

// Creates the Morebits window holding the form
function warnings_createFormWindow() {
    let Window = new Morebits.simpleWindow(620, 530);
    Window.setScriptName('ट्विंकल लाइट');
    Window.setTitle('Notify user');
    Window.addFooterLink('Plantillas de aviso a usuario', 'Wikipedia:Plantillas de aviso a usuario');
    let form = new Morebits.quickForm(warnings_submitMessage);

    form.append({
        type: 'input',
        value: '',
        name: 'search',
        label: 'Búsqueda:',
        id: 'search',
        size: '30',
        event: function quickFilter() {
            const searchInput = document.getElementById("search");
            const allCheckboxDivs = document.querySelectorAll("#checkboxContainer > div");
            if (this.value) {
                // Flushes the list before calling the search query function, then does it as a callback so that it happens in the right order
                function flushList(callback) {
                    for (let i = 0; i < allCheckboxDivs.length; i++) {
                        const div = allCheckboxDivs[i];
                        div.style.display = 'none';
                    }
                    callback();
                }
                // Finds matches for the search query within the checkbox list
                function updateList(searchString) {
                    for (let i = 0; i < allCheckboxDivs.length; i++) {
                        let checkboxText = allCheckboxDivs[i].childNodes[1].innerText
                        if (checkboxText.includes(searchString.toLowerCase()) || checkboxText.includes(searchString.toUpperCase())) {
                            const div = allCheckboxDivs[i];
                            div.style.display = '';
                        }
                    }
                }
                flushList(() => updateList(searchInput.value));
            }
            // Retrieves the full list if nothing is on the search input box
            if (this.value.length == 0) {
                for (let i = 0; i < allCheckboxDivs.length; i++) {
                    const div = allCheckboxDivs[i];
                    div.style.display = '';
                }
            }
        }
    })

    let optionBox = form.append({
        type: 'div',
        id: 'tagWorkArea',
        className: 'morebits-scrollbox',
        style: 'max-height: 28em; min-height: 0.5em;'
    })

    optionBox.append({
        type: 'checkbox',
        id: 'checkboxContainer',
        list: warnings_listBuilder(warnings_templateDict)
    })

    let optionsField = form.append({
        type: 'field',
        label: 'Opciones:'
    })

    optionsField.append({
        type: 'input',
        name: 'reason',
        label: 'Razón:',
        tooltip: '(Opcional) Escribe aquí el resumen de edición explicando la razón por la que se ha añadido la plantilla',
        style: 'width: 80%; margin-top: 0.5em;'
    })

    form.append({
        type: 'submit',
        label: 'Aceptar'
    });

    let result = form.render();
    Window.setContent(result);
    Window.display();

}

function warnings_submitMessage(e) {
    let form = e.target;
    let input = Morebits.quickForm.getInputData(form);
    let templateList = [];

    // First let's tidy up Morebit's array
    for (const [key, value] of Object.entries(input)) {
        if (value && !key.includes('_param') && key != 'notify' && key != 'reason' && key != 'search') {
            templateList.push([key])
        }
    }

    // Then we will assign each parameter to their corresponding value and make it accessible
    for (const element of templateList) {
        for (const [key, value] of Object.entries(input)) {
            if (key.includes('_param') && key.includes(element)) {
                templateList[element] = {
                    "param": key.split('-').pop(),
                    "paramValue": value
                }
            }
        }
    }


    if (warnedUser == currentUser) {
        alert("No puedes dejarte un aviso a ti mismo");
        return;
    } else {
        createStatusWindow();
        new Morebits.status("Paso 1", 'generando plantilla...', 'info');
        warnings_postsMessage(templateList, input)
            .then(function () {
                new Morebits.status("Finalizado", "actualizando página...", "status");
                setTimeout(() => { location.reload() }, 2000);
            })
            .catch(function () {
                new Morebits.status("Se ha producido un error", "Comprueba las ediciones realizadas", "error")
                setTimeout(() => { location.reload() }, 4000);
            })
    }

}

function warnings_postsMessage(templateList, input) {
    new Morebits.status("Paso 2", "publicando aviso en la página de discusión del usuario", "info");
    return isPageMissing(`Usuario_discusión:${warnedUser}`)
        .then(function (mustCreateNewTalkPage) {
            if (mustCreateNewTalkPage) {
                return new mw.Api().create(
                    `Usuario_discusión:${warnedUser}`,
                    { summary: `Añadiendo aviso de usuario mediante [[WP:Twinkle Lite|Twinkle Lite]]` + `${input.reason ? `. ${input.reason}` : ''}` },
                    `${warnings_templateBuilder(templateList)}~~~~`
                );
            } else {
                return new mw.Api().edit(
                    `Usuario_discusión:${warnedUser}`,
                    function (revision) {
                        return {
                            text: revision.content + `\n${warnings_templateBuilder(templateList)}~~~~`,
                            summary: `Añadiendo aviso de usuario mediante [[WP:Twinkle Lite|Twinkle Lite]]` + `${input.reason ? `. ${input.reason}` : ''}`,
                            minor: false
                        }
                    }
                )
            }
        })
}



;// CONCATENATED MODULE: ./src/index.js








const loadDependencies = (callback) => {
	mw.loader.using(['mediawiki.user', 'mediawiki.util', 'mediawiki.Title', 'jquery.ui', 'mediawiki.api', 'mediawiki.ForeignApi']);
	callback();
}

const loadMorebits = (callback) => {
	mw.loader.load('https://en.wikipedia.org/w/index.php?title=MediaWiki:Gadget-morebits.js&action=raw&ctype=text/javascript', 'text/javascript');
	mw.loader.load('https://en.wikipedia.org/w/index.php?title=MediaWiki:Gadget-morebits.css&action=raw&ctype=text/css', 'text/css');
	callback();
};

const initializeTwinkleLite = () => {
	console.log("Loading Twinkle Lite...");

	if (currentNamespace < 0 || !mw.config.get('wgArticleId')) {
		console.log("Special or non-existent page: PP will therefore not be loaded.");
		console.log("Special or non-existent page: DRM will therefore not be loaded.");
		console.log("Special or non-existent page: Speedy deletion will therefore not be loaded.");
	} else {
		const DRMportletLink = mw.util.addPortletLink('p-cactions', '#', 'Open CBD', 'example-button', 'Abre una consulta de borrado para esta página');
		if (DRMportletLink) {
			DRMportletLink.onclick = createFormWindow;
		}
		const PPportletLink = mw.util.addPortletLink('p-cactions', '#', 'Ask for protection', 'example-button', 'Solicita que esta página sea protegida');
		if (PPportletLink) {
			PPportletLink.onclick = pageprotection_createFormWindow;
		}
		const SDportletLink = mw.util.addPortletLink('p-cactions', '#', 'Quick erase', 'example-button', 'Solicita el borrado rápido de la página');
		if (SDportletLink) {
			SDportletLink.onclick = speedydeletion_createFormWindow;
		}
	}

	if (currentNamespace === 0 || currentNamespace === 104) {
		const TportleltLink = mw.util.addPortletLink('p-cactions', '#', 'Add template', 'example-button', 'Añade una plantilla a la página');
		TportleltLink.onclick = tags_createFormWindow;
	}

	if (currentNamespace === 2 || currentNamespace === 3 || (mw.config.get('wgPageName').indexOf("Especial:Contribuciones") > -1)) {
		const RportletLink = mw.util.addPortletLink('p-cactions', '#', 'Denunciar usuario', 'example-button', 'Informa de un problema en relación con el usuario');
		RportletLink.onclick = reports_createFormWindow;
		const WportletLink = mw.util.addPortletLink('p-cactions', '#', 'Avisar al usuario', 'example-button', 'Deja una plantilla de aviso al usuario en su página de discusión');
		WportletLink.onclick = warnings_createFormWindow;
	} else {
		console.log("Non-user page: Reports will therefore not be loaded.");
	}
};

const loadTwinkleLite = () => {
	loadDependencies(() => {
		loadMorebits(() => {
			initializeTwinkleLite();
		});
	})
};

loadTwinkleLite();
/******/ })()
;
//</nowiki>