|
|
Line 1: |
Line 1: |
| mw.loader.impl(function(){return["ext.gadget.Global-Calculator@4dil0",function($,jQuery,require,module){(function(){var mathFuncs=['abs','acos','acosh','asin','asinh','atan','atan2','atanh','cbrt','ceil','cos','cosh','exp','expm1','floor','hypot','log','log10','log2','log1p','max','min','pow','random','sign','sin','sinh','sqrt','tan','tanh','trunc','clz32'];var otherFuncs=['ifzero','coalesce','iffinite','ifnan','ifpositive','ifequal','round','jsround','not','and','or','bool','ifless','iflessorequal','ifgreater','ifgreaterorequal','ifbetween','xor','index','switch','radiogroup','bitand','bitor','bitxor','bitnot','bitleftshift','bitlogicrightshift','bitarithrightshift','if','getclick','timer','timeriterations','timertime'];var allFuncs=mathFuncs.concat(otherFuncs);var convertFloat=function(f){if(typeof f==='number'){return f;}f=f.replace(/×\s?10/,'e');return parseFloat(f.replace(/[×⁰¹²³⁴⁵⁶⁷⁸⁹⁻]/g,function(m){return({'⁰':0,'¹':1,'²':2,'³':3,'⁴':4,'⁵':5,'⁶':6,'⁷':7,'⁸':8,'⁹':9,'⁻':"-","×":"e"})[m];}));};var Numb=function(n){if(typeof n==='number'){
| | /** |
| this.value=n;}this.value=parseFloat(n);}
| | * Calculator lets you create interactive spreadsheet-like forms on a wikipage |
| Numb.prototype.toString=function(){return'Number<'+this.value+'>';}
| | * Documentation: https://www.mediawiki.org/wiki/Template:Calculator |
| var Ident=function(n){this.value=n;}
| | * Source code: https://www.mediawiki.org/wiki/MediaWiki:Gadget-Global-Calculator.js |
| Ident.prototype.toString=function(){return'IDENT<'+this.value+'>';}
| | */ |
| var Operator=function(val,args){this.op=val;this.args=args;}
| | mw.loader.load( 'https://www.mediawiki.org/w/load.php?modules=ext.gadget.Global-Calculator' ); |
| var Null=function(){}
| |
| var Parser=function(text){this.text=text;};var terminals={'IDENT':/^[a-zA-Z_][a-zA-Z0-9_]*/,'NUMBER':/^-?[0-9]+(?:\.[0-9]+)?(?:[eE][0-9]+|×10⁻?[⁰¹²³⁴⁵⁶⁷⁸⁹]+)*/,'WS':/^\s*/,'PLUSMINUS':/^[+-]/,'pi':/^(?:pi|π)(?![A-z_0-9-])/i,'true':/^(?:true)(?![A-z_0-9-])/,'false':/^(?:false)(?![A-z_0-9-])/,'epsilon':/^EPSILON(?![A-z_0-9-])/,'Infinity':/^Infinity(?![A-z_0-9-])/i,'-Infinity':/^Infinity(?![A-z_0-9-])/i,'NaN':/^NaN(?![A-z_0-9-])/i,'MULTIPLYDIV':/^[*\/%×÷]/i,};Parser.prototype={check:function(id){if(terminals[id]){return!!(this.text.match(terminals[id]))}return this.text.startsWith(id)},consume:function(id){if(terminals[id]){var res=this.text.match(terminals[id]);this.text=this.text.substring(res[0].length);return res[0];}if(this.text.startsWith(id)){this.text=this.text.substring(id.length);return id;}throw new Error("Expected "+id+" near "+this.text.substring(0,15));},parse:function(){if(this.text===undefined||this.text==='')return new Null();this.consume('WS');res=
| |
| this.expression();if(this.text.length!==0){throw new Error("Unexpected end of formula. Perhaps you forgot to close a parenthesis or are using an invalid function.");}return res;},expression:function(){var text2,res,res2;res=this.term();this.consume('WS');while(this.check("PLUSMINUS")){var op=this.consume("PLUSMINUS");res2=this.term();res=new Operator(op,[res,res2]);}return res;},argList:function(){var args=[];this.consume('WS');if(this.check(')')){this.consume(')');return args;}args[args.length]=this.expression();this.consume('WS');while(this.check(',')){this.consume(',');this.consume('WS');args[args.length]=this.expression();}this.consume('WS');this.consume(')');return args;},term:function(){var text2,res,res2;res=this.factor();this.consume('WS');while(this.check("MULTIPLYDIV")){var op=this.consume("MULTIPLYDIV");if(op==='×')op='*';if(op==='÷')op='/';res2=this.factor();res=new Operator(op,[res,res2]);}return res;},factor:function(){var res;if(this.check('pi')){this.consume('pi');
| |
| return new Numb(Math.PI)}if(this.check('true')){this.consume('true');return new Numb(1)}if(this.check('false')){this.consume('false');return new Numb(0)}if(this.check('Infinity')){this.consume('Infinity');return new Numb(Infinity);}if(this.check('-Infinity')){this.consume('-Infinity');return new Numb(-Infinity);}if(this.check('NaN')){this.consume('NaN');return new Numb(NaN);}if(this.check('epsilon')){this.consume('epsilon');return new Numb(Number.EPSILON);}for(var i in allFuncs){if(this.check(allFuncs[i]+'(')){this.consume(allFuncs[i]+'(');var argList=this.argList()
| |
| return new Operator(allFuncs[i],argList);}}if(this.check('IDENT')){return new Ident(this.consume('IDENT'));}if(this.check('NUMBER')){return new Numb(convertFloat(this.consume('NUMBER')));}if(this.check('(')){this.consume('(');res=this.expression();this.consume(')');return res;}if(this.check('-')){this.consume('-');this.consume('WS');if(this.check('-')){throw new Error("Double unary minus without parenthesis not allowed near "+this.text.substring(0,15));}res=this.factor()
| |
| return new Operator('*',[new Numb(-1),res]);}throw new Error("Expected to see a term (e.g. an identifier, number, function, opening parenthesis, etc) near "+this.text.substring(0,15));},};var almostEquals=function(a,b){var absA=Math.abs(a);var absB=Math.abs(b);var diff=Math.abs(a-b);var epsilon=Number.EPSILON;var minNormal=Math.pow(2,-1022);if(a===b){return true;}if(a==0||b==0||absA+absB<minNormal){return diff<epsilon*minNormal;}return diff/Math.min((absA+absB),Number.MAX_VALUE)<epsilon;}
| |
| var getValueOfElm=function(elm,mapping){var val;if(elm.tagName==='INPUT'||elm.tagName==='SELECT'){if(elm.type==='radio'||elm.type==='checkbox'){return elm.checked?convertFloat(elm.value):0;}val=elm.value;}else{val=elm.textContent;}if(typeof val==='string'){val=val.trim();var mapVals=[val,val.toLowerCase()];for(var k=0;k<mapVals.length;k++){if(mapping&&typeof mapping[mapVals[k]]==='number'){return mapping[mapVals[k]];}else if(mapping&&['Infinity','-Infinity','NaN'].indexOf(mapping[mapVals[k]])!==-1){return parseFloat(mapping[mapVals[k]]);}}}return convertFloat(val);}
| |
| var evaluate=function(ast){var that=this;var elmList=this.elmList;var i,then,ielse;if(ast instanceof Numb){return ast.value;}if(ast instanceof Ident){var elm=elmList[ast.value];if(elm===undefined){console.log("Calculator: Reference to '"+ast.value+"' but there is no field by that name");return NaN;}return getValueOfElm(elm,this.mappingInput[elm.id.replace(/^(?:calcdisambig-\d+-)?calculator-field-/,'')])}if(ast instanceof Operator){if('index'===ast.op){if(ast.args.length<2||!(ast.args[0]instanceof Ident)){return NaN;}var indexValue=Math.floor(this.evaluate(ast.args[1]));if(!Number.isSafeInteger(indexValue)||indexValue<0){return NaN;}var res=elmList[ast.args[0].value+indexValue];if(res===undefined){return ast.args.length>=3?this.evaluate(ast.args[2]):NaN;}return getValueOfElm(res,this.mappingInput[res.id.replace(/^(?:calcdisambig-\d+-)?calculator-field-/,'')]);}if(ast.op==='radiogroup'){if(ast.args.length<1||!(ast.args[0]instanceof Ident)){return NaN;}var radioName=ast.args[0].value;var
| |
| elm=this.parent.querySelector('input:checked[type=radio][name='+CSS.escape('calcgadget-'+this.rand+'-'+radioName)+']');if(!elm){return NaN;}return this.evaluate(new Ident(elm.id.replace(/^(?:calcdisambig-\d+-)?calculator-field-/,'')));}if(ast.op==='getclick'){if(ast.args.length<1||!(ast.args[0]instanceof Ident)){return NaN;}switch(ast.args[0].value.toLowerCase()){case'x':return this.clickX;case'percentx':return this.clickPercentX;case'y':return this.clickY;case'percenty':return this.clickPercentY;default:return NaN;}}if(ast.op==='timer'){if(!this.repeatInfo){return ast.args.length>=3?this.evaluate(ast.args[2]):0;}if(ast.args.length<1||(ast.args[0]instanceof Ident&&ast.args[0].value===this.repeatInfo.id)){return ast.args.length>=2?this.evaluate(ast.args[1]):1;}return ast.args.length>=3?this.evaluate(ast.args[2]):0;}if(ast.op==='timeriterations'){if(!this.repeatInfo){return NaN;}if(ast.args.length<1||(ast.args[0]instanceof Ident&&ast.args[0].value===this.repeatInfo.id)){return this.
| |
| repeatInfo.iterationsSoFar;}return NaN;}if(ast.op==='timertime'){if(!this.repeatInfo){return NaN;}if(ast.args.length<1||(ast.args[0]instanceof Ident&&ast.args[0].value===this.repeatInfo.id)){return(Date.now()-this.repeatInfo.timeStart)/1000;}return NaN;}evaledArgs=ast.args.map(function(i){return that.evaluate(i)});if(mathFuncs.indexOf(ast.op)!==-1){return Math[ast.op].apply(Math,evaledArgs);}if('coalesce'===ast.op){for(var k=0;k<evaledArgs.length;k++){if(!isNaN(evaledArgs[k])){return evaledArgs[k];}}return NaN;}if('ifzero'===ast.op){if(evaledArgs.length<1){return NaN;}then=evaledArgs.length<2?1:evaledArgs[1];ielse=evaledArgs.length<3?0:evaledArgs[2];return almostEquals(evaledArgs[0],0)?then:ielse;}if('if'===ast.op){if(evaledArgs.length<1){return NaN;}then=evaledArgs.length<2?1:evaledArgs[1];ielse=evaledArgs.length<3?0:evaledArgs[2];return!almostEquals(evaledArgs[0],0)?then:ielse;}if('ifequal'===ast.op){if(evaledArgs.length<2){return NaN;}then=evaledArgs.length<3?1:evaledArgs[2];ielse=
| |
| evaledArgs.length<4?0:evaledArgs[3];return almostEquals(evaledArgs[0],evaledArgs[1])?then:ielse;}if('iffinite'===ast.op){if(evaledArgs.length<1){return NaN;}then=evaledArgs.length<2?1:evaledArgs[1];ielse=evaledArgs.length<3?0:evaledArgs[2];return isFinite(evaledArgs[0])?then:ielse;}if('ifnan'===ast.op){if(evaledArgs.length<1){return NaN;}then=evaledArgs.length<2?1:evaledArgs[1];ielse=evaledArgs.length<3?0:evaledArgs[2];return isNaN(evaledArgs[0])?then:ielse;}if('ifpositive'===ast.op){if(evaledArgs.length<1){return NaN;}then=evaledArgs.length<2?1:evaledArgs[1];ielse=evaledArgs.length<3?0:evaledArgs[2];return evaledArgs[0]>=0?then:ielse;}if('ifless'===ast.op){if(evaledArgs.length<2){return NaN;}then=evaledArgs.length<3?1:evaledArgs[2];ielse=evaledArgs.length<4?0:evaledArgs[3];return evaledArgs[0]<evaledArgs[1]&&!almostEquals(evaledArgs[0],evaledArgs[1])?then:ielse;}if('ifgreater'===ast.op){if(evaledArgs.length<2){return NaN;}then=evaledArgs.length<3?1:evaledArgs[2];ielse=evaledArgs.
| |
| length<4?0:evaledArgs[3];return evaledArgs[0]>evaledArgs[1]&&!almostEquals(evaledArgs[0],evaledArgs[1])?then:ielse;}if('iflessorequal'===ast.op){if(evaledArgs.length<2){return NaN;}then=evaledArgs.length<3?1:evaledArgs[2];ielse=evaledArgs.length<4?0:evaledArgs[3];return evaledArgs[0]<=evaledArgs[1]||almostEquals(evaledArgs[0],evaledArgs[1])?then:ielse;}if('ifgreaterorequal'===ast.op){if(evaledArgs.length<2){return NaN;}then=evaledArgs.length<3?1:evaledArgs[2];ielse=evaledArgs.length<4?0:evaledArgs[3];return evaledArgs[0]>=evaledArgs[1]||almostEquals(evaledArgs[0],evaledArgs[1])?then:ielse;}if('ifbetween'===ast.op){if(evaledArgs.length<3){return NaN;}then=evaledArgs.length<4?1:evaledArgs[3];ielse=evaledArgs.length<5?0:evaledArgs[4];return evaledArgs[0]>=evaledArgs[1]&&evaledArgs[0]<=evaledArgs[2]?then:ielse;}if('bool'===ast.op){if(evaledArgs.length!==1){return NaN;}return isNaN(evaledArgs[0])||almostEquals(evaledArgs[0],0.0)?0:1;}if('not'===ast.op){if(evaledArgs.length!==1){return NaN;}
| |
| return isNaN(evaledArgs[0])||almostEquals(evaledArgs[0],0.0)?1:0;}if('xor'===ast.op){if(evaledArgs.length!==2){return NaN;}if(((isNaN(evaledArgs[0])||almostEquals(evaledArgs[0],0.0))&&!(isNaN(evaledArgs[1])||almostEquals(evaledArgs[1],0.0)))||((isNaN(evaledArgs[1])||almostEquals(evaledArgs[1],0.0))&&!(isNaN(evaledArgs[0])||almostEquals(evaledArgs[0],0.0)))){return 1;}else{return 0;}}if('and'===ast.op){for(i=0;i<evaledArgs.length;i++){if(isNaN(evaledArgs[i])||almostEquals(evaledArgs[i],0.0)){return evaledArgs[i];}}return evaledArgs.length>=1?evaledArgs[evaledArgs.length-1]:1;}if('or'===ast.op){for(i=0;i<evaledArgs.length;i++){if(!isNaN(evaledArgs[i])&&!almostEquals(evaledArgs[i],0.0)){return evaledArgs[i];}}return evaledArgs.length>=1?evaledArgs[evaledArgs.length-1]:0;}if('bitand'===ast.op){if(evaledArgs.length<1){return NaN;}res=evaledArgs[0]
| |
| for(i=1;i<evaledArgs.length;i++){res=res&evaledArgs[i];}return res;}if('bitor'===ast.op){if(evaledArgs.length<1){return NaN;}res=evaledArgs[0]
| |
| for(i=1;i<evaledArgs.length;i++){res=res|evaledArgs[i];}return res;}if('bitxor'===ast.op){if(evaledArgs.length<1){return NaN;}res=evaledArgs[0]
| |
| for(i=1;i<evaledArgs.length;i++){res=res^evaledArgs[i];}return res;}if('bitnot'===ast.op){if(evaledArgs.length<1){return NaN;}return~evaledArgs[0];}if('bitleftshift'===ast.op){if(evaledArgs.length<2){return NaN;}return evaledArgs[0]<<evaledArgs[1];}if('bitlogicrightshift'===ast.op){if(evaledArgs.length<2){return NaN;}return evaledArgs[0]>>>evaledArgs[1];}if('bitarithrightshift'===ast.op){if(evaledArgs.length<2){return NaN;}return evaledArgs[0]>>evaledArgs[1];}if('switch'===ast.op){if(evaledArgs.length<2){return NaN;}var defaultVal=NaN;if(evaledArgs.length%2===0){defaultVal=evaledArgs[evaledArgs.length-1];}for(i=1;i<evaledArgs.length-1;i+=2){if(evaledArgs[0]<=evaledArgs[i]||almostEquals(evaledArgs[i],evaledArgs[0])){return evaledArgs[i+1];}}return defaultVal;}if('round'===ast.op){var decimals=evaledArgs.length>=2?evaledArgs[1]:0;var p=Math.pow(10,decimals);var n=(evaledArgs[0]*p)*(1+Number.EPSILON);return Math.round(n)/p;}if(ast.op==='jsround'){return Math.round.apply(Math,evaledArgs);}
| |
| if(evaledArgs.length!==2){throw new Error("Unexpected number of args for "+ast.op);}if(ast.op==='*')return evaledArgs[0]*evaledArgs[1];if(ast.op==='/')return evaledArgs[0]/evaledArgs[1];if(ast.op==='+')return evaledArgs[0]+evaledArgs[1];if(ast.op==='-')return evaledArgs[0]-evaledArgs[1];if(ast.op==='%')return evaledArgs[0]%evaledArgs[1];throw new Error("Unrecognized operator "+ast.op);}return NaN;}
| |
| var getIdentifiers=function(tree){if(tree instanceof Ident){return new Set([tree.value]);}if(tree instanceof Operator){var res=new Set([]);var i=0;if(tree.op==='index'&&tree.args.length>0){i++;getIdentifiers(tree.args[0]).forEach(function(x){res.add(x+'*')});}else if((tree.op==='radiogroup')&&tree.args.length>0&&tree.args[0]instanceof Ident){i++;res.add('--radio-'+tree.args[0].value);}else if((tree.op==='timer')){if(tree.args.length>0&&tree.args[0]instanceof Ident){i++;res.add('--timer-active-'+tree.args[0].value);}else{res.add('--timer-active');}}else if(tree.op==='timertime'||tree.op==='timeriterations'){res.add('--timer-iteration');if(tree.args.length>0&&tree.args[0]instanceof Ident){res.add('--timer-iteration-'+tree.args[0].value);}else{res.add('--timer-iteration');}return res;}else if(tree.op==='getclick'){return res;}for(;i<tree.args.length;i++){getIdentifiers(tree.args[i]).forEach(function(x){res.add(x)});}return res;}return new Set();}
| |
| var buildBacklinks=function(items,radioGroups){var backlinks=Object.create(null);for(var item in items){var idents=getIdentifiers(items[item]);idents.forEach(function(ident){if(!backlinks[ident]){backlinks[ident]=[];}backlinks[ident].push(item);});}var identPrefix='--radio-';for(var groupName in radioGroups){if(backlinks[identPrefix+groupName]==undefined){backlinks[identPrefix+groupName]=[];}for(var i=0;i<radioGroups[groupName].length;i++){backlinks[identPrefix+groupName].push(radioGroups[groupName][i]);if(backlinks[radioGroups[groupName][i]]==undefined){backlinks[radioGroups[groupName][i]]=[];}backlinks[radioGroups[groupName][i]].push(identPrefix+groupName);}}return backlinks;};var setup=function($content){var containers=Array.from($content.find('.calculator-container'));for(var i=0;i<containers.length;i++){var calc=new CalculatorWidgets(Array.from(containers[i].getElementsByClassName('calculator-field')),containers[i]);}var elms=Array.from($content.find('.calculator-field'));new
| |
| CalculatorWidgets(elms,$content[0]);$content.find('.calculator-field-label').replaceWith(function(){var l=$('<label>');if(this.dataset.for!==undefined){if(!this.dataset.for.match(/^(?:calcdisambig-\d+-)?calculator-field-[a-zA-Z_][a-zA-Z0-9_]*$/)||!$content.find('#'+$.escapeSelector(this.dataset.for)).length){return this;}l.attr('for',this.dataset.for);}if(this.id){l.attr('id',this.id);}if(this.title){l.attr('title',this.title);}if(this.style.cssText){l.attr('style',this.style.cssText);}if(this.classList.contains('cdx-label__label')){mw.loader.load('@wikimedia/codex');}if(this.className!=='calculator-field-label'){var extraClass=this.dataset.calculatorClass===undefined?'':' '+this.dataset.calculatorClass
| |
| l.attr('class',this.className.replace(/(^| )calculator-field-label( |$)/g,' ')+extraClass);}l.append(this.childNodes);return l;});}
| |
| var doStats=function(){if(window.calculatorStatsAlreadyDone!==true){window.calculatorStatsAlreadyDone=true;mw.track('counter.gadget_calculator._all');mw.track('counter.gadget_calculator.'+mw.config.get('wgDBname')+'_all');var statName=mw.config.get('wgDBname')+'_'+mw.config.get('wgPageName');statName=encodeURIComponent(statName);statName=statName.replace(/[^a-zA-Z0-9_]/g,'_');mw.track('counter.gadget_calculator.'+statName);}}
| |
| var createSelect=function(elm){var sel=document.createElement('select');var mapping;try{mapping=JSON.parse(elm.dataset.calculatorMapping);}catch(e){console.log("Calculator: Error processing mapping of "+elm.id+". "+e.message);return sel;}if(typeof mapping!=='object'){console.log("Calculator: Error processing mapping of "+elm.id+". unexpected type");return sel;}var opt;for(var i in mapping){if(typeof mapping[i]==='object'){var optgroup=document.createElement('optgroup');optgroup.label=i;sel.appendChild(optgroup);for(var j in mapping[i]){if(typeof mapping[i][j]==='number'||['Infinity','-Infinity','NaN'].indexOf(mapping[i][j])!==-1){opt=document.createElement('option');opt.value=mapping[i][j];opt.appendChild(document.createTextNode(j));optgroup.appendChild(opt);}}}else if(typeof mapping[i]==='number'||['Infinity','-Infinity','NaN'].indexOf(mapping[i])!==-1){opt=document.createElement('option');opt.value=mapping[i];opt.appendChild(document.createTextNode(i));sel.appendChild(opt);}}return sel
| |
| ;}
| |
| var CalculatorWidgets=function(elms,parent){this.parent=parent;this.rand=Math.floor(Math.random()*1000000000)
| |
| this.itemList=Object.create(null);this.elmList=Object.create(null);this.backlinks=Object.create(null);this.inProgressRefresh=undefined;this.clickX=this.clickY=this.clickPercentX=this.clickPercentY=NaN;this.repeatInfo=null;var that=this;var radioGroups=Object.create(null);this.buttonInfo=Object.create(null);this.mappingInput=Object.create(null);this.mappingOutput=Object.create(null);this.repeatInfo=null;if(elms.length>200){console.log("Too many calculator widgets on page");return;}for(var i in elms){var elm=elms[i];var formula=elm.dataset.calculatorFormula;if(formula&&formula.length>2000){console.log("Skipping element with too long formula");continue;}var type=elm.dataset.calculatorType;var readonly=!!elm.dataset.calculatorReadonly;var id=elm.id.toString();if(id.match(/^(?:calcdisambig-\d+-)?calculator-field-__proto__$/)||elm.dataset.calculatorName==='__proto__'){throw new Error("Invalid calculator id: "+id);}if(!id){id='calculator-field-auto'+Math.floor(Math.random()*10000000)+
| |
| 'unnamed';}if(this.parent.classList.contains('calculator-container')&&document.getElementById(id)!==elm){var labelsToUpdate=this.parent.querySelectorAll(":scope .calculator-field-label[data-for=\""+CSS.escape(id)+"\"]");id='calcdisambig-'+this.rand+'-'+id;for(var l=0;l<labelsToUpdate.length;l++){labelsToUpdate[l].dataset.for=id;}}var defaultVal=(""+elm.textContent).trim();if(type===undefined||!id.match(/^(?:calcdisambig-\d+-)?calculator-field-[a-zA-Z_][a-zA-Z0-9_]*$/)){console.log("Skipping "+id);continue;}try{var formulaAST=(new Parser(formula)).parse();}catch(e){console.log("Error parsing formula of "+id+": "+e.message+". Formula given:"+formula);continue;}if(elm.className.match(/(^| )cdx-/)||(elm.dataset.calculatorClass&&elm.dataset.calculatorClass.match(/(^| )cdx-/))){mw.loader.load('@wikimedia/codex');}if(type!=='plain'&&type!=='passthru'){var input=type==='select'?createSelect(elm):document.createElement('input');input.className='calculator-field-live';if(elm.className!==
| |
| 'calculator-field')input.className+=' '+elm.className.replace(/(^| )calculator-field($| )/g,' ');input.readOnly=readonly
| |
| if(defaultVal!==''){input.value=convertFloat(defaultVal);}input.style.cssText=elm.style.cssText;if(elm.dataset.calculatorSize){var size=parseInt(elm.dataset.calculatorSize);input.size=size
| |
| input.style.width=type==='number'?"calc( "+size+'ch'+' + 20px)':size+'ch';}if(elm.dataset.calculatorClass)input.className+=' '+elm.dataset.calculatorClass;if(elm.dataset.calculatorSize)input.size=elm.dataset.calculatorSize;if(elm.dataset.calculatorMax)input.max=elm.dataset.calculatorMax;if(elm.dataset.calculatorMin)input.min=elm.dataset.calculatorMin;if(elm.dataset.calculatorPlaceholder)input.placeholder=elm.dataset.calculatorPlaceholder;if(elm.dataset.calculatorStep)input.step=elm.dataset.calculatorStep;if(elm.dataset.calculatorPrecision)input.dataset.calculatorPrecision=elm.dataset.calculatorPrecision;if(elm.dataset.calculatorExponentialPrecision)input.dataset.calculatorExponentialPrecision=elm.dataset.calculatorExponentialPrecision;if(elm.dataset.calculatorDecimals)input.dataset.calculatorDecimals=elm.dataset.calculatorDecimals;if(elm.dataset.calculatorNanText)input.dataset.calculatorNanText=elm.dataset.calculatorNanText;if(type==='radio'){if(elm.dataset.calculatorName)input.name=
| |
| 'calcgadget-'+this.rand+'-'+elm.dataset.calculatorName;if(radioGroups[elm.dataset.calculatorName]===undefined){radioGroups[elm.dataset.calculatorName]=[];}radioGroups[elm.dataset.calculatorName][radioGroups[elm.dataset.calculatorName].length]=id.replace(/^(?:calcdisambig-\d+-)?calculator-field-/,'');}if(elm.dataset.calculatorInputmode)input.inputMode=elm.dataset.calculatorInputmode;if(elm.dataset.calculatorEnterkeyhint)input.enterKeyHint=elm.dataset.calculatorEnterkeyhint;if(elm.getAttribute('aria-describedby')!==null)input.setAttribute('aria-describedby',elm.getAttribute('aria-describedby'));if(elm.getAttribute('aria-labelledby')!==null)input.setAttribute('aria-labelledby',elm.getAttribute('aria-labelledby'));if(elm.getAttribute('aria-label')!==null)input.setAttribute('aria-label',elm.getAttribute('aria-label'));if(elm.getAttribute('aria-owns')!==null)input.setAttribute('aria-owns',elm.getAttribute('aria-owns'));if(elm.getAttribute('aria-flowto')!==null)input.setAttribute(
| |
| 'aria-flowto',elm.getAttribute('aria-flowto'));if(elm.getAttribute('role')!==null)input.setAttribute('role',elm.getAttribute('role'));if(elm.dataset.calculatorAriaRole)input.setAttribute('role',elm.dataset.calculatorAriaRole);if(['true','false'].indexOf(elm.dataset.calculatorAriaAtomic)!==-1)input.setAttribute('aria-atomic',elm.dataset.calculatorAriaAtomic);if(elm.dataset.calculatorAriaRelevant)input.setAttribute('aria-relevant',elm.dataset.calculatorAriaRelevant);if(['off','polite','assertive'].indexOf(elm.dataset.calculatorAriaLive)!==-1){input.setAttribute('aria-live',elm.dataset.calculatorAriaLive);}else{if(formula){input.setAttribute('aria-live','polite');}}if(type==='number'||type==='text'||type==='radio'||type==='checkbox'||type==="hidden"||type==="range"){input.type=type;}if(type==='select'){if(elm.dataset.calculatorValue){input.value=elm.dataset.calculatorValue;}}if(type==='radio'||type==='checkbox'){input.onchange=this.changeHandler.bind(this);if(elm.dataset.calculatorChecked
| |
| ==='true'||elm.dataset.calculatorChecked==='1'){input.checked=true;}else if(elm.dataset.calculatorChecked==='false'||elm.dataset.calculatorChecked==='0'){input.checked=false;}else if(!isNaN(defaultVal)&&!almostEquals(defaultVal,0)){input.checked=true;}var checkValue=convertFloat(elm.dataset.calculatorValue||'');if(!isNaN(checkValue)&&!almostEquals(checkValue,0)){input.value=checkValue;input.dataset.calculatorValue=checkValue;}else if(!isNaN(defaultVal)&&!almostEquals(defaultVal,0)){input.value=defaultVal;input.dataset.calculatorValue=defaultVal;}else{input.value=1;input.dataset.calculatorValue=1;}}if(elm.dataset.calculatorMapping&&type==='text'){this.processMapping(elm.dataset.calculatorMapping,id.replace(/^(?:calcdisambig-\d+-)?calculator-field-/,''));}input.id=id;elm.replaceWith(input);elm=input;input.addEventListener('input',this.changeHandler.bind(this));}else{elm.classList.remove('calculator-field');elm.classList.add('calculator-field-live');if(elm.dataset.calculatorClass)elm.
| |
| className+=' '+elm.dataset.calculatorClass;if(['off','polite','assertive'].indexOf(elm.dataset.calculatorAriaLive)!==-1){elm.setAttribute('aria-live',elm.dataset.calculatorAriaLive);}else if(formula&&type!=='passthru'&&!elm.dataset.calculatorAriaLive){elm.setAttribute('aria-live','polite');}if(['true','false'].indexOf(elm.dataset.calculatorAriaAtomic)!==-1)elm.setAttribute('aria-atomic',elm.dataset.calculatorAriaAtomic);if(elm.dataset.calculatorAriaRole)elm.setAttribute('role',elm.dataset.calculatorAriaRole);if(elm.dataset.calculatorAriaRelevant)elm.setAttribute('aria-relevant',elm.dataset.calculatorAriaRelevant);if(elm.id===''){elm.id=id;}if(elm.dataset.calculatorMapping&&type==='plain'){this.processMapping(elm.dataset.calculatorMapping,id.replace(/^(?:calcdisambig-\d+-)?calculator-field-/,''));}}var itemId=id.replace(/^(?:calcdisambig-\d+-)?calculator-field-/,'');this.itemList[itemId]=formulaAST;this.elmList[itemId]=elm;}this.backlinks=buildBacklinks(this.itemList,radioGroups);if(
| |
| this.parent.dataset.calculatorRefreshOnLoad&&this.parent.dataset.calculatorRefreshOnLoad==='true'){this.inProgressRefresh=Object.create(null);var unsetBusy=this.setBusy();this.refresh(Object.keys(this.itemList).filter(function(a){return!(that.itemList[a]instanceof Null);}));this.inProgressRefresh=undefined;unsetBusy();}this.setupButtons()}
| |
| CalculatorWidgets.prototype.processMapping=function(mappingText,itemId){var mapping
| |
| try{mapping=JSON.parse(mappingText);}catch(e){console.log("Calculator: Error processing mapping of "+itemId+". "+e.message);return}if(typeof mapping!=='object'){console.log("Calculator: Error processing mapping of "+itemId+". unexpected type");return;}this.mappingInput[itemId]=mapping;var mapOut=Object.create(null);for(var i in mapping){if(typeof mapping[i]==='number'||['default','Infinity','-Infinity','NaN'].indexOf(mapping[i])!==-1){mapOut[mapping[i]]=i;}}this.mappingOutput[itemId]=mapOut;}
| |
| CalculatorWidgets.prototype.stopRepeat=function(){if(this.repeatInfo){if(this.repeatInfo.cancelIdentifier){window.clearInterval(this.repeatInfo.cancelIdentifier);}var id=this.repeatInfo.id;this.repeatInfo=null;this.inProgressRefresh=Object.create(null);var unsetBusy=this.setBusy();this.refresh(['--timer-active','--timer-active-'+id,'--timer-iteration','--timer-iteration-'+id]);this.inProgressRefresh=undefined;unsetBusy();}this.repeatInfo=null;}
| |
| CalculatorWidgets.prototype.startRepeat=function(maxIterations,id){if(this.repeatInfo){console.log("Calculator: Trying to start a repeat when one is already in progress. This should not happen");}this.repeatInfo={maxIterations:maxIterations,iterationsSoFar:0,cancelIdentifier:null,timeStart:Date.now(),id:event.currentTarget.id}
| |
| var id=this.repeatInfo.id;if(this.inProgressRefresh){console.log("Calculator: Refresh already in progress. This probably indicates a bug");}else{this.inProgressRefresh=Object.create(null);}var unsetBusy=this.setBusy();this.refresh(['--timer-active','--timer-active-'+id,'--timer-iteration','--timer-iteration-'+id]);this.inProgressRefresh=undefined;unsetBusy();}
| |
| CalculatorWidgets.prototype.incrementRepeatIteration=function(until){this.repeatInfo.iterationsSoFar++;if(this.repeatInfo.iterationsSoFar>this.repeatInfo.maxIterations){this.stopRepeat()
| |
| return false;}if(until){var untilRes=this.evaluate(until);if(!isNaN(untilRes)&&!almostEquals(untilRes,0)){this.stopRepeat();return false;}}var id=this.repeatInfo.id;if(this.inProgressRefresh){console.log("Calculator: Refresh already in progress. This probably indicates a bug");}else{this.inProgressRefresh=Object.create(null);}var unsetBusy=this.setBusy();this.refresh(['--timer-iteration','--timer-iteration-'+id]);this.inProgressRefresh=undefined;unsetBusy();return true;}
| |
| var makeButtonCallback=function(calc,forElms,formulaASTs,repeat,maxIterations,toggle,until){return function buttonCallback(event){var unsetBusy=calc.setBusy();if(toggle&&calc.repeatInfo&&calc.repeatInfo.id===event.currentTarget.id){calc.stopRepeat();unsetBusy();return;}if(maxIterations!==undefined||repeat!==undefined){calc.stopRepeat();if(maxIterations>1){calc.startRepeat(maxIterations,event.currentTarget.id);}}var doStuff=function(event){var unsetBusyInner=calc.setBusy()
| |
| var stillGoing=true;if(calc.repeatInfo){stillGoing=calc.incrementRepeatIteration(until)}if(stillGoing){for(var i=0;i<forElms.length;i++){if(!formulaASTs[i]||!forElms[i]){console.log("Skipping button update due to invalid formula or for attribute");continue;}var res=calc.evaluate(formulaASTs[i]);calc.setValue(forElms[i],res);forElms[i].dispatchEvent(new InputEvent('input'));}}unsetBusyInner();}
| |
| if(maxIterations===undefined||maxIterations>=1){calc.clickX=event.offsetX;calc.clickY=event.offsetY
| |
| calc.clickPercentX=100*event.offsetX/event.currentTarget.clientWidth
| |
| calc.clickPercentY=100*event.offsetY/event.currentTarget.clientHeight
| |
| doStuff();calc.clickX=calc.clickY=calc.clickPercentX=calc.clickPercentY=NaN;}unsetBusy();if(calc.repeatInfo&&maxIterations>1&&repeat>=500){calc.repeatInfo.cancelIdentifier=window.setInterval(doStuff,repeat);}}}
| |
| var connectButtonToFormula=function(calc,$button,forAttr,formulaAttr,repeatDuration,maxIterations,toggle,untilAttr){if(repeatDuration!==undefined){repeatDuration=Math.max(500,Math.ceil(parseFloat(repeatDuration)*1000))
| |
| if(isNaN(repeatDuration)){repeatDuration=undefined;}}if(toggle==='false'){toggle=false;}if(maxIterations!==undefined){maxIterations=parseInt(maxIterations);}else if(repeatDuration){maxIterations=Infinity;}if(typeof forAttr!=='string'||typeof formulaAttr!=='string'){return;}if(formulaAttr.length>2000||(untilAttr&&untilAttr.length>2000)){console.log("Skipping button with too long formula");return}var until=null;try{until=(new Parser(untilAttr)).parse();}catch(e){console.log("Calculator: Error parsing until formula of button "+$button[0].id+": "+e.message);}var forList=forAttr.split(';');var formulaList=formulaAttr.split(';');var forElms=[];var formulaASTs=[];for(var i=0;i<forList.length;i++){if(formulaList[i]===undefined){break;}forElms[i]=calc.elmList[forList[i]];try{formulaASTs[i]=(new Parser(formulaList[i])).parse();}catch(e){formulaASTs[i]=null;console.log("Calculator: Error parsing formula of button "+$button[0].id+" for "+forList[i]+": "+e.message);}}$button[0].addEventListener(
| |
| 'click',makeButtonCallback(calc,forElms,formulaASTs,repeatDuration,maxIterations,toggle,until));}
| |
| CalculatorWidgets.prototype.connectButtonDisable=function(button,formula){if(formula===''||formula==='0'||formula==='false'){return;}if(formula.length>2000){console.log("Calculator: Disable formula for button "+button.id+" is too long");return}try{var formulaAST=(new Parser(formula)).parse();}catch(e){console.log("Error parsing disable formula of button "+button.id+": "+e.message);return;}this.buttonInfo[button.id]={elm:button,formula:formulaAST,};var idents=getIdentifiers(formulaAST);var that=this;var item='--button-disable-'+button.id;idents.forEach(function(ident){if(!that.backlinks[ident]){that.backlinks[ident]=[];}that.backlinks[ident].push(item);});var curValue=this.evaluate(formulaAST)
| |
| if(!isNaN(curValue)&&!almostEquals(curValue,0)){button.disabled=true;}}
| |
| CalculatorWidgets.prototype.setupButtons=function(){var calc=this;$(this.parent).find('.calculator-field-button').replaceWith(function(){var b=$('<button type="button">');if(this.id&&this.id!=='__proto__'){b.attr('id',this.id);}else{b.attr('id','calculator-button-'+Math.ceil(Math.random()*100000000000));}if(this.title){b.attr('title',this.title);}if(this.style.cssText){b.attr('style',this.style.cssText);}if(this.classList.contains('cdx-button')){mw.loader.load('@wikimedia/codex');}if(this.className!=='calculator-field-button'){var extraClass=this.dataset.calculatorClass===undefined?'':' '+this.dataset.calculatorClass
| |
| b.attr('class',this.className.replace(/(^| )calculator-field-button( |$)/g,' ')+extraClass);}if(this.dataset.calculatorAlt){b.attr('aria-label',this.dataset.calculatorAlt);}if(this.dataset.calculatorAriaLive){b.attr('aria-live',this.dataset.calculatorAriaLive);}if(this.getAttribute('role')){b.attr('role',this.getAttribute('role'));}if(this.getAttribute('aria-owns')){b.attr('aria-owns',this.getAttribute('aria-owns'));}if(this.getAttribute('aria-flowto')){b.attr('aria-flowto',this.getAttribute('aria-flowto'));}if(this.dataset.calculatorDisabled!==undefined){if(this.dataset.calculatorDisabled==='true'||this.dataset.calculatorDisabled==='1'){b.attr('disabled',true);}else{calc.connectButtonDisable(b[0],this.dataset.calculatorDisabled);}}connectButtonToFormula(calc,b,this.dataset.calculatorFor,this.dataset.calculatorFormula,this.dataset.calculatorDelay,this.dataset.calculatorMaxIterations,this.dataset.calculatorToggle,this.dataset.calculatorUntil);b.append(this.childNodes);return b;});$(this
| |
| .parent).find('.calculator-field-buttonraw').each(function(){if(!this.id||this.id==='__proto__'){this.id='calculator-button-'+Math.ceil(Math.random()*100000000000);}connectButtonToFormula(calc,$(this),this.dataset.calculatorFor,this.dataset.calculatorFormula,this.dataset.calculatorDelay,this.dataset.calculatorMaxIterations,this.dataset.calculatorToggle,this.dataset.calculatorUntil);});};CalculatorWidgets.prototype.changeHandler=function(e){this.inProgressRefresh=Object.create(null);var unsetBusy=this.setBusy()
| |
| doStats();var itemId=e.target.id.replace(/^(?:calcdisambig-\d+-)?calculator-field-/,'');var itemsToRefresh=[this.backlinks[itemId]];this.inProgressRefresh[itemId]=true;this.setValueProperties(e.target,getValueOfElm(e.target,this.mappingInput[e.target.id.replace(/^(?:calcdisambig-\d+-)?calculator-field-/,'')]));var staritem=itemId.replace(/[0-9]+$/,'*');if(itemId.match(/[0-9]+$/)&&this.backlinks[staritem]){this.inProgressRefresh[staritem]=true;itemsToRefresh.push(this.backlinks[staritem]);}this.refresh(itemsToRefresh.flat());this.inProgressRefresh=undefined;unsetBusy();}
| |
| var format=function(n,options,mapping){var res=n.toString();if(typeof n!=="number"){return res;}if(mapping&&mapping[n]){return mapping[n];}if(mapping&&mapping['default']!==undefined){return mapping['default'];}if(isNaN(n)){return options.calculatorNanText?options.calculatorNanText:'?';}if(!isNaN(parseInt(options.calculatorDecimals))){res=n.toFixed(parseInt(options.calculatorDecimals));}if(!isNaN(parseInt(options.calculatorPrecision))){res=n.toPrecision(parseInt(options.calculatorPrecision));}if(!isNaN(parseInt(options.calculatorExponentialPrecision))){res=n.toExponential(parseInt(options.calculatorExponentialPrecision));}res=res.replace(/e([+-])([0-9]+)$/,function(m,sign,exp){var tmp="×10";if(sign==='-'){tmp+='⁻';}tmp+=exp.replace(/[0-9]/g,function(m){return['⁰','¹','²','³','⁴','⁵','⁶','⁷','⁸','⁹'][m];});return tmp;});return res;};CalculatorWidgets.prototype.setValuePropertiesSpecialPurpose=function(id){if(id.match(/^--button-disable-.+/)){var buttonId=id.substring(
| |
| 17);if(this.buttonInfo[buttonId]){var res=this.evaluate(this.buttonInfo[buttonId].formula);this.buttonInfo[buttonId].elm.disabled=!isNaN(res)&&!almostEquals(res,0);}else{console.log('Tried to refresh disable status for '+buttonId+' but there is no such button.');}}return;}
| |
| CalculatorWidgets.prototype.setValueProperties=function(elm,value){var itemId=elm.id.replace(/^(?:calcdisambig-\d+-)?calculator-field-/,'');elm.dataset.calculatorFieldValue=value.toFixed(5);if(!itemId.match(/^auto\d\d\d\d+unnamed$/)){this.parent.style.setProperty('--calculator-'+itemId,value);}if(!isNaN(value)&&!almostEquals(value,0)){elm.classList.remove('calculator-value-false');elm.classList.add('calculator-value-true');}else{elm.classList.remove('calculator-value-true');elm.classList.add('calculator-value-false');}}
| |
| CalculatorWidgets.prototype.refresh=function(itemIds){var i;var permMarks=Object.create(null);var tempMarks=Object.create(null);var topList=[];var that=this;if(!itemIds){return;}var visit=function(item){var i;if(permMarks[item]){return;}if(tempMarks[item]){if(!item.match(/^--radio-/)){console.log("Loop detected in calculator. '"+item+"' may not be updated properly. (This is expected for radio buttons)");}return;}tempMarks[item]=true;for(i=0;that.backlinks[item]&&i<that.backlinks[item].length;i++){visit(that.backlinks[item][i]);}if(item.match(/[0-9]+$/)){var staritem=item.replace(/[0-9]+$/,'*');for(i=0;that.backlinks[staritem]&&i<that.backlinks[staritem].length;i++){visit(that.backlinks[staritem][i]);}}permMarks[item]=true;topList.push(item);};for(i=0;i<itemIds.length;i++){if(itemIds[i]!==undefined){visit(itemIds[i]);}}for(i=topList.length-1;i>=0;i--){var itemId=topList[i];if(this.inProgressRefresh[itemId]){if(this.elmList[itemId].type!=='radio'){console.log("Loop Detected! Skipping "+
| |
| itemId);}continue;}if(itemId.match(/^--/)){this.setValuePropertiesSpecialPurpose(itemId);this.inProgressRefresh[itemId]=true;continue;}else if(!this.itemList[itemId]||this.itemList[itemId]instanceof Null){var elm=this.elmList[itemId];this.setValueProperties(elm,getValueOfElm(elm,this.mappingInput[itemId]));if(this.elmList[itemId].type!=='radio'){console.log("Tried to refresh field "+itemId+" with no formula");}continue;}this.inProgressRefresh[itemId]=true;var elm=this.elmList[itemId];if(elm.type==='radio'&&this.inProgressRefresh['--radio-'+elm.name.replace(/^calcgadget-\d+-/,'')]){this.setValueProperties(elm,getValueOfElm(elm,this.mappingInput[itemId]));continue;}var res=this.evaluate(this.itemList[itemId]);this.setValue(elm,res);}};CalculatorWidgets.prototype.setValue=function(elm,res){this.setValueProperties(elm,res);var mappingOut=this.mappingOutput[elm.id.replace(/^(?:calcdisambig-\d+-)?calculator-field-/,'')];if(elm.tagName==='INPUT'){elm.value=elm.type==="number"||elm.type===
| |
| "range"?res:format(res,elm.dataset,mappingOut);if(elm.type==='radio'||elm.type==='checkbox'){elm.checked=!isNaN(res)&&!almostEquals(res,0);if(!elm.checked&&elm.dataset.calculatorValue){elm.value=elm.dataset.calculatorValue;}}}else if(elm.tagName==='SELECT'){elm.value=res;}else if(elm.dataset.calculatorType!=='passthru'){elm.textContent=format(res,elm.dataset,mappingOut);}}
| |
| CalculatorWidgets.prototype.setBusy=function(){var curVal=this.parent.getAttribute('aria-busy');if(curVal==='true'){return function(){};}this.parent.setAttribute('aria-busy','true');var that=this;return function(){that.parent.setAttribute('aria-busy','false');};}
| |
| CalculatorWidgets.prototype.evaluate=evaluate;mw.hook('wikipage.content').add(setup);})();
| |
| },{"css":["body.skin-minerva input.calculator-field-live:not(.cdx-text-input__input):not(.cdx-checkbox__input):not(.cdx-radio__input){background:revert;border:revert}@media screen{ html.client-js .calculatorgadget-enabled{display:revert !important}html.client-js .calculatorgadget-fallback{display:none}}"]}];});
| |