/* pyRCV2: Preferential vote counting Copyright © 2020 Lee Yingtong Li (RunasSudo) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ importScripts('http://peterolson.github.com/BigRational.js/BigInt_BigRat.min.js', 'https://cdn.jsdelivr.net/npm/big.js@6.0.0/big.min.js', 'bundle.js'); onmessage = function(evt) { // Set settings if (evt.data.numbers === 'native') { py.pyRCV2.numbers.set_numclass(py.pyRCV2.numbers.Native); } if (evt.data.numbers === 'int') { py.pyRCV2.numbers.set_numclass(py.pyRCV2.numbers.NativeInt); } if (evt.data.numbers === 'rational') { py.pyRCV2.numbers.set_numclass(py.pyRCV2.numbers.Rational); } if (evt.data.numbers === 'fixed') { py.pyRCV2.numbers.set_numclass(py.pyRCV2.numbers.Fixed); py.pyRCV2.numbers.set_dps(evt.data.fixedDPs); } let election = py.pyRCV2.blt.readBLT(evt.data.data); postMessage({'type': 'init', 'election': { 'candidates': election.candidates.map(c => c.py_name) }}); // Create counter let counter; if (evt.data.transfers === 'wig') { counter = py.pyRCV2.method.base_stv.BaseWIGSTVCounter(election, evt.data.options); } else { counter = py.pyRCV2.method.base_stv.BaseUIGSTVCounter(election, evt.data.options); } // Reset let result = counter.reset(); postMessage({'type': 'result', 'result': { 'comment': result.comment, 'candidates': result.candidates.py_items().map(([c, cc]) => [c.py_name, { 'transfers': cc.transfers.pp(2), 'votes': cc.votes.pp(2), 'state': cc.state }]), 'exhausted': { 'transfers': result.exhausted.transfers.pp(2), 'votes': result.exhausted.votes.pp(2) }, 'loss_fraction': { 'transfers': result.loss_fraction.transfers.pp(2), 'votes': result.loss_fraction.votes.pp(2) }, 'total': result.total.pp(2), 'quota': result.quota.pp(2) }}); // Step election while (true) { result = counter.step(); if (py.isinstance(result, py.pyRCV2.model.CountCompleted)) { postMessage({'type': 'done'}); break; } else { postMessage({'type': 'result', 'result': { 'comment': result.comment, 'candidates': result.candidates.py_items().map(([c, cc]) => [c.py_name, { 'transfers': cc.transfers.pp(2), 'votes': cc.votes.pp(2), 'state': cc.state }]), 'exhausted': { 'transfers': result.exhausted.transfers.pp(2), 'votes': result.exhausted.votes.pp(2) }, 'loss_fraction': { 'transfers': result.loss_fraction.transfers.pp(2), 'votes': result.loss_fraction.votes.pp(2) }, 'total': result.total.pp(2), 'quota': result.quota.pp(2) }}); } } }