KOC Notebook

RangeCalculator

// ==UserScript==
// @name           KOC Notebook
// @version        20130929a
// @namespace      anote
// @include        *.kingdomsofcamelot.com/*main_src.php*
// @include        *.kingdomsofcamelot.com/*platforms/kabam*
// @include        *apps.facebook.com/kingdomsofcamelot/*
// @include        *kabam.com/kingdoms-of-camelot/play*
// @include        *facebook.com/connect/uiserver.php*
// @include        *facebook.com/*/serverfbml*
// @include        *facebook.com/dialog/feed*
// @include        *facebook.com/dialog/stream.publish*
// @include        *facebook.com/dialog/apprequests*
// @description    RangeCalculator
// ==/UserScript==


var Version = '20130929a';

// These switches are for testing, all should be set to false for released version:
var DEBUG_TRACE = false;
var DEBUG_SEARCH = false;
var ENABLE_SAMPLE_TAB = false;
var ENABLE_GM_AJAX_TRACE = false;
var SEND_ALERT_AS_WHISPER = false;
// end test switches

var JSON;if(!JSON){JSON={};}(function(){"use strict";function f(n){return n<10?'0'+n:n;}if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+'-'+f(this.getUTCMonth()+1)+'-'+f(this.getUTCDate())+'T'+f(this.getUTCHours())+':'+f(this.getUTCMinutes())+':'+f(this.getUTCSeconds())+'Z':null;};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf();};}var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==='string'?c:'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);})+'"':'"'+string+'"';}function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==='object'&&typeof value.toJSON==='function'){value=value.toJSON(key);}if(typeof rep==='function'){value=rep.call(holder,key,value);}switch(typeof value){case'string':return quote(value);case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==='[object Array]'){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||'null';}v=partial.length===0?'[]':gap?'[\n'+gap+partial.join(',\n'+gap)+'\n'+mind+']':'['+partial.join(',')+']';gap=mind;return v;}if(rep&&typeof rep==='object'){length=rep.length;for(i=0;i<length;i+=1){k=rep[i];if(typeof k==='string'){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}else{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}v=partial.length===0?'{}':gap?'{\n'+gap+partial.join(',\n'+gap)+'\n'+mind+'}':'{'+partial.join(',')+'}';gap=mind;return v;}}if(typeof JSON.stringify!=='function'){JSON.stringify=function(value,replacer,space){var i;gap='';indent='';if(typeof space==='number'){for(i=0;i<space;i+=1){indent+=' ';}}else if(typeof space==='string'){indent=space;}rep=replacer;if(replacer&&typeof replacer!=='function'&&(typeof replacer!=='object'||typeof replacer.length!=='number')){throw new Error('JSON.stringify');}return str('',{'':value});};}if(typeof JSON.parse!=='function'){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==='object'){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v;}else{delete value[k];}}}}return reviver.call(holder,key,value);}text=String(text);cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);});}if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof reviver==='function'?walk({'':j},''):j;}throw new SyntaxError('JSON.parse');};}}());
var JSON2 = JSON;

var Options = {
  nbWinIsOpen  : false,
  nbWinDrag    : true,
  nbWinPos     : {},
  nbTrackOpen  : true,
  currentTab   : null,
};

var GlobalOptions = {
  nbWideScreen : true,
  nbWideScreenStyle : 'normal',
  autoPublishPrivacySetting : 80,
  nbupdate : false,
  nbupdatebeta : 0,
};

var RCOptions = {
    rb    : 0,
    rdb   : 0,
    sb    : 0,
    sdb   : 0,
    rrb   : 0,
    rrdb  :	0,
    orb   :	0,
    ordb  :	0,
    osb   :	0,
    osdb  :	0,
    orrb  :	0,
    orrdb :	0,
};

var ResetAll=false;
var deleting=false;

readGlobalOptions ();
readOptions();

var Tabs = {};
var mainPop;
var nbPopUpTopClass = 'nbPopTop';
var CM = unsafeWindow.cm;

function nbStartup (){
  if (unsafeWindow.nbLoaded)
    return;
  unsafeWindow.nbLoaded = true;

  readOptions();
  readRCOptions();

  var styles = 'table.nbTabLined tr td {border:1px none none solid none; padding: 2px 5px; white-space:nowrap;}\
    table.nbOptions tr td {border:1px none none solid none; padding: 1px 3px; white-space:nowrap;}\
    .nbStat {border:1px solid; border-color:#000000; font-weight:bold; padding-top:2px; padding-bottom:2px; text-align:center; color:#ffffff ; background-color:#357;  -moz-border-radius:5px;}\
    button::-moz-focus-inner, input[type="submit"]::-moz-focus-inner { border: none; }\
    table.nbMainTab { empty-cells: show; margin-left: 5px; margin-top: 4px; padding: 1px;  padding-left:5px;}\
    table.nbMainTab tr td a {color:inherit }\
    table.nbMainTab tr td   {height:60%; empty-cells:show; padding: 0px 4px 0px 4px;  margin-top:5px; white-space:nowrap; border: 1px solid; border-style: none none solid none; -moz-border-radius:5px; }\
    table.nbMainTab tr td.spacer {padding: 0px 0px;}\
    table.nbMainTab tr td.notSel { color: #ffffff; font-size: 12px; font-weight:bold; -moz-border-radius: 10px; -moz-box-shadow: 0px 1px 3px #357544; text-shadow: -1px 1px 3px #666666; border: solid #615461 1px; background: -moz-linear-gradient(top, #6ff28e, #196b2c);}\
    table.nbMainTab tr td.sel { color: #000000; font-size: 12px; font-weight:bold; -moz-border-radius: 10px; -moz-box-shadow: 0px 1px 3px #357544; text-shadow: -1px 1px 3px #CECECE; border: solid #615461 1px; background: -moz-linear-gradient(top, #6ff28e, #196b2c);}\
    table.nbMainTab tr td:hover { color: #191919; font-size: 12px; font-weight:bold; text-shadow: -1px 1px 3px #CECECE; background: -moz-linear-gradient(top, #43cc7e, #20a129)}\
    tr.nbPopTop td { background-color:transparent; border:none; height: 21px; padding:0px;}\
    tr.nbretry_nbPopTop td { background-color:#a00; color:#fff; border:none; height: 21px;  padding:0px; }\
    tr.nbMainPopTop td { background-color:#ded; border:none; height: 42px; width:80%; padding:0px; }\
    tr.nbretry_nbMainPopTop td { background-color:#a00; color:#fff; border:none; height: 42px;  padding:0px; }\
    .nbPopMain  { border:1px solid #000000; -moz-box-shadow:inset 0px 0px 10px #6a6a6a; -moz-border-radius-bottomright: 20px; -moz-border-radius-bottomleft: 20px;}\
    .nbPopup  {border:5px ridge #666; opacity:2; -moz-border-radius:25px; -moz-box-shadow: 1px 1px 5px #000000; }'

  window.name = 'NB';

// TODO: Make sure WinPos is visible on-screen ?
  if (Options.nbWinPos==null || Options.nbWinPos.x==null|| Options.nbWinPos.x=='' || isNaN(Options.nbWinPos.x)){
    var c = getClientCoords (document.getElementById('main_engagement_tabs'));
    Options.nbWinPos.x = c.x+4;
    Options.nbWinPos.y = c.y+c.height;
    saveOptions ();
  }

  // Reset window xPos if the widescreen option is disabled
  if(!GlobalOptions.nbWideScreen && Options.nbWinPos.x > 700){
    var c = getClientCoords (document.getElementById('main_engagement_tabs'));
    Options.nbWinPos.x = c.x+4;
    saveOptions ();
  }

  mainPop = new nbPopup ('nb', Options.nbWinPos.x, Options.nbWinPos.y, 850,850, Options.nbWinDrag,
      function (){
        tabManager.hideTab();
        Options.nbWinIsOpen=false;
        saveOptions();
      });
  mainPop.autoHeight (true);

  mainPop.getMainDiv().innerHTML = '<STYLE>'+ styles +'</style>';
  AddMainTabLink('Notebook', eventHideShow, mouseMainTab);
  tabManager.init (mainPop.getMainDiv());
  actionLog ("KOC Notebook v"+ Version +" Loaded");

  if (Options.nbWinIsOpen && Options.nbTrackOpen){
    mainPop.show (true);
    tabManager.showTab();
  }
  window.addEventListener('unload', onUnload, false);
}

/****************************  Throne Item Caps Tab  ******************************/
Tabs.ThroneCaps = {
    tabOrder : 100,                    // order to place tab in top bar
    tabLabel : 'ThroneCaps',            // label to show in main window tabs
    myDiv : null,
    timer : null,

    init : function (div){    // called once, upon script startup
        var t = Tabs.ThroneCaps;
        t.myDiv = div;
        div.innerHTML = 'Removed. Look in Bot -> Throne -> Caps';
    },

    hide : function (){         // called whenever the main window is hidden, or another tab is selected
        var t = Tabs.ThroneCaps;
    },

    show : function (){         // called whenever this tab is shown
        var t = Tabs.ThroneCaps;
    },
}

/****************************  Range Calculator Tab  ******************************/
Tabs.RangeCalc = {
    tabOrder : 200,                    // order to place tab in top bar
    tabLabel : 'RangeCalc',            // label to show in main window tabs
    myDiv : null,
    timer : null,

    init : function (div){    // called once, upon script startup
        var t = Tabs.RangeCalc;
        t.myDiv = div;
        div.innerHTML = 'Enter all numbers as positive number<br><br>\
                    <table><tr><td></td><td>My Range</td><td>Opponent</td></tr>\
                    <tr><td>Range Buff:   </td><td><input id=myrangebuff type=text value=0></td>   <td><input id=opprangebuff type=text value=0></td></tr>\
                    <tr><td>Range Debuff: </td><td><input id=myrangedebuff type=text value=0></td> <td><input id=opprangedebuff type=text value=0></td></tr>\
                    <tr><td>Siege Buff:   </td><td><input id=mysiegebuff type=text value=0></td>   <td><input id=oppsiegebuff type=text value=0></td></tr>\
                    <tr><td>Siege Debuff: </td><td><input id=mysiegedebuff type=text value=0></td> <td><input id=oppsiegedebuff type=text value=0></td></tr>\
                    <tr><td>Ranged Buff:  </td><td><input id=myrangedbuff type=text value=0></td>  <td><input id=opprangedbuff type=text value=0></td></tr>\
                    <tr><td>Ranged Debuff:</td><td><input id=myrangeddebuff type=text value=0></td><td><input id=opprangeddebuff type=text value=0></td></tr></table>\
                    <br><br>\
                    A negative number here means you are outranged.<br>\
                    Siege Range Difference<input id=siegewinner type=text value=0><br>\
                    Ranged Range Difference<input id=rangedwinner type=text value=0><br><br>';

        t.loadRCOptions();

        document.getElementById('myrangebuff').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            if (e.target.value < 0) alert('Enter positive numbers!');
            RCOptions.rb = e.target.value;
            saveRCOptions();
            t.calculate();
        }, false);
        document.getElementById('myrangedebuff').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            if (e.target.value < 0) alert('Enter positive numbers!');
            RCOptions.rdb = e.target.value;
            saveRCOptions();
            t.calculate();
        }, false);
        document.getElementById('mysiegebuff').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            if (e.target.value < 0) alert('Enter positive numbers!');
            RCOptions.sb = e.target.value;
            saveRCOptions();
            t.calculate();
        }, false);
        document.getElementById('mysiegedebuff').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            if (e.target.value < 0) alert('Enter positive numbers!');
            RCOptions.sdb = e.target.value;
            saveRCOptions();
            t.calculate();
        }, false);
        document.getElementById('myrangedbuff').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            if (e.target.value < 0) alert('Enter positive numbers!');
            RCOptions.rrb = e.target.value;
            saveRCOptions();
            t.calculate();
        }, false);
        document.getElementById('myrangeddebuff').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            if (e.target.value < 0) alert('Enter positive numbers!');
            RCOptions.rrdb = e.target.value;
            saveRCOptions();
            t.calculate();
        }, false);
        document.getElementById('opprangebuff').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            if (e.target.value < 0) alert('Enter positive numbers!');
            RCOptions.orb = e.target.value;
            saveRCOptions();
            t.calculate();
        }, false);
        document.getElementById('opprangedebuff').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            if (e.target.value < 0) alert('Enter positive numbers!');
            RCOptions.ordb = e.target.value;
            saveRCOptions();
            t.calculate();
        }, false);
        document.getElementById('oppsiegebuff').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            if (e.target.value < 0) alert('Enter positive numbers!');
            RCOptions.osb = e.target.value;
            saveRCOptions();
            t.calculate();
        }, false);
        document.getElementById('oppsiegedebuff').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            if (e.target.value < 0) alert('Enter positive numbers!');
            RCOptions.osdb = e.target.value;
            saveRCOptions();
            t.calculate();
        }, false);
        document.getElementById('opprangedbuff').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            if (e.target.value < 0) alert('Enter positive numbers!');
            RCOptions.orrb = e.target.value;
            saveRCOptions();
            t.calculate();
        }, false);
        document.getElementById('opprangeddebuff').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            if (e.target.value < 0) alert('Enter positive numbers!');
            RCOptions.orrdb = e.target.value;
            saveRCOptions();
            t.calculate();
        }, false);
    },

    hide : function (){         // called whenever the main window is hidden, or another tab is selected
        var t = Tabs.RangeCalc;
    },

    show : function (){         // called whenever this tab is shown
        var t = Tabs.RangeCalc;
    },

    calculate : function () {
        var rb   = parseInt(document.getElementById('myrangebuff').value);
        var rdb  = parseInt(document.getElementById('myrangedebuff').value);
        var sb   = parseInt(document.getElementById('mysiegebuff').value);
        var sdb  = parseInt(document.getElementById('mysiegedebuff').value);
        var rrb  = parseInt(document.getElementById('myrangedbuff').value);
        var rrdb = parseInt(document.getElementById('myrangeddebuff').value);
        var orb   = parseInt(document.getElementById('opprangebuff').value);
        var ordb  = parseInt(document.getElementById('opprangedebuff').value);
        var osb   = parseInt(document.getElementById('oppsiegebuff').value);
        var osdb  = parseInt(document.getElementById('oppsiegedebuff').value);
        var orrb  = parseInt(document.getElementById('opprangedbuff').value);
        var orrdb = parseInt(document.getElementById('opprangeddebuff').value);

        var sdiff = (rb + sb - ordb - osdb) - (orb + osb - rdb - sdb);

        if (sdiff < -25)
            sdiff = -25;
        if (sdiff > 185)
            sdiff = 185;

        var rdiff = (rb + rrb - ordb - orrdb) - (orb + orrb - rdb - rrdb);
        if (rdiff < -25)
            rdiff = -25;
        if (rdiff > 185)
            rdiff = 185;

        document.getElementById('siegewinner').value = sdiff;
        document.getElementById('rangedwinner').value = rdiff;
    },
    
    loadRCOptions : function () {
        var t = Tabs.RangeCalc;
        readRCOptions();
        document.getElementById('myrangebuff').value     = RCOptions.rb;
        document.getElementById('myrangedebuff').value   = RCOptions.rdb;
        document.getElementById('mysiegebuff').value     = RCOptions.sb;
        document.getElementById('mysiegedebuff').value   = RCOptions.sdb;
        document.getElementById('myrangedbuff').value    = RCOptions.rrb;
        document.getElementById('myrangeddebuff').value  = RCOptions.rrdb;
        document.getElementById('opprangebuff').value    = RCOptions.orb;
        document.getElementById('opprangedebuff').value  = RCOptions.ordb;
        document.getElementById('oppsiegebuff').value    = RCOptions.osb;
        document.getElementById('oppsiegedebuff').value  = RCOptions.osdb;
        document.getElementById('opprangedbuff').value   = RCOptions.orrb;
        document.getElementById('opprangeddebuff').value = RCOptions.orrdb;
        t.calculate();
    },
}

