Увага: Після публікування слід очистити кеш браузера, щоб побачити зміни.

  • Firefox / Safari: тримайте Shift, коли натискаєте Оновити, або натисніть Ctrl-F5 чи Ctrl-Shift-R (⌘-R на Apple Mac)
  • Google Chrome: натисніть Ctrl-Shift-R (⌘-Shift-R на Apple Mac)
  • Internet Explorer / Edge: тримайте Ctrl, коли натискаєте Оновити, або натисніть Ctrl-F5
  • Opera: натисніть Ctrl-F5
(function(){
    function en(e) { return encodeURIComponent(e); }
    function el(e) { return document.createElement(e); }
    function tstamp(t) { return !t.getUTCFullYear() ? null : // Safari + Chrome
                                (t.getUTCFullYear()+":0"+(t.getUTCMonth()+1)+":0"+t.getUTCDate()+":0"+
                                 t.getUTCHours()   +":0"+ t.getUTCMinutes() +":0"+t.getUTCSeconds())
                                 .replace(/:0?(\d\d)/g, '$1'); }
    function ch(o) { for (var i in o) { return o[i]; } }
	var start = new Date("Sep 24 2023 21:00:00 +0000");
    var conf = {
            'start': start,
            'actual': new Date(),
            'end':   new Date(start.setDate(start.getDate()+14)),
            'criteria': {
                'count': 300,
                'registration': new Date(start.setDate(start.getDate()-90)).toISOString()
            },
            'pagepath': 'Вікіпедія:Вибори арбітрів/2023/Голосування',
            'talkpath': 'Вікіпедія:Вибори арбітрів/2023/Обговорення/',
            'votepath': 'Вікіпедія:Вибори арбітрів/2023/Голосування/'
        };
    var ico = {
            'up': '//upload.wikimedia.org/wikipedia/commons/thumb/',
            'supp'      : '2/2d/Support-gray.svg/39px-Support-gray.svg.png',
            'suppinact' : '8/8d/Support-colored.svg/39px-Support-colored.svg.png',
            'suppact'   : '5/5b/Support-filled.svg/39px-Support-filled.svg.png',
             'opp'      : 'e/e7/Oppose-gray.svg/39px-Oppose-gray.svg.png',
             'oppinact' : '0/06/Oppose-colored.svg/39px-Oppose-colored.svg.png',
             'oppact'   : '7/7d/Oppose-filled.svg/39px-Oppose-filled.svg.png'
        };
    var loc = {
        'votebutton': 'Проголосувати',
        'statuscriteria': 'Перевірка критеріїв…',
        'criteriafail': '<h3 class="voting-error">Ви не відповідаєте критеріям.</h3><p>Ваші голоси на цих виборах <b>не будуть враховані</b>.</p><p>Утім, якщо вам просто цікаво, як працює скрипт, ви можете подивитись на нього без збереження голосів.</p>',
        'criteriafailbutton': 'Переглянути',
        'votingend': '<big>Голосування завершилось</big>',
        'notstartyet': '<big>Голосування ще не розпочалось</big>',
        'loadingvotes': 'Перевірка наявних голосів…',
        'votinghelp': '<p>Розставте голоси «за» і «проти» поряд з іменами тих кандидатів, щодо яких у вас сформована думка. Ви зможете доповнити чи змінити вибір пізніше.</p>\
      </div>',
        'justbeforesave': 'Сміливо пишіть будь-які відгуки, пропозиції та повідомлення&nbsp;про&nbsp;помилки на&nbsp;<a href="/wiki/MediaWiki_talk:Voting.js">сторінці&nbsp;обговорення</a>.',
        'savebutton': 'Зберегти',
        'saveprog': '<b>Не закривайте сторінку</b> до завершення збереження.',
        'summary': '+\u200B',
        'thankyou': '<h3>Дякуємо за участь у виборах!</h3><p>Ви зможете змінити ваші голоси до кінця голосування.</p><p>Щойно віддані голоси можна подивитись на <a href="/wiki/Special:Mycontributions">сторінці внеску</a>.</p>'
    };
    var cand = 'Ahonc : AlexKozur : AS : JTs : Repakr : Submajstro : UeArtemis : Антон Даньків : Віщун : Долинський : Юрко Градовський'.split(' : ');
    var wgAPIPath = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/api.php?format=json&';
 
    var votes = {};
    var criteriaMatch;
    var saving = null;
    var aj = new XMLHttpRequest();
    var token = mw.user.tokens.get( 'csrfToken' );
 
    function votingStart() {
    	if (tstamp(conf.start)<tstamp(conf.actual)) {
    		if (tstamp(conf.end)>tstamp(conf.actual)) {
        		mw.loader.load('//uk.wikipedia.org/w/index.php?title=MediaWiki:Voting.css&action=raw&ctype=text/css', 'text/css');
        		btn.disabled = true;
        		btn.style.display = 'none';
        		status.innerHTML = loc.statuscriteria;
        		aj.onreadystatechange = votingStartContinue;
        		aj.open('GET', wgAPIPath + 'action=query&list=users&usprop=registration|editcount&ususers=' +
                		en(mw.config.get('wgUserName')) +
                		'&rawcontinue=', true);
        		aj.send('');
    		}
    		else votingEnd();
    	}
    	else votingNotStartYet();
    }
    function votingStartContinue() {
        if (aj.readyState != 4) return;
        if (aj.status != 200) { // temporary problems?
            votingStart();
            return;
        }
        userinfo = eval('(' + aj.responseText + ')').query.users[0];
        if (// a valid voter must be a non-anonymous user
            userinfo.missing !== undefined ||
            // who is not blocked
            userinfo.blockedby ||
            // whose editcount is at least conf.criteria.count
            userinfo.editcount < conf.criteria.count ||
            // and who is registered no later than conf.criteria.registration
            // "null" means "before 2005-12-29", user creation was not logged before then
            (userinfo.registration !== null && userinfo.registration > conf.criteria.registration))
            votingCriteriaFail();
        else {
            criteriaMatch = 1;
            votingContinue();
        }
    }
    function votingCriteriaFail() {
        status.innerHTML = loc.criteriafail;
        btn.style.display = '';
        btn.disabled = false;
        btn.value = loc.criteriafailbutton;
        btn.onclick = function(){criteriaMatch = 0; votingContinue();};
    }
    function votingContinue() {
        status.innerHTML = loc.loadingvotes;
        btn.style.display = '';
        btn.onclick = votingSave;
        btn.value = loc.savebutton;
        btn.disabled = true;
        // latest contributions in ns:4
        aj.open('GET', wgAPIPath + 'action=query' +
                '&list=usercontribs&ucnamespace=4&uclimit=500' +
                '&ucuser='  + en(mw.config.get('wgUserName'))     +
                (tstamp(conf.start) ? '&ucend=' + tstamp(conf.start) : '') +
                '&ucdir=older&rawcontinue='                   ,
                true);
        aj.onreadystatechange = votingDraw;
        aj.send('');
    }
    function votingDraw() {
        if (aj.readyState != 4) return;
        if (aj.status != 200) { // temporary problems?
            votingContinue();
            return;
        }
        btn.disabled = !criteriaMatch;
        status.innerHTML = '';
 
        for (i=0; i<cand.length; i++) votes[cand[i]] = {'orig':0, 'value':0};
       
        var query = eval('(' + aj.responseText + ')');
            query = query.query;
        var co = query.usercontribs;
 
        // retrieving votes; according to contributions, only latest ones are valid
        for (var i=co.length-1; i>=0; i--) {
            var m = co[i].title.indexOf(conf.votepath) == 0 && co[i].comment == loc.summary;
            if (m) m = co[i].title.match(/\/2023\/Голосування\/(.*?)\/([+-])$/);
            if (m) votes[m[1]] = { 'orig' : m[2]=='+' ? +1 : -1,
                                   'value': 0 };
        }
   
        // drawing
        var div1 = el('div');
            div1.id = 'voting-standard';
            div1.innerHTML = loc.votinghelp;
        var tab = el('table');
 
        var tr, img, td1, td2, td3, lin;
        for (i in votes) {
            if (i != '_') {
                tr = el('tr');
                td1 = el('td');
                img = el('img');
                img.alt = '+';
                img.width = img.height = 39;
                img.src = ico.up + (votes[i].orig == 1 ? ico.suppinact : ico.supp);
                lin = el('a');
                lin.href = '#';
                lin.title = '+';
                lin.appendChild(img);
                td1.appendChild(lin);
 
                td2 = el('td');
                img = el('img');
                img.alt = '-';
                img.width = img.height = 39;
                img.src = ico.up + (votes[i].orig == -1 ? ico.oppinact : ico.opp);
                lin = el('a');
                lin.href = '#';
                lin.title = '-';
                lin.appendChild(img);
                td2.appendChild(lin);
 
                td3 = el('td');
                td3.className = 'talklink';
                lin = el('a');
                lin.href = mw.config.get('wgServer') + mw.config.get('wgScript') + '?title=' + encodeURI(conf.talkpath + i);
                lin.target = '_blank';
                lin.innerHTML = i;
 
                td3.appendChild(lin);
 
                tr.appendChild(td1);
                tr.appendChild(td2);
                tr.appendChild(td3);
                tab.appendChild(tr);
            }
        }
        div1.appendChild(tab);
        // IE has problems inserting the table
        div1.innerHTML += '';
        var imgs = div1.getElementsByTagName('img');
        for (i=0; i<imgs.length; i++)
            imgs[i].parentNode.onclick = oncl;
 
        status.innerHTML = loc.justbeforesave;
        status.parentNode.insertBefore(div1, status);
    }
    function votingSave() {
		if (tstamp(conf.end)>tstamp(new Date())) {
	        if (saving == null) {
	            var div = el('div');
	            div.id = 'voting-saving';
	            div.innerHTML = '<div id="voting-progress"><div id="voting-progress-progress" style="width:0%">&nbsp;</div></div>' + loc.saveprog;
	            status.parentNode.appendChild(div);
	            btn.disabled = true;
	            document.getElementById('voting-standard').style.visibility = 'hidden';
	 
	            saving = {'cursor': 0, 'pages': []};
	 
	            for (var i in votes) {
	                if (votes[i].value != 0 && votes[i].orig != votes[i].value) {
	                    saving.pages[saving.cursor] = {'text': '\n# [[user:' + mw.config.get('wgUserName') + '|' + mw.config.get('wgUserName') + ']] ~' + '~~' + '~~\n',
	                                                   'page': conf.votepath + i + '/' + (votes[i].value==1?'+':'-')};
	                    saving.cursor++;
	                }
	            }
	            saving.cursor = -5;
	            if (saving.pages.length)
	                votingSave();
	            else
	                document.getElementById('voting-container').innerHTML = loc.thankyou;
	        } else {
	            if (saving.cursor != -5 && aj.readyState != 4) return;
	            if (aj.readyState == 4 && aj.status != 200) {
	                votingSave();
	                return;
	            }
	            if (saving.cursor == -5) saving.cursor = 0;
	            if (saving.cursor == -1) return;
	 
	            document.getElementById('voting-progress-progress').style.width = 100*(saving.cursor+1)/saving.pages.length + '%';
	            aj = new XMLHttpRequest();
	            aj.open('POST', mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/api.php', true);
	            aj.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
	            aj.onreadystatechange = votingSave;
	            aj.send('format=json&action=edit&summary=' + en(loc.summary) +
	                                 '&title=' + en(saving.pages[saving.cursor].page) +
	                                 '&appendtext=' + en(saving.pages[saving.cursor].text) +
	                                 '&token=' + en(token));
	            saving.cursor++;
	            if (!saving.pages[saving.cursor]) {;
	                saving.cursor = -1;
	                document.getElementById('voting-container').innerHTML = loc.thankyou;
	            }
	        }
		}
		else
			votingEnd();
    }
 
	function votingEnd() {
		status.innerHTML = loc.votingend;
        btn.style.display = '';
        btn.disabled = true;
        btn.value = loc.criteriafailbutton;
	}
	function votingNotStartYet() {
		status.innerHTML = loc.notstartyet;
        btn.style.display = '';
        btn.disabled = true;
        btn.value = loc.criteriafailbutton;
	}
    // onclick() for round buttons
    function oncl() {
        var imgs = this.parentNode.parentNode.getElementsByTagName('img');
        var link = this.parentNode.parentNode.getElementsByTagName('a')[2];
        var ca = link.innerHTML;
        var ti = this.title;
        var vo = ti=='+'?1:-1;
        votes[ca].value = (votes[ca].value==vo) ? 0 : vo;
 
        imgs[0].src = ico.up + (votes[ca].value== 1 ?ico.suppact:(votes[ca].orig== 1 ?ico.suppinact:ico.supp));
        imgs[1].src = ico.up + (votes[ca].value==-1 ?ico.oppact :(votes[ca].orig==-1 ?ico.oppinact :ico.opp));
 
        link.className = ['opp', '', 'supp'][votes[ca].value + 1];
 
        return false;
    }
 if (mw.config.get('wgPageName').replace(/_/g,' ') == conf.pagepath) {
    document.getElementById('voting-container').innerHTML = '';
    var btn = el('input');
    btn.type = 'button';
    btn.id = 'voting-button';
    btn.value = loc.votebutton;
    btn.onclick = votingStart;
    var status = el('div');
    status.id = 'voting-status';
 
    document.getElementById('voting-container').appendChild(status);
    document.getElementById('voting-container').appendChild(btn);
 }
})();