Wikipedia:WikiProject National Register of Historic Places/Progress/NRISonly.js

var wikitext = 'error' var NRISOnlyStructure=[]; // NRISOnlyStructure[table][row]["Titles"][item].StatName to get info var TotalToQuery=0; var TotalQueried=0; var OutputBase = "User:NationalRegisterBot/AllNRHPPages" var ErrorCount=0; var WarningCount="",0; // 0=status, 1=count var InitialTime=0; var ProgressDivTimer=0 // timer for updating ProgressDiv var DefaultQueryPause=1 // number of milliseconds to wait between each API query; increased by code if rate limit reached

function CheckPermission { if (mw.user.getName!="NationalRegisterBot"&&mw.user.getName!="Dudemanfellabra") { alert("Only NationalRegisterBot has been authorized to use the NRIS-only script!") return } else { NRISOnlyButtons } }

function NRISOnlyButtons { var pageName=mw.config.get('wgPageName') var button=document.createElement("input") button.setAttribute("type", "button"); button.setAttribute("id", "nrisonlybutton"); var content=document.getElementById('mw-content-text')

if (location.href.indexOf('action')==-1) { if (pageName=="Wikipedia:WikiProject_National_Register_of_Historic_Places/Progress") { button.setAttribute("value", "Update list for NationalRegisterBot"); button.setAttribute("onclick", "NRISOnlyClicked('update')"); } else if (pageName=="User:NationalRegisterBot/AllNRHPPages/Duplications") { button.setAttribute("value", "Gather duplicate stats"); button.setAttribute("onclick", "NRISOnlyClicked('duplicate')"); } else if (pageName=="User:NationalRegisterBot/NRISOnly") { button.setAttribute("value", "Tag these articles"); button.setAttribute("onclick", "NRISOnlyClicked('tag')"); } else { return; }       content.parentNode.insertBefore(button, content) } }