/****************************  Unit Stats Calculator Tab  ******************************/
Tabs.UnitCalc = {
    tabOrder : 300,                    // order to place tab in top bar
    tabLabel : 'UnitCalc',            // label to show in main window tabs
    myDiv : null,
    timer : null,

    Trp0 : { //mm
        Life : 400,
        Atk  : 100,
        Def  : 13,
        Spd  : 200,
        Rng  : 20,
    },
    Trp1 : { //scout
        Life : 20,
        Atk  : 6,
        Def  : 1,
        Spd  : 3000,
        Rng  : 20,
    },
    Trp2 : { //pike
        Life : 600,
        Atk  : 300,
        Def  : 33,
        Spd  : 300,
        Rng  : 50,
    },
    Trp3 : { //sw
        Life : 700,
        Atk  : 200,
        Def  : 63,
        Spd  : 275,
        Rng  : 30,
    },
    Trp4 : { //arch
        Life : 500,
        Atk  : 240,
        Def  : 25,
        Spd  : 250,
        Rng  : 1200,
    },
    Trp5 : { //cav
        Life : 1000,
        Atk  : 500,
        Def  : 45,
        Spd  : 1000,
        Rng  : 100,
    },
    Trp6 : { //hc
        Life : 2000,
        Atk  : 700,
        Def  : 87,
        Spd  : 750,
        Rng  : 80,
    },
    Trp7 : { //ball
        Life : 640,
        Atk  : 900,
        Def  : 40,
        Spd  : 100,
        Rng  : 1400,
    },
    Trp8 : { //ram
        Life : 10000,
        Atk  : 500,
        Def  : 40,
        Spd  : 120,
        Rng  : 600,
    },
    Trp9 : { //cat
        Life : 960,
        Atk  : 1200,
        Def  : 50,
        Spd  : 80,
        Rng  : 1500,
    },

    Trp10 : { //blood
        Life : 2100,
        Atk  : 1300,
        Def  : 45,
        Spd  : 900,
        Rng  : 150,
    },

    Trp11 : { //exec
        Life : 4200,
        Atk  : 1700,
        Def  : 70,
        Spd  : 500,
        Rng  : 120,
    },

    Trp12 : { //siegewall
        Life : 8400,
        Atk  : 200,
        Def  : 140,
        Spd  : 775,
        Rng  : 120,
    },

    Trp13 : { //flamearcher
        Life : 800,
        Atk  : 1700,
        Def  : 40,
        Spd  : 140,
        Rng  : 1600,
    },

    Trp14 : { //hussar
        Life : 2800,
        Atk  : 1050,
        Def  : 130,
        Spd  : 1150,
        Rng  : 120,
    },
    
    init : function (div){    // called once, upon script startup
        var t = Tabs.UnitCalc;
        t.myDiv = div;
        div.innerHTML = '<center><b>Unit Stats</b></center><br>\
            <table border=1><tr><td><b>Unit</b></td><td><b>Life</b></td><td><b>Atk</b></td><td><b>Def</b></td><td><b>Speed</b></td><td><b>Range</b></td><td style="background-color:black"></td><td><b>Unit</b></td><td><b>Life</b></td><td><b>Atk</b></td><td><b>Def</b></td><td><b>Speed</b></td><td><b>Range</b></td></tr>\
                            <tr><td>Mm        </td><td id=ucTrp0Life> </td><td id=ucTrp0Atk> </td><td id=ucTrp0Def> </td><td id=ucTrp0Spd> </td><td id=ucTrp0Rng> </td><td style="background-color:black"></td><td>Archer    </td><td id=ucTrp4Life> </td><td id=ucTrp4Atk> </td><td id=ucTrp4Def> </td><td id=ucTrp4Spd> </td><td id=ucTrp4Rng> </td></tr>\
                            <tr><td>Scout     </td><td id=ucTrp1Life> </td><td id=ucTrp1Atk> </td><td id=ucTrp1Def> </td><td id=ucTrp1Spd> </td><td id=ucTrp1Rng> </td><td style="background-color:black"></td><td>Ball      </td><td id=ucTrp7Life> </td><td id=ucTrp7Atk> </td><td id=ucTrp7Def> </td><td id=ucTrp7Spd> </td><td id=ucTrp7Rng> </td></tr>\
                            <tr><td>Pike      </td><td id=ucTrp2Life> </td><td id=ucTrp2Atk> </td><td id=ucTrp2Def> </td><td id=ucTrp2Spd> </td><td id=ucTrp2Rng> </td><td style="background-color:black"></td><td>Cat       </td><td id=ucTrp9Life> </td><td id=ucTrp9Atk> </td><td id=ucTrp9Def> </td><td id=ucTrp9Spd> </td><td id=ucTrp9Rng> </td></tr>\
                            <tr><td>Sword     </td><td id=ucTrp3Life> </td><td id=ucTrp3Atk> </td><td id=ucTrp3Def> </td><td id=ucTrp3Spd> </td><td id=ucTrp3Rng> </td><td style="background-color:black"></td><td>Blood     </td><td id=ucTrp10Life></td><td id=ucTrp10Atk></td><td id=ucTrp10Def></td><td id=ucTrp10Spd></td><td id=ucTrp10Rng></td></tr>\
							<tr><td>Cav       </td><td id=ucTrp5Life> </td><td id=ucTrp5Atk> </td><td id=ucTrp5Def> </td><td id=ucTrp5Spd> </td><td id=ucTrp5Rng> </td><td style="background-color:black"></td><td>Exec      </td><td id=ucTrp11Life></td><td id=ucTrp11Atk></td><td id=ucTrp11Def></td><td id=ucTrp11Spd></td><td id=ucTrp11Rng></td></tr>\
                            <tr><td>HC        </td><td id=ucTrp6Life> </td><td id=ucTrp6Atk> </td><td id=ucTrp6Def> </td><td id=ucTrp6Spd> </td><td id=ucTrp6Rng> </td><td style="background-color:black"></td><td>Siege Wall</td><td id=ucTrp12Life></td><td id=ucTrp12Atk></td><td id=ucTrp12Def></td><td id=ucTrp12Spd></td><td id=ucTrp12Rng></td></tr>\
                            <tr><td>Ram       </td><td id=ucTrp8Life> </td><td id=ucTrp8Atk> </td><td id=ucTrp8Def> </td><td id=ucTrp8Spd> </td><td id=ucTrp8Rng> </td><td style="background-color:black"></td><td>Flame Arch</td><td id=ucTrp13Life></td><td id=ucTrp13Atk></td><td id=ucTrp13Def></td><td id=ucTrp13Spd></td><td id=ucTrp13Rng></td></tr>\
                            <tr><td>          </td><td              > </td><td             > </td><td             > </td><td             > </td><td             > </td><td style="background-color:black"></td><td>Hussar    </td><td id=ucTrp14Life></td><td id=ucTrp14Atk></td><td id=ucTrp14Def></td><td id=ucTrp14Spd></td><td id=ucTrp14Rng></td></tr>\
                            </table><hr>\
                            <center><b>Config</b></center><br>\
                            <b>Knight Combat Points</b><input id=ucKnightLevel type=text value=300 size=4><br><br>\
							<b>Fey Altar (Sacrifice)</b> | Active: <input id=ucFeyAltarActive type=checkbox unchecked> | Bonus Amount <input id=ucFeyAltarBonus type=text value=40 size=4> (two alters with one at Level 10 is 40% boost. one alter at level 9 is 18%) <br><br>\
            <table border=1><tr><td><b>Research</b></td><td><b>Level</b></td><td style="background-color:black"></td><td><b>TR Stats</b></td><td><b>Life</b></td><td><b>Atk</b></td><td><b>Def</b></td><td><b>Spd</b></td><td><b>Rng</b></td></tr>\
                            <tr><td>Healing Potions (life)  </td><td><input id=ucResHP type=text value=12 size=4></td><td style="background-color:black"></td><td>TR All Buff</td>            <td><input id=ucLifeMod    type=text value=0 size=4></td><td><input id=ucAtkMod    type=text value=0 size=4></td><td><input id=ucDefMod    type=text value=0 size=4></td><td><input id=ucSpdMod    type=text value=0 size=4></td><td><input id=ucRngMod    type=text value=0 size=4></td></tr>\
                            <tr><td>Poisoned Edge (atk)     </td><td><input id=ucResPE type=text value=12 size=4></td><td style="background-color:black"></td><td>TR Infantry Buff</td>   <td><input id=ucLifeModInf type=text value=0 size=4></td><td><input id=ucAtkModInf type=text value=0 size=4></td><td><input id=ucDefModInf type=text value=0 size=4></td><td><input id=ucSpdModInf type=text value=0 size=4></td><td><input id=ucRngModInf type=text value=0 size=4></td></tr>\
                            <tr><td>Metal Alloys (def)      </td><td><input id=ucResMA type=text value=12 size=4></td><td style="background-color:black"></td><td>TR Ranged Buff</td>     <td><input id=ucLifeModRng type=text value=0 size=4></td><td><input id=ucAtkModRng type=text value=0 size=4></td><td><input id=ucDefModRng type=text value=0 size=4></td><td><input id=ucSpdModRng type=text value=0 size=4></td><td><input id=ucRngModRng type=text value=0 size=4></td></tr>\
                            <tr><td>Alloy Horseshoes (spd)  </td><td><input id=ucResAH type=text value=12 size=4></td><td style="background-color:black"></td><td>TR Siege Buff</td>      <td><input id=ucLifeModSig type=text value=0 size=4></td><td><input id=ucAtkModSig type=text value=0 size=4></td><td><input id=ucDefModSig type=text value=0 size=4></td><td><input id=ucSpdModSig type=text value=0 size=4></td><td><input id=ucRngModSig type=text value=0 size=4></td></tr>\
                            <tr><td>Fletching (rng)         </td><td><input id=ucResFL type=text value=12 size=4></td><td style="background-color:black"></td><td>TR Horsed Buff</td>     <td><input id=ucLifeModHor type=text value=0 size=4></td><td><input id=ucAtkModHor type=text value=0 size=4></td><td><input id=ucDefModHor type=text value=0 size=4></td><td><input id=ucSpdModHor type=text value=0 size=4></td><td><input id=ucRngModHor type=text value=0 size=4></td></tr></table><br>\
            <table border=1><tr><td><b>Guardians</b></td><td><b>Wood</b></td><td><b>Ore</b></td><td><b>Food</b></td><td><b>Stone</b></td></tr>\
                            <tr><td>Level</td>                  <td><input id=ucWood       type=text value=9 size=4></td>    <td><input id=ucOre   type=text value=9 size=4>  </td><td><input id=ucFood   type=text value=9 size=4></td><td><input id=ucStone    type=text value=9 size=4></td></tr>\
                            <tr><td>Active</td>                 <td><input id=ucWoodAct type=radio name=ucGuard checked></td><td><input id=ucOreAct type=radio name=ucGuard>  </td><td><input id=ucFoodAct type=radio name=ucGuard></td><td><input id=ucStoneAct type=radio name=ucGuard></td></tr>\
                            <tr><td>Set Bonus</td><td><input id=ucGuardSet type=checkbox unchecked></td><td></td><td></td><td></td></tr>\
                            <tr><td>Troops on Defense (Wood Guardian)</td><td><input id=ucDefending type=checkbox unchecked></td><td></td><td></td><td></td></tr>\
                            <tr><td>Item Boost</td><td>+20atk<input id=ucItemAtk20 type=checkbox unchecked></td><td>+50atk<input id=ucItemAtk50 type=checkbox unchecked></td><td>+20def<input id=ucItemDef20 type=checkbox unchecked></td><td>+50def<input id=ucItemDef50 type=checkbox unchecked></td></tr>\
                            <tr><td>Empowered Iron Blessing (Fey)</td><td></td><td><input id=ucOreBless type=checkbox unchecked></td><td> </td><td></td></tr>\
							</table>';
                            
        // Event listener Knight Level
        document.getElementById('ucKnightLevel').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=1 ;
            if (e.target.value < 1) alert('Enter positive numbers!');
            t.modifyUnitResearch();
        }, false);

        // Event listener Fey Altar
        document.getElementById('ucFeyAltarActive').addEventListener('change', function(e){
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucFeyAltarBonus').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=1 ;
            if (e.target.value < 1 || e.target.value > 40) alert('Enter a numbers between 1-40!');
            t.modifyUnitResearch();
        }, false);
		
		
        // Event listener Guardian
        document.getElementById('ucWood').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            if (e.target.vale > 12 ) alert('Enter a number between 0-12!');
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucOre').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            if (e.target.vale > 12 ) alert('Enter a number between 0-12!');
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucFood').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            if (e.target.vale > 12 ) alert('Enter a number between 0-12!');
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucStone').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            if (e.target.vale > 12 ) alert('Enter a number between 0-12!');
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucWoodAct').addEventListener('change', function(e){
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucOreAct').addEventListener('change', function(e){
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucFoodAct').addEventListener('change', function(e){
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucStoneAct').addEventListener('change', function(e){
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucGuardSet').addEventListener('change', function(e){
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucDefending').addEventListener('change', function(e){
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucOreBless').addEventListener('change', function(e){
            t.modifyUnitResearch();
        }, false);
        
        //Event listener Item Boosts
        document.getElementById('ucItemAtk20').addEventListener('change', function(e){
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucItemAtk50').addEventListener('change', function(e){
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucItemDef20').addEventListener('change', function(e){
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucItemDef50').addEventListener('change', function(e){
            t.modifyUnitResearch();
        }, false);
                
        // Event listener Research Level
        document.getElementById('ucResHP').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=1 ;
            if (e.target.value < 1 || e.target.vale > 12 ) alert('Enter a number between 1-12!');
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucResPE').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=1 ;
            if (e.target.value < 1 || e.target.vale > 12 ) alert('Enter a number between 1-12!');
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucResMA').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=1 ;
            if (e.target.value < 1 || e.target.vale > 12 ) alert('Enter a number between 1-12!');
            t.modifyUnitResearch();
        }, false);
                document.getElementById('ucResAH').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=1 ;
            if (e.target.value < 1 || e.target.vale > 12 ) alert('Enter a number between 1-12!');
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucResFL').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=1 ;
            if (e.target.value < 1 || e.target.vale > 12 ) alert('Enter a number between 1-12!');
            t.modifyUnitResearch();
        }, false);

        // Event listener Throne
        document.getElementById('ucLifeMod').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucLifeModInf').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucLifeModRng').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucLifeModSig').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucLifeModHor').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);

        document.getElementById('ucAtkMod').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucAtkModInf').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucAtkModRng').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucAtkModSig').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucAtkModHor').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);

        document.getElementById('ucDefMod').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucDefModInf').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucDefModRng').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucDefModSig').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucDefModHor').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);

        document.getElementById('ucSpdMod').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucSpdModInf').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucSpdModRng').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucSpdModSig').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucSpdModHor').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);

        document.getElementById('ucRngMod').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucRngModInf').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucRngModRng').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucRngModSig').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);
        document.getElementById('ucRngModHor').addEventListener('change', function(e){
            if (isNaN(e.target.value)) e.target.value=0 ;
            t.modifyUnitResearch();
        }, false);

        t.modifyUnitResearch();
    },

    hide : function (){         // called whenever the main window is hidden, or another tab is selected
        var t = Tabs.UnitCalc;
    },

    show : function (){         // called whenever this tab is shown
        var t = Tabs.UnitCalc;
    },

    modifyUnitResearch : function (){
        var t = Tabs.UnitCalc;
        var resLife = (5 * parseInt(document.getElementById('ucResHP').value)/100);
        var resAtk  = (5 * parseInt(document.getElementById('ucResPE').value)/100);
        var resDef  = (5 * parseInt(document.getElementById('ucResMA').value)/100);
        var resSpd  = (5 * parseInt(document.getElementById('ucResAH').value)/100);
        var resRng  = (5 * parseInt(document.getElementById('ucResFL').value)/100);
        var knight = parseFloat(document.getElementById('ucKnightLevel').value)/200;
        var guardLife = t.woodGuardTable(parseInt(document.getElementById('ucWood').value));
        var guardAtk = t.oreGuardTable(parseInt(document.getElementById('ucOre').value));
        var guardLifeAct =  document.getElementById('ucWoodAct').checked ? 1 : 0;
        var guardAtkAct = document.getElementById('ucOreAct').checked ? 1 : 0;
        var guardSetAct = document.getElementById('ucGuardSet').checked ? 1 : 0;
        var guardOreBless = document.getElementById('ucOreBless').checked ? 1 : 0;
        var defending = document.getElementById('ucDefending').checked ? 1 : 0;
        var itemAtk = 0;
        var itemDef = 0;
        var feyAltarAct = document.getElementById('ucFeyAltarActive').checked ? 1 : 0;
		var feyAltar = parseFloat(document.getElementById('ucFeyAltarBonus').value)/100;

        
        if (document.getElementById('ucItemAtk20').checked)
            itemAtk = 0.2 + itemAtk;
        if (document.getElementById('ucItemAtk50').checked)
            itemAtk = 0.5 + itemAtk;
        if (document.getElementById('ucItemDef20').checked)
            itemDef = 0.2 + itemDef;
        if (document.getElementById('ucItemDef50').checked)
            itemDef = 0.5 + itemDef;           
            
        // calculate guardian
        if (guardSetAct) { //if you have set bonus
            if (guardLifeAct && defending) { //if your want defending troop stats
                guardLife = (guardLife/2 + guardLife) / 100;
                guardAtk = (guardAtk/200) + guardOreBless*0.15 + guardOreBless*0.15*(guardAtk/200);
            }
            else if (guardAtkAct) {
                guardAtk = (1.5*guardAtk/100) + guardOreBless*0.15 + guardOreBless*(1.5*guardAtk/100);
                if(defending)
                    guardLife = guardLife/200;
                else
                    guardLife = 0;
            }
            else {
                guardAtk = (guardAtk/200) + guardOreBless*0.15 + guardOreBless*0.15*(guardAtk/200);
                if(defending)
                    guardLife = guardLife/200;
                else
                    guardLife = 0;
            }
        } else { // don't have set bonus
           if (guardLifeAct && defending) {
                guardLife = guardLife / 100;
                guardAtk = 0;
            }
            else if (guardAtkAct) {
                guardAtk = (guardAtk/100) + guardOreBless*0.15 + guardOreBless*0.15*(guardAtk/100);
                guardLife = 0;
            }
            else {
                guardAtk = 0;
                guardLife = 0;
            }            
        }
        
        //Trp0 - mm
        document.getElementById('ucTrp0Life').innerHTML = t.round1decimals( (1 + guardLife) * ( (1 + feyAltar*feyAltarAct) * t.Trp0.Life + (1 + feyAltar*feyAltarAct) * t.Trp0.Life * (resLife                    + t.maxBuff('life',parseFloat(document.getElementById('ucLifeMod').value),parseFloat(document.getElementById('ucLifeModInf').value))/100)));
        document.getElementById('ucTrp0Atk').innerHTML  = t.round1decimals( (1 + guardAtk)  * ( (1 + feyAltar*feyAltarAct) * t.Trp0.Atk  + (1 + feyAltar*feyAltarAct) * t.Trp0.Atk  * (resAtk  + knight + itemAtk + t.maxBuff('atk', parseFloat(document.getElementById('ucAtkMod' ).value),parseFloat(document.getElementById('ucAtkModInf' ).value))/100)));
        document.getElementById('ucTrp0Def').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp0.Def  + (1 + feyAltar*feyAltarAct) * t.Trp0.Def  * (resDef  + knight + itemDef + t.maxBuff('def', parseFloat(document.getElementById('ucDefMod' ).value),parseFloat(document.getElementById('ucDefModInf' ).value))/100)));
        document.getElementById('ucTrp0Spd').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp0.Spd  + (1 + feyAltar*feyAltarAct) * t.Trp0.Spd  * (                             t.maxBuff('spd', parseFloat(document.getElementById('ucSpdMod' ).value),parseFloat(document.getElementById('ucSpdModInf' ).value))/100)));
        document.getElementById('ucTrp0Rng').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp0.Rng  + (1 + feyAltar*feyAltarAct) * t.Trp0.Rng  * (                             t.maxBuff('rng', parseFloat(document.getElementById('ucRngMod' ).value),parseFloat(document.getElementById('ucRngModInf' ).value))/100)));

        //Trp1 - scout
        document.getElementById('ucTrp1Life').innerHTML = t.round1decimals( (1 + guardLife) * ( (1 + feyAltar*feyAltarAct) * t.Trp1.Life + (1 + feyAltar*feyAltarAct) * t.Trp1.Life * (resLife                    + t.maxBuff('life',parseFloat(document.getElementById('ucLifeMod').value),parseFloat(document.getElementById('ucLifeModInf').value))/100)));
        document.getElementById('ucTrp1Atk').innerHTML  = t.round1decimals( (1 + guardAtk)  * ( (1 + feyAltar*feyAltarAct) * t.Trp1.Atk  + (1 + feyAltar*feyAltarAct) * t.Trp1.Atk  * (resAtk  + knight + itemAtk + t.maxBuff('atk', parseFloat(document.getElementById('ucAtkMod' ).value),parseFloat(document.getElementById('ucAtkModInf' ).value))/100)));
        document.getElementById('ucTrp1Def').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp1.Def  + (1 + feyAltar*feyAltarAct) * t.Trp1.Def  * (resDef  + knight + itemDef + t.maxBuff('def', parseFloat(document.getElementById('ucDefMod' ).value),parseFloat(document.getElementById('ucDefModInf' ).value))/100)));
        document.getElementById('ucTrp1Spd').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp1.Spd  + (1 + feyAltar*feyAltarAct) * t.Trp1.Spd  * (                             t.maxBuff('spd', parseFloat(document.getElementById('ucSpdMod' ).value),parseFloat(document.getElementById('ucSpdModInf' ).value))/100)));
        document.getElementById('ucTrp1Rng').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp1.Rng  + (1 + feyAltar*feyAltarAct) * t.Trp1.Rng  * (                             t.maxBuff('rng', parseFloat(document.getElementById('ucRngMod' ).value),parseFloat(document.getElementById('ucRngModInf' ).value))/100)));

        //Trp2 - pike
        document.getElementById('ucTrp2Life').innerHTML = t.round1decimals( (1 + guardLife) * ( (1 + feyAltar*feyAltarAct) * t.Trp2.Life + (1 + feyAltar*feyAltarAct) * t.Trp2.Life * (resLife                    + t.maxBuff('life',parseFloat(document.getElementById('ucLifeMod').value),parseFloat(document.getElementById('ucLifeModInf').value))/100)));
        document.getElementById('ucTrp2Atk').innerHTML  = t.round1decimals( (1 + guardAtk)  * ( (1 + feyAltar*feyAltarAct) * t.Trp2.Atk  + (1 + feyAltar*feyAltarAct) * t.Trp2.Atk  * (resAtk  + knight + itemAtk + t.maxBuff('atk', parseFloat(document.getElementById('ucAtkMod' ).value),parseFloat(document.getElementById('ucAtkModInf' ).value))/100)));
        document.getElementById('ucTrp2Def').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp2.Def  + (1 + feyAltar*feyAltarAct) * t.Trp2.Def  * (resDef  + knight + itemDef + t.maxBuff('def', parseFloat(document.getElementById('ucDefMod' ).value),parseFloat(document.getElementById('ucDefModInf' ).value))/100)));
        document.getElementById('ucTrp2Spd').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp2.Spd  + (1 + feyAltar*feyAltarAct) * t.Trp2.Spd  * (                             t.maxBuff('spd', parseFloat(document.getElementById('ucSpdMod' ).value),parseFloat(document.getElementById('ucSpdModInf' ).value))/100)));
        document.getElementById('ucTrp2Rng').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp2.Rng  + (1 + feyAltar*feyAltarAct) * t.Trp2.Rng  * (                             t.maxBuff('rng', parseFloat(document.getElementById('ucRngMod' ).value),parseFloat(document.getElementById('ucRngModInf' ).value))/100)));

        //Trp3 - sw
        document.getElementById('ucTrp3Life').innerHTML = t.round1decimals( (1 + guardLife) * ( (1 + feyAltar*feyAltarAct) * t.Trp3.Life + (1 + feyAltar*feyAltarAct) * t.Trp3.Life * (resLife                    + t.maxBuff('life',parseFloat(document.getElementById('ucLifeMod').value),parseFloat(document.getElementById('ucLifeModInf').value))/100)));
        document.getElementById('ucTrp3Atk').innerHTML  = t.round1decimals( (1 + guardAtk)  * ( (1 + feyAltar*feyAltarAct) * t.Trp3.Atk  + (1 + feyAltar*feyAltarAct) * t.Trp3.Atk  * (resAtk  + knight + itemAtk + t.maxBuff('atk', parseFloat(document.getElementById('ucAtkMod' ).value),parseFloat(document.getElementById('ucAtkModInf' ).value))/100)));
        document.getElementById('ucTrp3Def').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp3.Def  + (1 + feyAltar*feyAltarAct) * t.Trp3.Def  * (resDef  + knight + itemDef + t.maxBuff('def', parseFloat(document.getElementById('ucDefMod' ).value),parseFloat(document.getElementById('ucDefModInf' ).value))/100)));
        document.getElementById('ucTrp3Spd').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp3.Spd  + (1 + feyAltar*feyAltarAct) * t.Trp3.Spd  * (                             t.maxBuff('spd', parseFloat(document.getElementById('ucSpdMod' ).value),parseFloat(document.getElementById('ucSpdModInf' ).value))/100)));
        document.getElementById('ucTrp3Rng').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp3.Rng  + (1 + feyAltar*feyAltarAct) * t.Trp3.Rng  * (                             t.maxBuff('rng', parseFloat(document.getElementById('ucRngMod' ).value),parseFloat(document.getElementById('ucRngModInf' ).value))/100)));

        //Trp4 - arch
        document.getElementById('ucTrp4Life').innerHTML = t.round1decimals( (1 + guardLife) * ( (1 + feyAltar*feyAltarAct) * t.Trp4.Life + (1 + feyAltar*feyAltarAct) * t.Trp4.Life * (resLife                    + t.maxBuff('life',parseFloat(document.getElementById('ucLifeMod').value),parseFloat(document.getElementById('ucLifeModRng').value))/100)));
        document.getElementById('ucTrp4Atk').innerHTML  = t.round1decimals( (1 + guardAtk)  * ( (1 + feyAltar*feyAltarAct) * t.Trp4.Atk  + (1 + feyAltar*feyAltarAct) * t.Trp4.Atk  * (resAtk  + knight + itemAtk + t.maxBuff('atk', parseFloat(document.getElementById('ucAtkMod' ).value),parseFloat(document.getElementById('ucAtkModRng' ).value))/100)));
        document.getElementById('ucTrp4Def').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp4.Def  + (1 + feyAltar*feyAltarAct) * t.Trp4.Def  * (resDef  + knight + itemDef + t.maxBuff('def', parseFloat(document.getElementById('ucDefMod' ).value),parseFloat(document.getElementById('ucDefModRng' ).value))/100)));
        document.getElementById('ucTrp4Spd').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp4.Spd  + (1 + feyAltar*feyAltarAct) * t.Trp4.Spd  * (                             t.maxBuff('spd', parseFloat(document.getElementById('ucSpdMod' ).value),parseFloat(document.getElementById('ucSpdModRng' ).value))/100)));
        document.getElementById('ucTrp4Rng').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp4.Rng  + (1 + feyAltar*feyAltarAct) * t.Trp4.Rng  * (resRng                     + t.maxBuff('rng', parseFloat(document.getElementById('ucRngMod' ).value),parseFloat(document.getElementById('ucRngModRng' ).value))/100)));

        //Trp5 - cav
        document.getElementById('ucTrp5Life').innerHTML = t.round1decimals( (1 + guardLife) * ( (1 + feyAltar*feyAltarAct) * t.Trp5.Life + (1 + feyAltar*feyAltarAct) * t.Trp5.Life * (resLife                    + t.maxBuff('life',parseFloat(document.getElementById('ucLifeMod').value),parseFloat(document.getElementById('ucLifeModHor').value))/100)));
        document.getElementById('ucTrp5Atk').innerHTML  = t.round1decimals( (1 + guardAtk)  * ( (1 + feyAltar*feyAltarAct) * t.Trp5.Atk  + (1 + feyAltar*feyAltarAct) * t.Trp5.Atk  * (resAtk  + knight + itemAtk + t.maxBuff('atk', parseFloat(document.getElementById('ucAtkMod' ).value),parseFloat(document.getElementById('ucAtkModHor' ).value))/100)));
        document.getElementById('ucTrp5Def').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp5.Def  + (1 + feyAltar*feyAltarAct) * t.Trp5.Def  * (resDef  + knight + itemDef + t.maxBuff('def', parseFloat(document.getElementById('ucDefMod' ).value),parseFloat(document.getElementById('ucDefModHor' ).value))/100)));
        document.getElementById('ucTrp5Spd').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp5.Spd  + (1 + feyAltar*feyAltarAct) * t.Trp5.Spd  * (resSpd                     + t.maxBuff('spd', parseFloat(document.getElementById('ucSpdMod' ).value),parseFloat(document.getElementById('ucSpdModHor' ).value))/100)));
        document.getElementById('ucTrp5Rng').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp5.Rng  + (1 + feyAltar*feyAltarAct) * t.Trp5.Rng  * (                             t.maxBuff('rng', parseFloat(document.getElementById('ucRngMod' ).value),parseFloat(document.getElementById('ucRngModHor' ).value))/100)));

        //Trp6 - hc
        document.getElementById('ucTrp6Life').innerHTML = t.round1decimals( (1 + guardLife) * ( (1 + feyAltar*feyAltarAct) * t.Trp6.Life + (1 + feyAltar*feyAltarAct) * t.Trp6.Life * (resLife                    + t.maxBuff('life',parseFloat(document.getElementById('ucLifeMod').value),parseFloat(document.getElementById('ucLifeModHor').value))/100)));
        document.getElementById('ucTrp6Atk').innerHTML  = t.round1decimals( (1 + guardAtk)  * ( (1 + feyAltar*feyAltarAct) * t.Trp6.Atk  + (1 + feyAltar*feyAltarAct) * t.Trp6.Atk  * (resAtk  + knight + itemAtk + t.maxBuff('atk', parseFloat(document.getElementById('ucAtkMod' ).value),parseFloat(document.getElementById('ucAtkModHor' ).value))/100)));
        document.getElementById('ucTrp6Def').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp6.Def  + (1 + feyAltar*feyAltarAct) * t.Trp6.Def  * (resDef  + knight + itemDef + t.maxBuff('def', parseFloat(document.getElementById('ucDefMod' ).value),parseFloat(document.getElementById('ucDefModHor' ).value))/100)));
        document.getElementById('ucTrp6Spd').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp6.Spd  + (1 + feyAltar*feyAltarAct) * t.Trp6.Spd  * (resSpd                     + t.maxBuff('spd', parseFloat(document.getElementById('ucSpdMod' ).value),parseFloat(document.getElementById('ucSpdModHor' ).value))/100)));
        document.getElementById('ucTrp6Rng').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp6.Rng  + (1 + feyAltar*feyAltarAct) * t.Trp6.Rng  * (                             t.maxBuff('rng', parseFloat(document.getElementById('ucRngMod' ).value),parseFloat(document.getElementById('ucRngModHor' ).value))/100)));

        //Trp7 - ball
        document.getElementById('ucTrp7Life').innerHTML = t.round1decimals( (1 + guardLife) * ( (1 + feyAltar*feyAltarAct) * t.Trp7.Life + (1 + feyAltar*feyAltarAct) * t.Trp7.Life * (resLife                    + t.maxBuff('life',parseFloat(document.getElementById('ucLifeMod').value),parseFloat(document.getElementById('ucLifeModSig').value))/100)));
        document.getElementById('ucTrp7Atk').innerHTML  = t.round1decimals( (1 + guardAtk)  * ( (1 + feyAltar*feyAltarAct) * t.Trp7.Atk  + (1 + feyAltar*feyAltarAct) * t.Trp7.Atk  * (resAtk  + knight + itemAtk + t.maxBuff('atk', parseFloat(document.getElementById('ucAtkMod' ).value),parseFloat(document.getElementById('ucAtkModSig' ).value))/100)));
        document.getElementById('ucTrp7Def').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp7.Def  + (1 + feyAltar*feyAltarAct) * t.Trp7.Def  * (resDef  + knight + itemDef + t.maxBuff('def', parseFloat(document.getElementById('ucDefMod' ).value),parseFloat(document.getElementById('ucDefModSig' ).value))/100)));
        document.getElementById('ucTrp7Spd').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp7.Spd  + (1 + feyAltar*feyAltarAct) * t.Trp7.Spd  * (resSpd                     + t.maxBuff('spd', parseFloat(document.getElementById('ucSpdMod' ).value),parseFloat(document.getElementById('ucSpdModSig' ).value))/100)));
        document.getElementById('ucTrp7Rng').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp7.Rng  + (1 + feyAltar*feyAltarAct) * t.Trp7.Rng  * (resRng                     + t.maxBuff('rng', parseFloat(document.getElementById('ucRngMod' ).value),parseFloat(document.getElementById('ucRngModSig' ).value))/100)));

        //Trp8 - ram
        document.getElementById('ucTrp8Life').innerHTML = t.round1decimals( (1 + guardLife) * ( (1 + feyAltar*feyAltarAct) * t.Trp8.Life + (1 + feyAltar*feyAltarAct) * t.Trp8.Life * (resLife                    + t.maxBuff('life',parseFloat(document.getElementById('ucLifeMod').value),parseFloat(document.getElementById('ucLifeModSig').value))/100)));
        document.getElementById('ucTrp8Atk').innerHTML  = t.round1decimals( (1 + guardAtk)  * ( (1 + feyAltar*feyAltarAct) * t.Trp8.Atk  + (1 + feyAltar*feyAltarAct) * t.Trp8.Atk  * (resAtk  + knight + itemAtk + t.maxBuff('atk', parseFloat(document.getElementById('ucAtkMod' ).value),parseFloat(document.getElementById('ucAtkModSig' ).value))/100)));
        document.getElementById('ucTrp8Def').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp8.Def  + (1 + feyAltar*feyAltarAct) * t.Trp8.Def  * (resDef  + knight + itemDef + t.maxBuff('def', parseFloat(document.getElementById('ucDefMod' ).value),parseFloat(document.getElementById('ucDefModSig' ).value))/100)));
        document.getElementById('ucTrp8Spd').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp8.Spd  + (1 + feyAltar*feyAltarAct) * t.Trp8.Spd  * (resSpd                     + t.maxBuff('spd', parseFloat(document.getElementById('ucSpdMod' ).value),parseFloat(document.getElementById('ucSpdModSig' ).value))/100)));
        document.getElementById('ucTrp8Rng').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp8.Rng  + (1 + feyAltar*feyAltarAct) * t.Trp8.Rng  * (                             t.maxBuff('rng', parseFloat(document.getElementById('ucRngMod' ).value),parseFloat(document.getElementById('ucRngModSig' ).value))/100)));

        //Trp9 - cat
        document.getElementById('ucTrp9Life').innerHTML = t.round1decimals( (1 + guardLife) * ( (1 + feyAltar*feyAltarAct) * t.Trp9.Life + (1 + feyAltar*feyAltarAct) * t.Trp9.Life * (resLife                    + t.maxBuff('life',parseFloat(document.getElementById('ucLifeMod').value),parseFloat(document.getElementById('ucLifeModSig').value))/100)));
        document.getElementById('ucTrp9Atk').innerHTML  = t.round1decimals( (1 + guardAtk)  * ( (1 + feyAltar*feyAltarAct) * t.Trp9.Atk  + (1 + feyAltar*feyAltarAct) * t.Trp9.Atk  * (resAtk  + knight + itemAtk + t.maxBuff('atk', parseFloat(document.getElementById('ucAtkMod' ).value),parseFloat(document.getElementById('ucAtkModSig' ).value))/100)));
        document.getElementById('ucTrp9Def').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp9.Def  + (1 + feyAltar*feyAltarAct) * t.Trp9.Def  * (resDef  + knight + itemDef + t.maxBuff('def', parseFloat(document.getElementById('ucDefMod' ).value),parseFloat(document.getElementById('ucDefModSig' ).value))/100)));
        document.getElementById('ucTrp9Spd').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp9.Spd  + (1 + feyAltar*feyAltarAct) * t.Trp9.Spd  * (resSpd                     + t.maxBuff('spd', parseFloat(document.getElementById('ucSpdMod' ).value),parseFloat(document.getElementById('ucSpdModSig' ).value))/100)));
        document.getElementById('ucTrp9Rng').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp9.Rng  + (1 + feyAltar*feyAltarAct) * t.Trp9.Rng  * (resRng                     + t.maxBuff('rng', parseFloat(document.getElementById('ucRngMod' ).value),parseFloat(document.getElementById('ucRngModSig' ).value))/100)));

        //Trp10 - blood
        //verified on 11/30 that bloods don't use infantry buff for atk/def. other stats unknown
        document.getElementById('ucTrp10Life').innerHTML = t.round1decimals( (1 + guardLife) * ( (1 + feyAltar*feyAltarAct) * t.Trp10.Life + (1 + feyAltar*feyAltarAct) * t.Trp10.Life * (resLife                    + t.maxBuff('life',parseFloat(document.getElementById('ucLifeMod').value),0)/100)));
        document.getElementById('ucTrp10Atk').innerHTML  = t.round1decimals( (1 + guardAtk)  * ( (1 + feyAltar*feyAltarAct) * t.Trp10.Atk  + (1 + feyAltar*feyAltarAct) * t.Trp10.Atk  * (resAtk  + knight + itemAtk + t.maxBuff('atk', parseFloat(document.getElementById('ucAtkMod' ).value),0)/100)));
        document.getElementById('ucTrp10Def').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp10.Def  + (1 + feyAltar*feyAltarAct) * t.Trp10.Def  * (resDef  + knight + itemDef + t.maxBuff('def', parseFloat(document.getElementById('ucDefMod' ).value),0)/100)));
        document.getElementById('ucTrp10Spd').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp10.Spd  + (1 + feyAltar*feyAltarAct) * t.Trp10.Spd  * (                             t.maxBuff('spd', parseFloat(document.getElementById('ucSpdMod' ).value),0)/100)));
        document.getElementById('ucTrp10Rng').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp10.Rng  + (1 + feyAltar*feyAltarAct) * t.Trp10.Rng  * (                             t.maxBuff('rng', parseFloat(document.getElementById('ucRngMod' ).value),0)/100)));

        //Trp11 - exec
        //verified on 11/30 that exec don't use infantry buff for atk/def. other stats unknown
        document.getElementById('ucTrp11Life').innerHTML = t.round1decimals( (1 + guardLife) * ( (1 + feyAltar*feyAltarAct) * t.Trp11.Life + (1 + feyAltar*feyAltarAct) * t.Trp11.Life * (resLife                    + t.maxBuff('life',parseFloat(document.getElementById('ucLifeMod').value),0)/100)));
        document.getElementById('ucTrp11Atk').innerHTML  = t.round1decimals( (1 + guardAtk)  * ( (1 + feyAltar*feyAltarAct) * t.Trp11.Atk  + (1 + feyAltar*feyAltarAct) * t.Trp11.Atk  * (resAtk  + knight + itemAtk + t.maxBuff('atk', parseFloat(document.getElementById('ucAtkMod' ).value),0)/100)));
        document.getElementById('ucTrp11Def').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp11.Def  + (1 + feyAltar*feyAltarAct) * t.Trp11.Def  * (resDef  + knight + itemDef + t.maxBuff('def', parseFloat(document.getElementById('ucDefMod' ).value),0)/100)));
        document.getElementById('ucTrp11Spd').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp11.Spd  + (1 + feyAltar*feyAltarAct) * t.Trp11.Spd  * (                             t.maxBuff('spd', parseFloat(document.getElementById('ucSpdMod' ).value),0)/100)));
        document.getElementById('ucTrp11Rng').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp11.Rng  + (1 + feyAltar*feyAltarAct) * t.Trp11.Rng  * (                             t.maxBuff('rng', parseFloat(document.getElementById('ucRngMod' ).value),0)/100)));

        //Trp12 - siege wall
        document.getElementById('ucTrp12Life').innerHTML = t.round1decimals( (1 + guardLife) * ( (1 + feyAltar*feyAltarAct) * t.Trp12.Life + (1 + feyAltar*feyAltarAct) * t.Trp12.Life * (resLife                    + t.maxBuff('life',parseFloat(document.getElementById('ucLifeMod').value),parseFloat(document.getElementById('ucLifeModSig').value))/100)));
        document.getElementById('ucTrp12Atk').innerHTML  = t.round1decimals( (1 + guardAtk)  * ( (1 + feyAltar*feyAltarAct) * t.Trp12.Atk  + (1 + feyAltar*feyAltarAct) * t.Trp12.Atk  * (resAtk  + knight + itemAtk + t.maxBuff('atk', parseFloat(document.getElementById('ucAtkMod' ).value),parseFloat(document.getElementById('ucAtkModSig' ).value))/100)));
        document.getElementById('ucTrp12Def').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp12.Def  + (1 + feyAltar*feyAltarAct) * t.Trp12.Def  * (resDef  + knight + itemDef + t.maxBuff('def', parseFloat(document.getElementById('ucDefMod' ).value),parseFloat(document.getElementById('ucDefModSig' ).value))/100)));
        document.getElementById('ucTrp12Spd').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp12.Spd  + (1 + feyAltar*feyAltarAct) * t.Trp12.Spd  * (                           + t.maxBuff('spd', parseFloat(document.getElementById('ucSpdMod' ).value),parseFloat(document.getElementById('ucSpdModSig' ).value))/100)));
        document.getElementById('ucTrp12Rng').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp12.Rng  + (1 + feyAltar*feyAltarAct) * t.Trp12.Rng  * (                           + t.maxBuff('rng', parseFloat(document.getElementById('ucRngMod' ).value),parseFloat(document.getElementById('ucRngModSig' ).value))/100)));
        
        //Trp13 - flame arch
        document.getElementById('ucTrp13Life').innerHTML = t.round1decimals( (1 + guardLife) * ( (1 + feyAltar*feyAltarAct) * t.Trp13.Life + (1 + feyAltar*feyAltarAct) * t.Trp13.Life * (resLife                    + t.maxBuff('life',parseFloat(document.getElementById('ucLifeMod').value),parseFloat(document.getElementById('ucLifeModRng').value))/100)));
        document.getElementById('ucTrp13Atk').innerHTML  = t.round1decimals( (1 + guardAtk)  * ( (1 + feyAltar*feyAltarAct) * t.Trp13.Atk  + (1 + feyAltar*feyAltarAct) * t.Trp13.Atk  * (resAtk  + knight + itemAtk + t.maxBuff('atk', parseFloat(document.getElementById('ucAtkMod' ).value),parseFloat(document.getElementById('ucAtkModRng' ).value))/100)));
        document.getElementById('ucTrp13Def').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp13.Def  + (1 + feyAltar*feyAltarAct) * t.Trp13.Def  * (resDef  + knight + itemDef + t.maxBuff('def', parseFloat(document.getElementById('ucDefMod' ).value),parseFloat(document.getElementById('ucDefModRng' ).value))/100)));
        document.getElementById('ucTrp13Spd').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp13.Spd  + (1 + feyAltar*feyAltarAct) * t.Trp13.Spd  * (                             t.maxBuff('spd', parseFloat(document.getElementById('ucSpdMod' ).value),parseFloat(document.getElementById('ucSpdModRng' ).value))/100)));
        document.getElementById('ucTrp13Rng').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp13.Rng  + (1 + feyAltar*feyAltarAct) * t.Trp13.Rng  * (resRng                     + t.maxBuff('rng', parseFloat(document.getElementById('ucRngMod' ).value),parseFloat(document.getElementById('ucRngModRng' ).value))/100)));

        //Trp14 - hussar
        document.getElementById('ucTrp14Life').innerHTML = t.round1decimals( (1 + guardLife) * ( (1 + feyAltar*feyAltarAct) * t.Trp14.Life + (1 + feyAltar*feyAltarAct) * t.Trp14.Life * (resLife                    + t.maxBuff('life',parseFloat(document.getElementById('ucLifeMod').value),parseFloat(document.getElementById('ucLifeModHor').value))/100)));
        document.getElementById('ucTrp14Atk').innerHTML  = t.round1decimals( (1 + guardAtk)  * ( (1 + feyAltar*feyAltarAct) * t.Trp14.Atk  + (1 + feyAltar*feyAltarAct) * t.Trp14.Atk  * (resAtk  + knight + itemAtk + t.maxBuff('atk', parseFloat(document.getElementById('ucAtkMod' ).value),parseFloat(document.getElementById('ucAtkModHor' ).value))/100)));
        document.getElementById('ucTrp14Def').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp14.Def  + (1 + feyAltar*feyAltarAct) * t.Trp14.Def  * (resDef  + knight + itemDef + t.maxBuff('def', parseFloat(document.getElementById('ucDefMod' ).value),parseFloat(document.getElementById('ucDefModHor' ).value))/100)));
        document.getElementById('ucTrp14Spd').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp14.Spd  + (1 + feyAltar*feyAltarAct) * t.Trp14.Spd  * (resSpd                     + t.maxBuff('spd', parseFloat(document.getElementById('ucSpdMod' ).value),parseFloat(document.getElementById('ucSpdModHor' ).value))/100)));
        document.getElementById('ucTrp14Rng').innerHTML  = t.round1decimals(                   ( (1 + feyAltar*feyAltarAct) * t.Trp14.Rng  + (1 + feyAltar*feyAltarAct) * t.Trp14.Rng  * (                             t.maxBuff('rng', parseFloat(document.getElementById('ucRngMod' ).value),parseFloat(document.getElementById('ucRngModHor' ).value))/100)));
    },

    maxBuff : function (stat,a,b) {
        if (stat == 'life')
            if (a+b > 250)
                return 250;
            else if (a+b < -50)
                return -50;
            else
                return a+b;
        if (stat == 'atk')
            if (a+b > 1000)
                return 1000;
            else if (a+b < -25)
                return -25;
            else
                return a+b;
        if (stat == 'def')
            if (a+b > 5000)
                return 5000;
            else if (a+b < -25)
                return -25;
            else
                return a+b;
        if (stat == 'spd')
            if (a+b > 375)
                return 375;
            else if (a+b < -50)
                return -50;
            else
                return a+b;
        if (stat == 'rng')
            if (a+b > 185)
                return 185;
            else if (a+b < -25)
                return -25;
            else
                return a+b;
    },

    round1decimals : function (number) {
        return Math.round(number * 10) / 10;
    },
    
    woodGuardTable : function (number) {
        if (number == '1')
            return 1;
        else if (number == '2')
            return 2;
        else if (number == '3')
            return 3;
        else if (number == '4')
            return 4;
        else if (number == '5')
            return 6;
        else if (number == '6')
            return 8;
        else if (number == '7')
            return 10;
        else if (number == '8')
            return 13;
        else if (number == '9')
            return 16;
        else if (number == '10')
            return 20;
        else if (number == '11')
            return 25;
        else if (number == '12')
            return 35;
        else
            return 0;
    },

    oreGuardTable : function (number) {
        if (number == '1')
            return 2;
        else if (number == '2')
            return 4;
        else if (number == '3')
            return 6;
        else if (number == '4')
            return 8;
        else if (number == '5')
            return 12;
        else if (number == '6')
            return 16;
        else if (number == '7')
            return 20;
        else if (number == '8')
            return 26;
        else if (number == '9')
            return 32;
        else if (number == '10')
            return 40;
        else if (number == '11')
            return 50;
        else if (number == '12')
            return 65;
        else
            return 0;
    },

}

