Участник:CryptoUser/yoficator.js

Материал из Decimal Wiki
Перейти к навигации Перейти к поиску

Замечание: Возможно, после публикации вам придётся очистить кэш своего браузера, чтобы увидеть изменения.

  • Firefox / Safari: Удерживая клавишу Shift, нажмите на панели инструментов Обновить либо нажмите Ctrl+F5 или Ctrl+R (⌘+R на Mac)
  • Google Chrome: Нажмите Ctrl+Shift+R (⌘+Shift+R на Mac)
  • Internet Explorer / Edge: Удерживая Ctrl, нажмите Обновить либо нажмите Ctrl+F5
  • Opera: Нажмите Ctrl+F5.
/*!
 * Скрипт-Ёфикатор для Википедии
 * Инструкция по использованию находится по адресу https://ru.wikipedia.org/wiki/Участник:Дима74/Скрипт-Ёфикатор
 * Историю изменений можно найти на гитхабе: https://github.com/dima74/Wikipedia-Yofication/commits/master
 * Файл сгенерирован с помощью webpack
 * 
 */!function(e){var t={};function o(i){if(t[i])return t[i].exports;var n=t[i]={i:i,l:!1,exports:{}};return e[i].call(n.exports,n,n.exports,o),n.l=!0,n.exports}o.m=e,o.c=t,o.d=function(e,t,i){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},o.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.t=function(e,t){if(1&t&&(e=o(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(o.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)o.d(i,n,function(t){return e[t]}.bind(null,n));return i},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,"a",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p="",o(o.s=0)}([function(e,t,o){"use strict";o.r(t);const i="https://yofication.fly.dev",n=window.location.hostname.includes(".m.wikipedia"),s=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),r=`<div style="${`\nposition: fixed;\nbottom: 30px;\nleft: 0;\nright: 0;\ndisplay: flex;\nz-index: 1;\n${s?"pointer-events: none;":""}\n`}">`+'<div id="yoficator-toast" style="\nmargin: auto;\nmin-width: 250px;\nbackground-color: #333;\ncolor: #fff;\ntext-align: center;\nborder-radius: 2px;\npadding: 16px;\ntransition: opacity 1s;\n">Спасибо, что используете скрипт-ёфикатор!</div></div>';let a=null,c=null;async function l(e,t=0){console.log(e),a||(!function(){const e=$(r).appendTo("body");a=document.getElementById("yoficator-toast"),O.isMobile&&(e.css({bottom:7}),$(a).css({padding:8}))}(),await u(0)),e=(e=e.replace(/\n/g,"<br />")).replace(/\[\[([^|]*)\|([^\]]*)]]/g,'<a href="/wiki/$1" style="color: #0ff;">$2</a>'),a.innerHTML=e,a.style.opacity=1,null!==c&&(clearTimeout(c),c=null),t&&(c=setTimeout(()=>a.style.opacity=0,t))}const d=localStorage.getItem("yoficator-m");function p(e,t="Непредвиденная ошибка. Пожалуйста, сообщите название текущей страницы [[Участник:Дима74|автору скрипта]]."){if(!e)throw l(t),new Error(t)}async function h(e,t={}){const o=t.errorMessage;delete t.errorMessage;try{e.includes("yofication")&&d&&(t.data.flag=d);const o=await $.ajax(e,t);return console.log(e),o}catch(e){throw l(o),e}}function u(e){return new Promise(t=>setTimeout(t,e))}const g=mw.config.get("wgPageName");var f=new class{isMainNamespace(){return 0===mw.config.get("wgNamespaceNumber")}async getWikitext(e){const t={action:"query",prop:"revisions",titles:e,rvprop:"content",format:"json"},o=await h("/w/api.php",{errorMessage:"Произошла ошибка при загрузки викитекста страницы",data:t});return Object.values(o.query.pages)[0].revisions[0]["*"]}isUsualPageView(){return mw.config.get("wgIsArticle")&&"view"===mw.config.get("wgAction")&&!mw.util.getParamValue("diff")}};const m={editSummary:"Ёфикация с помощью [[Участник:Дима74/Скрипт-Ёфикатор|скрипта-ёфикатора]]",minimumReplaceFrequency:35,minimumNumberReplacesForContinuousYofication:10,maximumNumberReplacesForContinuousYofication:null},w=`\n<p>Минимальная частота слов для ёфикации в процентах (0-100). Чем меньше значение, тем больше замен будет предлагаться.\n<input id="yoficator-minimumReplaceFrequency" type="number" placeholder="${m.minimumReplaceFrequency}">\n<p>Минимальное число замен, при которых статья будет рассматриваться при непрерывной ёфикации</p>\n<input id="yoficator-minimumNumberReplacesForContinuousYofication" type="number" placeholder="${m.minimumNumberReplacesForContinuousYofication}">\n<p>Максимальное число замен, при которых статья будет рассматриваться при непрерывной ёфикации</p>\n<input id="yoficator-maximumNumberReplacesForContinuousYofication" type="number" placeholder="нет ограничения">\n<p>Описание правки</p>\n<input id="yoficator-editSummary" type="text" value="${m.editSummary}" placeholder="${m.editSummary}">\n<p>Параметры сохраняются автоматически.</p>\n`;var y=new class{constructor(){for(const[e,t]of Object.entries(m)){const o=localStorage.getItem("yoficator-"+e);this[e]=null!==o?o:t}}initEditing(){$(".mw-parser-output").html(w),$("\n<style>\n.mw-parser-output p {\n\tfont-size: 15px; \n\tcolor: black;\n}\n\n.mw-parser-output input {\n\tbackground-color: transparent;\n\tborder: none;\n\tborder-bottom: 1px solid #9e9e9e;\n\tborder-radius: 0;\n\toutline: none;\n\theight: 3rem;\n\twidth: 100%;\n\tfont-size: 1rem;\n\tmargin: 0 0 20px 0;\n\tpadding: 0;\n\tbox-shadow: none;\n\tbox-sizing: border-box;\n\ttransition: all .3s;\n}\n\n::placeholder {\n\tcolor: #555;\n\topacity: 1;\n}\n</style>\n").appendTo(document.head);for(const e of $(".mw-parser-output input")){const t=e.id,o=localStorage.getItem(t);null!==o&&(e.value=o)}$(".mw-parser-output input").on("input",(function(){const e=this.value,t=this.id;""===e?localStorage.removeItem(t):localStorage.setItem(t,e)}))}};var x=new class{async getRandomPageName(){const e={errorMessage:"Не удалось получить следующую страницу для ёфикации",data:{minimum_number_replaces_for_continuous_yofication:y.minimumNumberReplacesForContinuousYofication,maximum_number_replaces_for_continuous_yofication:y.maximumNumberReplacesForContinuousYofication}};return await h(i+"/wikipedia/randomPageName",e)}async getWordPageName(e,t){const o={errorMessage:"Не удалось получить следующую страницу для ёфикации",data:{word:e,pageIndex:t}};return await h(i+"/wikipedia/wordPage",o)}async getReplacesByPageName(e){const t={errorMessage:"Произошла ошибка при загрузке списка замен",data:{minimumReplaceFrequency:y.minimumReplaceFrequency,title:e}};return await h(i+"/wikipedia/replacesByTitle",t)}async getReplacesByWikitext(e){const t={errorMessage:"Произошла ошибка при загрузке списка замен",data:{minimumReplaceFrequency:y.minimumReplaceFrequency,wikitext:e,currentPageName:g},method:"POST"};return await h(i+"/wikipedia/replacesByWikitext",t)}};function R(e){return e.replace(/ё/g,"е").replace(/Ё/g,"Е")}function b(e,t){for(const o of t){const t=o.yoword,i=R(t);p(R(e.substr(o.wordStartIndex,t.length))===i)}}function v(e,t){for(const o of t){const{wordStartIndex:t,yoword:i}=o;o.wordEndIndex=t+i.length,o.originalWord=e.substr(t,i.length)}}function I(e,t){if(e.length!==t.length)return!1;for(let o=0;o<e.length;++o){const i=e[o],n=t[o];if(!(i===n||"е"===i&&"ё"===n||"Е"===i&&"Ё"===n))return!1}return!0}function k(e,t,o){const i=window.getComputedStyle(t);for(const t of o)e.style[t]=i[t]}function C(e,t){k(e,t,["font-family","font-size","font-weight","line-height","letter-spacing"])}function S(e){null===e&&(e=0);const t=[[60,"green"],[40,"orange"],[0,"red"]];for(const[o,i]of t)if(e>=o)return i;p(!1)}class P{init(){}toggleReplaceVisible(e,t){}focusOnReplace(e){}toggleReplaceAccept(e,t){}onWindowResize(){}async onYoficationEnd(){}constructor(){this.currentReplaceIndex=-1,this.previousHighlightedReplace=null,this.ignoredEwords=new Set,this.isPaused=!1}get padding(){return 2}get frequencyHintHeight(){return 3}get styles(){return e=this.padding,t=this.frequencyHintHeight,`\n.yoficator-replace-active {\n\tbackground-color: aquamarine;\n\tposition: relative;\n\tdisplay: inline-flex;\n\tmargin: -${e-1}px -${e}px;\n\tpadding: ${e-1}px ${e}px;\n}\n\n.yoficator-replace-active.yoficator-replace-inside-quotes {\n\tbackground-color: #ef9a9a;\n}\n\n.yoficator-replace-active::before {\n\twidth: var(--frequency-hint-width);\n\tbackground-color: var(--frequency-hint-color);\n\tcontent: '';\n\theight: ${t}px;\n\tposition: absolute;\n\tleft: 0;\n\ttop: -${t}px;\n}\n`;var e,t}get currentReplace(){return this.replaces[this.currentReplaceIndex]}async perform(){if($(`<style>${this.styles}</style>`).appendTo(document.head),await this.init(),0===this.replaces.length)return l("Эта страница и так уже ёфицирована. \n(Не найдено замен для этой страницы)",7e3),void this.tryContinueContinuousYofication(!1);this.goToNextReplace(),this.initializeActions(),this.onWindowResizeBaseBinded=this.onWindowBaseResize.bind(this),window.addEventListener("resize",this.onWindowResizeBaseBinded)}initializeActions(){const e={KeyJ:this.acceptReplace,KeyF:this.rejectReplace,KeyG:this.rejectReplaceAndAllSameEwords,Semicolon:this.showCurrentReplaceAgain,KeyA:this.goToPreviousReplace,KeyQ:this.abortYofication,KeyW:this.openYowordWiktionaryPage,KeyR:this.openYowordGramotaRuPage,KeyS:this.openYowordStatPage,KeyN:this.openArticlePage,KeyL:this.openLink};this.onKeydown=t=>{if("KeyO"===t.code&&t.altKey)this.isPaused^=!0;else if(!this.isPaused&&t.code in e){if("KeyN"===t.code&&!O.isContinuousYofication)return;t.preventDefault(),e[t.code].call(this,t)}},document.addEventListener("keydown",this.onKeydown)}goToNextReplace(){p(this.currentReplaceIndex!==this.replaces.length);do{++this.currentReplaceIndex}while(!this.goToCurrentReplace())}goToPreviousReplace(){if(0!==this.currentReplaceIndex){for(--this.currentReplaceIndex;this.currentReplaceIndex>=0&&!this.goToCurrentReplace();)--this.currentReplaceIndex;if(this.currentReplaceIndex<0)throw this.currentReplaceIndex=0,"goToPreviousReplace: currentReplace < 0";this.currentReplace.isAccept=!1,this.toggleReplaceAccept(this.currentReplace,!1)}}goToCurrentReplace(){if(this.currentReplaceIndex===this.replaces.length)return this.onYoficationEndBase(),!0;p(this.currentReplaceIndex<this.replaces.length);const e=this.currentReplace,t=e.yoword,o=R(t);return!this.ignoredEwords.has(o)&&(l(`${(null===e.frequencyWikipedia?"?":`${e.frequencyWikipedia}%`)+(e.isSafe?" (safe)":"")}\n${t}\nЗамена ${this.currentReplaceIndex+1} из ${this.replaces.length}`),null!==this.previousHighlightedReplace&&this.toggleReplaceVisible(this.previousHighlightedReplace,!1),this.toggleReplaceVisible(this.currentReplace,!0),this.focusOnReplace(this.currentReplace),this.previousHighlightedReplace=e,!0)}acceptReplace(){this.currentReplace.isAccept=!0,this.toggleReplaceAccept(this.currentReplace,!0),this.goToNextReplace()}rejectReplace(){this.currentReplace.isAccept=!1,this.toggleReplaceAccept(this.currentReplace,!1),this.goToNextReplace()}rejectReplaceAndAllSameEwords(){const e=R(this.currentReplace.yoword);this.ignoredEwords.add(e),this.rejectReplace()}showCurrentReplaceAgain(){this.currentReplace&&this.focusOnReplace(this.currentReplace)}onWindowBaseResize(){this.onWindowResize(),this.currentReplace&&this.focusOnReplace(this.currentReplace)}abortYofication(){O.isContinuousYofication||(l(this.isPageMode?"Ёфикация отменена":"Ёфикация прервана",7e3),this.cleanUp()),this.tryContinueContinuousYofication(!1)}async cleanUp(){document.removeEventListener("keydown",this.onKeydown),window.removeEventListener("resize",this.onWindowResizeBaseBinded),null!==this.previousHighlightedReplace&&this.toggleReplaceVisible(this.previousHighlightedReplace,!1)}async onYoficationEndBase(){l("Завершаем ёфикацию..."),await u(0),await this.cleanUp(),await this.onYoficationEnd();const e=this.replaces.some(e=>e.isAccept);l(e?"Ёфикация завершена":"Ёфикация завершена\n(ни одна замена не была принята)",e?4e3:7e3),this.tryContinueContinuousYofication(e)}tryContinueContinuousYofication(e){O.isContinuousYofication&&(e?this.beforeContinueContinuousYofication():O.performContinuousYofication())}async beforeContinueContinuousYofication(){l("Производим правку..."),$("#wpSummary").val(y.editSummary),$("#wpMinoredit").prop("checked",!0),sessionStorage.setItem("yoficator:continuous-yofication-next-page",await O.nextPageNamePromise),$("#wpSave").click()}openYowordWiktionaryPage(){const e=this.currentReplace.yowordNormalized.toLowerCase();window.open(i+"/redirectToWiktionaryArticle/"+e)}openYowordGramotaRuPage(){const e=this.currentReplace.yowordNormalized.toLowerCase();window.open(i+"/redirectToGramotaRuPage/"+e)}openYowordStatPage(){const e=this.currentReplace.yowordNormalized;window.open(i+"/stat/"+e)}openArticlePage(){window.open("/wiki/"+g)}openLink(e){if(this.isPageMode)return;const t=this.currentReplace,o=this.wikitext.lastIndexOf("[[",t.wordStartIndex);if(-1===o)return;const i=this.wikitext.indexOf("]]",o);if(-1!==i&&t.wordStartIndex<i){const t=o+"[[".length;let n=this.wikitext.indexOf("|",o);(-1===n||n>i)&&(n=i);let s=this.wikitext.substring(t,n);if(e.shiftKey)for(const e of this.replaces)t<=e.wordStartIndex&&e.wordEndIndex<=n&&(s=s.replace(new RegExp(R(e.yoword),"g"),e.yoword));window.open("/wiki/"+encodeURIComponent(s.replace(/ /g,"_")))}}}class E extends P{async fetchReplaces(){if(this.wikitext=this.getWikitext(),O.isContinuousYofication&&this.isPageEditingByAnotherUser())return[];l("Загружаем список замен...");const e=await x.getReplacesByWikitext(this.wikitext);return b(this.wikitext,e),v(this.wikitext,e),this.markReplacesInsideQuotes(this.wikitext,e),e}markReplacesInsideQuotes(e,t){for(const o of t){const t=e.lastIndexOf("«",o.wordStartIndex);if(-1===t)continue;const i=e.indexOf("»",t);if(-1!==i&&o.wordStartIndex<i){const e=o.wordStartIndex-t,n=i-o.wordEndIndex+1;o.isInsideQuotes=e>7&&n>7}}}createReplaceElement(e){const t=document.createElement("span");return t.classList.add("yoficator-replace"),e.isInsideQuotes&&t.classList.add("yoficator-replace-inside-quotes"),t.style.setProperty("--frequency-hint-width",e.frequency+"%"),t.style.setProperty("--frequency-hint-color",S(e.frequencyWikipedia)),t.textContent=e.originalWord,t}async onYoficationEnd(){const e=this.getWikitext();I(this.wikitext,e)||console.warn("Итоговый викитекст отличается от исходного не только из-за ёфикации. Это ошибка если во время ёфикации викитекст не редактировался.")}isPageEditingByAnotherUser(){const e=this.wikitext.toLowerCase();return["редактирую","редактирую раздел","пишу","правлю","перерабатываю","перевожу","статья редактируется","викифицирую","inuse","inuse-by","processing"].some(t=>e.includes(`{{${t}`))}}class T extends E{async init(){if(O.isMobile&&($("#mw-panel, #mw-head, #mw-page-base").remove(),$("#content").css({margin:0}),$('<meta name="viewport" content="user-scalable=no, width=device-width, height=device-height, initial-scale=1" />').appendTo(document.head),this.removeOverlay=function(e,t,o){const i=window.innerHeight,n=window.innerWidth,s=s=>{s.preventDefault(),s.stopPropagation();const r=s.touches[0],a=r.clientY,c=r.clientX;a<=i/4?c>=n/2?e():window.location.href=`//ru.m.wikipedia.org/wiki/${g}?mobileaction=toggle_view_mobile`:c>=n/2?t():o()};window.addEventListener("touchstart",s,{passive:!1,capture:!0});const r=e=>e.preventDefault();for(const e of["scroll","touchmove","touchend"])window.addEventListener(e,r,{passive:!1});return()=>window.removeEventListener("touchstart",s)}(this.abortYofication.bind(this),this.acceptReplace.bind(this),this.rejectReplace.bind(this))),0===$(".CodeMirror").length)for(l("Ожидаем завершения загрузки редактора...");0===$(".CodeMirror").length;)await u(50);if(p($(".CodeMirror").length>0),this.cm=$(".CodeMirror")[0].CodeMirror,this.replaces=await super.fetchReplaces(),0===this.replaces.length)return;l("Обрабатываем замены..."),await u(0);for(const e of this.replaces){e.element=super.createReplaceElement(e);const t=this.cm.posFromIndex(e.wordStartIndex),o=this.cm.posFromIndex(e.wordEndIndex),i={atomic:!0,replacedWith:e.element,inclusiveLeft:!1,inclusiveRight:!1};e.cmMarker=this.cm.markText(t,o,i)}const e=this.cm.getScrollerElement();if(this.editorHeight=e.clientHeight,O.isContinuousYofication){const t=e.getBoundingClientRect(),o=O.isMobile?t.top-3:(t.top+t.bottom)/2-window.innerHeight/2;window.scrollBy(0,o)}}getWikitext(){return this.cm.getValue()}toggleReplaceVisible(e,t){e.element.classList.toggle("yoficator-replace-active",t)}focusOnReplace(e){const t=this.cm.posFromIndex(e.wordStartIndex),o=this.cm.posFromIndex(e.wordEndIndex-1),i=(this.cm.charCoords(t,"local").top+this.cm.charCoords(o,"local").bottom)/2;if(this.cm.scrollTo(null,i-this.editorHeight/2),!O.isMobile){this.cm.focus();const t=e.cmMarker.find();this.cm.setCursor(t.to,{bias:1})}}toggleReplaceAccept(e,t){e.element.textContent=t?e.yoword:e.originalWord}async cleanUp(){await super.cleanUp(),O.isMobile&&this.removeOverlay();for(const e of this.replaces){const{from:t,to:o}=e.cmMarker.find();this.cm.replaceRange(e.element.textContent,t,o),e.cmMarker.clear()}}}class N extends E{get padding(){return 4}get styles(){return super.styles+"\n.yoficator-replace {\n\talign-items: center;\n\tjustify-content: center;\n\tmargin-left: -3px;\n\tpadding-left: 3px;\n\twhite-space: nowrap;\n}\n\n.yoficator-replace:not(.yoficator-replace-active) {\n\tdisplay: none;\n}\n"}async initEditor(){await new Promise(e=>mw.hook("ve.activationComplete").add(e)),this.surface=ve.init.target.getSurface(),this.surfaceModel=this.surface.getModel(),this.surfaceView=this.surface.getView()}async init(){if(await this.initEditor(),this.replaces=await super.fetchReplaces(),0!==this.replaces.length){this.preventUpdateHighlightsPositions=!1,this.applyReplacePromises=[],l("Обрабатываем замены..."),await u(0),this.highlightsWrapper=document.createElement("div"),$(".ve-ui-overlay-local").append(this.highlightsWrapper);for(const e of this.replaces){const t=new ve.Range(e.wordStartIndex,e.wordEndIndex);e.fragment=this.surfaceModel.getLinearFragment(t,!0),e.element=super.createReplaceElement(e),e.element.style.position="absolute";const o=this.surfaceView.getNativeRange(t);p(o.startContainer===o.endContainer),C(e.element,o.startContainer.parentElement),this.highlightsWrapper.appendChild(e.element)}this.updateHighlightsPositions(),this.surfaceModel.connect(this,{documentUpdate:this.updateHighlightsPositions})}}getWikitext(){return this.surfaceModel.getLinearFragment(this.surfaceModel.getDocument().getDocumentRange()).getText(!0)}updateHighlightsPositions(){if(!this.preventUpdateHighlightsPositions)for(const e of this.replaces){e.rect=this.surfaceView.getSelection(e.fragment.getSelection()).getSelectionBoundingRect();let{left:t,top:o,width:i,height:n}=e.rect;$(e.element).css({left:t,top:o,width:i,height:n})}}toggleReplaceVisible(e,t){e.element.classList.toggle("yoficator-replace-active",t)}focusOnReplace(e){const t=e.rect.top+this.surfaceView.$element.offset().top,o=this.surfaceView.$window.height()-this.surface.toolbarHeight;document.scrollingElement.scrollTop=t-o/2,e.fragment.collapseToEnd().select()}toggleReplaceAccept(e,t){const o=this.toggleReplaceAcceptAsync(e,t);this.applyReplacePromises.push(o)}async toggleReplaceAcceptAsync(e,t){await u(0);const o=e.fragment.getText(),i=t?e.yoword:e.originalWord;i!==o&&(this.preventUpdateHighlightsPositions=!0,e.fragment.insertContent(i),this.preventUpdateHighlightsPositions=!1),this.currentReplaceIndex+1===this.replaces.length&&e.fragment.collapseToEnd().select()}onWindowResize(){this.updateHighlightsPositions()}async cleanUp(){await super.cleanUp(),await Promise.all(this.applyReplacePromises),this.highlightsWrapper.remove()}}class Y extends E{async init(){if(await $.when(mw.loader.using(["ext.wikiEditor"]),$.ready),this.textarea=document.getElementById("wpTextbox1"),this.replaces=await super.fetchReplaces(),0===this.replaces.length)return;this.editor=document.createElement("div"),this.editor.setAttribute("contenteditable","true"),this.editor.textContent=this.wikitext,this.editor.style.whiteSpace="pre-wrap",this.editor.style.overflowY="auto",this.editor.style.outline="none",C(this.editor,this.textarea),k(this.editor,this.textarea,["height","color","padding-left","padding-right","padding-top","padding-bottom","tab-size"]);const e=this.editor.firstChild;p(this.replaces.every((e,t)=>0===t||this.replaces[t-1].wordStartIndex<this.replaces[t].wordStartIndex));for(const t of[...this.replaces].reverse()){const o=e.splitText(t.wordStartIndex);o.splitText(t.yoword.length),t.element=super.createReplaceElement(t),this.editor.replaceChild(t.element,o)}this.textarea.style.display="none",this.textarea.parentElement.insertBefore(this.editor,null)}getWikitext(){return this.textarea.value}toggleReplaceVisible(e,t){e.element.classList.toggle("yoficator-replace-active",t)}focusOnReplace(e){const t=this.editor.getBoundingClientRect(),o=e.element.getBoundingClientRect(),i=t.bottom-t.top,n=o.bottom-o.top;this.editor.scrollTop+=o.top-t.top-(i-n)/2;const s=new Range;s.setStartAfter(e.element),s.setEndAfter(e.element);const r=window.getSelection();r.removeAllRanges(),r.addRange(s)}toggleReplaceAccept(e,t){e.element.textContent=t?e.yoword:e.originalWord}async cleanUp(){await super.cleanUp(),this.textarea.value=this.editor.textContent,this.editor.remove(),this.textarea.style.display=null}}class W{static isRussianLetterInWord(e){return 1===e.length&&e.match(/[а-яА-ЯёЁ\-\u00AD\u0301]/)}static checkWord(e,t,o){const i=o+e.length,n=0===o||!W.isRussianLetterInWord(t[o-1]),s=i===t.length||!W.isRussianLetterInWord(t[i]);return n&&s}static findIndexesOfWord(e,t){const o=[];let i,n=0;for(;-1!==(i=t.indexOf(e,n));)W.checkWord(e,t,i)&&o.push(i),n=i+e.length;return o}static longestPrefix(e,t){let o=0;for(;o<e.length&&o<t.length&&e[o]===t[o];)++o;return o}static longestSuffix(e,t){let o=0;for(;o<e.length&&o<t.length&&e[e.length-o-1]===t[t.length-o-1];)++o;return o}}function A(){window.history.pushState("","",window.location.href.replace("?yofication",""))}class L extends P{async init(){this.isPageMode=!0,this.root=$("#mw-content-text")[0],this.rootInner=$(".mw-parser-output")[0],await this.loadReplacesAndWikitext(),0!==this.replaces.length?(this.groupReplacesByYoword(),this.createHighlights(),this.createReplaces()):A()}async loadReplacesAndWikitext(){const e=f.getWikitext(g);l("Загружаем список замен...");const{replaces:t,revision:o,timestamp:i}=await x.getReplacesByPageName(g);this.replaces=t,this.timestamp=i,0!==t.length&&(l("Загружаем викитекст..."),this.wikitext=await e,p(o===mw.config.get("wgCurRevisionId")),b(this.wikitext,t),v(this.wikitext,t))}groupReplacesByYoword(){const e=this.replaces.map(e=>e.yoword);this.yowords=[...new Set(e)],this.yowordsToReplaces={};for(const e of this.yowords)this.yowordsToReplaces[e]={replaces:[]};for(const e of this.replaces){const t=30;e.contextBefore=this.wikitext.substring(e.wordStartIndex-t,e.wordStartIndex),e.contextAfter=this.wikitext.substring(e.wordEndIndex,e.wordEndIndex+t);const o=this.yowordsToReplaces[e.yoword];o.replaces.push(e),o.frequency=e.frequency}}createHighlights(){const e={};for(const t of this.yowords)e[t]=[];let t=0;const o=(o,i)=>{for(const n of this.yowords){const s=R(n);if(i.includes(s)){const r=W.findIndexesOfWord(s,i).map(e=>({wordStartIndex:e,wordNode:o,wordNodeValue:i,wordOrderIndex:[t,e]}));e[n].push(...r)}}++t},i={acceptNode:e=>null!==e.offsetParent?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT},n=document.createTreeWalker(this.root,NodeFilter.SHOW_ALL,i);for(;n.nextNode();){const e=n.currentNode;3===e.nodeType&&o(e,e.nodeValue)}for(const t of this.yowords){const o=[];for(const i of e[t]){const e=document.createRange();e.setStart(i.wordNode,i.wordStartIndex),e.setEnd(i.wordNode,i.wordStartIndex+t.length);const n=document.createElement("span");n.style.position="absolute",i.wordNode.before(n),n.parentElement.style.isolation="isolate",n.parentElement.style.opacity="0.99",this.addProgressToHighlight(n,this.yowordsToReplaces[t].frequency);const s=()=>{const t=e.getBoundingClientRect(),o=n.offsetParent.getBoundingClientRect(),i=t.left-o.left-2,s=t.top-o.top-2,r=t.width+4,a=t.height+4;$(n).css({left:i,top:s,width:r,height:a})};n.recalcPosition=s,n.recalcPosition(),$(n).css({background:"aquamarine",display:"none",zIndex:-1}),this.checkWordNode(i.wordNode,t)&&(i.highlightElement=n,o.push(i))}this.yowordsToReplaces[t].occurrences=o}}addProgressToHighlight(e,t){const o=document.createElement("span");e.appendChild(o);$(o).css({width:`${t}%`,backgroundColor:S(t),content:"",height:"5px",position:"absolute",left:"0",top:"-5px"})}checkWordNode(e,t){for(let o=e;o!==this.root;o=o.parentElement){if(1===o.nodeType){const e=["blockquote","a","pre","i"];for(const i of e)if(o.tagName.toLowerCase()===i)return console.log(`ignore word "${t}" inside <${i}>`),!1;const i=["poem"];for(const e of i)if(o.classList.contains(e))return console.log(`ignore word "${t}" inside .${e}`),!1;if("toc"===o.id)return console.log(`ignore word "${t}" inside #toc`),!1;const n=o.previousElementSibling;if("TD"===o.tagName&&null!==n&&"TD"===n.tagName&&n.innerHTML.includes("quote1.png"))return console.log(`ignore word "${t}" inside quote`),!1}if(o.parentElement===this.rootInner)for(let e=o;null!==e;e=e.previousSibling)if(1===e.nodeType&&"H"===e.tagName[0]&&e.childNodes.length>0){const o=(e.innerText||"").toLowerCase(),i=["литература","ссылки","примечания","сочинения","источники","труды"];for(const e of i)if(o.includes(e))return console.log(`ignore word "${t}" in section "${o}"`),!1;break}}return!0}getCommonLength(e,t,o){return W.longestSuffix(e,o.contextBefore)+W.longestPrefix(t,o.contextAfter)}createReplaces(){const e=[];for(const t of this.yowords){const o=this.yowordsToReplaces[t],i=[],n=30;for(const e of o.occurrences){const s=e.wordNodeValue,r=e.wordStartIndex,a=e.wordStartIndex+t.length,c=s.substring(Math.max(r-n,0),r),l=s.substring(a,Math.min(a+n,s.length)),d=o.replaces.map(e=>({replace:e,commonLength:this.getCommonLength(c,l,e)})).sort((e,t)=>t.commonLength-e.commonLength),h=o.occurrences.length,u=d.length,g=1===h&&1===u&&d[0].commonLength>=10,f=h>1&&1===u&&d[0].commonLength>=20,m=u>1&&d[0].commonLength>=10&&d[0].commonLength>1.5*d[1].commonLength;if(g||f||m){const t=d[0],n={...t.replace,highlightInfo:e,isAccept:!1};p(void 0!==n.wordStartIndex,"replace.wordStartIndex !== undefined");const s=o.replaces.indexOf(t.replace);p(-1!==s,"indexRemote === -1"),i.push({replace:n,indexRemote:s})}}const s=i.map(e=>e.indexRemote);if(new Set(s).size===s.length)for(const{replace:t,indexRemote:o}of i)e.push(t);else console.error(`${t}\nНесколько локальных вхождений были сопоставлены одному remote\n${s}`)}e.sort((e,t)=>{return o=e.highlightInfo.wordOrderIndex,i=t.highlightInfo.wordOrderIndex,o[0]===i[0]?o[1]-i[1]:o[0]-i[0];var o,i});for(const t of e)t.highlightElement=t.highlightInfo.highlightElement;console.log(""),console.log(`${"yoword".padEnd(20-"local".length+1)} local:remote => associated`);for(const t of this.yowords){const o=this.yowordsToReplaces[t],i=o.occurrences.length,n=o.replaces.length,s=e.filter(e=>e.yoword===t).length;console.log(`${t.padEnd(20)} ${i}:${n} => ${s}`)}console.log(""),this.replaces=e}toggleReplaceVisible(e,t){e.highlightElement.style.display=t?"block":"none"}focusOnReplace(e){const t=e.highlightElement;t.recalcPosition();const o=t.getBoundingClientRect(),i=window.scrollY+o.top-(window.innerHeight-o.height)/2;window.scrollTo(0,i)}async cleanUp(){await super.cleanUp(),A()}async onYoficationEnd(){if(this.replaces=this.replaces.filter(e=>e.isAccept),0===this.replaces.length)return;l("Делаем правку: \nПрименяем замены..."),await u(0);let e=this.wikitext;for(const t of this.replaces){const o=t.yoword;p(void 0!==t.wordStartIndex),p(void 0!==o),e=e.substr(0,t.wordStartIndex)+o+e.substr(t.wordStartIndex+o.length)}p(I(this.wikitext,e)),l("Делаем правку: \nОтправляем изменения...");const t=new mw.Api,o=await t.edit(g,t=>(p(t.content===this.wikitext,"Кто-то другой редактирует эту страницу прямо сейчас. Попробуйте ещё раз."),{text:e,summary:y.editSummary,minor:!0}));if("Success"!==o.result){console.log(o),p(!1,"Не удалось произвести правку: "+(o.info||"неизвестная ошибка"))}}}async function M(){(new(await async function(){const e=new URLSearchParams(window.location.search),t=e.get("action"),o=e.get("veaction");if(!t&&!o)return L;"edit"===o&&p(!1,"Визуальный редактор не поддерживается. Пожалуйста, переключитесь в режим викитекста.");if("editsource"===o)return N;if("edit"===t){return mw.user.options.get("usecodemirror")>0?T:Y}p(!1)}())).perform()}const B=new class{start(){const e=sessionStorage.getItem("yoficator:continuous-yofication-next-page");if(sessionStorage.removeItem("yoficator:continuous-yofication-next-page"),e)this.redirectContinuousYofication(e);else{if("Служебная:Ёфикация"===g)this.performContinuousYofication();else if("Служебная:Ёфикация/M"===g)localStorage.setItem("yoficator-m","true"),this.performContinuousYofication();else if(g.startsWith("Служебная:Ёфикация/")){const e=g.substring("Служебная:Ёфикация/".length);sessionStorage.setItem("yoficator:word",e),sessionStorage.setItem("yoficator:pageIndex","0"),this.performContinuousYofication()}else if("Участник:Дима74/Скрипт-Ёфикатор/Параметры"===g)y.initEditing();else if(window.location.search.includes("yofication")){if(this.isContinuousYofication=window.location.search.includes("continuous_yofication"),this.isMobile=this.isContinuousYofication&&s,M(),this.isContinuousYofication){const e=+sessionStorage.getItem("yoficator:pageIndex");sessionStorage.setItem("yoficator:pageIndex",e+1),this.nextPageNamePromise=this.getNextContinousYoficationPage()}}else n||(f.isUsualPageView()&&f.isMainNamespace()&&this.addPortletLink(),this.addYoficateButtonToToolbar());g.startsWith("Участник:Дима74/Тест")&&M()}}addPortletLink(){$.when(mw.loader.using("mediawiki.util"),$.ready).then(()=>{const e=mw.util.addPortletLink("p-cactions","/wiki/"+g+"?yofication","Ёфицировать","ca-yoficator","Ёфицировать страницу");$(e).click(e=>{e.preventDefault(),window.location.search.includes("action=edit")||window.history.pushState("","",window.location.href+"?yofication"),$("#ca-yoficator").remove(),M()})})}addYoficateButtonToToolbar(){mw.loader.using("ext.gadget.registerTool").done(()=>{registerTool({name:"yoficator",position:777,title:"Ёфицировать",label:"Ёфицировать",callback:M,classic:{icon:"https://yofication.fly.dev/static/yo_22.png"},visual:{icon:"https://yofication.fly.dev/static/yo_20.png",modes:["source"]}})})}async performContinuousYofication(){if(n&&s)return void $("#mw-mf-display-toggle")[0].click();l("Переходим к следующей странице: \nЗагружаем название статьи для ёфикации...");const e=await(this.isContinuousYofication?this.nextPageNamePromise:this.getNextContinousYoficationPage());l(`Переходим к странице «${e}»`),this.redirectContinuousYofication(e)}redirectContinuousYofication(e){if(""!==e){const t=encodeURIComponent(e.replace(/ /g,"_"));window.location.href=`//ru.wikipedia.org/w/index.php?title=${t}&action=edit&continuous_yofication`}else l("Закончились страницы для непрерываной ёфикации")}getNextContinousYoficationPage(){const e=sessionStorage.getItem("yoficator:word");if(e){const t=sessionStorage.getItem("yoficator:pageIndex");return x.getWordPageName(e,t)}return x.getRandomPageName()}};var O=t.default=B;$(()=>B.start())}]);