function NRISOnlyClicked(action) { // after button is clicked, disable it and perform action var nrisonlybutton = document.getElementById('nrisonlybutton') nrisonlybutton.disabled = true var ProgressDiv = document.createElement("div") ProgressDiv.setAttribute("id", "ProgressDiv") ProgressDiv.setAttribute("style", "width:600px; border:1px solid black; padding:5px; background:#ffffff") nrisonlybutton.parentNode.insertBefore(ProgressDiv, nrisonlybutton)

if (action=="update") { ProgressDiv.innerHTML = "Initializing..." getNRISOnlyProgressPageWikitext(mw.config.get('wgPageName')) // after wikitext fetched, SetupNRISOnlyTables is called } else if (action=="duplicate") { CheckDuplicates; } else if (action=="tag") { TagNRISOnly; } }

// create array of table structure to be populated later function SetupNRISOnlyTables { var table=document.getElementsByClassName('wikitable sortable');

// extract list names from Progress page for (var i=1; i<table.length; i++) { // skip national table var tr=table[i].getElementsByTagName("tr") NRISOnlyStructure[i-1]=[]; var skipOffset=1 // number of duplicate/skippable rows encountered so far for (var j=1; j<tr.length-2; j++) { // skip title row, statewide duplicates, and totals row var td=tr[j].getElementsByTagName("td") // fill in existing data in case error var link=td[1].getElementsByTagName("a") if (link.length!=0 && link[0].href.search("#")==-1) { NRISOnlyStructure[i-1][j-skipOffset]={}; NRISOnlyStructure[i-1][j-skipOffset].Titles=[]; // Placeholder for article names

link=decodeURI(link[0].href).split("/") link=link[link.length-1].replace(/_/g," ") NRISOnlyStructure[i-1][j-skipOffset].Link=link

NRISOnlyStructure[i-1][j-skipOffset].ID=td[0].innerHTML.substr(0,5) // for finding empty counties

NRISOnlyStructure[i-1][j-skipOffset].CatsQueried=0 // for querying later NRISOnlyStructure[i-1][j-skipOffset].TotalToCheck=0 NRISOnlyStructure[i-1][j-skipOffset].TotalChecked=0 } else { // must be a duplicate row skipOffset++ }       }    }    for (var i=0; i<NRISOnlyStructure.length; i++) { // count total number of lists to check TotalToQuery+=NRISOnlyStructure[i].length }

var ProgressDiv=document.getElementById("ProgressDiv") ProgressDiv.innerHTML+=" Done! "

var ProgressSpan=document.createElement("span") ProgressSpan.setAttribute("id", "ProgressSpan") ProgressDiv.appendChild(ProgressSpan) ProgressSpan.innerHTML = "Querying articles in each list... 0 (0%) of "+TotalToQuery+" lists complete."

var TimeSpan=document.createElement("span") TimeSpan.setAttribute("id", "TimeSpan") ProgressDiv.appendChild(TimeSpan) TimeSpan.innerHTML = ""

var EditSpan=document.createElement("span") EditSpan.setAttribute("id", "EditSpan") ProgressDiv.appendChild(EditSpan) EditSpan.innerHTML = ""

InitialTime=new Date // record starting time UpdateNRISOnlyProgressDiv; LoadNRISOnlyList(0,0); // begin querying first page }

// load next list to query function LoadNRISOnlyList(currentTable,currentRow) { // check if we need to go to the next table if (currentRow>NRISOnlyStructure[currentTable].length-1) { currentRow=0 currentTable++ }   // check if there are no more tables if (currentTable>NRISOnlyStructure.length-1) return;

setTimeout(function{ // short delay to prevent API overload       getNRISOnlyListWikitext(currentTable,currentRow);        LoadNRISOnlyList(currentTable,currentRow+1);    }, DefaultQueryPause); return; }

function NRISOnlyWikitextFetched(ajaxResponse,status,currentTable,currentRow) { if (status!="success") { NewNRISOnlyWarning("Wikitext "+ajaxResponse.errorThrown) setTimeout(function{ // try again after delay if rate limit reached           getNRISOnlyListWikitext(currentTable,currentRow);        }, 250); return; }   // won't get here unless successful var responseText=JSON.parse(ajaxResponse.responseText) var pagetext=responseText.query.pages[responseText.query.pageids[0]].revisions[0]["*"] if (responseText.query.redirects) { // if redirect, find section var SectionName="Undefined" for (var r in responseText.query.redirects) { if (typeof responseText.query.redirects[r].tofragment!="undefined") SectionName=responseText.query.redirects[r].tofragment.replace(/.27/g,"'") }

var regex = new RegExp("=[ ]*(\\[\\[(.*?\\|)?[ ]*)?"+SectionName+"([ ]*\\]\\])?[ ]*=", "g") var sectionheader=pagetext.match(regex) if (sectionheader == null) { // if no section found, check if one of known empty counties var EmptyCounties=["02270", "12067", "42023", "48017", "48023", "48033", "48069", "48075", "48079", "48083", "48103", "48107", "48119", "48131", "48155", "48165", "48195", "48207", "48219", "48247", "48269", "48279", "48341", "48369", "48389", "48415", "48421", "48431", "48433", "48437", "48445", "48461", "48475", "48501", "51735"]

var ID = NRISOnlyStructure[currentTable][currentRow].ID           var errorcode = 0 for (var k=0; k1) { // if still can't find a table or find multiple tables, fatal error NRISOnlyFatalError(0,currentTable,currentRow) return; }       }        var StartIndex=pagetext.indexOf(sectionheader[0]) var sectiontext=pagetext.substr(StartIndex,pagetext.indexOf("\n==",StartIndex)-StartIndex) // only look at relevant section

StartIndex=sectiontext.indexOf("{{NRHP header") if (StartIndex==-1) { if (sectiontext.indexOf("{{NRHP row")!=-1) { NRISOnlyFatalError(2,currentTable,currentRow) // incorrectly formatted table return; } else { // must be an empty county TotalQueried++ if (TotalQueried==TotalToQuery) DoneQueryingNRIS return; }       }        var tabletext=sectiontext.substr(StartIndex,sectiontext.indexOf("\n|}",StartIndex)-StartIndex) } else { // if not a redirect, default to first table on page var StartIndex=pagetext.indexOf("{{NRHP header") if (StartIndex==-1) { NRISOnlyFatalError(1,currentTable,currentRow) // no list found return; }       var tabletext=pagetext.substr(StartIndex,pagetext.indexOf("\n|}",StartIndex)-StartIndex) }

// now that tabletext has only relevant table, extract rows var Rows=[] var str = "{{" var start=0 var commentstart=0 while (true) { commentstart=tabletext.indexOf("",commentstart) commentstart=tabletext.indexOf("<!--",start) start=tabletext.indexOf(str,start) }       if (start==-1) break var open=1 var index=start+str.length while (open!=0 && index<tabletext.length) { // make sure to find correct matching close brackets for row template if (tabletext.substr(index,2)=="}}") { open-- index++ } else if (tabletext.substr(index,2)=="{{") { open++ index++ }           index++ }       var template=tabletext.substr(start,index-start) var regex = new RegExp("{{[\\s]*NRHP row(\\s)*\\|", "g") if (template.match(regex)!=null) Rows.push(template) // make sure it's the row template and not some other one start++ }   for (var i=0; i((?!<[ ]*?/[ ]*?(nowiki|pre)[ ]*?>)(.|\\n))*?"+Rows[i].replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")+"(.|\\n)*?<[ ]*?/[ ]*?(nowiki|pre)[ ]*?>", "g") if (tabletext.match(regex)!=null) {Rows.splice(i,1); i--} }

for (var i=0; i<Rows.length; i++) { // extract titles for querying var ThisRow=Rows[i]

var article=ThisRow.match(/\|[ ]*?article[ ]*?=[ ]*?.*?[\n|\|]/g) var blank=ThisRow.match(/\|[ ]*?article[ ]*?=[ ]*?[\n|\|]/g)                              // default to name param if article if (article==null||blank!=null) article=ThisRow.match(/\|[ ]*?name[ ]*?=[ ]*?.*?[\n|\|]/g) // blank or missing // strip param name, final line break article=article[0].replace(/\|[ ]*?(article|name)[ ]*?=[ ]*?/g,"").replace(/[\n|\|]/g,"").replace(/\<\!\-\-(.|[\r\n])*?\-\-\>/g,"").trim article=decodeURIComponent(article.split("#")[0].trim)    // corrections for weird titles

var refnum=ThisRow.match(/[0-9]{8}/g) // also extract refnums if (refnum!=null) { if (refnum[0]=="98000562"||refnum[0]=="98000563") refnum[0]="98000562,98000563"  // hard-code troublesome if (refnum[0]=="01000363"||refnum[0]=="01000364") refnum[0]="01000363,01000364"  // multistate duplicates if (refnum[0]=="02000529"||refnum[0]=="02000530") refnum[0]="02000529,02000530"  // ... refnum=refnum[0] } else { refnum="missing" }

var temp=NRISOnlyStructure[currentTable][currentRow].Titles temp[temp.length]={"name":article, "refnum":refnum, "exists":true, "isDab":false, "isTaggedNRISOnly":false, "isNRISOnly":false, "proseSize":0, "numberRefs":0} NRISOnlyStructure[currentTable][currentRow].Titles=temp }

var StartIndex=0 LoadNextNRISOnlyListQuery(StartIndex,currentTable,currentRow) return; }

// ready next batch of articles to query function LoadNextNRISOnlyListQuery(StartIndex,currentTable,currentRow) { if (StartIndex==NRISOnlyStructure[currentTable][currentRow].Titles.length) { // all queries begun for this list return; }   // must have some more rows to query if (NRISOnlyStructure[currentTable][currentRow].Titles.length-StartIndex>50) { var TempTitles=NRISOnlyStructure[currentTable][currentRow].Titles.slice(StartIndex,StartIndex+50) } else { var TempTitles=NRISOnlyStructure[currentTable][currentRow].Titles.slice(StartIndex) }

for (var i=0; i<TempTitles.length; i++) { // only extract article names TempTitles[i]=TempTitles[i].name }

StartIndex+=TempTitles.length setTimeout(function{ // short delay to prevent API overload       QueryNRISOnlyCats(TempTitles,StartIndex,currentTable,currentRow)        LoadNextNRISOnlyListQuery(StartIndex,currentTable,currentRow)    }, DefaultQueryPause); return; }

// query next batch of articles function QueryNRISOnlyCats(TempTitles,StartIndex,currentTable,currentRow) { var TitleList=TempTitles.join("|") $.ajax({       dataType: "json",        url: mw.util.wikiScript('api'),        data: {            format: 'json',            action: 'query',            prop: 'categories',            clcategories: 'Category:All disambiguation pages|Category:All articles sourced only to NRIS',            cllimit: 'max',            titles: TitleList,            redirects: 'true'        },        error: function(ArticlejsonObject,status,errorThrown) {ArticlejsonObject.errorThrown=errorThrown},        complete: function(ArticlejsonObject,status) {                NRISOnlyCatsChecked(ArticlejsonObject,status,TempTitles,StartIndex,currentTable,currentRow)            }    }); return; }

// parse API response for article query function NRISOnlyCatsChecked(ArticlejsonObject,status,TempTitles,StartIndex,currentTable,currentRow) { if (status!="success") { NewNRISOnlyWarning("Articles "+ArticlejsonObject.errorThrown)

setTimeout(function{ // try again after delay if rate limit reached           QueryNRISOnlyCats(TempTitles,StartIndex,currentTable,currentRow)        }, 250); return; }   // won't get here unless successful NRISOnlyStructure[currentTable][currentRow].CatsQueried+=TempTitles.length

var responseText=JSON.parse(ArticlejsonObject.responseText) if (responseText.query.normalized) { // normalize any weird titles for (var n in responseText.query.normalized) { for (var i=0; i<TempTitles.length; i++) { if (TempTitles[i]==responseText.query.normalized[n].from) TempTitles[i]=responseText.query.normalized[n].to           } for (var i=0; i<NRISOnlyStructure[currentTable][currentRow].Titles.length; i++) { // also update in main data array if (NRISOnlyStructure[currentTable][currentRow].Titles[i].name==responseText.query.normalized[n].from) { NRISOnlyStructure[currentTable][currentRow].Titles[i].name=responseText.query.normalized[n].to               } }       }    }    if (responseText.query.redirects) { // resolve any redirects also for (var r in responseText.query.redirects) { for (var i=0; i<TempTitles.length; i++) { if (TempTitles[i]==responseText.query.redirects[r].from) TempTitles[i]=responseText.query.redirects[r].to           } for (var i=0; i<NRISOnlyStructure[currentTable][currentRow].Titles.length; i++) { // also update in main data array if (NRISOnlyStructure[currentTable][currentRow].Titles[i].name==responseText.query.redirects[r].from) { NRISOnlyStructure[currentTable][currentRow].Titles[i].name=responseText.query.redirects[r].to               } }       }    }

// now determine if dab/NRIS-only for (var page in responseText.query.pages) { var pagetitle=responseText.query.pages[page].title // mark as redlink if (typeof responseText.query.pages[page].missing!="undefined") { for (var i=0; i<NRISOnlyStructure[currentTable][currentRow].Titles.length; i++) { if (NRISOnlyStructure[currentTable][currentRow].Titles[i].name==pagetitle) { NRISOnlyStructure[currentTable][currentRow].Titles[i].exists=false }           }        }        if (responseText.query.pages[page].categories) { for (var category in responseText.query.pages[page].categories) { // mark as link to dab if (responseText.query.pages[page].categories[category].title=="Category:All disambiguation pages") { for (var i=0; i<NRISOnlyStructure[currentTable][currentRow].Titles.length; i++) { if (NRISOnlyStructure[currentTable][currentRow].Titles[i].name==pagetitle) { NRISOnlyStructure[currentTable][currentRow].Titles[i].exists=false // dab=redlink NRISOnlyStructure[currentTable][currentRow].Titles[i].isDab=true }                   }                }                // mark already tagged NRIS-only if (responseText.query.pages[page].categories[category].title.indexOf("sourced only to NRIS")!=-1) { for (var i=0; i<NRISOnlyStructure[currentTable][currentRow].Titles.length; i++) { if (NRISOnlyStructure[currentTable][currentRow].Titles[i].name==pagetitle) { NRISOnlyStructure[currentTable][currentRow].Titles[i].isTaggedNRISOnly=true }                   }                }            }        }    }

if (NRISOnlyStructure[currentTable][currentRow].CatsQueried==NRISOnlyStructure[currentTable][currentRow].Titles.length) { var Titles=[]; for (var i=0; i<NRISOnlyStructure[currentTable][currentRow].Titles.length; i++) { // tally up articles to query if (NRISOnlyStructure[currentTable][currentRow].Titles[i].exists) { Titles.push(NRISOnlyStructure[currentTable][currentRow].Titles[i].name) NRISOnlyStructure[currentTable][currentRow].TotalToCheck++ }       }        // now begin querying article content and checking if NRIS-only StartIndex=0 LoadNextNRISOnlyPageQuery(Titles,StartIndex,currentTable,currentRow) } }

// load each existing page to check if it should be tagged NRIS-only function LoadNextNRISOnlyPageQuery(Titles,StartIndex,currentTable,currentRow) { if (StartIndex==Titles.length) { // all queries begun for this list if (Titles.length==0) { // some lists have no bluelinks TotalQueried++ if (TotalQueried==TotalToQuery) DoneQueryingNRIS }       return; }   // must have some more rows to query setTimeout(function{ // short delay to prevent API overload       QueryNextNRISOnlyPage(Titles,StartIndex,currentTable,currentRow)        StartIndex++        LoadNextNRISOnlyPageQuery(Titles,StartIndex,currentTable,currentRow)    }, DefaultQueryPause); return; }

// query the next page function QueryNextNRISOnlyPage(Titles,StartIndex,currentTable,currentRow) { $.ajax({       dataType: "json",        url: mw.util.wikiScript('api'),        data: {            format: 'json',            action: 'query',            prop: 'revisions',            rvprop: 'content',            titles: Titles[StartIndex],            indexpageids: true,            redirects: 'true'        },        error: function(ajaxResponse,status,errorThrown) {ajaxResponse.errorThrown=errorThrown},        complete: function(ajaxResponse,status) {            NRISOnlyPageWikitextFetched(ajaxResponse,status,Titles,StartIndex,currentTable,currentRow)        }    }) return; }

// parse API response for page wikitext function NRISOnlyPageWikitextFetched(ajaxResponse,status,Titles,StartIndex,currentTable,currentRow) { if (status!="success") { NewNRISOnlyWarning("Articles wikitext "+ajaxResponse.errorThrown)

setTimeout(function{ // try again after delay if rate limit reached           QueryNextNRISOnlyPage(Titles,StartIndex,currentTable,currentRow)        }, 250); return; }   // won't get here unless successful NRISOnlyStructure[currentTable][currentRow].TotalChecked++

// now determine prose size, number of references, etc.   var responseText=JSON.parse(ajaxResponse.responseText) for (var page in responseText.query.pages) { var pagetext = responseText.query.pages[page].revisions[0]['*'];

var prose=pagetext.replace(/\<\!\-\-(.|[\r\n])*?\-\-\>/g,"")                       // strip comments prose=prose.replace(/\/gi,"")          // strip refs prose=prose.replace(/==[ ]*?External links[ ]*?==(.|\n)*?(?=(==.*?==|$))/gi,"")    // strip external links section prose=prose.replace(/==[ ]*?See also[ ]*?==(.|\n)*?(?=(==.*?==|$))/gi,"")          // strip see also section prose=prose.replace(/==[ ]*?(References|Notes)[ ]*?==(.|\n)*?(?=(==.*?==|$))/gi,"") // strip references section // strip further reading section prose=prose.replace(/==[ ]*?(Further|Additional) reading[ ]*?==(.|\n)*?(?=(==.*?==|$))/gi,"") prose=prose.replace(/={2,5}.*?={2,5}/g,"")                                         // strip section titles // replace wikilinks with displayed text prose=prose.replace(/\\]/gi,"$2") prose=prose.replace(/\[[ ]*?http.*? (.*?)\]/g,"$1")                // replace inline external links with displayed text        prose=prose.replace(/'{2,5}(.*?)'{2,5}/g,"$1")                      // replace bold/italic with displayed text        prose=prose.replace(/\[\[[ ]*?Category:.*?\]\]/g,"")                                // strip categories        prose=prose.replace(/\[\[[ ]*?(Image|File):.*?\]\]/g,"")                            // strip images        prose=prose.replace(/\<[ ]*?gallery(.|\n)*?\<[ ]*?\/[ ]*?gallery[ ]*?\>/gi,"")      // strip galleries        while(true) {                                                                       // strip templates            var str="{{"            var start=prose.indexOf(str)            if (start==-1) break            var open=1            var index=start+str.length            while (open!=0 && index<prose.length) {                if (prose.substr(index,2)=="}}") {                    open--                    index++                } else if (prose.substr(index,2)=="{{") {                    open++                    index++                }                index++            }            prose=prose.replace(prose.substr(start,index-start),"")        }        prose=prose.replace(/{\|(.|\n)*?\|}/g,"")                   // strip tables        prose=prose.replace(/ /g," ")                          // replace nbsp with regular space        prose=prose.replace(/<[ ]*?br.*?>/g, "\n")                  // replace HTML line break with string line break        prose=prose.replace(/[ \n]+/g," ")                          // replace multiple spaces/linebreaks with single space        prose=prose.trim

for (var i=0; i<NRISOnlyStructure[currentTable][currentRow].Titles.length; i++) { // record prose size if (NRISOnlyStructure[currentTable][currentRow].Titles[i].name==Titles[StartIndex]) { NRISOnlyStructure[currentTable][currentRow].Titles[i].proseSize=prose.length }       }

var hasSpecialRefs=0 if (pagetext.indexOf("{{GR")!=-1||pagetext.indexOf("{{sfn")!=-1||pagetext.indexOf("{{Sfn")!=-1) { // these count as refs hasSpecialRefs=pagetext.match(/{{[ ]*(GR|sfn|Sfn)/g).length }

var Refs=pagetext.match(/\/gi) var comments=pagetext.match(/\<\!\-\-(.|[\r\n])*?\-\-\>/g)

if (Refs==null) { // if no refs, skip page (default numberRefs=0) if (hasSpecialRefs==0) continue; Refs=[] }

if (comments!=null) { for (var l=0; l/gi) if (CommentedRefs==null) continue for (var m=0; m<CommentedRefs.length; m++) { for (var n=0; n<Refs.length; n++) { if (Refs[n]==CommentedRefs[m]) {Refs.splice(n,1); n--} }               }            }        }

if (Refs.length==0) { // if all refs commented out, skip page (default numberRefs=0) if (hasSpecialRefs==0) continue; }

var citesNRIS=false for (var l=0; l)/gi) if (nameOfRef==null) { continue } else { nameOfRef = nameOfRef[0].replace(/("| )/g,'')               nameOfRef = nameOfRef.substr(5,nameOfRef.length-6)            }            namedRefs.push(nameOfRef)        }

var Duplicates=0 for (var l=0; l0) DistinctRefs+=hasSpecialRefs

for (var i=0; i1) continue; // not NRIS-only if more than one ref

if (citesNRIS&&DistinctRefs==1) { // if one ref and is NRIS-only, then tag for (var i=0; i<NRISOnlyStructure[currentTable][currentRow].Titles.length; i++) { // record number of refs if (NRISOnlyStructure[currentTable][currentRow].Titles[i].name==Titles[StartIndex]) { NRISOnlyStructure[currentTable][currentRow].Titles[i].isNRISOnly=true }           }        }    }

if (NRISOnlyStructure[currentTable][currentRow].TotalChecked==NRISOnlyStructure[currentTable][currentRow].TotalToCheck) { TotalQueried++ if (TotalQueried==TotalToQuery) DoneQueryingNRIS return; } }

// keep track of warnings encountered while querying API function NewNRISOnlyWarning(warning) { var NewWarning=true for (var i=0; i<WarningCount.length; i++) { // check if already encountered error if (warning==WarningCount[i][0]||WarningCount[i][0]=="") {WarningCount[i][0]=warning; WarningCount[i][1]++; NewWarning=false;} }   if (NewWarning) WarningCount[WarningCount.length]=[warning,1] // if new warning, make new entry

var test=0 for (var i=0; i<WarningCount.length; i++) { test+=WarningCount[i][1] }   if (test%50==0) DefaultQueryPause++ // for every 50 errors encountered, increase time between each query to throttle speed }

// these errors require user input; can't just be ignored function NRISOnlyFatalError(code,currentTable,currentRow) { var errorArray = ['No county section found for ','No list found for ','Incorrectly formatted list for '] var retry=confirm(errorArray[code]+NRISOnlyStructure[currentTable][currentRow].Link+"!\n\nCancel=Skip                  OK=Retry") if (retry) { getNRISOnlyListWikitext(currentTable,currentRow); } else { // if chose to skip, add one to error count TotalQueried++ ErrorCount++ if (TotalQueried==TotalToQuery) DoneQueryingNRIS }   return; }

// update ProgressDiv to let user know what's going on function UpdateNRISOnlyProgressDiv { var ProgressSpan=document.getElementById("ProgressSpan") var TimeSpan=document.getElementById("TimeSpan")

var PercentQueried=Math.round(TotalQueried/TotalToQuery*1000)/10 ProgressSpan.innerHTML = "Querying articles in each list... "+TotalQueried+" ("+PercentQueried+"%) of "+TotalToQuery+" lists complete."

if (TotalQueried>100) { var CurrentTime=new Date var SecondsElapsed = (CurrentTime-InitialTime)/1000 var Average = SecondsElapsed/TotalQueried SecondsElapsed=Math.round(SecondsElapsed) var MinutesElapsed = 0 while (SecondsElapsed>=60) { SecondsElapsed-=60 MinutesElapsed++ }       var SecondsRemaining = Math.round(Average*(TotalToQuery-TotalQueried)) var MinutesRemaining = 0 while (SecondsRemaining>=60) { SecondsRemaining-=60 MinutesRemaining++ }

var TimeRemainingStr = "" if (MinutesRemaining!=0) TimeRemainingStr=MinutesRemaining+" min " TimeRemainingStr+=SecondsRemaining+" sec" var TimeElapsedStr = "" if (MinutesElapsed!=0) TimeElapsedStr=MinutesElapsed+" min " TimeElapsedStr+=SecondsElapsed+" sec" TimeRemainingStr+=" ("+TimeElapsedStr+" elapsed)" } else { var TimeRemainingStr="Calculating..." }   TimeSpan.innerHTML=" Estimated time remaining: "+TimeRemainingStr

if (TotalQueried!=TotalToQuery) { // update ProgressDiv only at regular intervals to prevent CPU overload; stop once done ProgressDivTimer=setTimeout(function{           UpdateNRISOnlyProgressDiv;        }, 500); }   return; }

// get here once done querying everything function DoneQueryingNRIS { clearTimeout(ProgressDivTimer) var ProgressSpan=document.getElementById("ProgressSpan") var TimeSpan=document.getElementById("TimeSpan")

var CurrentTime=new Date var SecondsElapsed = (CurrentTime-InitialTime)/1000 SecondsElapsed=Math.round(SecondsElapsed) var MinutesElapsed = 0 while (SecondsElapsed>=60) { SecondsElapsed-=60 MinutesElapsed++ }   var TimeStr=" Time elapsed: " if (MinutesElapsed!=0) TimeStr+=MinutesElapsed+" min " TimeStr+=SecondsElapsed+" sec"

ProgressSpan.innerHTML="Querying articles in each list... Done!"+TimeStr

TimeSpan.innerHTML=" Compiling data (this could take a while)... "

setTimeout(function {CalculateNRISOnlyTotals},100); // small delay for non-Firefox browsers to update screen }

// now compile all the data function CalculateNRISOnlyTotals { var StartTime=new Date // for calculating computation time

var AllTitles = [];            // [name,refnum,list] - includes redlinks; used to find duplicates later

var Dabs = [];                 // [name,list] var MissingRefnum = [];        // [name,list] var ExistingTitles = [];       // name               - only bluelinks

var ToBeTagged = [];           // name var ToBeUntagged = [];         // name

var AllNRISOnly = [];          // name               - includes manually tagged articles var OneRefNotNRIS = [];        // name var Unreferenced = [];         // name

var ShortNRIS = [];            // [name,length]      - NRIS-only with <325 bytes prose var ShortNotNRIS = [];         // [name,length]      - not NRIS-only with <325 bytes prose var LongNRIS = [];             // [name,length]      - NRIS-only with >=325 bytes prose

var WorstNotNRIS = [];         // [name,length]      - 100 smallest non-NRIS-only var WorstNRIS = [];            // [name,length]      - 100 smallest NRIS-only

var Duplications = [];         // [name,refnum,[list1,..listn]]

for (var table=0; table<NRISOnlyStructure.length; table++) { for (var row=0; row<NRISOnlyStructure[table].length; row++) { for (var item=0; item<NRISOnlyStructure[table][row].Titles.length; item++) { var thisItem=NRISOnlyStructure[table][row].Titles[item] if (thisItem.refnum=="missing") { MissingRefnum[MissingRefnum.length]=[thisItem.name,NRISOnlyStructure[table][row].Link] } else { AllTitles[AllTitles.length]=[thisItem.name,thisItem.refnum,NRISOnlyStructure[table][row].Link] }               if (thisItem.isDab) Dabs[Dabs.length]=[thisItem.name,NRISOnlyStructure[table][row].Link] if (!thisItem.exists) continue; // if redlink, no longer care about it

// now no longer have to check for existence ExistingTitles.push(thisItem.name)

// tagging if (thisItem.isNRISOnly&&!thisItem.isTaggedNRISOnly) ToBeTagged.push(thisItem.name) // only untag if more than one ref; sometimes tag is added manually to NRIS mirrors if (!thisItem.isNRISOnly&&thisItem.isTaggedNRISOnly&&thisItem.numberRefs>1) ToBeUntagged.push(thisItem.name)

// referencing if (thisItem.isNRISOnly||(!thisItem.isNRISOnly&&thisItem.isTaggedNRISOnly&&thisItem.numberRefs<=1)) { // also include manually tagged in output AllNRISOnly.push(thisItem.name) }               if (!thisItem.isNRISOnly&&thisItem.numberRefs==1) OneRefNotNRIS.push(thisItem.name) if (thisItem.numberRefs==0) Unreferenced.push(thisItem.name)

// prose length if (thisItem.proseSize<325&thisItem.isNRISOnly) ShortNRIS[ShortNRIS.length]=[thisItem.name,thisItem.proseSize] if (thisItem.proseSize<325&!thisItem.isNRISOnly) ShortNotNRIS[ShortNotNRIS.length]=[thisItem.name,thisItem.proseSize] if (thisItem.proseSize>=325&thisItem.isNRISOnly) LongNRIS[LongNRIS.length]=[thisItem.name,thisItem.proseSize] }       }    }

// remove duplicates for (var i=0;i<ExistingTitles.length; i++) { for (var j=i+1;j<ExistingTitles.length; j++) { if (ExistingTitles[i]==ExistingTitles[j]) {ExistingTitles.splice(j,1);j--} }   }    for (var i=0;i<ToBeTagged.length; i++) { for (var j=i+1;j<ToBeTagged.length; j++) { if (ToBeTagged[i]==ToBeTagged[j]) {ToBeTagged.splice(j,1);j--} }   }    for (var i=0;i<ToBeUntagged.length; i++) { for (var j=i+1;j<ToBeUntagged.length; j++) { if (ToBeUntagged[i]==ToBeUntagged[j]) {ToBeUntagged.splice(j,1);j--} }   }    for (var i=0;i<AllNRISOnly.length; i++) { for (var j=i+1;j<AllNRISOnly.length; j++) { if (AllNRISOnly[i]==AllNRISOnly[j]) {AllNRISOnly.splice(j,1);j--} }   }    for (var i=0;i<OneRefNotNRIS.length; i++) { for (var j=i+1;j<OneRefNotNRIS.length; j++) { if (OneRefNotNRIS[i]==OneRefNotNRIS[j]) {OneRefNotNRIS.splice(j,1);j--} }   }    for (var i=0;i<Unreferenced.length; i++) { for (var j=i+1;j<Unreferenced.length; j++) { if (Unreferenced[i]==Unreferenced[j]) {Unreferenced.splice(j,1);j--} }   }    for (var i=0;i<ShortNRIS.length; i++) { for (var j=i+1;j<ShortNRIS.length; j++) { if (ShortNRIS[i][0]==ShortNRIS[j][0]) {ShortNRIS.splice(j,1);j--} }   }    for (var i=0;i b[1]) return 1; return 0;}) ShortNotNRIS.sort(function(a,b){if (a[1] < b[1]) return -1; if (a[1] > b[1]) return 1; return 0;}) // extract worst WorstNRIS=ShortNRIS.slice(0,100) WorstNotNRIS=ShortNotNRIS.slice(0,100) // now sort by name ShortNRIS.sort(function(a,b){if (a[0] < b[0]) return -1; if (a[0] > b[0]) return 1; return 0;}) ShortNotNRIS.sort(function(a,b){if (a[0] < b[0]) return -1; if (a[0] > b[0]) return 1; return 0;})

// sort the other arrays by name LongNRIS.sort(function(a,b){if (a[0] < b[0]) return -1; if (a[0] > b[0]) return 1; return 0;}) Dabs.sort(function(a,b){if (a[0] < b[0]) return -1; if (a[0] > b[0]) return 1; return 0;}) MissingRefnum.sort(function(a,b){if (a[0] < b[0]) return -1; if (a[0] > b[0]) return 1; return 0;}) // custom sort not needed for these ExistingTitles.sort ToBeTagged.sort ToBeUntagged.sort AllNRISOnly.sort OneRefNotNRIS.sort Unreferenced.sort

// now find duplicates across county lines for (var i=0;i<AllTitles.length; i++) { Duplications[Duplications.length]=[AllTitles[i][0],AllTitles[i][1],[AllTitles[i][2]]] // [name,refnum,[list]] for (var j=i+1;j<AllTitles.length; j++) { if (AllTitles[i][1]==AllTitles[j][1]) { Duplications[Duplications.length-1][2].push(AllTitles[j][2]) AllTitles.splice(j,1) j-- }       }        if (Duplications[Duplications.length-1][2].length==1) Duplications.pop // if no other lists added, not duplicate }

// now dump data to subpages var TimeSpan=document.getElementById("TimeSpan") var EditSpan=document.getElementById("EditSpan") var CurrentTime=new Date var SecondsElapsed = (CurrentTime-StartTime)/1000 SecondsElapsed=Math.round(SecondsElapsed) var MinutesElapsed = 0 while (SecondsElapsed>=60) { SecondsElapsed-=60 MinutesElapsed++ }   var TimeStr=" Time elapsed: " if (MinutesElapsed!=0) TimeStr+=MinutesElapsed+" min " TimeStr+=SecondsElapsed+" sec"

TimeSpan.innerHTML+="Done!"+TimeStr EditSpan.innerHTML=" Dumping data to subpages of " EditSpan.innerHTML+=""+OutputBase+"... 0 edits made."

var d=new Date; var months = ['January','February','March','April','May','June','July','August','September','October','November','December']; var year=d.getYear; if (year < 1000) year += 1900 var DateStr = months[d.getMonth]+" "+d.getDate+", "+year

var subpages=0 var firstletter=ExistingTitles[0].substr(0,1) var basewikitext = "" var partialwikitext = "=="+firstletter+"==\n{{refbegin|3}}\n" for (var k=0; k<ExistingTitles.length; k++) { var oldfirstletter = firstletter firstletter = ExistingTitles[k].substr(0,1) if (firstletter!=oldfirstletter) { // must be starting a new subpage, so edit the previous one partialwikitext+='{{refend}}' subpages++

NRISOnlyDump({               title: OutputBase+'/'+oldfirstletter,                text: partialwikitext,                summary:'Generate list of all NRHP articles beginning with '+oldfirstletter+' linked from county lists as of '+DateStr            },EditSpan,subpages,"no");

basewikitext+='*/'+oldfirstletter+'\n' partialwikitext='=='+firstletter+'==\n{{refbegin|3}}\n# '+ExistingTitles[k]+'\n' } else { partialwikitext+='# '+ExistingTitles[k]+'\n' }   }    partialwikitext+="{{refend}}" subpages++ NRISOnlyDump({ // manually edit final subpage       title: OutputBase+'/'+firstletter,        text: partialwikitext,        summary:'Generate list of all NRHP articles beginning with '+firstletter+' linked from county lists as of '+DateStr    },EditSpan,subpages,"no");

basewikitext+='*/'+firstletter+'\n */Duplications' subpages++

NRISOnlyDump({       title: OutputBase,        text: basewikitext,        summary: 'Generate list of all NRHP articles linked from county lists as of '+DateStr    },EditSpan,subpages,"no");

// now dump list of duplicates basewikitext = "{{TOC right}}\n\n" if (Duplications.length>0) { var multistate="==Multi-state==\n\n{{refbegin|2}}\n" var unknown="==Unknown==\n\n{{refbegin|2}}\n" var oldstate="" var state="" var prevstate="" var multiflag=false var unknownflag=false var firststateflag=true var partialwikitext="" for (var k=0; k0) {                    if (oldstate==""||state=="") {                        unknownflag=true                    } else if (state!=oldstate) {                        multiflag=true                    }                }                oldstate=state                partialwikitext+=""                partialwikitext+=Duplications[k][2][l].replace(/National Register of Historic Places listings (i|o)n /g,"")+"; "            }            partialwikitext=partialwikitext.substr(0,partialwikitext.length-2)            partialwikitext+=") \n" if (unknownflag) { unknown+=partialwikitext } else if (multiflag) { multistate+=partialwikitext } else { if (state!=prevstate) { if (firststateflag) { basewikitext+="=="+state+"==\n{{refbegin|2}}\n" firststateflag=false } else { basewikitext+="{{refend}}\n\n=="+state+"==\n{{refbegin|2}}\n" }               }                var smalltext=partialwikitext.match(/ (.)*?<\/small>/g)[0] var newsmalltext=smalltext.replace(/,[a-zA-Z .,]*?]]/g,"]]") // remove state names from dupes inside single state partialwikitext=partialwikitext.replace(smalltext,newsmalltext) basewikitext+=partialwikitext prevstate=state }       }        basewikitext+="{{refend}}\n " if (multistate!="==Multi-state==\n<div id=\"multistate\">\n{{refbegin|2}}\n") { basewikitext+="\n\n"+multistate+"\n{{refend}}\n " }       if (unknown!="==Unknown==\n<div id=\"unknown\">\n{{refbegin|2}}\n") { basewikitext+="\n\n"+unknown+"\n{{refend}}\n " }   }    NRISOnlyDump({        title: OutputBase+'/Duplications',        text: basewikitext,        summary:'Generate list of all NRHP articles duplicated across county lines as of '+DateStr    },EditSpan,subpages,"yes");

// now dump NRIS-only data var OutputPage="User:NationalRegisterBot/NRISOnly" EditSpan.innerHTML+=" Now outputting data to <a href='http://en.wikipedia.org/wiki/"+OutputPage+"'>"+OutputPage+"</a>... "

basewikitext="{{TOC right}}\n" if (ToBeTagged.length>0) { basewikitext+="==Articles that need to be tagged==\n<div id=\"tobetagged-div\">\n{{refbegin|3}}\n" for (var k=0; k<ToBeTagged.length; k++) { basewikitext+='# '+ToBeTagged[k]+'\n' }       basewikitext+="{{refend}} \n\n" }   if (ToBeUntagged.length>0) { basewikitext+="==Articles that need to be untagged==\n<div id=\"tobeuntagged-div\">\n{{refbegin|3}}\n" for (var k=0; k<ToBeUntagged.length; k++) { basewikitext+='# '+ToBeUntagged[k]+'\n' }       basewikitext+="{{refend}} \n\n" }   if (Dabs.length>0) { basewikitext+="==Links to disambiguation pages==\n{{refbegin|3}}\n" for (var k=0; k<Dabs.length; k++) { basewikitext+='# '+Dabs[k][0]+' ('           basewikitext+=Dabs[k][1].replace(/National Register of Historic Places listings (i|o)n /g,"")+')\n' }       basewikitext+="{{refend}}\n\n" }   if (MissingRefnum.length>0) { basewikitext+="==Missing refnum in county list==\n{{refbegin|3}}\n" for (var k=0; k<MissingRefnum.length; k++) { basewikitext+='# '+MissingRefnum[k][0]+' ('           basewikitext+=MissingRefnum[k][1].replace(/National Register of Historic Places listings (i|o)n /g,"")+')\n' }       basewikitext+="{{refend}}\n\n" }   if (Unreferenced.length>0) { basewikitext+="==Articles with no references==\n<div id=\"unreferenced-div\">\n{{refbegin|3}}\n" for (var k=0; k<Unreferenced.length; k++) { basewikitext+='# '+Unreferenced[k]+'\n' }       basewikitext+="{{refend}} \n\n" }   if (OneRefNotNRIS.length>0) { basewikitext+="==Articles with only one source that is not NRIS==\n{{refbegin|3}}\n" for (var k=0; k<OneRefNotNRIS.length; k++) { basewikitext+='# '+OneRefNotNRIS[k]+'\n' }       basewikitext+="{{refend}}\n\n" }   NRISOnlyDump({        title: OutputPage,        text: basewikitext,        summary:'Generate list of all NRHP articles to be tagged/untagged with Template:NRIS-only as of '+DateStr    },EditSpan,subpages,"");

// now substubs OutputPage="User:NationalRegisterBot/Substubs" basewikitext="" if (WorstNRIS.length>0) { basewikitext+="==Smallest 100 NRIS-only articles by prose size==\n{{refbegin|3}}\n" for (var k=0; k<WorstNRIS.length; k++) { basewikitext+='# '+WorstNRIS[k][0]+' ('+WorstNRIS[k][1]+' bytes)\n' }       basewikitext+="{{refend}}\n\n" }   if (WorstNotNRIS.length>0) { basewikitext+="==Smallest 100 articles by prose size NOT tagged NRIS-only==\n{{refbegin|3}}\n" for (var k=0; k<WorstNotNRIS.length; k++) { basewikitext+='# '+WorstNotNRIS[k][0]+' ('+WorstNotNRIS[k][1]+' bytes)\n' }       basewikitext+="{{refend}}\n\n" }

if (ShortNRIS.length>0||ShortNotNRIS.length>0) { basewikitext+="==Articles with less than 325 bytes of prose==\n" if (ShortNotNRIS.length>0) { basewikitext+="===Not tagged NRIS-only===\n{{refbegin|3}}\n" for (var k=0; k<ShortNotNRIS.length; k++) { basewikitext+='# '+ShortNotNRIS[k][0]+' ('+ShortNotNRIS[k][1]+' bytes)\n' }           basewikitext+="{{refend}}\n\n" if (ShortNRIS.length>0) basewikitext+="===Tagged NRIS-only===\n" }       if (ShortNRIS.length>0) { basewikitext+="{{refbegin|3}}\n" for (var k=0; k<ShortNRIS.length; k++) { basewikitext+='# '+ShortNRIS[k][0]+' ('+ShortNRIS[k][1]+' bytes)\n' }           basewikitext+="{{refend}}\n\n" }   }    if (LongNRIS.length>0) { basewikitext+="==Articles tagged NRIS-only with more than 325 bytes of prose==\n{{refbegin|3}}\n" for (var k=0; k<LongNRIS.length; k++) { basewikitext+='# '+LongNRIS[k][0]+' ('+LongNRIS[k][1]+' bytes)\n' }       basewikitext+="{{refend}}\n\n" }   NRISOnlyDump({        title: OutputPage,        text: basewikitext,        summary:'Generate list of all minimal (<325 bytes) NRHP stubs as of '+DateStr    },EditSpan,subpages,"");

// now all NRIS-only OutputPage="User:NationalRegisterBot/NRISOnly/All" basewikitext = "{{TOC right}}\n<div id=\"NRISOnly-div\">\n" if (AllNRISOnly.length>0) { var firstletter=AllNRISOnly[0].substr(0,1) basewikitext += "=="+firstletter+"==\n{{refbegin|3}}\n" for (var k=0; k<AllNRISOnly.length; k++) { var oldfirstletter = firstletter firstletter = AllNRISOnly[k].substr(0,1) if (firstletter!=oldfirstletter) { basewikitext+='{{refend}}\n=='+firstletter+'==\n{{refbegin|3}}\n# <li value="'               basewikitext+=parseFloat(k+1)+'">'+AllNRISOnly[k]+'\n' } else { basewikitext+='# '+AllNRISOnly[k]+'\n' }       }        basewikitext+="{{refend}} " }   NRISOnlyDump({        title: OutputPage,        text: basewikitext,        summary:'Generate list of all NRHP articles sourced only to NRIS as of '+DateStr    },EditSpan,subpages,"NRIS"); }

// gather information about duplicates from output function CheckDuplicates { var ProgressDiv=document.getElementById("ProgressDiv") ProgressDiv.innerHTML="Checking multi-state duplicates..." var MultiSpan = document.createElement("span") ProgressDiv.appendChild(MultiSpan)

var multistate=[]; var li=document.getElementById("multistate").getElementsByClassName("refbegin")[0].getElementsByTagName("li") for (var k=0; k<li.length; k++) { var links=li[k].getElementsByTagName("a") var refnum=li[k].innerHTML.match(/[0-9]{8}/)[0] var titles=[refnum]                                  // make refnum element 0; title=1; county lists=2,3,4,... for (var l=0; l<links.length; l++) { var temp=links[l].href.replace(/https:\/\/en\.wikipedia\.org\/w(iki)?\/(index\.php\?title=)?/,"").split("&")[0] titles.push(decodeURIComponent(temp).replace(/_/g," ")) }       multistate[multistate.length]=titles }   var wikitext="==National==\nThe following listings are included in two or more lists which are located in different states." wikitext+="\n{| class=\"wikitable sortable\" width=100%\n! {{NRHP color}} width=30% | Site\n! {{NRHP color}} width=30% | " wikitext+="Lists\n! {{NRHP color}} width=10% | Number of Duplicates\n! {{NRHP color}} width=30% colspan=7 | Stats\n"

var switchtabletext=" {{#tag:ref|}}}| Statewide}}"   switchtabletext+="{{!}}Click here for {{{1}}} duplicate information.}}{{#ifeq:{{{1}}}|National| |{{#ifeq:{{{1}}}|" switchtabletext+="{{First word|{{{1}}}|sep=,}}| | {{{1}}}|sep=,}} }}}} {{#switch:" switchtabletext+="{{{1}}}\n"

var Total=0 var TotalIllustrated=0 var TotalArticled=0 var TotalStub=0 var TotalStartPlus=0 var TotalUntagged=0 var TotalUnassessed=0 var TotalNRISOnly=0 for (var i=0; i<multistate.length; i++) { MultiSpan.innerHTML = " "+i+" of "+multistate.length+" complete..." wikitext+="|-\n| "+multistate[i][1]+" (#"+multistate[i][0]+")\n|\n" var temp=[multistate[i][1],0] // 0=not duplicated inside single state by default multistate[i][1]=temp var oldstate="" var state="" var totalstates=0

for (var j=2; j<multistate[i].length; j++) { wikitext+="*"+multistate[i][j].replace(/National Register of Historic Places listings (i|o)n /g,"")           wikitext+="\n" state=getState(multistate[i][j]) if (state!=oldstate) { totalstates++ } else { if (multistate[i][1][1]==0) { // tag as being duplicated inside one state (and record which state) for later use multistate[i][1][1]=state } else { multistate[i][1][multistate[i][1].length]=state }           }            oldstate=state }       var duplications=totalstates-1 Total+=duplications wikitext+="| align=center | "+duplications+"\n| colspan=7 | "

var StatsStr=getDuplicateStats(multistate[i]) if (StatsStr.indexOf("unarticled")==-1) TotalArticled+=duplications if (StatsStr.indexOf(", illustrated")!=-1) TotalIllustrated+=duplications if (StatsStr.indexOf("Stub-class")!=-1) TotalStub+=duplications if (StatsStr.indexOf("NRIS-only")!=-1) TotalNRISOnly+=duplications if (StatsStr.indexOf("Start+")!=-1) TotalStartPlus+=duplications if (StatsStr.indexOf("unassessed")!=-1) TotalUnassessed+=duplications if (StatsStr.indexOf("untagged")!=-1) TotalUntagged+=duplications

wikitext+=StatsStr+"\n" }   wikitext+="|-\n! colspan=2 | Total\n! "+Total+"\n! "+TotalIllustrated+"\n! "+TotalArticled+"\n! "+TotalStub+"\n! " wikitext+=TotalNRISOnly+"\n! "+TotalStartPlus+"\n! "+TotalUnassessed+"\n! "+TotalUntagged+"\n|}\n\n"

switchtabletext+="|National="+Total+" "+TotalIllustrated+"  -  "+TotalArticled+"  -  " switchtabletext+=TotalStub+" "+TotalNRISOnly+"  "+TotalStartPlus+"  -  "+TotalUnassessed switchtabletext+=" "+TotalUntagged+"  - \n"

MultiSpan.innerHTML = " Complete!"

for (var i=0; i<multistate.length; i++) { if (multistate[i][1][1]==0) {multistate.splice(i,1); i--}  // get rid of those not duplicated inside single states }

var StateSpan = document.createElement("span") ProgressDiv.appendChild(StateSpan) StateSpan.inerHTML="test" var CountySpan = document.createElement("span") ProgressDiv.appendChild(CountySpan) CountySpan.inerHTML="test" var ThisStateSpan = document.createElement("span") ProgressDiv.appendChild(ThisStateSpan) ThisStateSpan.inerHTML="test"

var StateStructure=[ ["Alabama", ["Jefferson County",["Jefferson County", "Birmingham"]], ["Mobile County",["Mobile County", "Mobile"]]], ["Alaska"], ["Arizona", ["Maricopa County",["Maricopa County", "Phoenix"]], ["Yavapai County",["Yavapai County", "Prescott"]]], ["Arkansas", ["Pulaski County",["Pulaski County", "Little Rock"]]], ["California", ["Los Angeles County",["Los Angeles County", "Los Angeles", "Pasadena"]]], ["Colorado", ["Denver County",["Downtown Denver","Northeast Denver","Southeast Denver","West Denver"]]], ["Connecticut", ["Fairfield County",["Fairfield County","Bridgeport","Greenwich","Stamford"]], ["Hartford County",["Hartford County","Hartford","Southington","West Hartford","Windsor"]], ["Middlesex County",["Middlesex County","Middletown"]], ["New Haven County",["New Haven County","New Haven"]]], ["Delaware", ["New Castle County",["northern New Castle County","southern New Castle County","Wilmington"]]], ["D.C."], ["Florida", ["Miami-Dade County",["Miami-Dade County","Miami"]]], ["Georgia"], ["Hawaii", ["Honolulu County",["Oahu","Northwestern Hawaiian Islands"]], ["Maui County",["Maui","Kahoolawe","Lanai","Molokai"]]], ["Idaho"], ["Illinois", ["Cook County",["Cook County","Central Chicago","North Side Chicago","South Side Chicago","West Side Chicago","Evanston"]]], ["Indiana", ["Marion County",["Marion County","Center Township, Marion County"]]], ["Iowa", ["Scott County",["Scott County","Downtown Davenport","east Davenport","west Davenport"]]], ["Kansas"], ["Kentucky", ["Jefferson County",["Jefferson County","Anchorage","Downtown Louisville","The Highlands, Louisville","Old Louisville","Portland, Louisville","Louisville's West End"]]], ["Louisiana"], ["Maine", ["Cumberland County",["Cumberland County","Portland"]]], ["Maryland", ["City of Baltimore",["Central Baltimore","East and Northeast Baltimore","North and Northwest Baltimore","South and Southeast Baltimore","West and Southwest Baltimore"]]], ["Massachusetts", ["Barnstable County",["Barnstable County","Barnstable"]], ["Bristol County",["Bristol County","Fall River","New Bedford","Taunton"]], ["Essex County",["Essex County","Andover","Gloucester","Ipswich","Lawrence","Lynn","Methuen","Salem"]], ["Hampden County",["Hampden County","Springfield"]], ["Middlesex County",["Middlesex County","Arlington","Cambridge","Concord","Framingham","Lexington","Lowell","Marlborough","Medford","Newton","Reading","Sherborn","Somerville","Stoneham","Wakefield","Waltham","Weston","Winchester"]], ["Norfolk County",["Norfolk County","Brookline","Milton","Quincy"]], ["Suffolk County",["Suffolk County","northern Boston","southern Boston"]], ["Worcester County",["Worcester County","northern Worcester County","Southbridge","Uxbridge","eastern Worcester","northwestern Worcester","southwestern Worcester"]]], ["Michigan", ["Wayne County",["Wayne County","Downtown and Midtown Detroit","Detroit"]]], ["Minnesota"], ["Mississippi"], ["Missouri", ["Jackson County",["Jackson County: Downtown Kansas City","Jackson County: Kansas City other"]], ["St. Louis",["Downtown and Downtown West St. Louis","St. Louis north and west of downtown","St. Louis south and west of downtown"]]], ["Montana"], ["Nebraska"], ["Nevada"], ["New Hampshire"], ["New Jersey", ["Bergen County",["Bergen County","Closter","Franklin Lakes","Ridgewood","Saddle River","Wyckoff"]]], ["New Mexico"], ["New York", ["Albany County",["Albany County","Albany"]], ["Dutchess County",["Dutchess County","Poughkeepsie","Rhinebeck"]], ["Erie County",["Erie County","Buffalo"]], ["Monroe County",["Monroe County","Rochester"]], ["Nassau County",["Hempstead (town)","North Hempstead (town)","Oyster Bay (town)"]], ["New York County",["Manhattan below 14th Street","Manhattan from 14th to 59th Streets","Manhattan above 59th to 110th Streets","Manhattan above 110th Street","Manhattan on islands"]], ["Onondaga County",["Onondaga County","Syracuse"]], ["Suffolk County",["Babylon (town)","Brookhaven (town)","East Hampton (town)","Huntington (town)","Islip (town)","Riverhead (town)","Shelter Island (town)","Smithtown (town)","Southampton (town)","Southold (town)"]], ["Westchester County",["northern Westchester County","southern Westchester County","New Rochelle","Peekskill","Yonkers"]]], ["North Carolina"], ["North Dakota"], ["Ohio", ["Cuyahoga County",["Cuyahoga County","Cleveland"]], ["Erie County",["Erie County","Sandusky"]], ["Franklin County",["Franklin County","Columbus"]], ["Hamilton County",["Hamilton County","downtown Cincinnati","eastern Cincinnati","western Cincinnati"]], ["Montgomery County",["Montgomery County","Dayton"]], ["Summit County",["Summit County","Akron"]]], ["Oklahoma"], ["Oregon", ["Multnomah County",["Multnomah County","North Portland","Northeast Portland","Northwest Portland","Southeast Portland","Southwest Portland"]]], ["Pennsylvania", ["Allegheny County",["Allegheny County","Pittsburgh"]], ["Chester County",["eastern Chester County","northern Chester County","southern Chester County"]], ["Lancaster County",["Lancaster County","Lancaster"]], ["Philadelphia",["Center City, Philadelphia","North Philadelphia","Northeast Philadelphia","Northwest Philadelphia","South Philadelphia","Southwest Philadelphia","West Philadelphia"]]], ["Rhode Island", ["Providence County",["Providence County","Pawtucket","Providence"]]], ["South Carolina", ["Charleston County",["Charleston County","Charleston"]], ["Greenville County",["Greenville County","Greenville"]], ["Richland County",["Richland County","Columbia"]], ["York County",["York County","Rock Hill"]]], ["South Dakota"], ["Tennessee"], ["Texas"], ["Utah", ["Salt Lake County",["Salt Lake County","Salt Lake City"]], ["Washington County",["Washington County","Zion National Park"]]], ["Vermont"], ["Virginia"], ["Washington", ["King County",["King County","Seattle"]], ["Pierce County",["Pierce County","Tacoma"]], ["Spokane County",["Spokane County","Spokane"]]], ["West Virginia"], ["Wisconsin", ["Dane County",["Dane County","Madison"]], ["Milwaukee County",["Milwaukee County","Milwaukee"]]], ["Wyoming"], ["Puerto Rico"], ["Guam"], ["Virgin Islands"], ["Northern Mariana Islands"], ["American Samoa"], ["Federated States of Micronesia"], ["Palau"], ["Marshall Islands"], ["U.S. Minor Outlying Islands"] ]

var states=document.getElementById("duplicates-div").getElementsByClassName("refbegin") var currentState=0 for (var i=0; i<StateStructure.length; i++) { StateSpan.innerHTML = " Now working on individual states... "+i+" of "+StateStructure.length+" complete..." var thisstate=[]; var li=states[currentState].getElementsByTagName("li") for (var j=0; j<li.length; j++) { var links=li[j].getElementsByTagName("a") var refnum=li[j].innerHTML.match(/[0-9]{8}/)[0] var titles=[refnum]                                  // make refnum element 0; title=1; county lists=2,3,4,... for (var l=0; l<links.length; l++) { var temp=links[l].href.replace(/https:\/\/en\.wikipedia\.org\/w(iki)?\/(index\.php\?title=)?/,"").split("&")[0] titles.push(decodeURIComponent(temp).replace(/_/g," ")) }           thisstate[thisstate.length]=titles }       var stateName=getState(thisstate[0][2]) wikitext+="=="+StateStructure[i][0]+"==\n" while (i<StateStructure.length&&stateName!=StateStructure[i][0]) { // if the state we're looking at isn't the next one in the structure array var tempstate=[]; for (var j=0; j<multistate.length; j++) { var inThisState=0 for (var k=1; k<multistate[j][1].length; k++) {                   // check if any multistate duplicates are if (multistate[j][1][k]==StateStructure[i][0]) inThisState=1  // duplicated in this state }               if (inThisState==1) { var temp=[]; for (var k=0; k<multistate[j].length; k++) { // make temp static temp[k]=multistate[j][k] }                   for (var k=2; k<temp.length; k++) { if (getState(temp[k])!=StateStructure[i][0]) {temp.splice(k,1); k--} // only pick out those in this state }                   tempstate[tempstate.length] = [temp[0],temp[1][0],temp[2],temp[3]] // refnum, title, list1, list2 for (var k=4; k<temp.length; k++) { tempstate[tempstate.length-1].push(temp[k]) // list3, list4,... }               }            }            var result=GenerateDuplicateTable(StateStructure,i,tempstate,stateName,CountySpan,ThisStateSpan) wikitext+=result[0] switchtabletext+=result[1]

i++ // look at next state in StateStructure and repeat until we find the one we're looking at            StateSpan.innerHTML = " Now working on individual states... "+i+" of "+StateStructure.length+" complete..." if (i!=StateStructure.length) wikitext+="=="+StateStructure[i][0]+"==\n" }       if (i!=StateStructure.length) { // now we know the state we're looking at has the duplications in thisstate array for (var j=0; j<multistate.length; j++) { var inThisState=0 for (var k=1; k<multistate[j][1].length; k++) {        // check if any multistate duplicates are also if (multistate[j][1][k]==stateName) inThisState=1  // duplicated in the current state }               if (inThisState==1) { var temp=[]; for (var k=0; k<multistate[j].length; k++) { // make temp static temp[k]=multistate[j][k] }                   for (var k=2; k<temp.length; k++) { if (getState(temp[k])!=stateName) {temp.splice(k,1); k--} // only pick out those in this state }                   thisstate[thisstate.length] = [temp[0],temp[1][0],temp[2],temp[3]] // refnum, title, list1, list2 for (var k=4; k<temp.length; k++) { thisstate[thisstate.length-1].push(temp[k]) // list3, list4,... }               }            }            var result=GenerateDuplicateTable(StateStructure,i,thisstate,stateName,CountySpan,ThisStateSpan) wikitext+=result[0] switchtabletext+=result[1]

CountySpan.innerHTML=" " ThisStateSpan.innerHTML=" " if (currentState<states.length-1) currentState++ // next state on the page }   }    CountySpan.innerHTML="" ThisStateSpan.innerHTML="" StateSpan.innerHTML = " Now working on individual states... Complete!" ProgressDiv.innerHTML+=" Now outputting data to " ProgressDiv.innerHTML+="<a href='http://en.wikipedia.org/wiki/WP:NRHPPROGRESS/Duplicates'>WP:NRHPPROGRESS/Duplicates</a>..."

switchtabletext+="|error error  -  error  -  error  error  error  " switchtabletext+="- error  error  - \n}}  \n"

var TOCtext="\n{{anchor|top}}\n{| style=\"margin:.5em; border:1px solid #000; padding:0;"   TOCtext+=" text-align:center\"\n| National\n \n"

for (var i=0; i<StateStructure.length; i++) { TOCtext+=""+StateStructure[i][0]+" " for (var j=1; j<StateStructure[i].length; j++) { if (j==1) TOCtext+="("           TOCtext+=""            TOCtext+=StateStructure[i][j][0].replace(", "+StateStructure[i][0],"").replace(" County","").replace("City of ","")            TOCtext+=", "        }        if (StateStructure[i].length>1) {            TOCtext=TOCtext.substr(0,TOCtext.length-2)  // remove final comma            TOCtext+=")" }       if (StateStructure[i][0]=="Wyoming") TOCtext+="\n \n" else if (i!=StateStructure.length-1) TOCtext+=" – " }   TOCtext+="\n|}\n\n"

wikitext=switchtabletext+TOCtext+wikitext+" "

var d=new Date; var months = ['January','February','March','April','May','June','July','August','September','October','November','December']; var year=d.getYear; if (year < 1000) year += 1900 var DateStr = months[d.getMonth]+" "+d.getDate+", "+year

// edit page with total wikitext NRISOnlyDump({       title: 'Wikipedia:WikiProject National Register of Historic Places/Progress/Duplicates',        text: wikitext,    summary:'Generate statistics about duplicates in NRHP lists as of '+DateStr    },ProgressDiv,0,"duplicates"); }

// tag/untag pages with the bot function TagNRISOnly { var tobetagged=document.getElementById('tobetagged-div') var tobeuntagged=document.getElementById('tobeuntagged-div') var ProgressDiv = document.getElementById('ProgressDiv')

var HiddenSpan=document.createElement("span") HiddenSpan.setAttribute("id", "HiddenSpan") HiddenSpan.setAttribute("style", "display:none") ProgressDiv.appendChild(HiddenSpan)

var TotalDone=0

var d=new Date; var months = ['January','February','March','April','May','June','July','August','September','October','November','December']; var year=d.getYear; if (year < 1000) year += 1900 var DateStr = months[d.getMonth]+" "+year

if (tobetagged!=null) { ProgressDiv.innerHTML = "Tagging articles that need to be tagged..." var ProgressSpan = document.createElement("span") ProgressSpan.setAttribute("id", "ProgressSpan") ProgressDiv.appendChild(ProgressSpan) ProgressSpan.innerHTML=" "

var sections=tobetagged.getElementsByClassName('refbegin') var total=0 for (var i=0; i<sections.length; i++) { var links=sections[i].getElementsByTagName('a') total+=links.length }       var tagged=0 var skipped=0 ProgressSpan.innerHTML=" 0 of "+total+" articles examined: 0 tagged, 0 skipped..." for (var i=0; i<sections.length; i++) { var links=sections[i].getElementsByTagName('a') for (var j=0; j<links.length; j++) { var wikitext=getNRISOnlyWikitext(links[j].title) if (wikitext!="error") { if (wikitext.match(/{{( |[\r\n])*?NRIS-only(.|[\r\n])*?}}/g)!=null) { // don't tag if already tagged TotalDone++ skipped++ links[j].style.backgroundColor = "yellow" ProgressSpan.innerHTML=" "+TotalDone+" of "+total+" articles examined: "+tagged+" tagged, " ProgressSpan.innerHTML+=skipped+" skipped..." continue }                   var result=NRISOnlyQuery([links[j].title],HiddenSpan) if (result[0][0]!=links[j].title) {    // check again to make sure list isn't outdated TotalDone++ skipped++ links[j].style.backgroundColor = "yellow" ProgressSpan.innerHTML=" "+TotalDone+" of "+total+" articles examined: "+tagged+" tagged, " ProgressSpan.innerHTML+=skipped+" skipped..." continue }

var multipleIssues=wikitext.match(/{{*?(multiple|many|mi|article|issues)?(issues)?( |[\r\n])*?\|/gi) var NRISstr="{{NRIS-only|date="+DateStr+"}}"

if (multipleIssues!=null) {          // if multiple issues tag, add NRIS-only to bottom of list var open=1 var start=wikitext.indexOf(multipleIssues[0]) var index=start+multipleIssues[0].length while (open!=0 && index<wikitext.length) { if (wikitext.substr(index,2)=="}}") { open-- index++ } else if (wikitext.substr(index,2)=="{{") { open++ index++ }                           index++ }                       index-=2 var full=wikitext.substr(start,index-start) if (wikitext.substr(index-1,1)!="\n") full+="\n" var oldsyntax=full.substr(2,full.length-2).match(/{{/g) if (oldsyntax==null) {   // if using old syntax full = full.replace(/\|*?one?source*?=(.|[\r\n])*?(\||$)/g, "|") // replace "|one source" if (full.substr(full.length-1,1)=="|") { full+="\n" } else { NRISstr="|"+NRISstr }                       } else {                  // replace "{{one source}}" full = full.replace(/{{*?(one|single|1)( |-)?(source|ref)( |[\r\n])*?\|(.|[\r\n])*?}}[\r\n]?/gi,"") }                       full+=NRISstr+"\n" wikitext = wikitext.substr(0,start)+full+wikitext.substr(index,wikitext.length-index) } else { wikitext=wikitext.replace(/{{*?(one|single|1)( |-)?(source|ref)( |[\r\n])*?\|(.|[\r\n])*?}}[\r\n]?/gi,"") wikitext = NRISstr+"\n"+wikitext }                   NRISOnlyDump({                        title: links[j].title,                        text: wikitext,                        summary:'Tag as only sourced to the National Register Information System'                    },ProgressSpan,TotalDone,"tag"); TotalDone++ tagged++ ProgressSpan.innerHTML=" "+TotalDone+" of "+total+" articles examined: "+tagged+" tagged, " ProgressSpan.innerHTML+=skipped+" skipped..." } else { TotalDone++     // skip if wikitext error skipped++ links[j].style.backgroundColor = "orange" ProgressSpan.innerHTML=" "+TotalDone+" of "+total+" articles examined: "+tagged+" tagged, " ProgressSpan.innerHTML+=skipped+" skipped..." }           }        }        ProgressSpan.innerHTML=" Tagging complete! "+tagged+" articles tagged successfully! "+skipped ProgressSpan.innerHTML+=" skipped as unnecessary." }   if (tobeuntagged!=null) { var str="" if (tobetagged!=null) { str=" Now u"       } else { str="U" }       ProgressDiv.innerHTML+=str+"ntagging articles that need to be untagged..." var ProgressSpan2 = document.createElement("span") ProgressSpan2.setAttribute("id", "ProgressSpan2") ProgressDiv.appendChild(ProgressSpan2) ProgressSpan2.innerHTML=" "

var TotalDone=0

var sections=tobeuntagged.getElementsByClassName('refbegin') var total=0 for (var i=0; i<sections.length; i++) { var links=sections[i].getElementsByTagName('a') total+=links.length }       var untagged=0 var skipped=0 ProgressSpan2.innerHTML=" 0 of "+total+" articles examined: 0 untagged, 0 skipped..."

for (var i=0; i<sections.length; i++) { var links=sections[i].getElementsByTagName('a') for (var j=0; j<links.length; j++) { var wikitext=getNRISOnlyWikitext(links[j].title) if (wikitext!="error") { if (wikitext.match(/{{( |[\r\n])*?NRIS-only(.|[\r\n])*?}}[\r\n]?/g)==null) { //don't untag if already untagged TotalDone++ skipped++ links[j].style.backgroundColor = "yellow" ProgressSpan2.innerHTML=" "+TotalDone+" of "+total+" articles examined: "+untagged+" untagged, " ProgressSpan2.innerHTML+=skipped+" skipped..." continue }                   var result=NRISOnlyQuery([links[j].title],HiddenSpan) if (result[1][0]!=links[j].title) {    // check again to make sure list isn't outdated TotalDone++ skipped++ links[j].style.backgroundColor = "yellow" ProgressSpan2.innerHTML=" "+TotalDone+" of "+total+" articles examined: "+untagged+" untagged, " ProgressSpan2.innerHTML+=skipped+" skipped..." continue }

var multipleIssues=wikitext.match(/{{*?(multiple|many|mi|article|issues)?(issues)?( |[\r\n])*?\|/gi)

if (multipleIssues!=null) {    // if multiple issues tag, check to see we're not leaving only one tag behind var open=1 var start=wikitext.indexOf(multipleIssues[0]) var index=start+multipleIssues[0].length while (open!=0 && index<wikitext.length) { if (wikitext.substr(index,2)=="}}") { open-- index++ } else if (wikitext.substr(index,2)=="{{") { open++ index++ }                           index++ }                       index-=2 var full=wikitext.substr(start,index-start) var oldsyntax=full.substr(2,full.length-2).match(/{{*?[^(NRIS)](.|[\r\n])*?}}/g) //match non-NRIS temp

if (oldsyntax==null) { var numberTemplates=full.substr(2,full.length-2).match(/\|/g).length - 2 } else { var numberTemplates=oldsyntax.length }

if (numberTemplates==0) {     // if NRIS-only is only template in multiple issues, remove entire block wikitext=wikitext.replace(full+"}}\n","") } else if (numberTemplates==1 && oldsyntax!=null) {      // if one template left, remove multiple issues wikitext = wikitext.replace(full+"}}", oldsyntax[0]) // and replace with other template } else {     // just remove if more than one other or if using old syntax wikitext = wikitext.replace(/\|?{{( |[\r\n])*?NRIS-only(.|[\r\n])*?}}[\r\n]?/g, '') }                   } else { wikitext = wikitext.replace(/{{( |[\r\n])*?NRIS-only(.|[\r\n])*?}}[\r\n]?/g, '') }

NRISOnlyDump({                       title: links[j].title,                        text: wikitext,                        summary:'Remove Template:NRIS-only; article has more than one reference'                    },ProgressSpan2,TotalDone,"tag"); TotalDone++ untagged++ ProgressSpan2.innerHTML=" "+TotalDone+" of "+total+" articles examined: "+untagged+" untagged, " ProgressSpan2.innerHTML+=skipped+" skipped..." } else { TotalDone++     // skip if wikitext error skipped++ links[j].style.backgroundColor = "orange" ProgressSpan2.innerHTML=" "+TotalDone+" of "+total+" articles examined: "+untagged+" untagged, " ProgressSpan2.innerHTML+=skipped+" skipped..." }           }        }        ProgressSpan2.innerHTML=" Untagging complete! "+untagged+" articles untagged successfully! "+skipped ProgressSpan2.innerHTML+=" skipped as unnecessary." } }

function getDuplicateStats(item) { var IllustratedStr = "illustrated" var countytext="" var Illustrated=0 for (var j=2; j<item.length; j++) { countytext=getNRISOnlyWikitext(item[j]) if (countytext!="error") { var StartIndex = 0 var str = "{{NRHP row" var skip = str.length; var index, RowLocations = []; while ((index = countytext.indexOf(str, StartIndex)) > -1) { RowLocations.push(index); StartIndex = index + skip; }               RowLocations.push(countytext.length)    // if duplicated entry happens to be last in table

var k=0 while (RowLocations[k]<countytext.indexOf(item[0])) { k++ }               var CountyRow=countytext.substr(RowLocations[k-1],RowLocations[k]-RowLocations[k-1]) CountyRow=CountyRow.replace(/\<\!\-\-(.|[\r\n])*?\-\-\>/g, "")     // get rid of commented out pictures if (CountyRow.match(/\|[ ]*?image[ ]*?=[ ]*?[a-zA-Z0-9]/g)!=null) Illustrated++ } else { alert("Error checking duplicate stats! Script aborted!") return }       }

if (Illustrated!=item.length-2&&Illustrated!=0) IllustratedStr="partially-"+IllustratedStr if (Illustrated==0) IllustratedStr="un"+IllustratedStr

var ArticledStr="articled" var AssessmentStr="" var NRISStr="" var title=""

if(Object.prototype.toString.call(item[1]) === '[object Array]') { // if in multistate, pick out first item in array var title=item[1][0] } else { var title = item[1] }

var nrisonlyquery=JSON.parse( // check if NRIS-only            $.ajax({ dataType: "json", url: mw.util.wikiScript('api'), data: { format: 'json', action: 'query', prop: 'categories', clcategories: 'Category:All articles sourced only to NRIS', cllimit: 'max', titles: title, redirects: 'true' },               async:false })           .responseText        );

if (nrisonlyquery.query.redirects) { // resolve any redirects for (var r in nrisonlyquery.query.redirects) { title=nrisonlyquery.query.redirects[r].to           } }

for (var page in nrisonlyquery.query.pages) { if (typeof nrisonlyquery.query.pages[page].missing!="undefined") { ArticledStr="un"+ArticledStr continue }           if (nrisonlyquery.query.pages[page].categories) { NRISStr="NRIS-only" }       }

var catlist='Category:FA-Class National Register of Historic Places articles‎|Category:A-Class National Register of ' catlist+='Historic Places articles‎|Category:GA-Class National Register of Historic Places articles‎|Category:B-Class ' catlist+='National Register of Historic Places articles‎|Category:C-Class National Register of Historic Places ' catlist+='articles‎|Category:Start-Class National Register of Historic Places articles‎|Category:Stub-Class National ' catlist+='Register of Historic Places articles‎|Category:Unassessed National Register of Historic Places ' catlist+='articles‎|Category:List-Class National Register of Historic Places articles|Category:Redirect-Class National ' catlist+='Register of Historic Places articles'

if (ArticledStr!="unarticled") { var statsquery=JSON.parse( // look at quality stats                $.ajax({ dataType: "json", url: mw.util.wikiScript('api'), data: { format: 'json', action: 'query', prop: 'categories', clcategories: catlist, cllimit: 'max', titles: 'Talk:'+title, redirects: 'true' },                   async:false })               .responseText            );

for (var page in statsquery.query.pages) { var tagged = "no" if (statsquery.query.pages[page].categories) { tagged = "yes" for (var category in statsquery.query.pages[page].categories) { var CatTitle=statsquery.query.pages[page].categories[category].title if (CatTitle.indexOf("Stub")!=-1) { AssessmentStr="Stub-class" continue }                       if (CatTitle.indexOf("Unassessed")!=-1||CatTitle.indexOf("Redirect")!=-1) { // also count rdr unassessed AssessmentStr="unassessed" continue }                       if  (CatTitle.indexOf("List")!=-1) { if (statsquery.query.pages[page].title.indexOf("National Register of Historic Places")!=-1){ ArticledStr="un"+ArticledStr continue } else { AssessmentStr="Stub-class" continue }                       }                        AssessmentStr="Start+" }               }                if (tagged=="no") { AssessmentStr="untagged" }           }        }

var StatsStr = ArticledStr+", "+IllustratedStr if (AssessmentStr!="") StatsStr+=", "+AssessmentStr if (NRISStr!="") StatsStr+=", "+NRISStr

return StatsStr }

function GenerateDuplicateTable(StateStructure,i,list,stateName,CountySpan,ThisStateSpan) { var wikitext="" var switchtabletext="" // check county-level duplicates CountySpan.innerHTML=" First checking county-level duplications in this state..." var NumberFound=0

for (var j=1; j<StateStructure[i].length; j++) { wikitext+="==="+StateStructure[i][j][0]+", "+StateStructure[i][0]+"===\n" var TotalCountyDuplicates=0 var TotalCountyArticled=0 var TotalCountyIllustrated=0 var TotalCountyStub=0 var TotalCountyNRISOnly=0 var TotalCountyStartPlus=0 var TotalCountyUnassessed=0 var TotalCountyUntagged=0

for (var k=0; k<list.length; k++) { var numberlists=list[k].length-2 var NumberInThisCounty=0 var temp=[]; for (var l=0; l<list[k].length; l++) { // make temp static temp[l]=list[k][l] }           for (var l=2; l<temp.length; l++) { var ListName=temp[l].replace(/National Register of Historic Places listings (i|o)n /g,"") ListName=ListName.replace(", "+stateName,"") var oldnumber=NumberInThisCounty for (var m=0; m<StateStructure[i][j][1].length; m++) { if (ListName==StateStructure[i][j][1][m]) NumberInThisCounty++ }               if (NumberInThisCounty==oldnumber) {temp.splice(l,1); l--}  // get rid of sublists not in this county }           if (NumberInThisCounty>1) { NumberFound++ CountySpan.innerHTML=" First checking county-level duplications in this state... " CountySpan.innerHTML+=NumberFound+" found so far..." TotalCountyDuplicates++ if (TotalCountyDuplicates==1) { wikitext+="{| class=\"wikitable sortable\" width=100%\n! {{NRHP color}} width=30% | Site\n! {{NRHP " wikitext+="color}} width=30% | Lists\n! {{NRHP color}} width=10% | Number of Duplicates\n! {{NRHP " wikitext+="color}} width=30% colspan=7 | Stats\n" }               wikitext+="|-\n| "+temp[1]+" (#"+temp[0]+")\n|\n" for (var m=2; m<temp.length; m++) { wikitext+="*"+temp[m].replace(/National Register of Historic Places listings (i|o)n /g,"")                   wikitext+="\n" }               var duplications=NumberInThisCounty-1 TotalCountyDuplicates+=duplications-1 wikitext+="| align=center | "+duplications+"\n| colspan=7 | "

var StatsStr=getDuplicateStats(temp) if (StatsStr.indexOf("unarticled")==-1) TotalCountyArticled+=duplications if (StatsStr.indexOf(", illustrated")!=-1) TotalCountyIllustrated+=duplications if (StatsStr.indexOf("Stub-class")!=-1) TotalCountyStub+=duplications if (StatsStr.indexOf("NRIS-only")!=-1) TotalCountyNRISOnly+=duplications if (StatsStr.indexOf("Start+")!=-1) TotalCountyStartPlus+=duplications if (StatsStr.indexOf("unassessed")!=-1) TotalCountyUnassessed+=duplications if (StatsStr.indexOf("untagged")!=-1) TotalCountyUntagged+=duplications

wikitext+=StatsStr+"\n"

if (NumberInThisCounty==numberlists) { // if only duplicated inside this county, get rid of it                    list.splice(k,1) k-- }           }        }        if (TotalCountyDuplicates==0) { wikitext+="There are no duplications across sublists of "+StateStructure[i][j][0] wikitext+=", "+StateStructure[i][0]+".\n\n"

switchtabletext+="   |"+StateStructure[i][j][0]+", "+StateStructure[i][0]+"=0  0  -  " switchtabletext+="0 -  0  0  0  -  0  0  - \n"

CountySpan.innerHTML=" First checking county-level duplications in this state... None found." } else { wikitext+="|-\n! colspan=2 | Total\n! "+TotalCountyDuplicates+"\n! "+TotalCountyIllustrated+"\n! " wikitext+=TotalCountyArticled+"\n! "+TotalCountyStub+"\n! "+TotalCountyNRISOnly+"\n! "+TotalCountyStartPlus wikitext+="\n! "+TotalCountyUnassessed+"\n! "+TotalCountyUntagged+"\n|}\n\n"

switchtabletext+="   |"+StateStructure[i][j][0]+", "+StateStructure[i][0]+"="+TotalCountyDuplicates+"  " switchtabletext+=TotalCountyIllustrated+" -  "+TotalCountyArticled+"  -  " switchtabletext+=TotalCountyStub+" "+TotalCountyNRISOnly+"  "+TotalCountyStartPlus switchtabletext+=" -  "+TotalCountyUnassessed+"  "+TotalCountyUntagged+"  - \n"

CountySpan.innerHTML=" First checking county-level duplications in this state... Complete! "+TotalCountyDuplicates+" found." }   }    if (StateStructure[i].length==1) { CountySpan.innerHTML=" First checking county-level duplications in this state... None found." }   ThisStateSpan.innerHTML=" Now checking statewide duplicates..." if (StateStructure[i].length>1) wikitext+="==="+StateStructure[i][0]+" Statewide===\n" if (list.length==0) { wikitext+="There are no duplications across sublists of "+StateStructure[i][0]+".\n\n"

switchtabletext+="|"+StateStructure[i][0]+"=0 0  -  0  -  0  0  0" switchtabletext+=" -  0  0  - \n" } else { var TotalStateDuplicates=0 var TotalStateArticled=0 var TotalStateIllustrated=0 var TotalStateStub=0 var TotalStateNRISOnly=0 var TotalStateStartPlus=0 var TotalStateUnassessed=0 var TotalStateUntagged=0

wikitext+="{| class=\"wikitable sortable\" width=100%\n! {{NRHP color}} width=30% | Site\n! {{NRHP " wikitext+="color}} width=30% | Lists\n! {{NRHP color}} width=10% | Number of Duplicates\n! {{NRHP " wikitext+="color}} width=30% colspan=7 | Stats\n"

for (var j=0; j<list.length; j++) { ThisStateSpan.innerHTML=" Now checking statewide duplicates... " ThisStateSpan.innerHTML+=j+" of "+list.length+" examined so far..."

wikitext+="|-\n| "+list[j][1]+" (#"+list[j][0]+")\n|\n" for (var m=2; m<list[j].length; m++) { wikitext+="*"               wikitext+=list[j][m].replace(/National Register of Historic Places listings (i|o)n /g,"")+"\n" }

var thisDuplicateStates=[]; for (var l=2; l<list[j].length; l++) { var ListName=list[j][l].replace(/National Register of Historic Places listings (i|o)n /g,"") ListName=ListName.replace(", "+stateName,"") thisDuplicateStates.push(ListName) for (var k=1; k<StateStructure[i].length; k++) { for (var m=0; m<StateStructure[i][k][1].length; m++) { if (ListName==StateStructure[i][k][1][m]) { thisDuplicateStates[thisDuplicateStates.length-1]=StateStructure[i][k][0] }                   }                }            }

for (var l=0;l<thisDuplicateStates.length; l++) {   // shrink list if duplicated inside single county for (var m=l+1;m<thisDuplicateStates.length; m++) { if (thisDuplicateStates[l]==thisDuplicateStates[m]) {thisDuplicateStates.splice(m,1);m--} }           }            var duplications=thisDuplicateStates.length-1

TotalStateDuplicates+=duplications wikitext+="| align=center | "+duplications+"\n| colspan=7 | "

var StatsStr=getDuplicateStats(list[j]) if (StatsStr.indexOf("unarticled")==-1) TotalStateArticled+=duplications if (StatsStr.indexOf(", illustrated")!=-1) TotalStateIllustrated+=duplications if (StatsStr.indexOf("Stub-class")!=-1) TotalStateStub+=duplications if (StatsStr.indexOf("NRIS-only")!=-1) TotalStateNRISOnly+=duplications if (StatsStr.indexOf("Start+")!=-1) TotalStateStartPlus+=duplications if (StatsStr.indexOf("unassessed")!=-1) TotalStateUnassessed+=duplications if (StatsStr.indexOf("untagged")!=-1) TotalStateUntagged+=duplications

wikitext+=StatsStr+"\n" }       wikitext+="|-\n! colspan=2 | Total\n! "+TotalStateDuplicates+"\n! "+TotalStateIllustrated+"\n! " wikitext+=TotalStateArticled+"\n! "+TotalStateStub+"\n! "+TotalStateNRISOnly+"\n! "+TotalStateStartPlus wikitext+="\n! "+TotalStateUnassessed+"\n! "+TotalStateUntagged+"\n|}\n\n"

switchtabletext+="|"+StateStructure[i][0]+"="+TotalStateDuplicates+" "+TotalStateIllustrated+"  -  " switchtabletext+=TotalStateArticled+" -  "+TotalStateStub+"  "+TotalStateNRISOnly+"  " switchtabletext+=TotalStateStartPlus+" -  "+TotalStateUnassessed+"  "+TotalStateUntagged switchtabletext+=" - \n" }   return [wikitext,switchtabletext] }

// subroutine to determine state from list name function getState(title) { var temp=title.split(", ") var state=temp[temp.length-1] if (state=="Philadelphia") state="Pennsylvania" if (temp[0]==state||state.indexOf(':')!=-1) { if (title.indexOf("Chicago")!=-1) state="Illinois" else if (title.indexOf("St. Louis")!=-1) state="Missouri" else if (title.indexOf("Kansas City")!=-1) state="Missouri" else if (title.indexOf("Baltimore")!=-1) state="Maryland" else if (title.indexOf("Manhattan")!=-1) state="New York" else if (title.indexOf("Philadelphia")!=-1) state="Pennsylvania" else if (title.indexOf("Zion")!=-1) state="Utah" else state="" }   return state }

// dump lists to subpages function NRISOnlyDump(info,Span,subpages,doneEditing) { var api = new mw.Api;

api.postWithToken( "edit", {       action: "edit",        title: info.title,        summary: info.summary,        text: info.text,        bot: 'true'        },        {async:false}) .done( function(data) {       if (data && data.edit && data.edit.result && data.edit.result=="Success") {            if (doneEditing=="no") {                Span.innerHTML=" Dumping data to subpages of "                Span.innerHTML+="<a href='http://en.wikipedia.org/wiki/"+OutputBase+"'>"+OutputBase+"</a>... "+subpages+" edits made."            } else if (doneEditing=="yes") {                Span.innerHTML=" Dumping data to subpages of "                Span.innerHTML+="<a href='http://en.wikipedia.org/wiki/"+OutputBase+"'>"+OutputBase+"</a>... Done! "+subpages                Span.innerHTML+=" subpages edited successfully!"            } else if (doneEditing=="NRIS") {                Span.innerHTML+="Done! Click link to see output!"

// output technical information to console var WarningText="NRHP Progress Warnings: " for (var i=0; i<WarningCount.length; i++) { WarningText+=WarningCount[i][0]+" ("+WarningCount[i][1]+"), " }               if (WarningCount[0][0]!="") { WarningText=WarningText.substr(0,WarningText.length-2) } else { WarningText="NRHP Progress Warnings: none" }               throw(WarningText) } else if (doneEditing=="duplicates") { Span.innerHTML+=" Output saved! Click link to see it." }       } else { Span.innerHTML += " The edit query returned an error! Aborting script." alert('Edit query error:\n'+data.error.code+': '+data.error.info+'\nClick OK to view raw wikitext for latest subpage.'); var popup = open(""); var div = popup.document.createElement("div"); div.innerHTML=info.title+"  "+info.text popup.document.body.appendChild(div); }   })    .fail( function { Span.innerHTML += " The edit query returned an error! Aborting script." alert('Ajax failure. Click OK to view raw wikitext for latest subpage.'); var popup = open(""); var div = popup.document.createElement("div"); div.innerHTML=info.title+"  "+info.text popup.document.body.appendChild(div); }); }

function getNRISOnlyProgressPageWikitext(title) {   // asynchronous fetch of Progress page wikitext $.ajax({       dataType: "json",        url: mw.util.wikiScript('api'),        data: {            format: 'json',            action: 'query',            prop: 'revisions',            rvprop: 'content',            titles: title,            indexpageids: true,            redirects: 'true'        },        error: function {wikitext="error"},        success: function(output) {            for (page in output.query.pages) {                wikitext=output.query.pages[page].revisions[0]['*'];            }        },        complete: function {            if (wikitext=="error") {                var ProgressDiv=document.getElementById("ProgressDiv")                ProgressDiv.innerHTML+=" Unable to fetch wikitext! Script aborted."            } else {                SetupNRISOnlyTables            }        }    }) }

function getNRISOnlyListWikitext(currentTable,currentRow) {  // asynchronous fetch of each list's wikitext $.ajax({       dataType: "json",        url: mw.util.wikiScript('api'),        data: {            format: 'json',            action: 'query',            prop: 'revisions',            rvprop: 'content',            titles: NRISOnlyStructure[currentTable][currentRow].Link,            indexpageids: true,            redirects: 'true'        },        error: function(ajaxResponse,status,errorThrown) {ajaxResponse.errorThrown=errorThrown},        complete: function(ajaxResponse,status) {NRISOnlyWikitextFetched(ajaxResponse,status,currentTable,currentRow)}    }) }

function getNRISOnlyWikitext(title) {  // legacy synchronous fetch Wikitext of each page for tagging try { var output=JSON.parse(           $.ajax({ dataType: "json", url: mw.util.wikiScript('api'), data: { format: 'json', action: 'query', prop: 'revisions', rvprop: 'content', titles: title, indexpageids: true, redirects: 'true' },               async:false })           .responseText        ); for (page in output.query.pages) { wikitext = output.query.pages[page].revisions[0]['*']; }       return wikitext }   catch(err) { return "error" } }

// legacy check to see if article is NRIS-only used during tagging function NRISOnlyQuery(toQuery,SubpageSpan) { // look through wikitext of each article to find NRIS-only ones var ToBeTagged=[]; var ToBeUntagged=[]; var Unreferenced=[]; var OneRefNotNRIS=[]; var AllNRISOnly=[]; var Substubs=[]; var Errors=[]; var isTagged="no" for (var k=1;k<toQuery.length+1; k++) { SubpageSpan.innerHTML = " Finding NRIS-only articles... Querying page "+k+" of "+toQuery.length+" in this county..." var wikitext=getNRISOnlyWikitext(toQuery[k-1]) isTagged="no" if (wikitext!="error") { // calculate prose size var prose=wikitext.replace(/\<\!\-\-(.|[\r\n])*?\-\-\>/g,"")                       // strip comments prose=prose.replace(/\<ref[^e](.|[\r\n])*?([ ]*?\/|\<\/ref[ ]*?)\>/gi,"")          // strip refs prose=prose.replace(/==[ ]*?External links[ ]*?==(.|\n)*?(?=(==.*?==|$))/gi,"")    // strip external links section prose=prose.replace(/==[ ]*?See also[ ]*?==(.|\n)*?(?=(==.*?==|$))/gi,"")          // strip see also section prose=prose.replace(/==[ ]*?(References|Notes)[ ]*?==(.|\n)*?(?=(==.*?==|$))/gi,"") // strip references section // strip further reading section prose=prose.replace(/==[ ]*?(Further|Additional) reading[ ]*?==(.|\n)*?(?=(==.*?==|$))/gi,"") prose=prose.replace(/={2,5}.*?={2,5}/g,"")                                         // strip section titles // replace wikilinks with displayed text prose=prose.replace(/\\]/gi,"$2") prose=prose.replace(/\[[ ]*?http.*? (.*?)\]/g,"$1")                // replace inline external links with displayed text            prose=prose.replace(/'{2,5}(.*?)'{2,5}/g,"$1")                      // replace bold/italic with displayed text            prose=prose.replace(/\[\[[ ]*?Category:.*?\]\]/g,"")                                // strip categories            prose=prose.replace(/\[\[[ ]*?(Image|File):.*?\]\]/g,"")                            // strip images            prose=prose.replace(/\<[ ]*?gallery(.|\n)*?\<[ ]*?\/[ ]*?gallery[ ]*?\>/gi,"")      // strip galleries            while(true) {                                                                       // strip templates                var str="{{"                var start=prose.indexOf(str)                if (start==-1) break                var open=1                var index=start+str.length                while (open!=0 && index<prose.length) {                    if (prose.substr(index,2)=="}}") {                        open--                        index++                    } else if (prose.substr(index,2)=="{{") {                        open++                        index++                    }                    index++                }                prose=prose.replace(prose.substr(start,index-start),"")            }            prose=prose.replace(/{\|(.|\n)*?\|}/g,"")                   // strip tables            prose=prose.replace(/ /g," ")                          // replace nbsp with regular space            prose=prose.replace(/<[ ]*?br.*?>/g, "\n")                  // replace HTML line break with string line break            prose=prose.replace(/[ \n]+/g," ")                          // replace multiple spaces/linebreaks with single space            prose=prose.trim

if (prose.length<325) Substubs[Substubs.length]=[toQuery[k-1],prose.length]

if (wikitext.match(/{{( |[\r\n])*?NRIS-only(.|[\r\n])*?}}/g)!=null) isTagged="yes" if (wikitext.indexOf("{{GR")!=-1||wikitext.indexOf("{{sfn")!=-1||wikitext.indexOf("{{Sfn")!=-1) { if (isTagged=="yes") ToBeUntagged.push(toQuery[k-1]) continue }           var Refs=wikitext.match(/\<ref[^e](.|[\r\n])*?([ ]*?\/|\<\/ref[ ]*?)\>/gi) var comments=wikitext.match(/\<\!\-\-(.|[\r\n])*?\-\-\>/g)

if (Refs==null) {    // if no refs, count as unreferenced Unreferenced.push(toQuery[k-1]) continue }

if (comments!=null) { for (var l=0; l<comments.length; l++) { var CommentedRefs=comments[l].match(/\<ref[^e](.|[\r\n])*?([ ]*?\/|\<\/ref[ ]*?)\>/gi) if (CommentedRefs==null) continue for (var m=0; m<CommentedRefs.length; m++) { for (var n=0; n<Refs.length; n++) { if (Refs[n]==CommentedRefs[m]) {Refs.splice(n,1); n--} }                   }                }            }

if (Refs.length==0) {   // if all refs commented out, count as unreferenced Unreferenced.push(toQuery[k-1]) continue }

var citesNRIS="no" for (var l=0; l<Refs.length; l++) { if (Refs[l].indexOf("{{NRISref")!=-1) citesNRIS="yes" }

var namedRefs=[]; var Duplications=[]; for (var l=0; l<Refs.length; l++) { var nameOfRef=Refs[l].match(/name[ ]*?=.*?(\/|\>)/gi) if (nameOfRef==null) { continue } else { nameOfRef = nameOfRef[0].replace(/("| )/g,'')                   nameOfRef = nameOfRef.substr(5,nameOfRef.length-6)                }                namedRefs.push(nameOfRef)                Duplications.push(1)                for (var m=0; m<namedRefs.length-1; m++) {   // if title is duplicated, count how many times                    if (nameOfRef==namedRefs[m]) {                        namedRefs.splice(m,1)                        Duplications[Duplications.length-1] = Duplications[m] + 1                        Duplications.splice(m,1);                        m--                    }                }            }            if (namedRefs.length==2&&namedRefs[0]==namedRefs[1]) Duplications[0]++ // fix for if all refs are same            var toSubtract=0            for (var l=0; l<Duplications.length; l++) {                toSubtract = toSubtract + Duplications[l] - 1            }

var DistinctRefs = Refs.length-toSubtract

if (DistinctRefs>1) { if (isTagged=="yes") ToBeUntagged.push(toQuery[k-1]) // untag if ref has been added since tag placed continue }           if (citesNRIS=="no") {OneRefNotNRIS.push(toQuery[k-1]);continue} // if only one ref and not NRIS, count that if (isTagged=="no") ToBeTagged.push(toQuery[k-1]) // only push if the only ref is NRISref and it's not already tagged AllNRISOnly.push(toQuery[k-1]) } else { Errors.push(toQuery[k-1]); continue; }   }    return [ToBeTagged,ToBeUntagged,Unreferenced,OneRefNotNRIS,AllNRISOnly,Substubs,Errors] }

$(window).load(CheckPermission);