/****************************  Advisor Tab  ******************************/
Tabs.Advisor = {
    tabOrder : 400,                    // order to place tab in top bar
    tabLabel : 'Advisor',            // label to show in main window tabs
    myDiv : null,
    timer : null,

    init : function (div){    // called once, upon script startup
        var t = Tabs.Advisor;
        t.myDiv = div;
        div.innerHTML = 'Unique Advisors<br>\
                        Show: <input id=advisorKay type=checkbox checked> Kay | <input id=advisorWynn type=checkbox checked> Wynn |\
                        <input id=advisorMordred type=checkbox checked> Mordred | <input id=advisorHarbinger type=checkbox checked> Harbinger |\
                        <input id=advisorWarhorse type=checkbox checked> Warhorse | <input id=advisorWinter type=checkbox checked> Father Winter\
                        <TABLE border=1 id=tableAdvisor>\
                        <tbody id=tableKay>\
                        <tr><th>Advisor      </th><th>Row</th><th>Attribute                </th><th>+1   </th><th>+2   </th><th>+3   </th><th>+4   </th><th>+5   </th><th>+6   </th><th>+7   </th><th>+8   </th><th>+9   </th><th>+10  </th><th>+11  </th><th>+12  </th><th>Attribute</th></tr>\
                        <tr><td>Kay          </td><td>1  </td><td>Siege Attak Debuff       </td><td>-6.5 </td><td>-9.5 </td><td>-14  </td><td>-20  </td><td>-27.5</td><td>-36.5</td><td>-47  </td><td>-59  </td><td>-72.5</td><td>-87.5</td><td>-104 </td><td>-122 </td><td>Siege Attak Debuff</td></tr>\
                        <tr><td>Kay          </td><td>2  </td><td>Accuracy Debuff          </td><td>-0.06</td><td>-0.08</td><td>-0.11</td><td>-0.15</td><td>-0.2 </td><td>-0.26</td><td>-0.33</td><td>-0.41</td><td>-0.5 </td><td>-0.6 </td><td>-0.71</td><td>-0.83</td><td>Accuracy Debuff</td></tr>\
                        <tr><td>Kay          </td><td>3  </td><td>Life                     </td><td>+13  </td><td>+19  </td><td>+28  </td><td>+40  </td><td>+55  </td><td>+73  </td><td>+94  </td><td>+118 </td><td>+145 </td><td>+175 </td><td>+208 </td><td>+244 </td><td>Life</td></tr>\
                        <tr><td>Kay          </td><td>4  </td><td>Defense                  </td><td>+106 </td><td>+118 </td><td>+136 </td><td>+160 </td><td>+190 </td><td>+226 </td><td>+268 </td><td>+316 </td><td>+370 </td><td>+430 </td><td>+496 </td><td>+568 </td><td>Defense</td></tr>\
                        <tr><td>Kay          </td><td>5  </td><td>Range Debuff             </td><td>-6.5 </td><td>-9.5 </td><td>-14  </td><td>-20  </td><td>-27.5</td><td>-36.5</td><td>-47  </td><td>-59  </td><td>-72.5</td><td>-87.5</td><td>-104 </td><td>-122 </td><td>Range Debuff</td></tr>\
                        </tbody>\
                        <tbody id=tableWynn>\
                        <tr><th>Advisor      </th><th>Row</th><th>Attribute                </th><th>+1   </th><th>+2   </th><th>+3   </th><th>+4   </th><th>+5   </th><th>+6   </th><th>+7   </th><th>+8   </th><th>+9   </th><th>+10  </th><th>+11  </th><th>+12  </th><th>Attribute</th></tr>\
                        <tr><td>Wynn         </td><td>1  </td><td>Research Speed           </td><td>+14  </td><td>+18  </td><td>+24  </td><td>+32  </td><td>+42  </td><td>+54  </td><td>+68  </td><td>+84  </td><td>+102 </td><td>+122 </td><td>+144 </td><td>+168 </td><td>Research Speed</td></tr>\
                        <tr><td>Wynn         </td><td>2  </td><td>Aetherstone Cap          </td><td>+7   </td><td>+11  </td><td>+17  </td><td>+25  </td><td>+35  </td><td>+47  </td><td>+61  </td><td>+77  </td><td>+95  </td><td>+115 </td><td>+137 </td><td>+161 </td><td>Aetherstone Cap</td></tr>\
                        <tr><td>Wynn         </td><td>3  </td><td>Storehouse Protection    </td><td>+13  </td><td>+19  </td><td>+28  </td><td>+40  </td><td>+55  </td><td>+73  </td><td>+94  </td><td>+118 </td><td>+145 </td><td>+175 </td><td>+208 </td><td>+244 </td><td>Storehouse Protection</td></tr>\
                        <tr><td>Wynn         </td><td>4  </td><td>Troop Training Speed     </td><td>+44  </td><td>+52  </td><td>+64  </td><td>+80  </td><td>+100 </td><td>+124 </td><td>+152 </td><td>+184 </td><td>+220 </td><td>+260 </td><td>+304 </td><td>+353 </td><td>Troop Training Speed</td></tr>\
                        <tr><td>Wynn         </td><td>5  </td><td>Upkeep Reduction         </td><td>+6   </td><td>+8   </td><td>+11  </td><td>+15  </td><td>+20  </td><td>+26  </td><td>+33  </td><td>+41  </td><td>+50  </td><td>+60  </td><td>+71  </td><td>+83  </td><td>Upkeep Reduction</td></tr>\
                        </tbody>\
                        <tbody id=tableMordred>\
                        <tr><th>Advisor      </th><th>Row</th><th>Attribute                </th><th>+1   </th><th>+2   </th><th>+3   </th><th>+4   </th><th>+5   </th><th>+6   </th><th>+7   </th><th>+8   </th><th>+9   </th><th>+10  </th><th>+11  </th><th>+12  </th><th>Attribute</th></tr>\
                        <tr><td>Mordred      </td><td>1  </td><td>Troop Training Speed     </td><td>+14  </td><td>+18  </td><td>+24  </td><td>+32  </td><td>+42  </td><td>+54  </td><td>+68  </td><td>+84  </td><td>+102 </td><td>+122 </td><td>+144 </td><td>+168 </td><td>Troop Training Speed</td></tr>\
                        <tr><td>Mordred      </td><td>2  </td><td>Reinforcement March Speed</td><td>+24  </td><td>+32  </td><td>+44  </td><td>+60  </td><td>+80  </td><td>+104 </td><td>+132 </td><td>+164 </td><td>+200 </td><td>+240 </td><td>+284 </td><td>+332 </td><td>Reinforcement March Speed</td></tr>\
                        <tr><td>Mordred      </td><td>3  </td><td>Range Debuff             </td><td>-3   </td><td>-5   </td><td>-8   </td><td>-12  </td><td>-17  </td><td>-23  </td><td>-30  </td><td>-38  </td><td>-47  </td><td>-57  </td><td>-68  </td><td>-80  </td><td>Range Debuff</td></tr>\
                        <tr><td>Mordred      </td><td>4  </td><td>Defense                  </td><td>+106 </td><td>+118 </td><td>+136 </td><td>+160 </td><td>+190 </td><td>+226 </td><td>+268 </td><td>+316 </td><td>+370 </td><td>+430 </td><td>+496 </td><td>+568 </td><td>Defense</td></tr>\
                        <tr><td>Mordred      </td><td>5  </td><td>Construction Speed       </td><td>+27  </td><td>+33  </td><td>+42  </td><td>+54  </td><td>+69  </td><td>+87  </td><td>+108 </td><td>+132 </td><td>+159 </td><td>+189 </td><td>+222 </td><td>+258 </td><td>Construction Speed</td></tr>\
                        </tbody>\
                        <tbody id=tableHarbinger>\
                        <tr><th>Advisor      </th><th>Row</th><th>Attribute                </th><th>+1   </th><th>+2   </th><th>+3   </th><th>+4   </th><th>+5   </th><th>+6   </th><th>+7   </th><th>+8   </th><th>+9   </th><th>+10  </th><th>+11  </th><th>+12  </th><th>Attribute</th></tr>\
                        <tr><td>Harbinger    </td><td>1  </td><td>Horsed Combat Speed      </td><td>+7   </td><td>+11  </td><td>+17  </td><td>+25  </td><td>+35  </td><td>+47  </td><td>+61  </td><td>+77  </td><td>+95  </td><td>+115 </td><td>+137 </td><td>+161 </td><td>Horsed Combat Speed</td></tr>\
                        <tr><td>Harbinger    </td><td>2  </td><td>Ranged Range Debuff      </td><td>-3   </td><td>-5   </td><td>-8   </td><td>-12  </td><td>-17  </td><td>-23  </td><td>-30  </td><td>-38  </td><td>-47  </td><td>-57  </td><td>-68  </td><td>-80  </td><td>Ranged Range Debuff</td></tr>\
                        <tr><td>Harbinger    </td><td>3  </td><td>Defense Debuff           </td><td>-44  </td><td>-52  </td><td>-64  </td><td>-80  </td><td>-100 </td><td>-124 </td><td>-152 </td><td>-184 </td><td>-220 </td><td>-260 </td><td>-304 </td><td>-353 </td><td>Defense Debuff</td></tr>\
                        <tr><td>Harbinger    </td><td>4  </td><td>Attack Debuff            </td><td>-13  </td><td>-19  </td><td>-28  </td><td>-40  </td><td>-55  </td><td>-73  </td><td>-94  </td><td>-118 </td><td>-145 </td><td>-175 </td><td>-208 </td><td>-244 </td><td>Attack Debuff</td></tr>\
                        <tr><td>Harbinger    </td><td>5  </td><td>Life Debuff              </td><td>-7   </td><td>-11  </td><td>-17  </td><td>-25  </td><td>-35  </td><td>-47  </td><td>-61  </td><td>-77  </td><td>-95  </td><td>-115 </td><td>-137 </td><td>-161 </td><td>Life Debuff</td></tr>\
                        </tbody>\
                        <tbody id=tableWarhorse>\
                        <tr><th>Advisor      </th><th>Row</th><th>Attribute                </th><th>+1   </th><th>+2   </th><th>+3   </th><th>+4   </th><th>+5   </th><th>+6   </th><th>+7   </th><th>+8   </th><th>+9   </th><th>+10  </th><th>+11  </th><th>+12  </th><th>Attribute</th></tr>\
                        <tr><td>Warhorse     </td><td>1  </td><td>Attack Debuff            </td><td>-13  </td><td>-19  </td><td>-28  </td><td>-40  </td><td>-55  </td><td>-73  </td><td>-94  </td><td>-118 </td><td>-145 </td><td>-175 </td><td>-208 </td><td>-244 </td><td>Attack Debuff</td></tr>\
                        <tr><td>Warhorse     </td><td>2  </td><td>Horsed Life              </td><td>+7   </td><td>+11  </td><td>+17  </td><td>+25  </td><td>+35  </td><td>+47  </td><td>+61  </td><td>+77  </td><td>+95  </td><td>+115 </td><td>+137 </td><td>+161 </td><td>Horsed Life</td></tr>\
                        <tr><td>Warhorse     </td><td>3  </td><td>Horsed Defense           </td><td>+23  </td><td>+29  </td><td>+38  </td><td>+50  </td><td>+65  </td><td>+83  </td><td>+104 </td><td>+128 </td><td>+155 </td><td>+185 </td><td>+218 </td><td>+254 </td><td>Horsed Defense</td></tr>\
                        <tr><td>Warhorse     </td><td>4  </td><td>Life                     </td><td>+7   </td><td>+11  </td><td>+17  </td><td>+25  </td><td>+35  </td><td>+47  </td><td>+61  </td><td>+77  </td><td>+95  </td><td>+115 </td><td>+137 </td><td>+161 </td><td>Life</td></tr>\
                        <tr><td>Warhorse     </td><td>5  </td><td>Defense                  </td><td>+44  </td><td>+52  </td><td>+64  </td><td>+80  </td><td>+100 </td><td>+124 </td><td>+152 </td><td>+184 </td><td>+220 </td><td>+260 </td><td>+304 </td><td>+353 </td><td>Defense</td></tr>\
                        </tbody>\
                        <tbody id=tableWinter>\
                        <tr><th>Advisor      </th><th>Row</th><th>Attribute                </th><th>+1   </th><th>+2   </th><th>+3   </th><th>+4   </th><th>+5   </th><th>+6   </th><th>+7   </th><th>+8   </th><th>+9   </th><th>+10  </th><th>+11  </th><th>+12  </th><th>Attribute</th></tr>\
                        <tr><td>Father Winter</td><td>1  </td><td>Life                     </td><td>+7   </td><td>+11  </td><td>+17  </td><td>+25  </td><td>+35  </td><td>+47  </td><td>+61  </td><td>+77  </td><td>+95  </td><td>+115 </td><td>+137 </td><td>+161 </td><td>Life</td></tr>\
                        <tr><td>Father Winter</td><td>2  </td><td>Range                    </td><td>+1.5 </td><td>+-   </td><td>+-   </td><td>+-   </td><td>+-   </td><td>+-   </td><td>+-   </td><td>+-   </td><td>+-   </td><td>+-   </td><td>+-   </td><td>+-   </td><td>Range</td></tr>\
                        <tr><td>Father Winter</td><td>3  </td><td>Defense                  </td><td>+44  </td><td>+52  </td><td>+64  </td><td>+80  </td><td>+100 </td><td>+124 </td><td>+152 </td><td>+184 </td><td>+220 </td><td>+260 </td><td>+304 </td><td>+353 </td><td>Defense</td></tr>\
                        <tr><td>Father Winter</td><td>4  </td><td>Combat Speed             </td><td>+13  </td><td>+19  </td><td>+28  </td><td>+40  </td><td>+55  </td><td>+73  </td><td>+94  </td><td>+118 </td><td>+145 </td><td>+175 </td><td>+208 </td><td>+244 </td><td>Combat Speed</td></tr>\
                        <tr><td>Father Winter</td><td>5  </td><td>March Speed              </td><td>+16.5</td><td>+-   </td><td>+-   </td><td>+-   </td><td>+-   </td><td>+-   </td><td>+-   </td><td>+-   </td><td>+-   </td><td>+-   </td><td>+-   </td><td>+-   </td><td>March Speed</td></tr>\
                        </tbody>\
                        </table>';
                        
        document.getElementById('advisorKay').addEventListener('change', function(e){
            t.modifyAdvisor();
        }, false);
        document.getElementById('advisorWynn').addEventListener('change', function(e){
            t.modifyAdvisor();
        }, false);
        document.getElementById('advisorMordred').addEventListener('change', function(e){
            t.modifyAdvisor();
        }, false);
        document.getElementById('advisorHarbinger').addEventListener('change', function(e){
            t.modifyAdvisor();
        }, false);
        document.getElementById('advisorWarhorse').addEventListener('change', function(e){
            t.modifyAdvisor();
        }, false);
        document.getElementById('advisorWinter').addEventListener('change', function(e){
            t.modifyAdvisor();
        }, false);
    },

    hide : function (){         // called whenever the main window is hidden, or another tab is selected
        var t = Tabs.Advisor;
    },

    show : function (){         // called whenever this tab is shown
        var t = Tabs.Advisor;
    },
    
    modifyAdvisor : function (){
        var t = Tabs.Advisor;
        var kay = document.getElementById('advisorKay').checked ? 1 : 0;
        var wynn = document.getElementById('advisorWynn').checked ? 1 : 0;
        var mordred = document.getElementById('advisorMordred').checked ? 1 : 0;
        var harbinger = document.getElementById('advisorHarbinger').checked ? 1 : 0;
        var warhorse = document.getElementById('advisorWarhorse').checked ? 1 : 0;
        var winter = document.getElementById('advisorWinter').checked ? 1 : 0;
        
        if (kay)
            document.getElementById('tableKay').style.display = '';
        else
            document.getElementById('tableKay').style.display = 'none';

        if (wynn)
            document.getElementById('tableWynn').style.display = '';
        else
            document.getElementById('tableWynn').style.display = 'none';

        if (mordred)
            document.getElementById('tableMordred').style.display = '';
        else
            document.getElementById('tableMordred').style.display = 'none';

        if (harbinger)
            document.getElementById('tableHarbinger').style.display = '';
        else
            document.getElementById('tableHarbinger').style.display = 'none';
            
        if (warhorse)
            document.getElementById('tableWarhorse').style.display = '';
        else
            document.getElementById('tableWarhorse').style.display = 'none';
            
        if (winter)
            document.getElementById('tableWinter').style.display = '';
        else
            document.getElementById('tableWinter').style.display = 'none';
    
    },
    
}

