Jump to content
Wikipedia The Free Encyclopedia

User:MrDenjiLover/CHNSAW.js

From Wikipedia, the free encyclopedia
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump.
This code will be executed when previewing this page.
This user script seems to have a documentation page at User:MrDenjiLover/CHNSAW.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
 // <nowiki>
 (function(){
 'use strict';

 constisDiffPage=mw.config.get('wgAction')==='view'&&mw.config.get('wgDiffNewId');
 constisUserTalkPage=mw.config.get('wgCanonicalNamespace')==='User_talk';
 constisUserPage=mw.config.get('wgCanonicalNamespace')==='User';
 constisPrefsPage=mw.config.get('wgPageName')==='User:MrDenjiLover/CHNSAW/Prefs';

 if(isPrefsPage){
 constprefsContainer=document.createElement('div');
 prefsContainer.style.cssText=`
  max-width: 600px;
  margin: 20px auto;
  padding: 20px;
  background: white;
  border: 2px solid #a2a9b1;
  border-radius: 8px;
  `;

 constsavedShortcut=localStorage.getItem('chnsaw-shortcut')||'`';

 prefsContainer.innerHTML=`
  <h2 style="margin-top: 0; color: #202122;">CHNSAW Preferences</h2>
  <p style="color: #54595d;">Manage your CHNSAW settings</p>
  <hr style="border: none; border-top: 1px solid #a2a9b1; margin: 15px 0;">
  <div style="margin-bottom: 20px;">
  <h3 style="font-size: 16px; color: #202122;">Keyboard Shortcut</h3>
  <p style="font-size: 13px; color: #54595d; margin-bottom: 10px;">Choose the key to open CHNSAW</p>
  <select id="chnsaw-shortcut-select" style="width: 100%; padding: 8px; border: 1px solid #a2a9b1; border-radius: 3px; font-size: 13px; margin-bottom: 10px;">
  <option value="\`">\` (backtick)</option>
  <option value="-">- (minus)</option>
  <option value="=">= (equals)</option>
  <option value="[">[ (left bracket)</option>
  <option value="]">] (right bracket)</option>
  <option value="\\">\\ (backslash)</option>
  <option value=",">, (comma)</option>
  <option value=".">. (period)</option>
  <option value="/">/ (forward slash)</option>
  <option value=";">; (semicolon)</option>
  <option value="'">' (quote)</option>
  </select>
  <button id="chnsaw-save-shortcut" style="padding: 8px 16px; background: #36c; color: white; border: none; border-radius: 3px; cursor: pointer; font-size: 13px; font-weight: bold;">Save Shortcut</button>
  <div id="chnsaw-shortcut-status" style="margin-top: 10px; font-size: 12px; display: none;"></div>
  </div>
  <hr style="border: none; border-top: 1px solid #a2a9b1; margin: 15px 0;">
  <div style="margin-bottom: 15px;">
  <h3 style="font-size: 16px; color: #202122;">Button Position</h3>
  <p style="font-size: 13px; color: #54595d; margin-bottom: 10px;">Reset the CHNSAW button to its default position (bottom-right corner)</p>
  <button id="chnsaw-reset-position" style="padding: 8px 16px; background: #36c; color: white; border: none; border-radius: 3px; cursor: pointer; font-size: 13px; font-weight: bold;">Reset Position</button>
  <div id="chnsaw-reset-status" style="margin-top: 10px; font-size: 12px; display: none;"></div>
  </div>
  `;

 constcontentDiv=document.getElementById('mw-content-text');
 if(contentDiv){
 contentDiv.innerHTML='';
 contentDiv.appendChild(prefsContainer);
 }

 constshortcutSelect=document.getElementById('chnsaw-shortcut-select');
 shortcutSelect.value=savedShortcut;

 document.getElementById('chnsaw-save-shortcut').addEventListener('click',()=>{
 constnewShortcut=shortcutSelect.value;
 localStorage.setItem('chnsaw-shortcut',newShortcut);
 conststatus=document.getElementById('chnsaw-shortcut-status');
 status.textContent=`✓ Shortcut saved! Press ${newShortcut} to open CHNSAW.`;
 status.style.display='block';
 status.style.color='#14866d';
 });

 document.getElementById('chnsaw-reset-position').addEventListener('click',()=>{
 localStorage.removeItem('chnsaw-position');
 conststatus=document.getElementById('chnsaw-reset-status');
 status.textContent='✓ Position reset! Reload any page to see the button in its default position.';
 status.style.display='block';
 status.style.color='#14866d';
 });

 return;
 }

 if(!isDiffPage&&!isUserTalkPage&&!isUserPage){
 return;
 }

 constoldId=mw.config.get('wgDiffOldId');
 constnewId=mw.config.get('wgDiffNewId');
 constpageTitle=mw.config.get('wgPageName');

 constcontainer=document.createElement('div');
 container.id='antivandal-container';

 constsavedPos=localStorage.getItem('chnsaw-position');
 letposStyle='bottom: 20px; right: 20px;';

 if(savedPos){
 constpos=JSON.parse(savedPos);
 posStyle=`top: ${pos.top}px; left: ${pos.left}px;`;
 }

 container.style.cssText=`
  position: fixed;
 ${posStyle}
  z-index: 10000;
  font-family: sans-serif;
  cursor: move;
  `;

 constminButton=document.createElement('button');
 minButton.id='antivandal-min';
 minButton.title='CHNSAW Anti-Vandalism Tool';
 minButton.style.cssText=`
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background: #ff8c00;
  color: white;
  border: 2px solid #d67000;
  font-weight: bold;
  cursor: pointer;
  font-size: 14px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.3);
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  `;

 consticon=document.createElement('img');
 icon.src='https://upload.wikimedia.org/wikipedia/en/9/9c/CHNSAW_Anti-Vandal_logo.png';
 icon.style.cssText=`
  width: 30px;
  height: 30px;
  object-fit: contain;
  `;
 minButton.appendChild(icon);

 constpanel=document.createElement('div');
 panel.id='antivandal-panel';
 panel.style.cssText=`
  display: none;
  background: white;
  border: 2px solid #a2a9b1;
  border-radius: 8px;
  padding: 15px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.3);
  min-width: 320px;
  max-height: 600px;
  overflow-y: auto;
  position: fixed;
  z-index: 10001;
  `;

 letpanelHTML=`
  <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
  <h3 style="margin: 0; font-size: 16px; color: #202122;">CHNSAW</h3>
  <button id="antivandal-close" style="background: none; border: none; font-size: 20px; cursor: pointer; color: #72777d;">&times;</button>
  </div>`;

 if(isDiffPage){
 panelHTML+=`
  <div style="margin-bottom: 10px; font-size: 13px; color: #54595d;">
  <strong>Page:</strong> <span id="av-page"></span><br>
  <strong>Diff:</strong> <span id="av-diff"></span>
  </div>
  <div style="margin-bottom: 10px;">
  <label style="display: block; margin-bottom: 5px; font-size: 13px; color: #202122;">Revert reason:</label>
  <select id="av-reason" style="width: 100%; padding: 5px; border: 1px solid #a2a9b1; border-radius: 3px; font-size: 13px;">
  <option value="vandalism">Vandalism</option>
  <option value="test">Test edit</option>
  <option value="spam">Spam</option>
  <option value="delete">Removing content</option>
  <option value="unsourced">Unsourced content</option>
  <option value="blp">BLP violation</option>
  <option value="error">Introducing errors</option>
  <option value="attack">Personal attacks</option>
  <option value="advert">Advertising</option>
  <option value="npov">Not neutral (POV)</option>
  <option value="defamatory">Defamatory content</option>
  <option value="llm">Unreviewed LLM content</option>
  <option value="joke">Joke edits</option>
  <option value="own">Ownership of articles</option>
  <option value="image">Improper image use</option>
  <option value="custom">Custom reason...</option>
  </select>
  </div>
  <div id="av-custom-reason" style="display: none; margin-bottom: 10px;">
  <input type="text" id="av-custom-input" placeholder="Enter custom reason" style="width: 100%; padding: 5px; border: 1px solid #a2a9b1; border-radius: 3px; font-size: 13px; box-sizing: border-box;">
  </div>
  <div style="margin-bottom: 10px;">
  <button id="av-revert" style="width: 100%; padding: 8px; background: #36c; color: white; border: none; border-radius: 3px; cursor: pointer; font-size: 13px; font-weight: bold;">Revert</button>
  </div>
  <hr style="border: none; border-top: 1px solid #a2a9b1; margin: 15px 0;">`;
 }

 if(isUserTalkPage){
 panelHTML+=`
  <div style="margin-bottom: 10px; font-size: 13px; color: #54595d;">
  <strong>User:</strong> <span id="av-talk-user"></span>
  </div>`;
 }

 if(isUserPage){
 panelHTML+=`
  <div style="margin-bottom: 10px; font-size: 13px; color: #54595d;">
  <strong>User:</strong> <span id="av-user-page"></span>
  </div>`;
 }

 panelHTML+=`
  <div style="margin-bottom: 10px;">
  <label style="display: block; margin-bottom: 5px; font-size: 13px; color: #202122; font-weight: bold;">Warning Options</label>
  </div>`;

 if(!isUserPage){
 panelHTML+=`
  <div style="margin-bottom: 10px;">
  <label style="display: flex; align-items: center; font-size: 13px; color: #202122;">
  <input type="checkbox" id="av-auto-level" style="margin-right: 5px;">
  Auto-detect warning level
  </label>
  <div id="av-level-info" style="margin-top: 5px; font-size: 12px; color: #54595d; display: none;"></div>
  </div>
  <div id="av-manual-level" style="margin-bottom: 10px;">
  <label style="display: block; margin-bottom: 5px; font-size: 13px; color: #202122;">Warning level:</label>
  <select id="av-warn-level" style="width: 100%; padding: 5px; border: 1px solid #a2a9b1; border-radius: 3px; font-size: 13px;">
  <option value="1">Level 1 (Notice)</option>
  <option value="2">Level 2 (Caution)</option>
  <option value="3">Level 3 (Warning)</option>
  <option value="4">Level 4 (Final warning)</option>
  <option value="4im">Level 4im (Only warning)</option>
  </select>
  </div>
  <div style="margin-bottom: 10px;">
  <label style="display: block; margin-bottom: 5px; font-size: 13px; color: #202122;">Warning type:</label>
  <select id="av-warn-type" style="width: 100%; padding: 5px; border: 1px solid #a2a9b1; border-radius: 3px; font-size: 13px;">
  <option value="vandalism">Vandalism</option>
  <option value="test">Test edits</option>
  <option value="spam">Spam</option>
  <option value="delete">Removing content</option>
  <option value="unsourced">Unsourced content</option>
  <option value="blp">BLP violations</option>
  <option value="error">Introducing errors</option>
  <option value="attack">Personal attacks</option>
  <option value="advert">Advertising</option>
  <option value="npov">Not neutral (POV)</option>
  <option value="defamatory">Defamatory content</option>
  <option value="llm">Unreviewed LLM content</option>
  <option value="joke">Joke edits</option>
  <option value="own">Ownership of articles</option>
  <option value="image">Improper image use</option>
  </select>
  </div>
  <div style="margin-bottom: 10px;">
  <label style="display: block; margin-bottom: 5px; font-size: 13px; color: #202122;">Article vandalized:</label>
  <input type="text" id="av-warn-page" placeholder="Article name" style="width: 100%; padding: 5px; border: 1px solid #a2a9b1; border-radius: 3px; font-size: 13px; box-sizing: border-box;">
  </div>
  <div style="display: flex; gap: 8px;">`;
 }else{
 panelHTML+=`
  <div style="margin-bottom: 10px;">
  <label style="display: block; margin-bottom: 5px; font-size: 13px; color: #202122; font-weight: bold;">Report Options</label>
  </div>
  <div style="margin-bottom: 10px;">
  <label style="display: block; margin-bottom: 5px; font-size: 13px; color: #202122;">Report to:</label>
  <select id="av-report-board" style="width: 100%; padding: 5px; border: 1px solid #a2a9b1; border-radius: 3px; font-size: 13px;">
  <option value="aiv">AIV (Administrator intervention against vandalism)</option>
  <option value="uaa">UAA (Usernames for administrator attention)</option>
  </select>
  </div>
  <div id="av-report-reason-container">
  <div id="av-aiv-reasons" style="margin-bottom: 10px;">
  <label style="display: block; margin-bottom: 5px; font-size: 13px; color: #202122;">Reason:</label>
  <select id="av-aiv-reason" style="width: 100%; padding: 5px; border: 1px solid #a2a9b1; border-radius: 3px; font-size: 13px;">
  <option value="nothere">Clearly not here to build an encyclopedia</option>
  <option value="finalwarn">Vandalism after final warning</option>
  <option value="vandalonly">Obvious vandalism only account</option>
  </select>
  </div>
  <div id="av-uaa-reasons" style="margin-bottom: 10px; display: none;">
  <label style="display: block; margin-bottom: 5px; font-size: 13px; color: #202122;">Reason:</label>
  <select id="av-uaa-reason" style="width: 100%; padding: 5px; border: 1px solid #a2a9b1; border-radius: 3px; font-size: 13px;">
  <option value="inappropriate">Inappropriate username</option>
  <option value="disruptive">Disruptive username</option>
  <option value="promotional">Promotional username</option>
  </select>
  </div>
  </div>
  <div style="display: flex; gap: 8px;">
  <button id="av-report-user" style="width: 100%; padding: 8px; background: #d33; color: white; border: none; border-radius: 3px; cursor: pointer; font-size: 13px; font-weight: bold;">Report User</button>
  </div>`;
 }

 if(isDiffPage){
 panelHTML+=`
  <button id="av-warn-only" style="flex: 1; padding: 8px; background: #fc3; color: #000; border: none; border-radius: 3px; cursor: pointer; font-size: 13px; font-weight: bold;">Warn Only</button>
  <button id="av-revert-warn" style="flex: 1; padding: 8px; background: #d33; color: white; border: none; border-radius: 3px; cursor: pointer; font-size: 13px; font-weight: bold;">Revert & Warn</button>`;
 }elseif(isUserTalkPage){
 panelHTML+=`
  <button id="av-warn-only" style="width: 100%; padding: 8px; background: #fc3; color: #000; border: none; border-radius: 3px; cursor: pointer; font-size: 13px; font-weight: bold;">Post Warning</button>`;
 }

 if(!isUserPage){
 panelHTML+=`</div>`;
 }

 panelHTML+=`
  <div id="av-status" style="margin-top: 10px; font-size: 12px; padding: 8px; border-radius: 3px; display: none;"></div>`;

 panel.innerHTML=panelHTML;

 container.appendChild(minButton);
 container.appendChild(panel);
 document.body.appendChild(container);

 letisDragging=false;
 letoffsetX=0;
 letoffsetY=0;

 container.addEventListener('mousedown',(e)=>{
 if(e.target===container||e.target===minButton||e.target===icon){
 isDragging=true;
 offsetX=e.clientX-container.offsetLeft;
 offsetY=e.clientY-container.offsetTop;
 container.style.cursor='grabbing';
 }
 });

 document.addEventListener('mousemove',(e)=>{
 if(isDragging){
 e.preventDefault();
 letnewLeft=e.clientX-offsetX;
 letnewTop=e.clientY-offsetY;

 constbuttonWidth=50;
 constbuttonHeight=50;

 letmaxWidth,maxHeight;

 if(panel.style.display==='block'){
 maxWidth=panel.offsetWidth||320;
 maxHeight=panel.offsetHeight||500;
 }else{
 maxWidth=buttonWidth;
 maxHeight=buttonHeight;
 }

 newLeft=Math.max(0,Math.min(newLeft,window.innerWidth-maxWidth));
 newTop=Math.max(0,Math.min(newTop,window.innerHeight-maxHeight));

 container.style.left=newLeft+'px';
 container.style.top=newTop+'px';
 container.style.right='auto';
 container.style.bottom='auto';
 }
 });

 document.addEventListener('mouseup',()=>{
 if(isDragging){
 isDragging=false;
 container.style.cursor='move';

 constpos={
 top:container.offsetTop,
 left:container.offsetLeft
 };
 localStorage.setItem('chnsaw-position',JSON.stringify(pos));
 }
 });

 constshortcutKey=localStorage.getItem('chnsaw-shortcut')||'`';

 document.addEventListener('keydown',(e)=>{
 if(e.key===shortcutKey&&!e.ctrlKey&&!e.altKey&&!e.metaKey){
 constactiveElement=document.activeElement;
 if(activeElement.tagName==='INPUT'||activeElement.tagName==='TEXTAREA'||activeElement.isContentEditable){
 return;
 }

 e.preventDefault();

 if(panel.style.display==='none'||panel.style.display===''){
 constbuttonRect=container.getBoundingClientRect();

 panel.style.display='block';

 setTimeout(()=>{
 constpanelWidth=panel.offsetWidth;
 constpanelHeight=panel.offsetHeight;

 letpanelLeft=buttonRect.left;
 letpanelTop=buttonRect.top;

 if(panelLeft+panelWidth>window.innerWidth){
 panelLeft=window.innerWidth-panelWidth;
 }
 if(panelTop+panelHeight>window.innerHeight){
 panelTop=window.innerHeight-panelHeight;
 }
 if(panelLeft<0)panelLeft=0;
 if(panelTop<0)panelTop=0;

 panel.style.left=panelLeft+'px';
 panel.style.top=panelTop+'px';

 minButton.style.display='none';
 },0);
 }else{
 panel.style.display='none';
 minButton.style.display='flex';
 }
 }
 });

 if(isDiffPage){
 document.getElementById('av-page').textContent=pageTitle.replace(/_/g,' ');
 document.getElementById('av-diff').textContent=`${oldId}${newId}`;
 document.getElementById('av-warn-page').value=pageTitle.replace(/_/g,' ');
 }

 if(isUserTalkPage){
 constusername=pageTitle.replace('User_talk:','');
 document.getElementById('av-talk-user').textContent=username.replace(/_/g,' ');
 }

 if(isUserPage){
 constusername=pageTitle.replace('User:','');
 document.getElementById('av-user-page').textContent=username.replace(/_/g,' ');

 document.getElementById('av-report-board').addEventListener('change',(e)=>{
 constaivReasons=document.getElementById('av-aiv-reasons');
 constuaaReasons=document.getElementById('av-uaa-reasons');

 if(e.target.value==='aiv'){
 aivReasons.style.display='block';
 uaaReasons.style.display='none';
 }else{
 aivReasons.style.display='none';
 uaaReasons.style.display='block';
 }
 });
 }

 minButton.addEventListener('click',()=>{
 constbuttonRect=container.getBoundingClientRect();

 panel.style.display='block';

 setTimeout(()=>{
 constpanelWidth=panel.offsetWidth;
 constpanelHeight=panel.offsetHeight;

 letpanelLeft=buttonRect.left;
 letpanelTop=buttonRect.top;

 if(panelLeft+panelWidth>window.innerWidth){
 panelLeft=window.innerWidth-panelWidth;
 }
 if(panelTop+panelHeight>window.innerHeight){
 panelTop=window.innerHeight-panelHeight;
 }
 if(panelLeft<0)panelLeft=0;
 if(panelTop<0)panelTop=0;

 panel.style.left=panelLeft+'px';
 panel.style.top=panelTop+'px';

 minButton.style.display='none';
 },0);
 });

 document.getElementById('antivandal-close').addEventListener('click',()=>{
 panel.style.display='none';
 minButton.style.display='flex';
 });

 if(isDiffPage){
 document.getElementById('av-reason').addEventListener('change',(e)=>{
 constcustomDiv=document.getElementById('av-custom-reason');
 customDiv.style.display=e.target.value==='custom'?'block':'none';

 constwarnTypeSelect=document.getElementById('av-warn-type');
 if(e.target.value!=='custom'&&warnTypeSelect){
 warnTypeSelect.value=e.target.value;
 }
 });
 }

 if(!isUserPage){
 document.getElementById('av-auto-level').addEventListener('change',(e)=>{
 constmanualLevel=document.getElementById('av-manual-level');
 manualLevel.style.display=e.target.checked?'none':'block';
 });
 }

 functionshowStatus(msg,type){
 conststatus=document.getElementById('av-status');
 status.textContent=msg;
 status.style.display='block';
 status.style.background=type==='error'?'#fee7e6':type==='success'?'#d5fdf4':'#eaecf0';
 status.style.color=type==='error'?'#d33':type==='success'?'#14866d':'#202122';
 }

 asyncfunctiongetVandal(){
 if(isUserTalkPage||isUserPage){
 returnpageTitle.replace('User_talk:','').replace('User:','').replace(/_/g,' ');
 }

 try{
 constresp=awaitfetch(`/w/api.php?action=query&prop=revisions&revids=${newId}&format=json`);
 constdata=awaitresp.json();
 constpages=data.query.pages;
 constpage=pages[Object.keys(pages)[0]];
 if(page.revisions&&page.revisions[0]){
 returnpage.revisions[0].user;
 }
 }catch(err){
 console.error('Error getting vandal username:',err);
 }
 returnnull;
 }

 asyncfunctioncountWarnings(username){
 try{
 constresp=awaitfetch(`/w/api.php?action=query&prop=revisions&titles=User_talk:${encodeURIComponent(username)}&rvprop=content&rvslots=main&formatversion=2&format=json`);
 constdata=awaitresp.json();

 if(data.query&&data.query.pages&&data.query.pages[0]){
 constpage=data.query.pages[0];

 if(page.revisions&&page.revisions[0]&&page.revisions[0].slots&&page.revisions[0].slots.main){
 constcontent=page.revisions[0].slots.main.content;

 constl1=(content.match(/Information\.svg/gi)||[]).length;
 constl2=(content.match(/Information[_ ]orange\.svg/gi)||[]).length;
 constl3=(content.match(/Nuvola[_ ]apps[_ ]important\.svg/gi)||[]).length;
 constl4=(content.match(/Stop[_ ]hand[_ ]nuvola\.svg/gi)||[]).length;

 console.log('Warning counts:',{l1,l2,l3,l4});

 return{level1:l1,level2:l2,level3:l3,level4:l4,total:l1+l2+l3+l4};
 }
 }
 }catch(err){
 console.error('Error counting warnings:',err);
 }
 return{level1:0,level2:0,level3:0,level4:0,total:0};
 }

 functiondetermineWarningLevel(warnings){
 lethighestLevel=0;

 if(warnings.level1>0)highestLevel=1;
 if(warnings.level2>0)highestLevel=2;
 if(warnings.level3>0)highestLevel=3;
 if(warnings.level4>0)highestLevel=4;

 if(highestLevel===4)return'4im';
 if(highestLevel===3)return'4';
 if(highestLevel===2)return'3';
 if(highestLevel===1)return'2';
 return'1';
 }

 asyncfunctionwarnUser(){
 constautoLevel=document.getElementById('av-auto-level').checked;
 constwarnPage=document.getElementById('av-warn-page').value.trim();
 consttype=document.getElementById('av-warn-type').value;

 if(!warnPage){
 showStatus('Please specify an article name','error');
 returnfalse;
 }

 showStatus('Getting user info...','info');

 constusername=awaitgetVandal();
 if(!username){
 showStatus('Error: Could not find user to warn','error');
 returnfalse;
 }

 letlevel;
 if(autoLevel){
 showStatus('Detecting warning level...','info');
 constwarnings=awaitcountWarnings(username);
 level=determineWarningLevel(warnings);

 constlevelInfo=document.getElementById('av-level-info');
 levelInfo.textContent=`Detected: ${warnings.total} previous warning(s). Using level ${level}.`;
 levelInfo.style.display='block';
 }else{
 level=document.getElementById('av-warn-level').value;
 }

 showStatus(`Warning user ${username}...`,'info');

 try{
 consttokenResp=awaitfetch(`/w/api.php?action=query&meta=tokens&type=csrf&format=json`);
 consttokenData=awaittokenResp.json();
 consttoken=tokenData.query.tokens.csrftoken;

 constnow=newDate();
 constmonthNames=['January','February','March','April','May','June',
 'July','August','September','October','November','December'];
 constsectionTitle=`${monthNames[now.getMonth()]}${now.getFullYear()}`;

 constparseResp=awaitfetch(`/w/api.php?action=parse&page=User_talk:${encodeURIComponent(username)}&prop=sections&format=json`);
 constparseData=awaitparseResp.json();

 letsectionExists=false;
 if(parseData.parse&&parseData.parse.sections){
 sectionExists=parseData.parse.sections.some(s=>s.line===sectionTitle);
 }

 consttemplateMap={
 'vandalism':'uw-vandalism',
 'test':'uw-test',
 'spam':'uw-spam',
 'delete':'uw-delete',
 'unsourced':'uw-unsourced',
 'blp':'uw-biog',
 'error':'uw-error',
 'attack':'uw-npa',
 'advert':'uw-advert',
 'npov':'uw-npov',
 'defamatory':'uw-defamatory',
 'llm':'uw-llm',
 'joke':'uw-joke',
 'own':'uw-own',
 'image':'uw-image'
 };

 consttemplate=templateMap[type]||'uw-vandalism';
 consttemplateName=`${template}${level}`;

 letwarningText;
 if(sectionExists){
 warningText=`\n\n{{subst:${templateName}|${warnPage}}} ~~~~`;
 }else{
 warningText=`\n\n== ${sectionTitle} ==\n{{subst:${templateName}|${warnPage}}} ~~~~`;
 }

 constparams=newURLSearchParams({
 action:'edit',
 title:`User_talk:${username}`,
 appendtext:warningText,
 summary:`Warning: ${templateName} ([[User:MrDenjiLover/CHNSAW Anti-Vandal|CHNSAW]])`,
 token:token,
 format:'json'
 });

 constwarnResp=awaitfetch('/w/api.php',{
 method:'POST',
 headers:{
 'Content-Type':'application/x-www-form-urlencoded',
 },
 body:params
 });

 constwarnData=awaitwarnResp.json();

 if(warnData.edit&&warnData.edit.result==='Success'){
 if(isDiffPage){
 showStatus(`✓ Warning posted to User talk:${username}. Redirecting in 5 seconds...`,'success');
 setTimeout(()=>{
 window.location.href=`/wiki/User_talk:${encodeURIComponent(username)}`;
 },5000);
 }else{
 showStatus(`✓ Warning posted to User talk:${username}. Refreshing in 5 seconds...`,'success');
 setTimeout(()=>{
 window.location.reload();
 },5000);
 }
 returntrue;
 }else{
 showStatus('Error: '+(warnData.error?.info||'Could not post warning'),'error');
 returnfalse;
 }
 }catch(err){
 showStatus('Error: '+err.message,'error');
 returnfalse;
 }
 }

 asyncfunctionreportUser(){
 constboard=document.getElementById('av-report-board').value;

 showStatus('Getting user info...','info');

 constusername=awaitgetVandal();
 if(!username){
 showStatus('Error: Could not find user to report','error');
 returnfalse;
 }

 letreason,reportPage;

 if(board==='aiv'){
 constaivReason=document.getElementById('av-aiv-reason').value;
 constreasonMap={
 'nothere':'Clearly [[WP:NOTHERE]]',
 'finalwarn':'Vandalism after final warning',
 'vandalonly':'Obvious vandalism only account'
 };
 reason=reasonMap[aivReason];
 reportPage='Wikipedia:Administrator_intervention_against_vandalism';
 }else{
 constuaaReason=document.getElementById('av-uaa-reason').value;
 constreasonMap={
 'inappropriate':'Inappropriate username',
 'disruptive':'Disruptive username',
 'promotional':'Promotional username'
 };
 reason=reasonMap[uaaReason];
 reportPage='Wikipedia:Usernames_for_administrator_attention';
 }

 showStatus(`Reporting ${username} to ${board.toUpperCase()}...`,'info');

 try{
 consttokenResp=awaitfetch(`/w/api.php?action=query&meta=tokens&type=csrf&format=json`);
 consttokenData=awaittokenResp.json();
 consttoken=tokenData.query.tokens.csrftoken;

 constreportText=`\n\n{{subst:Vandal|${username}}} ${reason} ~~~~`;

 constparams=newURLSearchParams({
 action:'edit',
 title:reportPage,
 appendtext:reportText,
 summary:`Reporting [[User:${username}]] ([[User:MrDenjiLover/CHNSAW Anti-Vandal|CHNSAW]])`,
 token:token,
 format:'json'
 });

 constreportResp=awaitfetch('/w/api.php',{
 method:'POST',
 headers:{
 'Content-Type':'application/x-www-form-urlencoded',
 },
 body:params
 });

 constreportData=awaitreportResp.json();

 if(reportData.edit&&reportData.edit.result==='Success'){
 showStatus(`✓ User reported to ${board.toUpperCase()}. Redirecting in 3 seconds...`,'success');
 setTimeout(()=>{
 window.location.href=`/wiki/${reportPage.replace(/ /g,'_')}`;
 },3000);
 returntrue;
 }else{
 showStatus('Error: '+(reportData.error?.info||'Could not report user'),'error');
 returnfalse;
 }
 }catch(err){
 showStatus('Error: '+err.message,'error');
 returnfalse;
 }
 }

 asyncfunctionrevertEdit(warn){
 constreasonSelect=document.getElementById('av-reason');
 letreason=reasonSelect.value;

 if(reason==='custom'){
 reason=document.getElementById('av-custom-input').value.trim();
 if(!reason){
 showStatus('Please enter a custom reason','error');
 return;
 }
 }else{
 constreasons={
 'vandalism':'Reverted vandalism',
 'test':'Reverted test edit',
 'spam':'Reverted spam',
 'delete':'Reverted removal of content',
 'unsourced':'Reverted unsourced content',
 'blp':'Reverted BLP violation',
 'error':'Reverted introduction of errors',
 'attack':'Reverted personal attacks',
 'advert':'Reverted advertising',
 'npov':'Reverted non-neutral edit',
 'defamatory':'Reverted defamatory content',
 'llm':'Reverted unreviewed LLM content',
 'joke':'Reverted joke edit',
 'own':'Reverted ownership behavior',
 'image':'Reverted improper image use'
 };
 reason=reasons[reason];
 }

 showStatus('Reverting...','info');

 try{
 consttokenResp=awaitfetch(`/w/api.php?action=query&meta=tokens&type=csrf&format=json`);
 consttokenData=awaittokenResp.json();
 consttoken=tokenData.query.tokens.csrftoken;

 constparams=newURLSearchParams({
 action:'edit',
 title:pageTitle,
 undo:newId,
 undoafter:oldId,
 summary:reason+' ([[User:MrDenjiLover/CHNSAW Anti-Vandal|CHNSAW]])',
 token:token,
 format:'json'
 });

 constrevertResp=awaitfetch('/w/api.php',{
 method:'POST',
 headers:{
 'Content-Type':'application/x-www-form-urlencoded',
 },
 body:params
 });

 constrevertData=awaitrevertResp.json();

 if(revertData.edit&&revertData.edit.result==='Success'){
 showStatus('✓ Reverted successfully!','success');

 if(warn){
 awaitwarnUser();
 }
 }else{
 showStatus('Error: '+(revertData.error?.info||'Unknown error'),'error');
 }
 }catch(err){
 showStatus('Error: '+err.message,'error');
 }
 }

 if(isDiffPage){
 document.getElementById('av-revert').addEventListener('click',()=>revertEdit(false));
 document.getElementById('av-revert-warn').addEventListener('click',()=>revertEdit(true));
 }

 if(!isUserPage){
 document.getElementById('av-warn-only').addEventListener('click',()=>warnUser());
 }else{
 document.getElementById('av-report-user').addEventListener('click',()=>reportUser());
 }

 })();
 // </nowiki>

AltStyle によって変換されたページ (->オリジナル) /