User:Tzusheng/Wikibench-Editquality.js

//

// Campaign Page

(function ($, mw) {   $(document).ready(function { var wgPageName = "User:Tzusheng/sandbox/Wikipedia:Wikibench/Campaign:Editquality"; if (mw.config.get("wgPageName") === wgPageName && mw.config.get("wgAction") === "view") { mw.loader.using(["oojs-ui-core", "oojs-ui-widgets", "oojs-ui-windows"]).done(function {

// init var WIKIBENCH_PREFIX = "Tzusheng/sandbox/Wikipedia:Wikibench"; var WIKIBENCH_NAMESPACE = 2; var entityType = "diff"; var language = "en"; var entityPageSplit = "-"; var facets = ["editDamage", "userIntent"]; var facetNames = { editDamage: "edit damage", userIntent: "user intent" };               var facetLabels = { editDamage: ["damaging", "not damaging"], userIntent: ["bad faith", "good faith"] };               var facetColors = { editDamage: ["#fee7e6", "#d5fdf4"], userIntent: ["#fee7e6", "#d5fdf4"] };               var userName = mw.config.get("wgUserName"); var mwApi = new mw.Api;

function calculateStandardDeviation(numbers) { // Step 1: Calculate the mean var sum = 0; for (var i = 0; i < numbers.length; i++) { sum += numbers[i]; }                   var mean = sum / numbers.length; // Step 2: Calculate the sum of squared differences var squaredDifferencesSum = 0; for (var j = 0; j < numbers.length; j++) { var difference = numbers[j] - mean; squaredDifferencesSum += difference * difference; }                   // Step 3: Calculate the variance var variance = squaredDifferencesSum / numbers.length; // Step 4: Calculate the standard deviation (square root of variance) var standardDeviation = Math.sqrt(variance); return standardDeviation; }

function getPrefixedPages(entityType, queryContinue, deferred, results) { deferred = deferred || $.Deferred; queryContinue = queryContinue || {}; results = results || []; var prefix = WIKIBENCH_PREFIX + "/Entity:" + entityType.charAt(0).toUpperCase + entityType.slice(1) + "/"; var params = { action: "query", prop: "revisions", rvprop: "content", generator: "allpages", gapprefix: prefix, gaplimit: 500, gapnamespace: WIKIBENCH_NAMESPACE, format: "json", formatversion: 2 };

Object.assign(params, queryContinue)

mwApi.get(params) .done(function(data) {                           var pages = data.query.pages;                            pages.forEach(function(page){ // console.log(page); // console.log(page.revisions); if (page.revisions !== undefined) { // band-aid page['content'] = page.revisions[0].content; delete page['revisions']; results.push(page); }                           });                            if(data.continue){                                getPrefixedPages(entityType, data.continue, deferred, results);                            }else{                                deferred.resolve(results);                            }                        }) .fail(function(e) {                           deferred.fail(e);                        });

return deferred.promise; }

getPrefixedPages(entityType).done(function(results) {                   var label;                    var tableDiv = $(".wikibench-data-table")                    var tbody = tableDiv.find("tbody");                    tbody.find("tr").remove; // remove the empty line                    function sortColumn(columnId, order) {                        var header = tableDiv.find(columnId);                        if (order === "ascending") {                            if (header.attr("title") === "Sort ascending") { // note: title is not the current sorting state                                header.click;                            } else if (header.attr("title") === "Sort initial") {                                header.click.click;                            } else {                                // do nothing because the column is already ascending                            } } else if (order === "descending") { if (header.attr("title") === "Sort ascending") { header.click.click; } else if (header.attr("title") === "Sort descending") { header.click; } else { // do nothing because the column is already descending }                       } else { // do nothing }                   }                    var button1 = new OO.ui.ButtonWidget({label: "provide more labels"}); button1.on("click", function {                       sortColumn("#table-header-editDamage-your-label", "ascending");                        sortColumn("#table-header-label-count", "ascending");                    }); var button2 = new OO.ui.ButtonWidget({label: "compare my labels"}); button2.on("click", function {                       sortColumn("#table-header-userIntent-primary-label", "descending");                        sortColumn("#table-header-editDamage-primary-label", "descending");                        sortColumn("#table-header-userIntent-your-label", "descending");                        sortColumn("#table-header-editDamage-your-label", "descending");                    }); var button3 = new OO.ui.ButtonWidget({label: "build consensus (edit damage)"}); button3.on("click", function {                       sortColumn("#table-header-label-count", "descending");                        sortColumn("#table-header-editDamage-disagreement", "descending")                    }); var button4 = new OO.ui.ButtonWidget({label: "build consensus (user intent)"}); button4.on("click", function {                       sortColumn("#table-header-label-count", "descending");                        sortColumn("#table-header-userIntent-disagreement", "descending");                    }); var layoutBefore = new OO.ui.HorizontalLayout({                       items: [                            new OO.ui.LabelWidget({ label: "I want to:" }),                            button1,                            button2,                            button3,                            button4                        ]                    }); tableDiv.before(layoutBefore.$element);

var searchInputDiff = new OO.ui.SearchInputWidget({                       placeholder: "oldid/newid"                    }); searchInputDiff.on("enter", function {                       window.open("/wiki/Special:Diff/" + searchInputDiff.getValue, "_blank");                    }); var layoutAfter = new OO.ui.HorizontalLayout({                       items: [                            new OO.ui.LabelWidget({ label: "Direct submission:" }),                            searchInputDiff                        ]                    }) tableDiv.after(layoutAfter.$element);

var tableLabelColors = {}; for (var i = 0; i < facets.length; i++) { tableLabelColors[facets[i]] = {}; for (var j = 0; j < facetLabels[facets[i]].length; j++) { tableLabelColors[facets[i]][facetLabels[facets[i]][j]] = facetColors[facets[i]][j]; }                   }

var primaryLabelCounts = {}; facets.forEach(function(f) {                       primaryLabelCounts[f] = {};                        facetLabels[f].forEach(function(l) { primaryLabelCounts[f][l] = 0; })                   })

for (var r = 0; r < results.length; r++) { label = JSON.parse(results[r].content.split(entityPageSplit)[1]); var primaryLabel = {}; var userLabels = {}; var individualLabels = {}; var lowConfidenceIndicator = {}; for (var i = 0; i < facets.length; i++) { var f = facets[i]; lowConfidenceIndicator[f] = false; primaryLabel[f] = label.facets[f].primaryLabel.label; userLabels[f] = ""; individualLabels[f] = []; primaryLabelCounts[f][primaryLabel[f]] += 1; for (var j = 0; j < label.facets[f].individualLabels.length; j++) { // handle user labels if (label.facets[f].individualLabels[j].userName === userName) { userLabels[f] = label.facets[f].individualLabels[j].label; if (label.facets[f].individualLabels[j].lowConfidence) { lowConfidenceIndicator[f] = true; }                               }                                // handle individual labels for disagreements if (label.facets[f].individualLabels[j].label === facetLabels[f][0]) { if (label.facets[f].individualLabels[j].lowConfidence) { individualLabels[f].push(-0.5); }                                   else { individualLabels[f].push(-1); }                               }                                if (label.facets[f].individualLabels[j].label === facetLabels[f][1]) { if (label.facets[f].individualLabels[j].lowConfidence) { individualLabels[f].push(0.5); }                                   else { individualLabels[f].push(1); }                               }                            }                        }

var hrefLink = "";

tbody.append($(" ")                           .append($(" ").text(label.entityId).wrapInner(hrefLink).attr("scope", "row"))                            .append($(" ").text(primaryLabel[facets[0]]).attr("bgcolor", tableLabelColors[facets[0]][primaryLabel[facets[0]]]))                            .append($(" ").text(userLabels[facets[0]] + ((lowConfidenceIndicator[facets[0]])?("*"):(""))).attr("bgcolor", tableLabelColors[facets[0]][userLabels[facets[0]]]))                            .append($(" ").text(calculateStandardDeviation(individualLabels[facets[0]]).toFixed(3)))                            .append($(" ").text(primaryLabel[facets[1]]).attr("bgcolor", tableLabelColors[facets[1]][primaryLabel[facets[1]]]))                            .append($(" ").text(userLabels[facets[1]] + ((lowConfidenceIndicator[facets[1]])?("*"):(""))).attr("bgcolor", tableLabelColors[facets[1]][userLabels[facets[1]]])) .append($(" ").text(calculateStandardDeviation(individualLabels[facets[1]]).toFixed(3))) .append($(" ").text(label.facets[facets[0]].individualLabels.length.toString)) );                   }

for (var i = 0; i < facets.length; i++) { var f = facets[i]; var tmp0 = primaryLabelCounts[f][facetLabels[f][0]]; var tmp1 = primaryLabelCounts[f][facetLabels[f][1]]; mwApi.get({                           action: "parse",                            text: "",                            contentmodel: "wikitext"                        }).done(function(ret) {                            $("#wikibench-data-curation-charts").append(ret.parse.text["*"]);                        }); }               });            });        }    }); })(jQuery, mediaWiki);

// Entity Page

(function ($, mw) {   $(document).ready(function { // init var wikibenchURL = "User:Tzusheng/sandbox/Wikipedia:Wikibench"; var wikibenchTalkURL = "User_talk:Tzusheng/sandbox/Wikipedia:Wikibench" var campaignURL = wikibenchURL + "/Campaign:Editquality"; var campaignTalkURL = wikibenchTalkURL + "/Campaign:Editquality"; var entityType = "diff"; var entityPagePrefix = wikibenchURL + "/Entity:" + entityType.charAt(0).toUpperCase + entityType.slice(1) + "/"; var entityPagePrefixArchive = wikibenchURL + "/Archive/Entity:" + entityType.charAt(0).toUpperCase + entityType.slice(1) + "/"; var entityPageHeader = ""; var entityPageSplit = "-"; var language = "en"; var facets = ["editDamage", "userIntent"]; var facetNames = { editDamage: "edit damage", userIntent: "user intent" };       var facetLabels = { editDamage: ["damaging", "not damaging"], userIntent: ["bad faith", "good faith"] };       var facetIcons = { editDamage: ["alert", "success"], userIntent: ["alert", "success"] };       var facetColors = { editDamage: ["#b32424", "#14866d"], userIntent: ["#b32424", "#14866d"] };

// get config var wgPageName = mw.config.get("wgPageName");

if((wgPageName.startsWith(entityPagePrefix) || (wgPageName.startsWith(entityPagePrefixArchive))) && mw.config.get("wgAction") === "view") {

// widgets var divRender = $(".mw-parser-output"); var diffTableHeader = " "; var diffTableContent, diffTableTitle; var windowManager; var noticeBox; var revdelBox; var newPageBox; var primaryFieldset; var userFieldset; var userLabel = {}; var userLowConfidences = {}; var userNote = {}; var individualFieldset = {}; var stackBars = {}; var stackBarText = {}; var lowConfidenceHtmlSnippet = "(low confidence) "

var mwApi = new mw.Api; var entityId = wgPageName.substring(entityPagePrefix.length); var userName = mw.config.get("wgUserName"); var userId = mw.config.get("wgUserId");

mwApi.get({               action: "parse",                page: wgPageName,                prop: "wikitext"            }).done(function(ret) {                mw.loader.using(["oojs-ui-core", "oojs-ui-widgets", "oojs-ui-windows", "mediawiki.diff.styles"]).done(function{ var label = JSON.parse(ret.parse.wikitext["*"].split(entityPageSplit)[1]);

/* ===== WINDOR MANAGER ===== */ windowManager = new OO.ui.WindowManager; $(document.body).append(windowManager.$element);

noticeBox = new OO.ui.MessageWidget({                       type: "notice",                        label: new OO.ui.HtmlSnippet("Please do not directly edit the source of this page. To update the primary or your label, click the edit buttons below. To discuss, visit the talk page. To view the labeling progress of the campaign, visit the campaign page.")                    });

revdelBox = new OO.ui.MessageWidget({                       type: "warning",                        label: new OO.ui.HtmlSnippet("This diff has been revdel\'d. Please visit the campaign talk page for an ongoing discussion about handling revdel\'d diffs.")                    });

newPageBox = new OO.ui.MessageWidget({                       type: "warning",                        label: new OO.ui.HtmlSnippet("This diff is a new page creation. Please visit the campaign talk page for an ongoing discussion about handling new pages.")                    }); /* ===== PRIMARY LABEL ===== */ primaryFieldset = new OO.ui.FieldsetLayout({                        label: "Primary label",                        classes: ["wikibench-entity-primary-label"],                    });

var labelColor = {}; for (var i = 0; i < facets.length; i++) { labelColor[facets[i]] = {}; for (var j = 0; j < facetLabels[facets[i]].length; j++) { labelColor[facets[i]][facetLabels[facets[i]][j]] = facetColors[facets[i]][j]; }                   }

for (var i = 0; i < facets.length; i++) { var f = facets[i]; var facetPrimaryLabel = new OO.ui.LabelWidget({                           label: new OO.ui.HtmlSnippet("" + label.facets[f].primaryLabel.label + " ")                        }); primaryFieldset.addItems(                           new OO.ui.FieldLayout(facetPrimaryLabel, { label: facetNames[f].charAt(0).toUpperCase + facetNames[f].slice(1), align: "left" })                       )                    }

primaryFieldset.addItems([                       new OO.ui.FieldLayout( new OO.ui.LabelWidget({                               label: $("")                                    .attr("href","/wiki/User:"+label.facets[facets[0]].primaryLabel.lastModifier)                                    .text(label.facets[facets[0]].primaryLabel.lastModifier)                            }), { label: "Last modifier", align: "left" }                       ),                        new OO.ui.FieldLayout( new OO.ui.LabelWidget({                               label: label.facets[facets[0]].primaryLabel.touched                            }), { label: "Last modified time", align: "left" }                       )                    ]);

var editPrimaryBtn = new OO.ui.ButtonWidget({                       label: "Edit",                        disabled: true // Change to false when doing demo                    });

// Make a subclass of ProcessDialog for editing the primary label function EditPrimaryDialog( config ) { EditPrimaryDialog.super.call( this, config ); }                   OO.inheritClass( EditPrimaryDialog, OO.ui.ProcessDialog );

// Specify a name for .addWindows EditPrimaryDialog.static.name = "editPrimaryDialog"; EditPrimaryDialog.static.title = "Edit primary label"; EditPrimaryDialog.static.actions = [ {                            flags: [ "primary", "progressive" ], label: "Publish changes", action: "publish" },                       {                             flags: "safe", label: "Cancel" }                   ];

// Customize the initialize function to add content and layouts: EditPrimaryDialog.prototype.initialize = function { EditPrimaryDialog.super.prototype.initialize.call( this ); this.panel = new OO.ui.PanelLayout( {                            padded: true,                             expanded: false                         } ); this.content = new OO.ui.FieldsetLayout; this.primaryLabelMessage = new OO.ui.MessageWidget({                           type: "warning",                            label: new OO.ui.HtmlSnippet("When editing primary labels, be bold yet respectful of others' views. Wikibench will notify the last modifier on the talk page</a> with <a href=\"/wiki/Wikipedia:Signatures#Using_four_tildes\">your signature</a> after publishing changes.")                        });

this.content.addItems([this.primaryLabelMessage]);

this.primaryFacetBtns = {}; for (var i = 0 ; i < facets.length; i++) { this.primaryFacetBtns[facets[i]] = new OO.ui.ButtonSelectWidget({                               items: [                                    new OO.ui.ButtonOptionWidget({ data: facetLabels[facets[i]][0], label: facetLabels[facets[i]][0], icon: facetIcons[facets[i]][0] }),                                   new OO.ui.ButtonOptionWidget({ data: facetLabels[facets[i]][1], label: facetLabels[facets[i]][1], icon: facetIcons[facets[i]][1] })                               ]                            });                            this.primaryFacetBtns[facets[i]].selectItemByLabel(label.facets[facets[i]].primaryLabel.label); this.content.addItems([                               new OO.ui.FieldLayout(this.primaryFacetBtns[facets[i]], { label: facetNames[facets[i]].charAt(0).toUpperCase + facetNames[facets[i]].slice(1), align: "left" })                           ]);                        }

this.primaryLabelSummary = new OO.ui.TextInputWidget({                           placeholder: "Briefly describe your changes"                        });

this.content.addItems([                           new OO.ui.FieldLayout(this.primaryLabelSummary, { label: "Edit summary", align: "top" })                       ]);

this.panel.$element.append( this.content.$element ); this.$body.append( this.panel.$element ); };

EditPrimaryDialog.prototype.getBodyHeight = function { return this.panel.$element.outerHeight( true ); };

// Specify processes to handle the actions. EditPrimaryDialog.prototype.getActionProcess = function ( action ) { if ( action === "publish" ) { // Create a new process to handle the action return new OO.ui.Process( function {                                var primaryLabels = {}                                var summary = this.primaryLabelSummary.getValue;                                for (var i = 0; i < facets.length; i++) {                                    primaryLabels[facets[i]] = this.primaryFacetBtns[facets[i]].findSelectedItem.getData;                                }                                mwApi.get({ action: "query", prop: "revisions", rvprop: "content", titles: wgPageName, format: "json" }).done(function(ret) { var revisions = ret.query.pages; var pageId = Object.keys(revisions)[0]; var submitContent = JSON.parse(revisions[pageId].revisions[0]["*"].split(entityPageSplit)[1]); var lastModifier = submitContent.facets[facets[0]].primaryLabel.lastModifier; for (var i = 0; i < facets.length; i++) { submitContent.facets[facets[i]].primaryLabel.lastModifier = userName; submitContent.facets[facets[i]].primaryLabel.lastModifierId = userId; submitContent.facets[facets[i]].primaryLabel.label = primaryLabels[facets[i]]; submitContent.facets[facets[i]].primaryLabel.touched = new Date(new Date.getTime).toUTCString; submitContent.facets[facets[i]].primaryLabel.autolabeled = false; }                                   mwApi.postWithToken("csrf",{                                        action: "edit",                                        title: wgPageName,                                        section: 0,                                        text: entityPageHeader + "\n" + entityPageSplit + "\n" + JSON.stringify(submitContent),                                        summary: "Primary label change from the Wikibench entity page: " + summary,                                    }).done(function(result,jqXHR) {                                        // notify the previous labeler on the talk page                                        mwApi.postWithToken("csrf", { action: "edit", title: wikibenchTalkURL + "/Entity:" + entityType.charAt(0).toUpperCase + entityType.slice(1) + "/" + entityId, section: "new", sectiontitle: "The primary label has been edited", text: " " + userName + " edited the primary label that you previously submitted. If you disagree with the change, please kindly engage in a discussion on this talk page and consider seeking a third opinion if needed. ~" }).done(function(result,jqXHR) { location.reload; });                                   });                                });                            }, this ); }                       // Fallback to parent handler return EditPrimaryDialog.super.prototype.getActionProcess.call( this, action ); };

// Create a new process dialog window. var editPrimaryDialog = new EditPrimaryDialog;

// Add the window to window manager using the addWindows method. windowManager.addWindows( [ editPrimaryDialog ] );

editPrimaryBtn.on("click", function {                       windowManager.openWindow( editPrimaryDialog );                    });

var discussPrimaryBtn = new OO.ui.ButtonWidget({                       label: "Talk"                    });

discussPrimaryBtn.on("click", function {                       window.open("/wiki/" + wikibenchTalkURL + "/Entity:" + entityType.charAt(0).toUpperCase + entityType.slice(1) + "/" + entityId, "_self");                    })

// primaryFieldset.addItems(                   //     new OO.ui.FieldLayout(editPrimaryBtn, { //        align: "left" //    })                    // );                    primaryFieldset.addItems(                        new OO.ui.FieldLayout(new OO.ui.Widget({                            content: [                                new OO.ui.HorizontalLayout({ items: [ editPrimaryBtn, discussPrimaryBtn ]                               })                            ]                        }), {                            align: "left" })                   );

/* ===== USER LABEL ===== */ userFieldset = new OO.ui.FieldsetLayout({                        label: "Your label (" + userName + ")",                        classes: ["wikibench-entity-user-label"]                    });

for (var i = 0; i < facets.length; i++) { var f = facets[i]; userLabel[f] = undefined; userNote[f] = ""; var displayLabelName = "undefined"; label.facets[f].individualLabels.forEach(function(l) {                           if (userName === l.userName) {                                userLabel[f] = l.label;                                userLowConfidences[f] = l.lowConfidence;                                userNote[f] = l.note;                                displayLabelName = "<font color=\"" + labelColor[f][l.label] + "\">" + l.label + " ";                                if (l.lowConfidence) {                                    displayLabelName = displayLabelName + " " + lowConfidenceHtmlSnippet;                                }                            }                        }); userFieldset.addItems(                           new OO.ui.FieldLayout( new OO.ui.LabelWidget({                                   label: new OO.ui.HtmlSnippet(displayLabelName)                                }), { label: facetNames[f].charAt(0).toUpperCase + facetNames[f].slice(1), align: "left" })                       );                    }

var editUserBtn = new OO.ui.ButtonWidget({                       label: "Edit",                        disabled: true // Change to false when doing demo                    });

// Make a subclass of Process Dialog for editing the user label function EditUserLabelDialog(config) { EditUserLabelDialog.super.call(this, config); }                   OO.inheritClass(EditUserLabelDialog, OO.ui.ProcessDialog);

EditUserLabelDialog.static.name = "editUserLabelDialog"; EditUserLabelDialog.static.title = "Edit your label"; EditUserLabelDialog.static.actions = [ {                           flags: ["primary", "progressive"], label: "Publish changes", action: "publish" },                       {                            flags: "safe", label: "Cancel" }                   ];

EditUserLabelDialog.prototype.initialize = function { EditUserLabelDialog.super.prototype.initialize.call(this); this.panel = new OO.ui.PanelLayout({                           padded: true,                            expanded: false                        }); this.content = new OO.ui.FieldsetLayout; this.userFacetBtns = {}; this.userFacetLowConfidenceCheckboxes = {}; this.userFacetNoteInputs = {}; for (var i = 0; i < facets.length; i++) { var f = facets[i]; this.userFacetBtns[f] = new OO.ui.ButtonSelectWidget({                               items: [                                    new OO.ui.ButtonOptionWidget({ data: facetLabels[f][0], label: facetLabels[f][0], icon: facetIcons[f][0] }),                                   new OO.ui.ButtonOptionWidget({ data: facetLabels[f][1], label: facetLabels[f][1], icon: facetIcons[f][1] })                               ]                            });                            if (userLabel[f] !== undefined) { this.userFacetBtns[f].selectItemByLabel(userLabel[f]); }                           this.userFacetLowConfidenceCheckboxes[f] = new OO.ui.CheckboxInputWidget; if (userLowConfidences[f] === true) { this.userFacetLowConfidenceCheckboxes[f].setSelected(true); }                           this.userFacetNoteInputs[f] = new OO.ui.TextInputWidget({                                value: userNote[f]                            }) this.content.addItems([                               new OO.ui.FieldLayout(this.userFacetBtns[f], { label: facetNames[f].charAt(0).toUpperCase + facetNames[f].slice(1), align: "left" }),                               new OO.ui.FieldLayout(new OO.ui.Widget({                                    content: [                                        new OO.ui.HorizontalLayout({ items: [ this.userFacetLowConfidenceCheckboxes[f], new OO.ui.LabelWidget({label: "low confidence"}) ]                                       })                                    ]                                }), {                                    label: " ", align: "left" }),                               new OO.ui.FieldLayout(this.userFacetNoteInputs[f], { label: "Note for " + facetNames[f], align: "left" })                           ])                        }

this.panel.$element.append(this.content.$element); this.$body.append(this.panel.$element); }

EditUserLabelDialog.prototype.getBodyHeight = function { return this.panel.$element.outerHeight(true); }

EditUserLabelDialog.prototype.getActionProcess = function(action) { if ( action === "publish" ) { // Create a new process to handle the action return new OO.ui.Process( function {                                var tmpUserLabel = {};                                var tmpUserLowConfidences = {};                                var tmpUserNote = {};                                for (var i = 0; i < facets.length; i++) {                                    tmpUserLabel[facets[i]] = this.userFacetBtns[facets[i]].findSelectedItem.getData;                                    tmpUserLowConfidences[facets[i]] = this.userFacetLowConfidenceCheckboxes[facets[i]].isSelected;                                    tmpUserNote[facets[i]] = this.userFacetNoteInputs[facets[i]].getValue;                                }                                mwApi.get({ action: "query", prop: "revisions", rvprop: "content", titles: wgPageName, format: "json" }).done(function(ret) { var revisions = ret.query.pages; var pageId = Object.keys(revisions)[0]; var submitContent = JSON.parse(revisions[pageId].revisions[0]["*"].split(entityPageSplit)[1]); for (var i = 0; i < facets.length; i++) { var isUserLabelExist = false; var f = facets[i]; var submitLabel = { "userName": userName, "userId": userId, "label": tmpUserLabel[f], "note": tmpUserNote[f], "origin": "wikibench-enwiki-entity-page", "created": new Date(new Date.getTime).toUTCString, "touched": new Date(new Date.getTime).toUTCString, "lowConfidence": tmpUserLowConfidences[f], "category": [] }                                       for (var j = 0; j < submitContent.facets[f].individualLabels.length; j++) { if (submitContent.facets[f].individualLabels[j].userName === userName) { submitLabel.created = submitContent.facets[f].individualLabels[j].created; submitContent.facets[f].individualLabels[j] = submitLabel; isUserLabelExist = true; break; }                                       }                                        if (!isUserLabelExist) { submitContent.facets[f].individualLabels.push(submitLabel); }                                   }                                    mwApi.postWithToken("csrf",{                                        action: "edit",                                        title: wgPageName,                                        section: 0,                                        text: entityPageHeader + "\n" + entityPageSplit + "\n" + JSON.stringify(submitContent),                                        summary: "Individual label edit from the Wikibench entity page",                                    }).done(function(result,jqXHR) {                                        location.reload;                                    }) });;                           }, this ); }                       // Fallback to parent handler return EditUserLabelDialog.super.prototype.getActionProcess.call( this, action ); }                   var editUserLabelDialog = new EditUserLabelDialog; windowManager.addWindows([editUserLabelDialog]); editUserBtn.on("click", function {                       windowManager.openWindow(editUserLabelDialog);                    });

userFieldset.addItems([                       new OO.ui.FieldLayout(editUserBtn, { align: "left" })                   ]);

divRender.find("table").remove; // remove warning message divRender.find("hr").remove; // remove horizontal line divRender.find("p").remove; // remove json content

divRender .append(noticeBox.$element) .append(" Difference between revisions ") .append("<div id=\"wikibench-entity-page-diff-table\"> ") .append(" Primary and your labels ") .append(primaryFieldset.$element) .append(userFieldset.$element);

/* ===== INDIVIDUAL LABEL ===== */ for (var i = 0; i < facets.length; i++) { var f = facets[i]; individualFieldset[f] = {}; var labelCount = {}; var labelLowConfidenceCount = {}; for (var j = 0; j < facetLabels[f].length; j++) { var l = facetLabels[f][j]; labelCount[l] = 0; labelLowConfidenceCount[l] = 0; individualFieldset[f][l] = new OO.ui.FieldsetLayout({                               icon: "expand",                                classes: ["wikibench-entity-individual-labels"]                            }); label.facets[f].individualLabels.forEach(function(individualLabel) {                               if (individualLabel.label === l) {                                    var labelText = "<a href=\"/wiki/User:" + individualLabel.userName + "\">" + individualLabel.userName + "</a>";                                    labelCount[l]++;                                    if (individualLabel.lowConfidence) {                                        labelLowConfidenceCount[l]++;                                        labelText = labelText + " " + lowConfidenceHtmlSnippet;                                    }                                    individualFieldset[f][l].addItems( new OO.ui.FieldLayout(                                           new OO.ui.LabelWidget({label: individualLabel.note}),                                            {label: new OO.ui.HtmlSnippet(labelText)}                                        ) );                               }                            });                            individualFieldset[f][l].setLabel(l + " (" + labelCount[l].toString + ")"); individualFieldset[f][l].$group.toggle(false); }

// stack bars (assume binary labels) var stackBarCounts = [ labelCount[facetLabels[f][0]] - labelLowConfidenceCount[facetLabels[f][0]], labelLowConfidenceCount[facetLabels[f][0]], labelLowConfidenceCount[facetLabels[f][1]], labelCount[facetLabels[f][1]] - labelLowConfidenceCount[facetLabels[f][1]] ];                       var stackBarTotal = 0; var stackBarNames = [ facetLabels[f][0], facetLabels[f][0] + " (low confidence)", facetLabels[f][1] + " (low confidence)", facetLabels[f][1] ];                       var stackBarColors = ["#b32424", "#fee7e6", "#d5fdf4", "#14866d"] stackBarText[f] = "";

divRender .append(" " + facetNames[f].charAt(0).toUpperCase + facetNames[f].slice(1) + " labels ") .append(" Label distribution ") .append("<div id=\"Wikibench-StackBar-" + f + "\"> ") .append(" Individual labels "); for (var j = 0; j < facetLabels[f].length; j++) { var l = facetLabels[f][j]; divRender.append(individualFieldset[f][l].$element); individualFieldset[f][l].$element.find(".oo-ui-fieldsetLayout-header").click(function{                               var header = $(this);                                var content = header.next;                                content.slideToggle(function  { header.children(".oo-ui-iconElement-icon").toggleClass("oo-ui-icon-collapse").toggleClass("oo-ui-icon-expand"); });                           })                        }                    }

// get and append the stackbars outside the for loop to bypass the await time // p.s. await is not available in ES5 facets.forEach(function(f) {                       mwApi.get({ action: "parse", text: stackBarText[f], contentmodel: "wikitext" }).done(function(ret) { $("#Wikibench-StackBar-"+f).append(ret.parse.text["*"]); });                   });

// diff table mwApi.get({                       action: "compare",                        fromrev: parseInt(entityId.split("/")[0]),                        torev: parseInt(entityId.split("/")[1]),                    }).done(function(ret) {                        diffTableContent = ret.compare["*"];                        diffTableTitle =                         "<tr class=\"diff-title\" lang=\"" + language + "\">" +                            "<td colspan=\"2\" class=\"diff-otitle diff-side-deleted\">" +                                "<div id=\"mw-diff-otitle1\">" +                                     " <a href=\"/wiki/Special:Permalink/" + ret.compare.fromrevid + "\">Revision before edit</a> " +                                " " +                                "<div id=\"mw-diff-otitle3\"> <span class=\"comment\">Revision ID: " + ret.compare.fromrevid + "  " +                                "<div id=\"mw-diff-otitle5\"> " + " " +                           "<td colspan=\"2\" class=\"diff-ntitle diff-side-added\">" + "<div id=\"mw-diff-ntitle1\">" + " <a href=\"/wiki/Special:Permalink/" + ret.compare.torevid + "\">Revision after edit</a> " + " (<a href=\"/wiki/Special:Diff/" + ret.compare.fromrevid + "/" + ret.compare.torevid + "\">diff page</a>)" + " " +                               "<div id=\"mw-diff-ntitle3\"> <span class=\"comment\">Revision ID: " + ret.compare.torevid + "  " + // "<div id=\"mw-diff-ntitle5\"> " + " " +                       " " +                        " <td colspan=\"4\" class=\"diff-multi\" lang=\"" + language + "\">" + label.entityNote + "  "; divRender.find("#wikibench-entity-page-diff-table").append(diffTableHeader + diffTableTitle + diffTableContent + diffTableFooter); }).fail(function(e) { if (entityId.split("/")[0] === "false") { divRender.find("#wikibench-entity-page-diff-table").append(newPageBox.$element); }                       else { divRender.find("#wikibench-entity-page-diff-table").append(revdelBox.$element); }                   });                });            });        }    }); })(jQuery, mediaWiki);

// Plug-In /* (function ($, mw) {   $(document).ready(function { if(mw.config.get("wgDiffNewId") !== null) {

// init var wikibenchURL = "User:Tzusheng/sandbox/Wikipedia:Wikibench"; var campaignURL = "User:Tzusheng/sandbox/Wikipedia:Wikibench/Campaign:Editquality"; var entityType = "diff"; var entityPageSplit = "-"; var facets = ["editDamage", "userIntent"]; var facetNames = { editDamage: "edit damage", userIntent: "user intent" };           var facetHelp = { editDamage: "Please check the <a href=\"/wiki/" + campaignURL + "#Label_definitions\">campaign page</a> for the definition of edit damage. The optional checkbox on the right lets you specify that you provide the label with lower confidence when you're not so sure.", userIntent: "Please check the <a href=\"/wiki/" + campaignURL + "#Label_definitions\">campaign page</a> for the definition of user intent. The optional checkbox on the right lets you specify that you provide the label with lower confidence when you're not so sure." };           var facetLabels = { editDamage: ["damaging", "not damaging"], userIntent: ["bad faith", "good faith"] };           var facetIcons = { editDamage: ["alert", "success"], userIntent: ["alert", "success"] }           var successMessage = "Your submission has been recorded"; var warningMessage = "Your submission has been recorded but is different from the primary label"; // get config var mwApi = new mw.Api; var diffNewId = mw.config.get("wgDiffNewId"); var diffOldId = mw.config.get("wgDiffOldId"); var userName = mw.config.get("wgUserName"); var userId = mw.config.get("wgUserId"); var revisionId; // revision ID of the entity page, not the diff page var entityPageTitle = wikibenchURL + "/Entity:" + entityType.charAt(0).toUpperCase + entityType.slice(1) + "/" + diffOldId.toString + "/" + diffNewId.toString; var entityPageHeader = ""; var routingMessage = "You are welcome to review other Wikipedians' labels on the <a href=\"/wiki/" + entityPageTitle + "\">entity page of this " + entityType + "</a> or close this message for resubmission.";

// labels var primaryLabels = {}; var autolabeled = {}; var userLabels = {}; var userLowConfidences = {}; var userNotes = {};

// widgets var facetBtns = {}; var facetLowConfidenceCheckboxes = {}; var facetWidgets = {}; var facetNoteInputs = {}; // assume notes might be different var submitBtn; var submitMessage;

var getEntityPage = mwApi.get({ // get the entity page. if it doesn't exist, return revisionId = "-1"               action: "query",                prop: "revisions",                rvprop: "content",                titles: entityPageTitle,                format: "json"            });

var parseEntityPage = getEntityPage.then(function(ret) {               revisionId = Object.keys(ret.query.pages)[0];                if (revisionId !== "-1") { // the entity page already exists                                        var revisions = ret.query.pages;                    var pageId = Object.keys(revisions)[0];                    var entityPageContent = JSON.parse(revisions[pageId].revisions[0]["*"].split(entityPageSplit)[1]);                    facets.forEach(function(f) { primaryLabels[f] = entityPageContent.facets[f].primaryLabel.label; autolabeled[f] = entityPageContent.facets[f].primaryLabel.autolabeled; entityPageContent.facets[f].individualLabels.forEach(function(l) {                           if (userName === l.userName) {                                userLabels[f] = l.label;                                userLowConfidences[f] = l.lowConfidence;                                userNotes[f] = l.note;                            }                        }); });               }            });

var renderPlugIn = parseEntityPage.then(function {               mw.loader.using(["oojs-ui-core", "oojs-ui-widgets", "oojs-ui-windows"]).done(function{ facets.forEach(function(f) {                       facetBtns[f] = new OO.ui.ButtonSelectWidget({ items: [ new OO.ui.ButtonOptionWidget({                                   data: facetLabels[f][0],                                    label: facetLabels[f][0],                                    icon: facetIcons[f][0]                                }), new OO.ui.ButtonOptionWidget({                                   data: facetLabels[f][1],                                    label: facetLabels[f][1],                                    icon: facetIcons[f][1]                                }) ]                       });                        if (!$.isEmptyObject(userLabels)) {                            facetBtns[f].selectItemByLabel(userLabels[f]);                        }

facetBtns[f].on("choose", function(item){                           userLabels[f] = item.getData;                        });

facetLowConfidenceCheckboxes[f] = new OO.ui.CheckboxInputWidget;

if (!$.isEmptyObject(userLowConfidences[f])) { facetLowConfidenceCheckboxes[f].setSelected(userLowConfidences[f]); }

facetWidgets[f] = new OO.ui.Widget({                           content: [                                new OO.ui.HorizontalLayout({ items: [ facetBtns[f], facetLowConfidenceCheckboxes[f], new OO.ui.LabelWidget({label: "low confidence"}) ]                               })                            ]                        });

facetNoteInputs[f] = new OO.ui.TextInputWidget({});

if (!$.isEmptyObject(userNotes)){ facetNoteInputs[f].setValue(userNotes[f]); }                   });

submitBtn = new OO.ui.ButtonWidget({                       label: "Submit",                        flags: ["primary", "progressive"]                    });

submitMessage = new OO.ui.MessageWidget({                       showClose: true                    });

submitMessage.toggle(false);

var fieldset = new OO.ui.FieldsetLayout({                        label: new OO.ui.HtmlSnippet("Wikibench Plug-In"),                        id: "wikibench-diff-plugin",                        help: new OO.ui.HtmlSnippet("<a href=\"/wiki/" + campaignURL + "\">Editquality Campaign</a>"),                        helpInline: true                    });

// if user label already exists, compare it with the primary label and update submitMessage accordingly if (!$.isEmptyObject(userLabels)) { var isSameAsPrimary = true; if (!$.isEmptyObject(primaryLabels)) { // make sure the primary label exist facets.forEach(function(f) {                               if (userLabels[f] !== primaryLabels[f]) {                                    isSameAsPrimary = false;                                }                            }); }                       if (isSameAsPrimary) { submitMessage.setType("success"); submitMessage.setLabel(new OO.ui.HtmlSnippet(" " + successMessage + " " + " " + routingMessage)); }                       else { var primaryLabelMessage = "("                           for (var i = 0; i < facets.length; i++) {                                primaryLabelMessage += primaryLabels[facets[i]];                                primaryLabelMessage += ", ";                            }                            primaryLabelMessage = primaryLabelMessage.slice(0,-2) + ")"; submitMessage.setType("warning"); submitMessage.setLabel(new OO.ui.HtmlSnippet(" " + warningMessage + " " + primaryLabelMessage + " " + " " + routingMessage)); }                       submitMessage.toggle(true); submitBtn.setDisabled(true); submitBtn.toggle(false); }

// add all the widgets to feildset fieldset.addItems(                       new OO.ui.FieldLayout( new OO.ui.LabelWidget({label: diffOldId.toString + "/" + diffNewId.toString}), { label: "Diff IDs", align: "left" })                   );

for (var i = 0; i < facets.length; i++) { fieldset.addItems(                           new OO.ui.FieldLayout(facetWidgets[facets[i]], { label: facetNames[facets[i]].charAt(0).toUpperCase + facetNames[facets[i]].slice(1), align: "left", help: new OO.ui.HtmlSnippet(facetHelp[facets[i]]) })                       );                    }

for (var i = 0; i < facets.length; i++) { fieldset.addItems(                           new OO.ui.FieldLayout(facetNoteInputs[facets[i]], { label: "Note for " + facetNames[facets[i]].toLowerCase, align: "left", help: "An optional note that explains the labels you provide and, in case of low confidence, why so." })                       );                    }

fieldset.addItems([                       new OO.ui.FieldLayout(submitBtn, {}),                        new OO.ui.FieldLayout(submitMessage, {})                    ]);

//$("#mw-oldid").after(fieldset.$element); //$(".mw-revslider-container").after(fieldset.$element); $("#contentSub").after(fieldset.$element);

submitBtn.on("click", function {

// labels and user login are required for submission var isLabelUndefined = false; facets.forEach(function(f) {                           if (userLabels[f] === undefined) {                                isLabelUndefined = true;                            }                        }); if (isLabelUndefined) { OO.ui.alert("Labels are required for submission."); }                       else if (userName === null){ OO.ui.alert("User login is required for submission."); }                       else {

// TODO: consider autolabel here

mwApi.get({ // get primary label again in case there are any changes from others                               action: "query",                                prop: "revisions",                                rvprop: "content",                                titles: entityPageTitle,                                format: "json"                            }).done(function(ret) {                                var submitLabels = {};                                var submitContent;                                facets.forEach(function(f) { submitLabels[f] = { "userName": userName, "userId": userId, "label": userLabels[f], "note": facetNoteInputs[f].getValue, "origin": "wikibench-enwiki-diff-plugin", "created": new Date(new Date.getTime).toUTCString, "touched": new Date(new Date.getTime).toUTCString, "lowConfidence": facetLowConfidenceCheckboxes[f].isSelected, "category": [] }                               });                                if (Object.keys(ret.query.pages)[0] === "-1") { // entity page doesn't exist                                    submitContent = {                                        "entityType": entityType,                                        "entityId": diffOldId.toString + "/" + diffNewId.toString,                                        "entityNote": $("td.diff-multi").text,                                        "facets": {}                                    }                                    facets.forEach(function(f) { submitContent.facets[f] = {}; submitContent.facets[f]["primaryLabel"] = { "lastModifier": userName, "lastModifierId": userId, "label": userLabels[f], "touched": submitLabels[f].touched, "autolabeled": false };                                       submitContent.facets[f]["individualLabels"] = [submitLabels[f]]; });                               }                                else { // entity page already exists                                    var revisions = ret.query.pages;                                    var pageId = Object.keys(revisions)[0];                                    submitContent = JSON.parse(revisions[pageId].revisions[0]["*"].split(entityPageSplit)[1]);                                    for (var i = 0; i < facets.length; i++) {                                        var f = facets[i];                                        var isUserLabelExist = false;                                        primaryLabels[f] = submitContent.facets[f].primaryLabel.label; // get primary label again in case someone updates it in between                                        for (var j = 0; j < submitContent.facets[f].individualLabels.length; j++) {                                            if (submitContent.facets[f].individualLabels[j].userName === userName) { submitLabels[f].created = submitContent.facets[f].individualLabels[j].created; submitContent.facets[f].individualLabels[j] = submitLabels[f]; isUserLabelExist = true; break; }                                       }                                        if (isUserLabelExist && (submitContent.facets[f].individualLabels.length === 1) && (submitContent.facets[f].primaryLabel.lastModifier === userName)) { // allow changing the primary label from the plug-in if the user is the only laber submitter submitContent.facets[f]["primaryLabel"] = { "lastModifier": userName, "lastModifierId": userId, "label": userLabels[f], "touched": submitLabels[f].touched, "autolabeled": false };                                           primaryLabels[f] = submitContent.facets[f]["primaryLabel"].label; // update primary label for submitMessage }                                       if (!isUserLabelExist) { submitContent.facets[f]["individualLabels"].push(submitLabels[f]); }                                   }                                }

mwApi.postWithToken("csrf",{                                   action: "edit",                                    title: entityPageTitle,                                    section: 0,                                    text: entityPageHeader + "\n" + entityPageSplit + "\n" + JSON.stringify(submitContent),                                    summary: "Label submission from the Wikibench diff plug-in",                                }).done(function(result,jqXHR){

var isSameAsPrimary = true; if (!$.isEmptyObject(primaryLabels)) { // primary label already exist facets.forEach(function(f) {                                           if (userLabels[f] !== primaryLabels[f]) {                                                isSameAsPrimary = false;                                            }                                        }); }

if (isSameAsPrimary) { submitMessage.setType("success"); submitMessage.setLabel(new OO.ui.HtmlSnippet(" " + successMessage + " " + " " + routingMessage)); }                                   else { var primaryLabelMessage = "("                                       facets.forEach(function(f) { primaryLabelMessage += primaryLabels[f]; primaryLabelMessage += ", "; });                                       primaryLabelMessage = primaryLabelMessage.slice(0,-2) + ")"; submitMessage.setType("warning"); submitMessage.setLabel(new OO.ui.HtmlSnippet(" " + warningMessage + " " + primaryLabelMessage + " " + " " + routingMessage)); }                                   submitMessage.toggle(true); submitBtn.setDisabled(true); submitBtn.toggle(false);

}).fail(function(code,result){ if ( code === "http" ) { mw.log( "HTTP error: " + result.textStatus ); // result.xhr contains the jqXHR object } else if ( code === "ok-but-empty" ) { mw.log( "Got an empty response from the server" ); } else { mw.log( "API error: " + code ); }                               });                            });                         }                    });

submitMessage.on("close", function {                       submitMessage.toggle(false);                        submitBtn.setDisabled(false);                        submitBtn.toggle(true);                    }); });           });

$.when(renderPlugIn).done(function(data) {               //console.log("done");            }); }   }); })(jQuery, mediaWiki);

// Evaluation page

(function ($, mw) {   $(document).ready(function { var wgPageName = "User:Tzusheng/sandbox/Wikipedia:Wikibench/Evaluation:Editquality"; if (mw.config.get("wgPageName") === wgPageName && mw.config.get("wgAction") === "view") { mw.loader.using(["oojs-ui-core", "oojs-ui-widgets", "oojs-ui-windows"]).done(function {

// init var WIKIBENCH_PREFIX = "Tzusheng/sandbox/Wikipedia:Wikibench"; var WIKIBENCH_NAMESPACE = 2; var RATE_LIMIT = 10; var ROUND_PRECISION = 2; var entityType = "diff"; var language = "en"; var entityPageSplit = "-"; var facets = ["editDamage", "userIntent"]; var facetNames = { editDamage: "edit damage", userIntent: "user intent" };               var facetLabels = { editDamage: ["damaging", "not damaging"], userIntent: ["bad faith", "good faith"] };               var facetColors = { editDamage: ["#fee7e6", "#d5fdf4"], userIntent: ["#fee7e6", "#d5fdf4"] };               var mwApi = new mw.Api;

var tableDiv = $("#enwiki-evaluation-editquality"); var tbody = tableDiv.find("tbody");

var progressBar = new OO.ui.ProgressBarWidget( {                   progress: false                }); tableDiv.after(progressBar.$element); // var loadDataBtn = new OO.ui.ButtonWidget({               //     label: "Load " + RATE_LIMIT.toString + " more edits"                // });

var requestLimitMessage = new OO.ui.MessageWidget({                   type: "error",                    showClose: true,                    label: new OO.ui.HtmlSnippet("The table isn't loading due to rate limits imposed by ORES and LiftWing. Please try again later in a few seconds by refreshing your browser.")                }); requestLimitMessage.toggle(false); requestLimitMessage.on("close", function {                   requestLimitMessage.toggle(false);                    // loadDataBtn.toggle(true);                }); tableDiv.after(requestLimitMessage.$element);

var tableLabelColors = {}; for (var i = 0; i < facets.length; i++) { tableLabelColors[facets[i]] = {}; for (var j = 0; j < facetLabels[facets[i]].length; j++) { tableLabelColors[facets[i]][facetLabels[facets[i]][j]] = facetColors[facets[i]][j]; }               }                tableLabelColors["reverted"] = "#fee7e6"; tableLabelColors["not reverted"] = "#d5fdf4"; var probColors = "#72777d";

var tableRows = {}; // var revids = []; var promises = []; var liftwing = {}; var ores = {};

function calculateStandardDeviation(numbers) { // Step 1: Calculate the mean var sum = 0; for (var i = 0; i < numbers.length; i++) { sum += numbers[i]; }                   var mean = sum / numbers.length; // Step 2: Calculate the sum of squared differences var squaredDifferencesSum = 0; for (var j = 0; j < numbers.length; j++) { var difference = numbers[j] - mean; squaredDifferencesSum += difference * difference; }                   // Step 3: Calculate the variance var variance = squaredDifferencesSum / numbers.length; // Step 4: Calculate the standard deviation (square root of variance) var standardDeviation = Math.sqrt(variance); return standardDeviation; }

function sortColumn(columnId, order) { var header = tableDiv.find(columnId); if (order === "ascending") { if (header.attr("title") === "Sort ascending") { // note: title is not the current sorting state header.click; } else if (header.attr("title") === "Sort initial") { header.click.click; } else { // do nothing because the column is already ascending }                   } else if (order === "descending") { if (header.attr("title") === "Sort ascending") { header.click.click; } else if (header.attr("title") === "Sort descending") { header.click; } else { // do nothing because the column is already descending }                   } else { // do nothing }               }

var button1 = new OO.ui.ButtonWidget({label: "Wikibench and ORES"}); button1.on("click", function {                   sortColumn("#table-header-userIntent-ores", "descending");                    sortColumn("#table-header-editDamage-ores", "descending");                    sortColumn("#table-header-userIntent-wikibench", "descending");                    sortColumn("#table-header-editDamage-wikibench", "descending");                }); var button2 = new OO.ui.ButtonWidget({label: "Wikibench and LiftWing"}); button2.on("click", function {                   sortColumn("#table-header-reverted-liftwing", "descending");                    sortColumn("#table-header-userIntent-wikibench", "descending");                    sortColumn("#table-header-editDamage-wikibench", "descending");                }); var button3 = new OO.ui.ButtonWidget({label: "ORES and LiftWing"}); button3.on("click", function {                   sortColumn("#table-header-reverted-liftwing", "descending");                    sortColumn("#table-header-userIntent-ores", "descending");                    sortColumn("#table-header-editDamage-ores", "descending");                }); var layoutSortBtns = new OO.ui.HorizontalLayout({                   items: [                        new OO.ui.LabelWidget({ label: "I want to compare:" }),                        button1,                        button2,                        button3                    ]                }); tableDiv.before(layoutSortBtns.$element); layoutSortBtns.toggle(false);

function getPrefixedPages(entityType, queryContinue, deferred, results) { deferred = deferred || $.Deferred; queryContinue = queryContinue || {}; results = results || []; var prefix = WIKIBENCH_PREFIX + "/Entity:" + entityType.charAt(0).toUpperCase + entityType.slice(1) + "/"; var params = { action: "query", prop: "revisions", rvprop: "content", generator: "allpages", gapprefix: prefix, gaplimit: 500, gapnamespace: WIKIBENCH_NAMESPACE, format: "json", formatversion: 2 };

Object.assign(params, queryContinue)

mwApi.get(params) .done(function(data) {                           var pages = data.query.pages;                            pages.forEach(function(page){ if (page.revisions !== undefined) { page['content'] = page.revisions[0].content; delete page['revisions']; results.push(page); }                           });                            if(data.continue){                                getPrefixedPages(entityType, data.continue, deferred, results);                            }else{                                deferred.resolve(results);                            }                        }) .fail(function(e) {                           deferred.fail(e);                        });

return deferred.promise; }

getPrefixedPages(entityType).done(function(results) {

// tableDiv.after(loadDataBtn.$element);

function shuffle(array) { let currentIndex = array.length, randomIndex; // While there remain elements to shuffle. while (currentIndex != 0) { // Pick a remaining element. randomIndex = Math.floor(Math.random * currentIndex); currentIndex--; // And swap it with the current element. [array[currentIndex], array[randomIndex]] = [ array[randomIndex], array[currentIndex]]; }                       return array; }                   shuffle(results);

var startIndex = 0;

// loadDataBtn.on("click", function {

var renderCount = 0; var revids = [];

for (var i = startIndex; i < results.length; i++) { if (renderCount >= RATE_LIMIT) { break; }                           label = JSON.parse(results[i].content.split(entityPageSplit)[1]); if ((label.entityId.split("/")[0] !== "false") && (label.entityNote === "")) { // exclude new page and multiple changes var newId = label.entityId.split("/")[1]; tableRows[newId] = {}; tableRows[newId]["entityId"] = label.entityId; tableRows[newId]["wikibench"] = {} tableRows[newId]["ores"] = {}; facets.forEach(function(f) {                                   tableRows[newId]["wikibench"][f] = label.facets[f];                                }) revids.push(newId); var request1 = $.ajax({                                   url: 'https://api.wikimedia.org/service/lw/inference/v1/models/revertrisk-language-agnostic:predict',                                    crossDomain: true,                                    method: 'post',                                    contentType: 'application/x-www-form-urlencoded',                                    data: '{"rev_id":' + newId + ', "lang": "en"}'                                }).done( function ( result, textStatus, jqXHR ) {                                    liftwing[result.revision_id.toString] = result["output"];                                }); promises.push(request1);

// var request2 = $.ajax({                               //     url: "https://ores.wikimedia.org/v3/scores/enwiki",                                //     data: {                                //         "context": "enwiki",                                //         "models": "damaging|goodfaith",                                //         "revids": newId.toString                                //     },                                //     timeout: 30 * 1000, // 30 seconds                                //     dataType: "json",                                //     type: "GET"                                // }).done(function ( result, textStatus, jqXHR ){                                //     ores[Object.keys(result["enwiki"]["scores"])[0]] = Object.values(result["enwiki"]["scores"])[0]                                // }); // promises.push(request2); renderCount++; }                       }                        var request2 = $.ajax({                            url: "https://ores.wikimedia.org/v3/scores/enwiki",                            data: {                                "context": "enwiki",                                "models": "damaging|goodfaith",                                "revids": revids.join("|")                            },                            timeout: 30 * 1000, // 30 seconds                            dataType: "json",                            type: "GET"                        }).done(function ( result, textStatus, jqXHR ){                            for (var r = 0; r < revids.length; r++) {                                ores[revids[r].toString] = result["enwiki"]["scores"][revids[r].toString];                            }                        }); promises.push(request2);

$.when.apply(null, promises).done(function {                           if (startIndex === 0) {                                tbody.find("tr").remove; // remove the empty line                            }                            for (var r = 0; r < revids.length; r++) {                                var row = tableRows[revids[r]];                                var liftwing_prediction = liftwing[revids[r]]["prediction"] ? "reverted" : "not reverted";                                var ores_prediction_editDamage = ores[revids[r]]["damaging"]["score"]["prediction"] ? "damaging" : "not damaging";                                var ores_prediction_userIntent = ores[revids[r]]["goodfaith"]["score"]["prediction"] ? "good faith" : "bad faith";                                var individualLabels = {};                                // calculate wikibench agreement for (var i = 0; i < facets.length; i++) { var f = facets[i]; individualLabels[f] = []; for (var j = 0; j < row["wikibench"][f].individualLabels.length; j++) { // handle individual labels for disagreements var individualLabel = row["wikibench"][f].individualLabels[j]; if (individualLabel.label === facetLabels[f][0]) { if (individualLabel.lowConfidence) { individualLabels[f].push(-0.5); }                                           else { individualLabels[f].push(-1); }                                       }                                        if (individualLabel.label === facetLabels[f][1]) { if (individualLabel.lowConfidence) { individualLabels[f].push(0.5); }                                           else { individualLabels[f].push(1); }                                       }                                    }                                }

var hrefLink = "<a href=\"/wiki/User:" + WIKIBENCH_PREFIX + "/Entity:" + entityType.charAt(0).toUpperCase + entityType.slice(1) + "/" + row["entityId"] + "\"></a>"; tbody.append($(" ")                                   .append($(" ").text(row["entityId"]).wrapInner(hrefLink).attr("scope", "row"))                                    .append($(" ").html(row["wikibench"][facets[0]].primaryLabel.label + " <span style=\"color:" + probColors + "\">(" + (1 - calculateStandardDeviation(individualLabels[facets[0]])).toFixed(ROUND_PRECISION).toString + ") ").attr("bgcolor", tableLabelColors[facets[0]][row["wikibench"][facets[0]].primaryLabel.label]))                                    .append($(" ").html(ores_prediction_editDamage + " <span style=\"color:" + probColors + "\">(" + ores[revids[r]]["damaging"]["score"]["probability"][ores[revids[r]]["damaging"]["score"]["prediction"].toString].toFixed(ROUND_PRECISION).toString + ") ").attr("bgcolor", tableLabelColors[facets[0]][ores_prediction_editDamage]))                                    .append($(" ").html(row["wikibench"][facets[1]].primaryLabel.label + " <span style=\"color:" + probColors + "\">(" + (1 - calculateStandardDeviation(individualLabels[facets[1]])).toFixed(ROUND_PRECISION).toString + ") ").attr("bgcolor", tableLabelColors[facets[1]][row["wikibench"][facets[1]].primaryLabel.label])) .append($(" ").html(ores_prediction_userIntent + " <span style=\"color:" + probColors + "\">(" + ores[revids[r]]["goodfaith"]["score"]["probability"][ores[revids[r]]["goodfaith"]["score"]["prediction"].toString].toFixed(ROUND_PRECISION).toString + ") ").attr("bgcolor", tableLabelColors[facets[1]][ores_prediction_userIntent])) .append($(" ").html(liftwing_prediction + " <span style=\"color:" + probColors + "\">(" + liftwing[revids[r]]["probabilities"][liftwing[revids[r]]["prediction"].toString].toFixed(ROUND_PRECISION).toString + ") ").attr("bgcolor", tableLabelColors[liftwing_prediction])) );                           }                            progressBar.toggle(false);                            layoutSortBtns.toggle(true);                            startIndex += renderCount;                            requestLimitMessage.toggle(false);                        }).fail(function(e) {                            // loadDataBtn.toggle(false);                            requestLimitMessage.toggle(true);                            progressBar.toggle(false);                        }); // });               });            });        }    }); })(jQuery, mediaWiki);

// Import CSS mw.loader.load("//meta.wikimedia.org/w/index.php?title=User:Tzusheng/Wikibench.css&action=raw&ctype=text/css", 'text/css');

// QOL $.when( mw.loader.using( [ 'mediawiki.util' ] ), $.ready ).then( function {	mw.util.addPortletLink( 'p-personal', 'https://en.wikipedia.org/wiki/User:Tzusheng/sandbox/Wikipedia:Wikibench/Campaign:Editquality', 'Wikibench', 'pt-wikibench', 'wikibench', null, '#pt-preferences' ); } );

//