/*********************************** Options Tab ***********************************/
Tabs.Options = {
  tabOrder: 800,
  myDiv : null,
  fixAvailable : {},

  init : function (div){
    var t = Tabs.Options;
    t.myDiv = div;
    try {      
      m = '<DIV style="height:500px; max-height:500px; overflow-y:auto"><TABLE width=100% class=nbOptions cellspacing=0 cellpadding=0>\
        <TR><TD colspan=2><B>Notebook Config:</b></td></tr>\
        <TR><TD></td><TD><INPUT id=nbupdatenow type=submit value="Update Now"></td></tr>\
        </table><BR><BR></div>';
      div.innerHTML = m;

      document.getElementById('nbupdatenow').addEventListener ('click', function(){
            AutoUpdater_152625.call(true,true);
      },false);    
    
    } catch (e) {
      div.innerHTML = '<PRE>'+ e.name +' : '+ e.message +'</pre>';  
    }      
  },

  hide : function (){
  },

  show : function (){
  },

}

/*********************************** Issues Tab ***********************************/
Tabs.Issues = {
  tabOrder: 850,
    tabLabel : 'Issues',            // label to show in main window tabs
    myDiv : null,
    timer : null,

    init : function (div){    // called once, upon script startup
        var t = Tabs.Issues;
        t.myDiv = div;
        div.innerHTML = 'Known Issues<br><br>';
        div.innerHTML += '1. Bloods, Execs do not benefit from infantry tr items<br>';
        div.innerHTML += '2. Siege Walls do not benefit from alloy horseshoes research<br>';
        div.innerHTML += '3. Ore guardian bonus in ascended cities have greater attack stats<br>';
        div.innerHTML += '4. Ore guardian bonus is applied to defending troops (from kabam forums)<br>';
        div.innerHTML += '<br>';
    },

    hide : function (){         // called whenever the main window is hidden, or another tab is selected
        var t = Tabs.Issues;
    },

    show : function (){         // called whenever this tab is shown
        var t = Tabs.Issues;
    },

}

/*********************************** Log Tab ***********************************/
Tabs.ActionLog = {
  tabOrder: 900,
  tabLabel : 'Log',
  myDiv : null,
  logTab : null,
  maxEntries: 300,
  last50 : [],
  state : null,

  init : function (div){
    var t = Tabs.ActionLog;
    t.myDiv = div;
    t.myDiv.innerHTML = '<DIV class=nbStat>ACTION LOG - VERSION: '+ Version+'</div><DIV style="height:535px; max-height:535px; overflow-y:auto">\
      <TABLE cellpadding=0 cellspacing=0 id=nbactionlog class=nbTabLined><TR><TD></td><TD width=95%></td></table></div>';
    t.logTab = document.getElementById('nbactionlog');
    t.state = 1;
    var a = JSON2.parse(GM_getValue ('log_'+getServerId(), '[]'));
    if (matTypeof(a) == 'array'){
      t.last50 = a;
      for (var i=0; i<t.last50.length; i++)
        t._addTab (t.last50[i].msg, t.last50[i].ts);
    }
    window.addEventListener('unload', t.onUnload, false);
  },

  hide : function (){
  },

  show : function (){
  },

  onUnload : function (){
    var t = Tabs.ActionLog;
    if (!ResetAll) GM_setValue ('log_'+getServerId(), JSON2.stringify(t.last50));
  },

  _addTab : function (msg, ts){
    var t = Tabs.ActionLog;
    if (t.state != 1)
      return;
    if (t.logTab.rows.length >= t.maxEntries)
      t.logTab.deleteRow(t.maxEntries-1);
    var row = t.logTab.insertRow(0);
    row.vAlign = 'top';
    row.insertCell(0).innerHTML = ts;
    row.insertCell(1).innerHTML = msg;
  },

  log : function (msg){
    var t = Tabs.ActionLog;
    var ts = new Date().toTimeString().substring (0,8);
    t._addTab (msg, ts);
    while (t.last50.length >= 50)
      t.last50.shift();
    t.last50.push ({msg:msg, ts:ts});
  },
}

function actionLog (msg){
  if (!Tabs.ActionLog.tabDisabled)
    Tabs.ActionLog.log (msg);
}

var tabManager = {
  tabList : {},           // {name, obj, div}
  currentTab : null,

  init : function (mainDiv){
    var t = tabManager;
    var sorter = [];
    for (k in Tabs){
      if (!Tabs[k].tabDisabled){
        t.tabList[k] = {};
        t.tabList[k].name = k;
        t.tabList[k].obj = Tabs[k];
        if (Tabs[k].tabLabel != null)
          t.tabList[k].label = Tabs[k].tabLabel;
        else
          t.tabList[k].label = k;
        if (Tabs[k].tabOrder != null)
          sorter.push([Tabs[k].tabOrder, t.tabList[k]]);
        else
          sorter.push([1000, t.tabList[k]]);
        t.tabList[k].div = document.createElement('div');
      }
    }

    sorter.sort (function (a,b){return a[0]-b[0]});
    var m = '<TABLE cellspacing=3 class=nbMainTab><TR>';
    for (var i=0; i<sorter.length; i++) {
      m += '<TD class=spacer></td><TD align=center class=notSel id=nbtc'+ sorter[i][1].name +' ><A><SPAN>'+ sorter[i][1].label +'</span></a></td>';
      //m += '<TD align=center class=notSel id=nbtc'+ sorter[i][1].name +' ><A><SPAN>'+ sorter[i][1].label +'</span></a></td>';
      if ((i+1)%9 == 0) m+='</tr><TR>';
    }
    m+='</tr></table>';
    //m += '<TD class=spacer width=90% align=right>'+ Version +'&nbsp;</td></tr></table>';
    mainPop.getMainTopDiv().innerHTML = m;

    for (k in t.tabList) {
      if (t.tabList[k].name == Options.currentTab)
        t.currentTab =t.tabList[k] ;
      document.getElementById('nbtc'+ k).addEventListener('click', this.e_clickedTab, false);
      var div = t.tabList[k].div;
      div.style.display = 'none';
      div.style.height = '100%';
      mainDiv.appendChild(div);
      try {
        t.tabList[k].obj.init(div);
      } catch (e){
        div.innerHTML = "INIT ERROR: "+ e;
      }
    }

    if (t.currentTab == null)
      t.currentTab = sorter[0][1];
    t.setTabStyle (document.getElementById ('nbtc'+ t.currentTab.name), true);
    t.currentTab.div.style.display = 'block';
  },

  hideTab : function (){
    var t = tabManager;
    t.currentTab.obj.hide();
  },

  showTab : function (){
    var t = tabManager;
    t.currentTab.obj.show();
  },

  setTabStyle : function (e, selected){
    if (selected){
      e.className = 'sel';
    } else {
      e.className = 'notSel';
    }
  },

  e_clickedTab : function (e){
    var t = tabManager;
    var newTab = t.tabList[e.target.parentNode.parentNode.id.substring(4)];
    if (t.currentTab.name != newTab.name){
      t.setTabStyle (document.getElementById ('nbtc'+ t.currentTab.name), false);
      t.setTabStyle (document.getElementById ('nbtc'+ newTab.name), true);
      t.currentTab.obj.hide ();
      t.currentTab.div.style.display = 'none';
      t.currentTab = newTab;
      newTab.div.style.display = 'block';
      Options.currentTab = newTab.name;
    }
    newTab.obj.show();
  },
}

function onUnload (){
  Options.nbWinPos = mainPop.getLocation();
  if (!ResetAll) saveOptions();
}

function mouseMainTab (me){   // right-click on main button resets window location
  if (me.button == 2){
    var c = getClientCoords (document.getElementById('main_engagement_tabs'));
    mainPop.setLocation ({x: c.x+4, y: c.y+c.height});
  }
}

function eventHideShow (){
  if (mainPop.toggleHide(mainPop)){
    tabManager.showTab();
    Options.nbWinIsOpen = true;
  } else {
    tabManager.hideTab();
    Options.nbWinIsOpen = false;
  }
  saveOptions();
}

function hideMe (){
  mainPop.show (false);
  tabManager.hideTab();
  Options.nbWinIsOpen = false;
  saveOptions();
}

function showMe (){
  mainPop.show (true);
  tabManager.showTab();
  Options.nbWinIsOpen = true;
  saveOptions();
}

// example: http://www150.kingdomsofcamelot.com
var myServerId = null;
function getServerId() {
  if (myServerId == null){
    var m=/^[a-zA-Z]+([0-9]+)\./.exec(document.location.hostname);
    if (m)
      myServerId = m[1];
    else
      myServerId = '??';
  }
  return myServerId;
}

function logit (msg){
  var now = new Date();
  GM_log (getServerId() +' @ '+ now.toTimeString().substring (0,8) +'.' + now.getMilliseconds() +': '+  msg);
}

function saveOptions (){
  var serverID = getServerId();
  setTimeout (function (){GM_setValue ('Options_'+serverID, JSON2.stringify(Options));}, 0);
}

function saveRCOptions (){
  var serverID = getServerId();
  setTimeout (function (){GM_setValue ('RCOptions_'+serverID, JSON2.stringify(RCOptions));}, 0);
}

function readLayoutOptions (){
    var serverID = getServerId();
     s = GM_getValue ('LayoutOptions_'+serverID, '[]');
      if (s != null){
        opts = JSON2.parse (s);
        for (k in opts){
              if (matTypeof(opts[k]) == 'object')
                for (kk in opts[k])
                      layoutOptions[k][kk] = opts[k][kk];
    else
        layoutOptions[k] = opts[k];
    }
  }
}

function readOptions (){
  var serverID = getServerId();
  s = GM_getValue ('Options_'+serverID);
  if (s != null){
    opts = JSON2.parse (s);
    for (k in opts){
      if (matTypeof(opts[k]) == 'object')
        for (kk in opts[k])
          Options[k][kk] = opts[k][kk];
      else
        Options[k] = opts[k];
    }
  }
}

function readGlobalOptions (){
  GlobalOptions = JSON2.parse (GM_getValue ('Options_??', '{}'));
}

function readRCOptions (){
  var serverID = getServerId();
  s = GM_getValue ('RCOptions_'+serverID);
  if (s != null){
    opts = JSON2.parse (s);
    for (k in opts){
      if (matTypeof(opts[k]) == 'object')
        for (kk in opts[k])
          RCOptions[k][kk] = opts[k][kk];
      else
        RCOptions[k] = opts[k];
    }
  }
}


function createButton (label,id){
  var a=document.createElement('a');
  a.className='button20';
  a.id = id;
  a.innerHTML='<span style="color: #ff6">'+ label +'</span>';
  return a;
}

function AddMainTabLink(text, eventListener, mouseListener) {
  var a = createButton (text,'botbutton');
  a.className='tab';
  var tabs=document.getElementById('main_engagement_tabs');
  if(!tabs) {
    tabs=document.getElementById('topnav_msg');
    if (tabs)
      tabs=tabs.parentNode;
  }
  if (tabs) {
    var e = tabs.parentNode;
    var gmTabs = null;
    for (var i=0; i<e.childNodes.length; i++){
      var ee = e.childNodes[i];
      if (ee.tagName && ee.tagName=='DIV' && ee.className=='tabs_engagement' && ee.id!='main_engagement_tabs'){
        gmTabs = ee;
        break;
      }
    }
    if (gmTabs == null){
      gmTabs = document.createElement('div');
      gmTabs.className='tabs_engagement';
      gmTabs.style.background='#ca5';
      tabs.parentNode.insertBefore (gmTabs, tabs);
      gmTabs.style.whiteSpace='nowrap';
      gmTabs.style.width='735px';
      gmTabs.lang = 'en_NB';
    }
    gmTabs.appendChild(a);
    a.addEventListener('click',eventListener, false);
    if (mouseListener != null)
      a.addEventListener('mousedown',mouseListener, true);
    return a;
  }
  return null;
}

function AddSubTabLink(text, eventListener, id) {
  var a = createButton (text,'botbutton');
  a.className='tab';
  var tabs=document.getElementById('main_engagement_tabs');
  if(!tabs) {
    tabs=document.getElementById('topnav_msg');
    if (tabs)
      tabs=tabs.parentNode;
  }
  if (tabs) {
    var e = tabs.parentNode;
    var gmTabs = null;
    for (var i=0; i<e.childNodes.length; i++){
      var ee = e.childNodes[i];
      if (ee.tagName && ee.tagName=='DIV' && ee.className=='tabs_engagement' && ee.id!='main_engagement_tabs'){
        gmTabs = ee;
        break;
      }
    }
    if (gmTabs == null){
      gmTabs = document.createElement('div');
      gmTabs.className='tabs_engagement';
      gmTabs.style.background='#ca5';
      tabs.parentNode.insertBefore (gmTabs, tabs);
      gmTabs.style.whiteSpace='nowrap';
      gmTabs.style.width='735px';
      gmTabs.lang = 'en_NB';
    }
    gmTabs.appendChild(a);
    a.addEventListener('click',eventListener, false);
    if (id != null)
      a.id = id;
    return a;
  }
  return null;
}


/************* Updater code *************/
// Function for displaying a confirmation message modal popup similar to the default javascript confirm() function
// but with the advantage being that it won't halt all other javascript being executed on the page.
// Original Author: Thomas Chapin (April 6, 2011)
function display_confirm(confirm_msg,ok_function,cancel_function){
    if(!confirm_msg){confirm_msg="";}

    var container_div = document.getElementById('modal_js_confirm');
    var div;
    if(!container_div) {
        container_div=document.createElement('div');
        container_div.id='modal_js_confirm';
        container_div.style.position='absolute';
        container_div.style.top='0px';
        container_div.style.left='0px';
        container_div.style.width='100%';
        container_div.style.height='1px';
        container_div.style.overflow='visible';
        container_div.style.zIndex=10000000;

        div=document.createElement('div');
        div.id='modal_js_confirm_contents';
        div.style.zIndex=10000000;
        div.style.backgroundColor='#eee';
        div.style.fontFamily='"lucida grande",tahoma,verdana,arial,sans-serif';
        div.style.fontSize='11px';
        div.style.textAlign='center';
        div.style.color='#333333';
        div.style.border='2px outset #666';
        div.style.padding='10px';
        div.style.position='relative';
        div.style.width='300px';
        div.style.height='100px';
        div.style.margin='300px auto 0px auto';
        div.style.display='block';

        container_div.appendChild(div);
        document.body.appendChild(container_div);

        div.innerHTML = '<div style="text-align:center"><div>'+confirm_msg+'</div><br/><div>Press OK to continue.</div><br><button id="modal_js_confirm_ok_button">OK</button> <button id="modal_js_confirm_cancel_button">Cancel</button></div>';
        var ok_button = document.getElementById('modal_js_confirm_ok_button');
        ok_button.addEventListener('click',function() {
            if(ok_function && typeof(ok_function) == "function"){
                ok_function();
            }
            container_div.parentNode.removeChild(container_div);
        },false);
        var cancel_button = document.getElementById('modal_js_confirm_cancel_button');
        cancel_button.addEventListener('click',function() {
            if(cancel_function && typeof(cancel_function) == "function"){
                cancel_function();
            }
            container_div.parentNode.removeChild(container_div);
        },false);
    }
}

// The following code is released under public domain.

var AutoUpdater_152625 = {
    id: 152625,
    days: 1,
    name: "KOC Notebook",
    version: Version,
    beta: GlobalOptions.nbupdatebeta,
    betaUrl : 'http://koc-power-bot.googlecode.com/svn/trunk/KOCpowerBot.user.js',
    time: new Date().getTime(),
    call: function(response, secure) {
        GM_xmlhttpRequest({
            method: 'GET',
        url: this.beta ? this.betaUrl : 'http'+(secure ? 's' : '')+'://userscripts.org/scripts/source/'+this.id+'.meta.js',
        onload: function(xpr) {AutoUpdater_152625.compare(xpr, response);},
            onerror: function(xpr) {if (secure) AutoUpdater_152625.call(response, false);}
        });
    },
    enable: function() {
        GM_registerMenuCommand("Enable "+this.name+" updates", function() {
            GM_setValue('updated_152625', new Date().getTime()+'');
            AutoUpdater_152625.call(true, true)
        });
    },
    compareVersion: function(r_version, l_version) {
        var r_parts = r_version.split(''),
            l_parts = l_version.split(''),
            r_len = r_parts.length,
            l_len = l_parts.length,
            r = l = 0;
        for(var i = 0, len = (r_len > l_len ? r_len : l_len); i < len && r == l; ++i) {
            r = +(r_parts[i] || '0');
            l = +(l_parts[i] || '0');
        }
        return (r !== l) ? r > l : false;
    },
    compare: function(xpr,response) {
        this.xversion=/\/\/\s*@version\s+(.+)\s*\n/i.exec(xpr.responseText);
        this.xname=/\/\/\s*@name\s+(.+)\s*\n/i.exec(xpr.responseText);
        if ( (this.xversion) && (this.xname[1] == this.name) ) {
            this.xversion = this.xversion[1];
            this.xname = this.xname[1];
        } else {
            if ( (xpr.responseText.match("the page you requested doesn't exist")) || (this.xname[1] != this.name) ) {
                //GM_setValue('updated_152625', 'off');
            }
            return false;
        }
        var updated = this.compareVersion(this.xversion, this.version);

        if ( updated ) {

            display_confirm('A new version of '+this.xname+' is available.\nDo you wish to install the latest version?',
                // Ok
                function(){
                    try {
                        location.href = AutoUpdater_152625.beta ? AutoUpdater_152625.betaUrl :  'http://userscripts.org/scripts/source/152625.user.js';
                    } catch(e) {}
                },
                // Cancel
                function(){
                    if ( AutoUpdater_152625.xversion ) {
                        if(confirm('Do you want to turn off auto updating for this script?')) {
                            //GM_setValue('updated_152625', 'off');
                            GlobalOptions.nbupdate = false;
                            GM_setValue ('Options_??', JSON2.stringify(GlobalOptions));
                            AutoUpdater_152625.enable();
                            alert('Automatic updates can be re-enabled for this script in the Options tab.');
                        }
                    }
                }
            );

        } else if (response){
            alert('No updates available for '+this.name);
        }
    },
    check: function(tf) {
        if (!tf){
            this.enable();
        } else {
            GM_registerMenuCommand("Check "+this.name+" for updates", function() {
                GM_setValue('updated_152625', new Date().getTime()+'');
                AutoUpdater_152625.call(true, true)
            });
            if (+this.time > (+GM_getValue('updated_152625', 0) + 1000*60*60*24*this.days)) {
                GM_setValue('updated_152625', this.time+'');
                this.call(false, true);
            }
        }
    }
};
if (typeof(GM_xmlhttpRequest) !== 'undefined' && typeof(GM_updatingEnabled) === 'undefined') { // has an updater?
    try {
        AutoUpdater_152625.check(GlobalOptions.nbupdate);
    } catch(e) {
        AutoUpdater_152625.check(GlobalOptions.nbupdate);
    }
}
/********* End updater code *************/

/************  LIB classes/functions .... **************/
function getClientCoords(e){
  if (e==null)
    return {x:null, y:null, width:null, height:null};
  var x=0, y=0;
  ret = {x:0, y:0, width:e.clientWidth, height:e.clientHeight};
  while (e.offsetParent != null){
    ret.x += e.offsetLeft;
    ret.y += e.offsetTop;
    e = e.offsetParent;
  }
  return ret;
}

var WinManager = {
  wins : {},    // prefix : nbPopup obj
  didHide : [],


  get : function (prefix){
    var t = WinManager;
    return t.wins[prefix];
  },

  add : function (prefix, pop){
    var t = WinManager;
    t.wins[prefix] = pop;
    if (unsafeWindow.cpopupWins == null)
      unsafeWindow.cpopupWins = {};
    unsafeWindow.cpopupWins[prefix] = pop;
  },

  hideAll : function (){
    var t = WinManager;
    t.didHide = [];
    for (k in t.wins){
      if (t.wins[k].isShown()){
        t.didHide.push (t.wins[k]);
        t.wins[k].show (false);
      }
    }
  },
  restoreAll : function (){
    var t = WinManager;
    for (var i=0; i<t.didHide.length; i++)
      t.didHide[i].show (true);
  },

  delete : function (prefix){
    var t = WinManager;
    delete t.wins[prefix];
    delete unsafeWindow.cpopupWins[prefix];
  }
}


// creates a 'popup' div
// prefix must be a unique (short) name for the popup window
function nbPopup (prefix, x, y, width, height, enableDrag, onClose) {
  var pop = WinManager.get(prefix);
  if (pop){
    pop.show (false);
    return pop;
  }
  this.BASE_ZINDEX = 111111;

  // protos ...
  this.show = show;
  this.toggleHide = toggleHide;
  this.getTopDiv = getTopDiv;
  this.getMainTopDiv = getMainTopDiv;
  this.getMainDiv = getMainDiv;
  this.getLayer = getLayer;
  this.setLayer = setLayer;
  this.setEnableDrag = setEnableDrag;
  this.getLocation = getLocation;
  this.setLocation = setLocation;
  this.focusMe = focusMe;
  this.isShown = isShown;
  this.unfocusMe = unfocusMe;
  this.centerMe = centerMe;
  this.destroy = destroy;
  this.autoHeight = autoHeight;

  // object vars ...
  this.div = document.createElement('div');
  this.prefix = prefix;
  this.onClose = onClose;

  var t = this;
  this.div.className = 'nbPopup '+ prefix +'_nbPopup';
  this.div.id = prefix +'_outer';
  this.div.style.background = "#fff";
  this.div.style.zIndex = this.BASE_ZINDEX        // KOC modal is 100210 ?
  this.div.style.display = 'none';
  this.div.style.width = width + 'px';
  this.div.style.height = height + 'px';
  this.div.style.maxHeight = height + 'px';
  this.div.style.overflowY = 'show';
  this.div.style.position = "absolute";
  this.div.style.top = y +'px';
  this.div.style.left = x + 'px';

  if (nbPopUpTopClass==null)
    topClass = 'nbPopupTop '+ prefix +'_nbPopupTop';
  else
    topClass = nbPopUpTopClass +' '+ prefix +'_'+ nbPopUpTopClass;

  var m = '<TABLE cellspacing=0 width=100% ><TR id="'+ prefix +'_bar" class="'+ topClass +'"><TD width=99% valign=bottom><SPAN id="'+ prefix +'_top"></span></td>\
      <TD id='+ prefix +'_X align=right valign=middle onmouseover="this.style.cursor=\'pointer\'" style="color:#fff; background:#333; font-weight:bold; font-size:14px; padding:0px 5px; -moz-border-radius-topright: 20px;">x</td></tr>\
      </table><TABLE cellspacing=0 width=100% ><TR><TD height=100% valign=top class="nbPopMain '+ prefix +'_nbPopMain" colspan=2 id="'+ prefix +'_main"></td></tr></table>';
  document.body.appendChild(this.div);
  this.div.innerHTML = m;
  document.getElementById(prefix+'_X').addEventListener ('click', e_XClose, false);
  this.dragger = new CWinDrag (document.getElementById(prefix+'_bar'), this.div, enableDrag);

  this.div.addEventListener ('mousedown', e_divClicked, false);
  WinManager.add(prefix, this);

  function e_divClicked (){
    t.focusMe();
  }
  function e_XClose (){
    t.show(false);
    if (t.onClose != null)
      t.onClose();
  }
  function autoHeight (onoff){
    if (onoff)
      t.div.style.height = '';
    else
      t.div.style.height = t.div.style.maxHeight;
  }
  function focusMe (){
    t.setLayer(5);
    for (k in unsafeWindow.cpopupWins){
      if (k != t.prefix)
        unsafeWindow.cpopupWins[k].unfocusMe();
    }
  }
  function unfocusMe (){
    t.setLayer(-5);
  }
  function getLocation (){
    return {x: parseInt(this.div.style.left), y: parseInt(this.div.style.top)};
  }
  function setLocation (loc){
    t.div.style.left = loc.x +'px';
    t.div.style.top = loc.y +'px';
  }
  function destroy (){
    document.body.removeChild(t.div);
    WinManager.delete (t.prefix);
  }
  function centerMe (parent){
    if (parent == null){
      var coords = getClientCoords(document.body);
    } else
      var coords = getClientCoords(parent);
    var x = ((coords.width - parseInt(t.div.style.width)) / 2) + coords.x;
    var y = ((coords.height - parseInt(t.div.style.height)) / 2) + coords.y;
    if (x<0)
      x = 0;
    if (y<0)
      y = 0;
    t.div.style.left = x +'px';
    t.div.style.top = y +'px';
  }
  function setEnableDrag (tf){
    t.dragger.setEnable(tf);
  }
  function setLayer(zi){
    t.div.style.zIndex = ''+ (this.BASE_ZINDEX + zi);
  }
  function getLayer(){
    return parseInt(t.div.style.zIndex) - this.BASE_ZINDEX;
  }
  function getTopDiv(){
    return document.getElementById(this.prefix+'_top');
  }
  function getMainDiv(){
    return document.getElementById(this.prefix+'_main');
  }
  function getMainTopDiv(){
      return document.getElementById(this.prefix+'_top');
  }
  function isShown (){
    return t.div.style.display == 'block';
  }
  function show(tf){
    if (tf){
      t.div.style.display = 'block';
      t.focusMe ();
    } else {
      t.div.style.display = 'none';
    }
    return tf;
  }
  function toggleHide(t){
    if (t.div.style.display == 'block') {
      return t.show (false);
    } else {
      return t.show (true);
    }
  }
}

function CWinDrag (clickableElement, movingDiv, enabled) {
  var t=this;
  this.setEnable = setEnable;
  this.setBoundRect = setBoundRect;
  this.debug = debug;
  this.dispEvent = dispEvent;
  this.lastX = null;
  this.lastY = null;
  this.enabled = true;
  this.moving = false;
  this.theDiv = movingDiv;
  this.body = document.body;
  this.ce = clickableElement;
  this.moveHandler = new CeventMove(this).handler;
  this.outHandler = new CeventOut(this).handler;
  this.upHandler = new CeventUp(this).handler;
  this.downHandler = new CeventDown(this).handler;
  this.clickableRect = null;
  this.boundRect = null;
  this.bounds = null;
  this.enabled = false;
  if (enabled == null)
    enabled = true;
  this.setEnable (enabled);

  function setBoundRect (b){    // this rect (client coords) will not go outside of current body
    this.boundRect = boundRect;
    this.bounds = null;
  }

  function setEnable (enable){
    if (enable == t.enabled)
      return;
    if (enable){
      clickableElement.addEventListener('mousedown',  t.downHandler, false);
      t.body.addEventListener('mouseup', t.upHandler, false);
    } else {
      clickableElement.removeEventListener('mousedown', t.downHandler, false);
      t.body.removeEventListener('mouseup', t.upHandler, false);
    }
    t.enabled = enable;
  }

  function CeventDown (that){
    this.handler = handler;
    var t = that;
    function handler (me){
      if (t.bounds == null){
        t.clickableRect = getClientCoords(clickableElement);
        t.bodyRect = getClientCoords(document.body);
        if (t.boundRect == null)
          t.boundRect = t.clickableRect;
        t.bounds = {top:10-t.clickableRect.height, bot:t.bodyRect.height-25, left:40-t.clickableRect.width, right:t.bodyRect.width-25};
      }
      if (me.button==0 && t.enabled){
        t.body.addEventListener('mousemove', t.moveHandler, true);
        t.body.addEventListener('mouseout', t.outHandler, true);
        t.lastX = me.clientX;
        t.lastY = me.clientY;
        t.moving = true;
      }
    }
  }

  function CeventUp  (that){
    this.handler = handler;
    var t = that;
    function handler (me){
      if (me.button==0 && t.moving)
        _doneMoving(t);
    }
  }

  function _doneMoving (t){
    t.body.removeEventListener('mousemove', t.moveHandler, true);
    t.body.removeEventListener('mouseout', t.outHandler, true);
    t.moving = false;
  }

  function CeventOut  (that){
    this.handler = handler;
    var t = that;
    function handler (me){
      if (me.button==0){
        t.moveHandler (me);
      }
    }
  }

  function CeventMove (that){
    this.handler = handler;
    var t = that;
    function handler (me){
      if (t.enabled && !t.wentOut){
        var newTop = parseInt(t.theDiv.style.top) + me.clientY - t.lastY;
        var newLeft = parseInt(t.theDiv.style.left) + me.clientX - t.lastX;
        if (newTop < t.bounds.top){     // if out-of-bounds...
          newTop = t.bounds.top;
          _doneMoving(t);
        } else if (newLeft < t.bounds.left){
          newLeft = t.bounds.left;
          _doneMoving(t);
        } else if (newLeft > t.bounds.right){
          newLeft = t.bounds.right;
          _doneMoving(t);
        } else if (newTop > t.bounds.bot){
          newTop = t.bounds.bot;
          _doneMoving(t);
        }
        t.theDiv.style.top = newTop + 'px';
        t.theDiv.style.left = newLeft + 'px';
        t.lastX = me.clientX;
        t.lastY = me.clientY;
      }
    }
  }

  function debug  (msg, e){
    logit ("*************** "+ msg +" ****************");
    logit ('clientWidth, Height: '+ e.clientWidth +','+ e.clientHeight);
    logit ('offsetLeft, Top, Width, Height (parent): '+ e.offsetLeft +','+ e.offsetTop +','+ e.offsetWidth +','+ e.offsetHeight +' ('+ e.offsetParent +')');
    logit ('scrollLeft, Top, Width, Height: '+ e.scrollLeft +','+ e.scrollTop +','+ e.scrollWidth +','+ e.scrollHeight);
  }

  function dispEvent (msg, me){
    logit (msg + ' Button:'+ me.button +' Screen:'+ me.screenX +','+ me.screenY +' client:'+  me.clientX +','+ me.clientY +' rTarget: '+ me.relatedTarget);
  }
}

Array.prototype.compare = function(testArr) {
    if (this.length != testArr.length) return false;
    for (var i = 0; i < testArr.length; i++) {
        if (this[i].compare) {
            if (!this[i].compare(testArr[i])) return false;
        }
        if (this[i] !== testArr[i]) return false;
    }
    return true;
}
String.prototype.StripQuotes = function() {
    return this.replace(/"/g,'');
}

String.prototype.entityTrans = { '&':'&amp;', '<':'&lt;',  '>':'&gt;',  '\"':'&quot;', '\'':'&#039', '<':'\\u003c', '/':'\\/', '\\':'\\\\', '\"':'\\\"','{':'&#123;','}':'&#125;'};
String.prototype.htmlSpecialChars = function() {
  var ret = this.toString();
  for (k in this.entityTrans)
     ret  = ret.split(k).join(this.entityTrans[k]);
  return ret;
}
String.prototype.htmlSpecialCharsDecode = function() {
  var ret = this.toString();
  for (k in this.entityTrans)
     ret = ret.split(this.entityTrans[k]).join(k);
  return ret;
}
String.prototype.trim = function () {
    return this.replace(/^\s*/, "").replace(/\s*$/, "");
}
String.prototype.escape_space = function(){
    var s = this.split(" ");
    for(var i=0; i<s.length; i++)
        s[i] = escape(s[i]);
    //return s.join(" ");
    return this.replace(/</ig,"&#60;");
}
String.prototype.unescape_space = function(){
    var s = this.split(" ");
    for(var i=0; i<s.length; i++)
        s[i] = unescape(s[i]);
    //return s.join(" ");
    return this;
}

function matTypeof (v){
  if (typeof (v) == 'object'){
    if (!v)
      return 'null';
//    else if (unsafeWindow.Object.prototype.toString.apply(v) === '[object Array]')
    else if (v.constructor.toString().indexOf("Array")>=0 && typeof(v.splice)=='function')
      return 'array';
    else return 'object';
  }
  return typeof (v);
}

function unixTime (){
  return parseInt (new Date().getTime() / 1000) + unsafeWindow.g_timeoff;
}

/**********************
 part       full
 Xd Xh Xm   Xd Xh Xm Xs
 Xh Xm      Xh Xm Xs
 Xm Xs      Xm Xs
 Xs         Xs
**********************/
function timestr(time, full) {
  time = parseInt (time);
  var m = [];
  var t = time;
  if (t < 61)
    return  t + 's';
  if (t > 86400){
    m.push (parseInt(t/86400));
    m.push ('d ');
    t %= 86400;
  }
  if (t>3600 || time>3600){
    m.push (parseInt(t/3600));
    m.push ('h ');
    t %= 3600;
  }
  m.push (parseInt(t/60));
  m.push ('m');
  if (full || time<=3600 ){
    m.push (' ');
    m.push (t%60);
    m.push ('s');
  }
  return m.join ('');
}

nbStartup ();