Recipe Counter

Counts known recipes and tracks missing recipes in your crafting discovery pages in Kingdom of Loathing.

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name           Recipe Counter
// @namespace      kol.interface.unfinished
// @description    Counts known recipes and tracks missing recipes in your crafting discovery pages in Kingdom of Loathing.
// @include        https://*kingdomofloathing.com/craft.php*
// @include        https://*.kingdomofloathing.com/account.php
// @include        http://kol.coldfront.net/thekolwiki/index.php/Cocktailcrafting_Discoveries*
// @include        http://kol.coldfront.net/thekolwiki/index.php/Cooking_Discoveries*
// @include        http://kol.coldfront.net/thekolwiki/index.php/Meat-Pasting_Discoveries*
// @include        http://kol.coldfront.net/thekolwiki/index.php/Meatsmithing_Discoveries*
// @include        http://kol.coldfront.net/thekolwiki/index.php/Miscellaneous_Discoveries*
// @version        3.989
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_xmlhttpRequest
// ==/UserScript==

//Version 3.989
// - Murderbots
//Version 3.988
// - Robortender
//Version 3.987
// - more eldritch essentials
//Version 3.986
// - eldritch essentials
//Version 3.985
// - fix thanksgetting
//Version 3.984
// - thanksgetting
//Version 3.983
// - change to data uri for images used
//Version 3.982
// - fix overzealous use of https
//Version 3.981
// - change to https
//Version 3.98
// - spurious smithing, gunpasting, hi-yo silver
//Version 3.97
// - patent medicines
//Version 3.96
// - perfect cocktails
//Version 3.95
// - guncraft
//Version 3.94
// - heavy metallurgy
//Version 3.93
// - velvetry
//Version 3.92
// - retro-electrical
//Version 3.91
// - add baking, and retire jewelry, moving recipes to meat-pasting
//Version 3.90
// - cool winery
//Version 3.89
// - add Crimbo stuff
//Version 3.88
// - add Post-Apocalyptica
//Version 3.87
// - add @grant, switch GM_log to console.log, remove auto-update
//Version 3.86
// - spookyraven stuff, crash-site stuff, June/2014 familiar stuff
//Version 3.85
// - sugar cubans
//Version 3.84
// - spring break beach stuff
//Version 3.83
// - V11 stuff
//Version 3.82
// - added lynrd stuff
//Version 3.81
// - add Sugar Scale Structures to miscellaneous
//Version 3.80
// - add Smiths-ing to cocktails, cooking, meatpasting, meatsmithing
// - add Weapons: Swords to meatpasting, Loathsome Smithery to meatsmithing
//Version 3.79
// - added tin-kering to miscellaneous
//Version 3.78
// - added cluster stuff to miscellanous, cooking, cocktails
//Version 3.77
// - added Aquatic Jewelry
// - added Sea Leatherworking
//Version 3.76
// - added Cosmic Potions to miscellaneous
// - added Papier-Mache to cooking
//Version 3.75
// - added Oil Rigging to miscellaneous
//Version 3.74
// - added 'tonstruction and Wax Wear to miscellaneous
//Version 3.73
// - added Papier Mache to miscellaneous
//Version 3.72
// - added Hot Daubery to miscellaneous
//Version 3.71
// - added category Confectionery to meatsmithing and cocktailcrafting
// - added Peppermints to meatpasting and miscellaneous
//Version 3.70
// - added category Confectionery to cooking
//Version 3.69
// - added categories: Confectionery to jewelry and meat-pasting, 
//   and Festive Crimbo Cocktails to cocktailcrafting.
//Version 3.68
// - added sticky paper and rough stuff category to meatpasting discoveries
//Version 3.674
// - fix suddenly re-broken Humpy Dumplings
//Version 3.673
// - added honey stuff
//Version 3.672
// - added knob cake
//Version 3.671
// - more Amazing Ideas
//Version 3.67
// - added new recipe sections from April 2011 IOTM
//Version 3.665
// - fix https/http issue in auto-update
//Version 3.66
// - fix weirdness with vial of jus de larmes, due to it's italicization
// - update shared account-menu tab code
//Version 3.65
// - incorporate Charon the Hand's code for a shared account menu tab
//Version 3.64
// - fix account menu so it works with the new account menu update
//Version 3.63
// - added an account menu entry to update recipe lists manually.
//Version 3.62
// - more robust when an auto-check fails or is incomplete
//Version 3.61
// - added Paperclip Paraphernalia
//Version 3.6
// - improved new discovery detection, based on md5 sums of the wiki table
//   text rather than last edit date of the page.
//Version 3.5
// - fix to work around kol's fuzzy matching system which would sometimes
//   cause the script to wrongly report info in the mouse-over text and
//   miscolour the item text after clicking on a missing recipe.
//Version 3.4
// - now checks and lets you know if wiki discovery pages (list of recipes)
//   has been updated so you can revisit it to refresh the recipes list.
//Version 3.3
// - sped up missing ingredient checking considerably and
//   it also retrieves the item counts, but only if you have
//   (ever) enabled chat (you do not need to be in chat).
//   Slower route is used when chat commands cannot be used.
//Version 3.2
// - added auto-update checking
//Version 3.1.1
// - updated Cooking recipe sections with Popsicles.
//Version 3.1
// - added ability to check inventory for ingredients of missing recipes.
//   Click on the item name and it looks through through your inventory, changing
//   the colour the item to either gray or black depending on whether you have
//   all the ingredients.  Mouseover text shows which ingredient is missing if
//   just one.
//Version 3.0.1
// - added Smoked Pottery to miscellaneous
//Version 3.0
// - added crafting links for missing recipes, which take you to the appropriate 
//   crafting page, with the selection boxes filled if you have the items.
// - script state is now persistent, with counts and any displayed missing recipes
//   not disappearing if you actually craft something.  
// - The "show missing" button is now a toggle instead of a one-time button, and
//   so can be applied by default as you switch discovery pages.
//Version 2.0
// - added gathering and display of missing recipes
//Version 1.3
// - add sub-counts for sections
//Version 1.2
// - add miscellaneous discoveries
//Version 1.1

// current page title if at a kol discoveries page
var knownPage='';

var pageLinks={'Meat-Pasting Discoveries:':'craft.php?mode=combine',
               'Cocktailcrafting Discoveries:':'craft.php?mode=cocktail',
               'Meatsmithing Discoveries:':'craft.php?mode=smith',
               'Cooking Discoveries:':'craft.php?mode=cook',
               'Miscellaneous Discoveries:':'craft.php?mode=discoveries'};

function doPage() {
    // find table root of area interested in
    var node,root;
    var listing = document.getElementsByTagName('b');
    for (var i=0;i<listing.length;i++) {
        var node = listing[i];
        if (node.firstChild && pageLinks[node.firstChild.data]) {
            root = node.parentNode;
            knownPage = node.firstChild.data; // ugh
            while (root && root.tagName!='TABLE')
                root = root.parentNode;
            break;
        }
    }
    if (root) {
        GM_setValue('missinga','');
        GM_setValue('missingb','');
        // count
        var count = document.evaluate('.//img[contains(@onclick,"descitem")]',root,null,
                                    XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null).snapshotLength;
        node.firstChild.data = node.firstChild.data.substr(0,node.firstChild.data.length-1)+
            ' ('+count+' known):';
        addButton(node);
        addSubcounts(root);
        if (GM_getValue('showmissing',''))
            showMissing();
    } else {
        // direct crafting page?
        var a = document.getElementById('a');
        var b = document.getElementById('b');
        if (a && b) {
            var ma = GM_getValue('missinga');
            var mb = GM_getValue('missingb');
            if (ma) {
                selectOption(a,ma);
                selectOption(b,mb);
                GM_setValue('missinga','');
                GM_setValue('missingb','');
            }
        }
    }
}

function selectOption(sbox,txt) {
    for (var i=0;i<sbox.options.length;i++) {
        if (sbox.options[i].text.indexOf(txt)==0 &&
            sbox.options[i].text.replace(/\s*\([0-9]+\)\s*/,'')==txt) {
            sbox.selectedIndex = i;
            return;
        }
    }
}

function addButton(node) {
    var v = document.createElement('a');
    v.setAttribute('href','#');
    v.setAttribute('id','showmissingbutton');
    v.setAttribute('style','font-size:x-small;color:white;vertical-align:middle;');
    fixupButton(v);
    v.addEventListener('click',bHandler,false);
    var p = knownPage.replace(/:.*$/,'').replace(/ /g,'_');
    v.setAttribute('discoveries_page',p);
    node.parentNode.appendChild(document.createTextNode('\u00a0\u00a0\u00a0'));
    node.parentNode.appendChild(v);

    if (GM_getValue(p+'_oldmd5',0)!=GM_getValue(p+'_newmd5',-1)) {
        node.parentNode.appendChild(document.createTextNode('\u00a0\u00a0\u00a0'));
        v = document.createElement('a');
        v.setAttribute('href','http://kol.coldfront.net/thekolwiki/index.php/'+p);
        v.setAttribute('style','font-size:x-small;color:yellow;vertical-align:middle;');
        v.setAttribute('title','Updated discoveries list detected!');
        v.setAttribute('id','recipecountdisoveriesnotice');
        v.setAttribute('target','_blank');
        v.appendChild(document.createTextNode('Click to update discoveries list'));
        node.parentNode.appendChild(v);
    } else {
        v = document.getElementById('recipecountdiscoveriesnotice');
        if (v) {
            v.parentNode.removeChild(v);
        }
    }
}

function fixupButton(v) {
    if (GM_getValue('showmissing','')) {
        v.setAttribute('title','Click to hide all missing recipes on this page.');
        if (v.firstChild)
            v.replaceChild(document.createTextNode('[Hide Missing]'),v.firstChild);
        else
            v.appendChild(document.createTextNode('[Hide Missing]'));
    } else {
        v.setAttribute('title','Click to display all missing recipes on this page.');
        if (v.firstChild)
            v.replaceChild(document.createTextNode('[Show Missing]'),v.firstChild);
        else
            v.appendChild(document.createTextNode('[Show Missing]'));
    }
}

function showMissing() {
    var v = document.getElementById('showmissingbutton');
    if (GM_getValue('showmissing','')) {
        if (!missing()) {
            var page = v.getAttribute('discoveries_page');
            var pages = page.replace(/_/g,' ');
            var goWiki = document.createElement('a');
            goWiki.setAttribute('title','Click to go to the full list of '+pages+' recipes on the KoL wiki.');
            goWiki.setAttribute('target','_blank');
            goWiki.setAttribute('style','font-size:x-small;color:white;vertical-align:middle;');
            goWiki.setAttribute('href','http://kol.coldfront.net/thekolwiki/index.php/'+page);
            goWiki.appendChild(document.createTextNode('[Load all '+pages+']'));
            v.parentNode.appendChild(goWiki);
        }
    } else {
        var xx = document.getElementsByClassName('showmissingaddition');
        for (var i=xx.length-1;i>=0;i--) {
            var x = xx[i];
            x.parentNode.removeChild(x);
        }
    }
    fixupButton(v);
}

function bHandler(e) {
    var b = GM_getValue('showmissing','');
    GM_setValue('showmissing', (b ? '' : 'true'));
    showMissing();
}

function addSubcounts(root) {
    var tbls = document.evaluate( './/table', root, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
    for (var i=tbls.snapshotLength-1;i>=0;i--) {
        var tbl = tbls.snapshotItem(i);
        var id = tbl.getAttribute('id');
        if (id && id.indexOf('table_')==0) {
            // found one

            var count=0;
            var listing = tbl.getElementsByTagName('img');
            for (var j=0;j<listing.length;j++) {
                var imgnode = listing[j];
                var click;
                if (click=imgnode.getAttribute('onclick')) {
                    if (click.indexOf('descitem')==0) {
                        count++;
                    }
                }
            }

            // count the images
            if (tbl.previousSibling) {
                var hdr = tbl.previousSibling.previousSibling;
                if (hdr && hdr.tagName=='CENTER' && hdr.firstChild) {
                    var f = document.createElement('font');
                    f.setAttribute('style','font-size:x-small;');
                    f.appendChild(document.createTextNode('  ('+count+' recipe'+((count==1)? '' : 's')+')'));
                    hdr.firstChild.appendChild(f);
                }
            }
        }
    }
}

var rlists = [{title:'Cocktailcrafting Discoveries',
               sections:['Amazing Ideas','Confectionery','Clustercocktails','Cool Winery','Distillations','Eldritch Essentials','Evil Fruity Girl Drinks',
                         'Eww','Extra-Fruity Girl Drinks',
                         'Fancy Garnishes','Festive Crimbo Cocktails','Fruity Girl Drinks','Hilarious Jokes','Infused Wines',
                         'Miscellaneous','Miscellaneous Boozery','Mushroom Wines','Perfect Cocktails','Post-Apocalyptica', 'Premium Cocktails','Schnapps',
                         'Robortender Recipes','Simple Cocktails','Smiths-ing','Specialty Beers','Tiny Plastic Sword Drinks',
                         'Underwater Cocktails']},
              {title:'Cooking Discoveries',
               sections:['Advanced Sauceror Potions','Amazing Ideas','Baking','Brownies','Casseroles','Clusterbaking','Confectionery',
                         'Confections','Dirty Exploits','Eldritch Essentials','Evil Noodle Dishes','Evil Sauceror Potions','Familiar',
                         'High-Pressure Potions','Kabobs','Key Limes','Miscellaneous','Miscellaneous Cookery', 'Miscellaneous Potions',
                         'Nemesis Quest Slimes','Noodle Dishes','Papier-Mache','Patent Medicines','Pies','Pizzas','Popsicles','Pork Gem Potions','Post-Apocalyptica',
                         'Quest Items','Sauceror Potions','Secret Sauces','Smiths-ing','Space Foods','Stir-Fries','Tempura','Tex-Mex',
                         'Tex-Mex-Italian','Thanksgarden Creations','Transmutations']},
              {title:'Meat-Pasting Discoveries',
               sections:['Amazing Ideas','Aquatic Jewelry','Campground Items','Clusterbombs','Confectionery','Decoys','Elemental Jewelry','Expensive Pork Elf Jewelry',
                         'Familiars','Gear','Genetic Engineering','Guncraft','Gunpasting','Hi-Yo Silver','Hilarious Jokes','Horrifying Jewelry','Miscellaneous',
                         'Miscellaneous Jewelry','Murderbot Technology','Parts','Parts for Campground Items',
                         'Parts for Familiars','Peppermints','Pork Elf Jewelry','Post-Apocalyptica','Primordial Soup','Quest Items','Rainbow Pearl Jewelry','Retro-Electrical','Rough Stuff',
                         'Smiths-ing','Spacetime Bending','Usable Items','Vampire Pearl Jewelry','Weapons: Swords']},
              {title:'Meatsmithing Discoveries',
               sections:['Armor: Accessories','Armor: Advanced Accessories','Armor: Advanced Hats',
                         'Armor: Advanced Pants','Armor: Advanced Shields', 'Armor: Advanced Shirts', 'Armor: Hats',
                         'Armor: Pants','Armor: Shields','Armor: Shirts','Campground Items', 'Confectionery','Depleted Grimacite', 'Gear','Ghast Irony',
                         'Ingredients','Loathsome Smithery','Miscellaneous Smithery','Post-Apocalyptica','Quest Weapons','Sea Leatherworking','Slimy Things',
                         'Smiths-ing','Spacetime Bending','Spurious Smithing','Weapons: Advanced Crossbows',
                         'Weapons: Advanced Staves','Weapons: Advanced Swords','Weapons: Clubs',
                         'Weapons: Crossbows','Weapons: Miscellaneous','Weapons: Staves',
                         'Weapons: Swords','Weapons: Utensils','Weapons: Whips']},
              {title:'Miscellaneous Discoveries',
               sections:["'tonstruction",'BRICKO Beasts','BRICKO Bits','Balloon Bendings','Clingfilm Creations',
                         'Cold Comforts','Cosmic Potions','Duct Tape Designs','Eldritch Essentials','Heavy Metallurgy','Honey Stuff','Hot Daubery','Mummy Wrapping Manufacturings',
                         'Oil Rigging','Palm-Frond Preparations','Paperclip Paraphernalia','Papier-Mache','Peppermints','Plaiddery','Smoked Pottery',
                         'Snailmail Structures','Spacetime Bending','Spooky Bark Surprises','Sugar Cubans','Sugar Scale Structures','Tin-kering',
                         'Turtlemail Treasures','Velvetry','Wax Wear','Wumpus Hair Weavings']}];

// locate all missing recipes
function missing() {
    var s = knownPage;
    //console.log('knownPage='+s);
    if (!s) {
        return;
    }
    for (var i=0;i<rlists.length;i++) {
        if (s.indexOf(rlists[i].title)>=0) {
            var r = missingInPage(retrieveCopy(rlists[i].title));
            if (!r)
                return false;
            insertMissing(r);
            return true;
        }
    }
}

// set by missingInPage and used by insertMissing
var secMap = {};

// uses the secMap and the given list of missing recipes to create fake versions
function insertMissing(r) {
    for (var s in r) {
        var tbl = secMap[s];
        var lastr = null;
        if (tbl && tbl.rows.length>0 && tbl.rows[tbl.rows.length-1].cells.length<3) {
            lastr = tbl.rows[tbl.rows.length-1];
        }
        for (var e in r[s]) {
            if (r[s][e]) {
                for (var j=0;j<r[s][e].length;j++) {
                    if (lastr) {
                        createMissing(lastr,e,r[s][e][j]);
                        lastr = null;
                    } else {
                        // TBD: what if tbl is null?
                        if (!tbl) {
                            if (secMap['last_table']) {
                                tbl = insertMissingTable(secMap['last_table'].nextSibling,s);
                            } else {
                                var root = document.evaluate( '//td[contains(text(),"You haven\'t made any discoveries in this field yet")]/text()', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE,null);
                                tbl = insertMissingTable(root.singleNodeValue.nextSibling,s);
                            }
                            secMap[s] = tbl;
                        }
                        lastr = tbl.insertRow(-1);
                        lastr.setAttribute('class','showmissingaddition');
                        createMissing(lastr,e,r[s][e][j]);
                    }
//                  console.log('missing in '+s+': '+e+' = '+r[s][e][j]);
                }
            }
        }
    }
    
}

// creates a table for a section s
function insertMissingTable(root,s) {
    var c = document.createElement('center');
    var tbl = document.createElement('table');
    var b = document.createElement('b');
    var br1 = document.createElement('br');
    var br2 = document.createElement('br');
    c.setAttribute('class','showmissingaddition');
    tbl.setAttribute('class','showmissingaddition');
    br1.setAttribute('class','showmissingaddition');
    br2.setAttribute('class','showmissingaddition');
    b.innerHTML = s;
    b.setAttribute('style','color:red;');
    c.appendChild(b);
    root.parentNode.insertBefore(br1,root);
    root.parentNode.insertBefore(c,root);
    root.parentNode.insertBefore(br2,root);
    root.parentNode.insertBefore(tbl,root);
    return tbl;
}


// locate missing recipes in the current kol discoveries page, given a list of recipes
function missingInPage(r) {
    if (!r) {
        alert('You need to visit the KoL Wiki discoveries pages (http://kol.coldfront.net/thekolwiki/index.php/Discoveries) to initialize the recipe list.  Visit each of the 6 pages of Recipes on the wiki, then re-open a recipe page in the game and try again.');
        return;
    }
    secMap = {};
    var tbls = document.evaluate( '//table', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
    for (var i=0;i<tbls.snapshotLength;i++) {
        var tbl = tbls.snapshotItem(i);
        var id = (tbl) ? tbl.getAttribute('id') : null;
        if (id && id.indexOf('table_')==0) {
            // found one
            // figure out which section this represents
            var sec = tbl.previousSibling;
            while (sec && sec.tagName!='CENTER')
                sec = sec.previousSibling;
            if (sec) {
                sec = sec.firstChild.firstChild.innerHTML;
            }
            var es = document.evaluate( './/td', tbl, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
            for (var j=0;j<es.snapshotLength;j+=2) {
                var e = es.snapshotItem(j);
                var f = es.snapshotItem(j+1);
                var item = (f.firstChild.firstChild.nodeType==3) ? f.firstChild.firstChild.data : f.firstChild.firstChild.innerHTML;
                if (!item) continue;
                var itemr = f.firstChild.nextSibling;
                if (itemr.tagName!='FONT') itemr = itemr.nextSibling;
                var components = '';
                for (var k=0;k<itemr.childNodes.length;k++) {
                    if (itemr.childNodes[k].nodeType==3) {
                        components += itemr.childNodes[k].data;
                    } else if (itemr.childNodes[k].tagName=='I') {
                        components += '<i>'+itemr.childNodes[k].innerHTML+'</i>';
                    }
                }
                components = components.replace(/\([0-9]+\)/g,'').replace(/\+[\s]*$/,'').replace(/  /g,' ').replace(/\s\s+/,' ').replace(/ *$/,'').replace(/^ */,'');
                
                // check that we have a section
                if (sec) {
                    if (r && r[sec] && r[sec][item]) {
                        var hi = hasRecipe(r[sec][item],components);
                        if (hi>=0) {
                            r[sec][item].splice(hi,1);
                        }
                    }
                } else if (r) {
                    for (var s in r) {
                        if (r[s][item]) {
                            var hi = hasRecipe(r[s][item],components);
                            if (hi>=0) {
                                r[s][item].splice(hi,1);
                                sec = s;
                                break;
                            }
                        }
                    }
                }
            }
            secMap[sec] = tbl; // store for later
            secMap['last_table'] = tbl;
        }
    }
    return r;
}

// check the given list for a recipe combination, and return the index or -1
function hasRecipe(clist,c) {
    if (!clist)
        return -1;
    var c2 = c.match(/(^[^+]*)\+(.*$)/);
    if (c2) {
        c2 = c2[2] +' + '+c2[1];
        c2 = c2.replace(/\+[\s]*$/,'').replace(/  /g,' ').replace(/ *$/,'').replace(/^ */,'');
    }
    for (var i=0;i<clist.length;i++) {
        if (clist[i] == c || (c2 && clist[i] == c2)) {
            return i;
        }
    }
    return -1;
}

// creates a new entry for a missing title+components, and
// attaches the resulting td's to the given tr
function createMissing(tr,title,components) {
    var td1 = tr.insertCell(-1);
    var td2 = tr.insertCell(-1);
    td1.setAttribute('class','showmissingaddition');
    td2.setAttribute('class','showmissingaddition');
    td1.setAttribute('valign','center');
    td2.setAttribute('valign','top');
    var i = document.createElement('img');
    i.setAttribute('class','hand');
    i.setAttribute('src','data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAABEklEQVRIie2WyxHDMAhE0xR10Q6NUAK1UALHzYl8haXIljOZyR5laR6flfAFX9LlJ8DuDhGBiMDMzgGLCIjoBiYiMPNacGb6ukZEcPd1YACIiO+AH5WlVtVmgMwMZm5+nwZnpqr6VgUAMLMnH1QmLMFmBmZuHnztdyURKQ3YBGe5VBVE1Mysp4go21GC82BloK1AIuLpulV7S3BlIGbeLHUGKyKbAZbgyhiVqVJmNnTNyh6v6u0meO/jMBJwWepeSdPxI9l9BO7J3eHuYGYQ0W09H5BlYOCe9aMJM5gpsLt3+5Qmmp3LTfDorF0ynXqZpPMPzXhUp8/j1Cx0N3iPpsGqOvVwHAIe/SE4FLxXf/BpugJUkH7bCBPJ3QAAAABJRU5ErkJggg==');
    td1.appendChild(i);
    var b = document.createElement('b');
    b.setAttribute('style','color:red;');
    b.innerHTML = title;
    td2.appendChild(b);
    var f = document.createElement('font');
    f.setAttribute('size','1');
    f.setAttribute('color','red');

    if (knownPage!='Miscellaneous Discoveries:') {
        var f2 = document.createElement('font');
        f2.setAttribute('size','2');
        f2.setAttribute('color','red');
        var ia = document.createElement('a');
        ia.appendChild(document.createTextNode('make?'));
        ia.setAttribute('title','Click to go the crafting page for this missing recipe');
        ia.setAttribute('href','#');
        ia.setAttribute('missinga',components.replace(/\s*\+.*/,''));
        ia.setAttribute('missingb',((components.indexOf('+')>0) ? components.replace(/[^+]*\+\s*/,'') : ''));
        ia.addEventListener('click',missingButtonHandler,false);
        f2.appendChild(document.createTextNode('\u00A0['));
        f2.appendChild(ia);
        f2.appendChild(document.createTextNode(']'));
        f.appendChild(f2);

        b.setAttribute('missinga',components.replace(/\s*\+.*/,''));
        b.setAttribute('missingb',((components.indexOf('+')>0) ? components.replace(/[^+]*\+\s*/,'') : ''));
        b.setAttribute('title','click to check for ingredients');
        b.addEventListener('click',checkIngredientsHandler,false);
    }
    f.appendChild(document.createElement('br'));
    f.appendChild(document.createTextNode(components));
    td2.appendChild(f);
}

function missingButtonHandler() {
    GM_setValue('missinga',this.getAttribute('missinga').replace(/<[^>]+>/g,''));
    GM_setValue('missingb',this.getAttribute('missingb').replace(/<[^>]+>/g,''));
    window.location.href = pageLinks[knownPage];
}

// return a new copy of the master recipes 
function retrieveCopy(page) {
    var r = JSON.parse(GM_getValue('recipes','{}'));
    return r[page];
}

// scrape data from a kol wiki page
function gather(m5) {
    var recipes = JSON.parse(GM_getValue('recipes','{}'));

    var s = window.location.pathname.replace(/_/g,' ');
    //console.log('Gathering...'+s);
    for (var i=0;i<rlists.length;i++) {
        if (s.indexOf(rlists[i].title)>=0) {
            gatherRecipes(rlists[i],recipes);
            var p = rlists[i].title.replace(/:.*$/,'').replace(/ /g,'_');
            GM_setValue(p+'_oldmd5',m5);
            GM_setValue(p+'_newmd5',m5);
        }
    }
    GM_setValue('recipes',JSON.stringify(recipes));
}

// scrape data from a specific kol wiki page
function gatherRecipes(rlist,recipes) {
    var s = {};
    for (var i=0;i<rlist.sections.length;i++) {
        var r = gatherRecipesSection(rlist.sections[i]);
        s[rlist.sections[i]] = r;
        
    }
    recipes[rlist.title] = s;
    // var p = rlist.title.replace(/:.*$/,'').replace(/ /g,'_')+'_last';
    // GM_setValue(p,(new Date()).toUTCString());
    //console.log('setting '+p+' to '+GM_getValue(p));
}

// scrapte data for the given section of a kol wiki page
function gatherRecipesSection(section) {
    var r = {};
    var sec = document.evaluate( '//span[@class="mw-headline"]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
    //var sec = document.evaluate( '//span[text()="'+section+'"]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
//  console.log('gathering for section '+section);
    var rx = new RegExp('','');
    for (var j=0;j<sec.snapshotLength;j++) {
        var sn = sec.snapshotItem(j).innerHTML;
        if (sn.replace(/^ */,'').replace(/ *$/,'')==section) {
            var hp = sec.snapshotItem(j).parentNode;
            if (hp && hp.tagName=='H2') {
                hp = hp.nextSibling.nextSibling;
                while (hp && hp.tagName!='H2') {
                    var i;
                    var tbls = document.evaluate( './/td', hp, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
                    for (i=0;i<tbls.snapshotLength-1;i+=2) {
                        var e = tbls.snapshotItem(i);
                        
                        var f = tbls.snapshotItem(i+1);
                        var n = f.firstChild.firstChild.innerHTML;
                        var c = '';
                        for (var k=0;k<f.firstChild.nextSibling.nextSibling.childNodes.length;k++) {
                            var s = f.firstChild.nextSibling.nextSibling.childNodes[k];
                            if (s.innerHTML)
                                c += s.innerHTML;
                            else if (s.nodeType==3)
                                c += s.data;
                            else if (c)
                                c += ' + ';
                        }
                        c = c.replace(/\+[\s]*$/,'').replace(/  /g,' ').replace(/ *$/,'').replace(/^ */,'');
                        if (c) {
//                          console.log('found recipe for '+n+', consisting of: '+c);
                            if (r[n]) r[n][r[n].length] = c;
                            else r[n] = [c];
                        }
                    }
                    if (i>0) 
                        return r;
                    hp = hp.nextSibling;
                }
            }
        }
    }
    return r;
}

// called when the confused image is clicked on.
function checkIngredientsHandler(e) {
    this.removeEventListener('click',checkIngredientsHandler,false);
    checkIngredientsFast(this,this.getAttribute('missinga'),this.getAttribute('missingb'));
}

// utility function, stolen from other scripts
function GM_get(dest, callback)
{   GM_xmlhttpRequest({
      method: 'GET',
      url: dest,
        //onerror:function(error) { console.log("GM_get Error: " + error); },
        onload:function(details) {
            if( typeof(callback)=='function' ){
                callback(details.responseText);
}   }   }); }

// if chat not enabled use the slow route
function checkIngredientsSlow(item,ing1,ing2) {
    //item.setAttribute('style','color:pink;');
    //item.setAttribute('title','checking...');
    var r1b = false;
    var r2b = false;
    GM_get('http://'+window.location.host+'/inventory.php?which=1',function(response){
        if(response!=''){
            var r1 = new RegExp('<b[^>]*>'+ing1+'</b>','gm');
            var r2 = new RegExp('<b[^>]*>'+ing2+'</b>','gm');
            if (!r1b) r1b = r1.test(response);
            if (!r2b) r2b = r2.test(response);
            if (r1b && r2b) {
                item.setAttribute('style','color:black;');
                item.addEventListener('click',checkIngredientsHandler,false);
                item.setAttribute('title','Ingredients found in inventory at last check.  Click to check again.');
            } else {
                GM_get('http://'+window.location.host+'/inventory.php?which=2',function(response){
                        if(response!=''){
                            if (!r1b) r1b = r1.test(response);
                            if (!r2b) r2b = r2.test(response);
                            if (r1b && r2b) {
                                item.setAttribute('style','color:black;');
                                item.addEventListener('click',checkIngredientsHandler,false);
                                item.setAttribute('title','Ingredients found in inventory at last check.  Click to check again.');
                            } else {
                                GM_get('http://'+window.location.host+'/inventory.php?which=3',function(response){
                                        if(response!=''){
                                            if (!r1b) r1b = r1.test(response);
                                            if (!r2b) r2b = r2.test(response);
                                            if (r1b && r2b) {
                                                item.setAttribute('style','color:black;');
                                                item.setAttribute('title','Ingredients found in inventory at last check.  Click to check again.');
                                            } else {
                                                item.setAttribute('style','color:gray;');
                                                if (r1b) 
                                                    item.setAttribute('title','Ingredient '+ing2+' not found in inventory. Click to check again.');
                                                else if (r2b) 
                                                    item.setAttribute('title','Ingredient '+ing1+' not found in inventory. Click to check again.');
                                                else 
                                                    item.setAttribute('title','Ingredients not found in inventory. Click to check again.');
                                            }
                                            item.addEventListener('click',checkIngredientsHandler,false);
                                        }});
                            }
                        }});
            }
        }});
}

// faster checking but requires chat is enabled
function checkIngredientsFast(item,ing1,ing2) {
    item.setAttribute('style','color:pink;');
    item.setAttribute('title','checking...');
    if (ing1.match(/<[^>]+>/) || ing2.match(/<[^>]+>/))
        return checkIngredientsSlow(item,ing1,ing2);
    var pd = findPwdhash();
    if (!pd) {
        console.log('cound not find pwd or playerid');
        return;
    }
    //console.log('pwd='+pd.pwd);
    //console.log('pid='+pd.pid);
    GM_get('http://'+window.location.host+'/submitnewchat.php?playerid='+pd.pid+'&pwd='+pd.pwd+'&graf=/count '+encodeURI(ing1),
           function(response) {
               if(response!='') {
                   //console.log('response: '+response);
                   var r1 = response.match(/(<[^>]*>)*You have ([0-9]*) ([^<]*)\./);
                   GM_get('http://'+window.location.host+'/submitnewchat.php?playerid='+pd.pid+'&pwd='+pd.pwd+'&graf=/count '+encodeURI(ing2),
                          function(response) {
                              if(response!='') {
                                  var r2 = response.match(/(<[^>]*>)*You have ([0-9]*) ([^<]*)\./);
                                  if (r1 && r2) {
                                      verifyItems(item,ing1,ing2,pd,r1,r2);
                                  } else {
                                      setItemState(item,r1,r2,ing1,ing2);
                                  }
                              }});
               } else {
                   checkIngredientsSlow(item,ing1,ing2);
               }});
}

function setItemState(item,r1,r2,ing1,ing2) {
    if (r1 && r2) {
        item.setAttribute('style','color:black;');
        item.setAttribute('title','Found '+r1[2]+' '+r1[3]+' and '+r2[2]+' '+r2[3]+' at last check.  Click to check again.');
    } else {
        item.setAttribute('style','color:gray;');
        if (r1) 
            item.setAttribute('title','Found '+r1[2]+' '+r1[3]+' but no '+ing2+' in your inventory. Click to check again.');
        else if (r2) 
            item.setAttribute('title','Found '+r2[2]+' '+r2[3]+' but no '+ing1+' in your inventory. Click to check again.');
        else 
            item.setAttribute('title','Neither ingredient is in your inventory. Click to check again.');
    }
    item.addEventListener('click',checkIngredientsHandler,false);
}

function verifyItems(item,ing1,ing2,pd,r1,r2) {
    GM_get('http://'+window.location.host+'/submitnewchat.php?playerid='+pd.pid+'&pwd='+pd.pwd+'&graf=/examine '+encodeURI(ing1),
           function(response) {
               var r3 = response.match(/^<[^>]*>Examining: ([^<]*)/);
               if (r3) r3 = (r3[1]==ing1) ? r3 : null;
               GM_get('http://'+window.location.host+'/submitnewchat.php?playerid='+pd.pid+'&pwd='+pd.pwd+'&graf=/examine '+encodeURI(ing2),
                      function(response) {
                          var r4 = response.match(/^<[^>]*>Examining: ([^<]*)/);
                          if (r4) r4 = (r4[1]==ing2) ? r4 : null;
                          setItemState(item,(r3) ? r1 : null,(r4) ? r2 : null,ing1,ing2);
                      });
           });
}

function checkDiscoveries() {
    for (p in pageLinks) {
        var purl = p.replace(/:.*$/,'').replace(/ /g,'_');
        GM_xmlhttpRequest({
                method: 'GET',
                    url: 'http://kol.coldfront.net/thekolwiki/index.php/'+purl,
                    onload: function(details) {
                    var q = this.url.replace(/[^/]*\//g,'');
                    if (details.responseText) {
                        var mdf = getPageMD5(details.responseText);
                        //console.log('new md5 for '+q+': '+mdf);
                        GM_setValue(q+'_newmd5',mdf);
                    } 
                }
            });
    }
}

function getPageMD5(raw) {
    var text = '';
    var j,i = raw.indexOf('<table>');
    while(raw && i>=0) {
        raw = raw.substr(i+7);
        j = raw.indexOf('</table>');
        if (j<0)
            break; // bad parse?
        text = text + raw.substr(0,j);
        raw = raw.substr(j);
        i = raw.indexOf('<table>');
    }
    text = text.replace(/<[^>]*>/g,'');
    text = text.replace(/[\s\n]+/g,'');
    var m = MD5(text);
    //console.log('md5 of '+text);
    return m;
}

function findPwdhash() {
    var somef=window.parent.frames;
    var goo = null;
    for(var j=0;j<somef.length;j++) {
        if (somef[j].name=="charpane") {
            goo=somef[j];
            var page = goo.document.documentElement.innerHTML;
            var pwdh = page.match(/pwdhash\s*=\s*\"([a-f0-9]+)\"/);
            if (pwdh) {
                var plid = page.match(/playerid\s*=\s*([a-f0-9]+)/);
                if (plid) {
                    return {pwd:pwdh[1],pid:plid[1]};
                }
            }
        }
    }
}


/**
*
*  MD5 (Message-Digest Algorithm)
*  http://www.webtoolkit.info/
*
**/
 
var MD5 = function (string) {
 
    function RotateLeft(lValue, iShiftBits) {
        return (lValue<<iShiftBits) | (lValue>>>(32-iShiftBits));
    }
 
    function AddUnsigned(lX,lY) {
        var lX4,lY4,lX8,lY8,lResult;
        lX8 = (lX & 0x80000000);
        lY8 = (lY & 0x80000000);
        lX4 = (lX & 0x40000000);
        lY4 = (lY & 0x40000000);
        lResult = (lX & 0x3FFFFFFF)+(lY & 0x3FFFFFFF);
        if (lX4 & lY4) {
            return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
        }
        if (lX4 | lY4) {
            if (lResult & 0x40000000) {
                return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
            } else {
                return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
            }
        } else {
            return (lResult ^ lX8 ^ lY8);
        }
    }
 
    function F(x,y,z) { return (x & y) | ((~x) & z); }
    function G(x,y,z) { return (x & z) | (y & (~z)); }
    function H(x,y,z) { return (x ^ y ^ z); }
    function I(x,y,z) { return (y ^ (x | (~z))); }
 
    function FF(a,b,c,d,x,s,ac) {
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
        return AddUnsigned(RotateLeft(a, s), b);
    };
 
    function GG(a,b,c,d,x,s,ac) {
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
        return AddUnsigned(RotateLeft(a, s), b);
    };
 
    function HH(a,b,c,d,x,s,ac) {
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
        return AddUnsigned(RotateLeft(a, s), b);
    };
 
    function II(a,b,c,d,x,s,ac) {
        a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
        return AddUnsigned(RotateLeft(a, s), b);
    };
 
    function ConvertToWordArray(string) {
        var lWordCount;
        var lMessageLength = string.length;
        var lNumberOfWords_temp1=lMessageLength + 8;
        var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64;
        var lNumberOfWords = (lNumberOfWords_temp2+1)*16;
        var lWordArray=Array(lNumberOfWords-1);
        var lBytePosition = 0;
        var lByteCount = 0;
        while ( lByteCount < lMessageLength ) {
            lWordCount = (lByteCount-(lByteCount % 4))/4;
            lBytePosition = (lByteCount % 4)*8;
            lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount)<<lBytePosition));
            lByteCount++;
        }
        lWordCount = (lByteCount-(lByteCount % 4))/4;
        lBytePosition = (lByteCount % 4)*8;
        lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80<<lBytePosition);
        lWordArray[lNumberOfWords-2] = lMessageLength<<3;
        lWordArray[lNumberOfWords-1] = lMessageLength>>>29;
        return lWordArray;
    };
 
    function WordToHex(lValue) {
        var WordToHexValue="",WordToHexValue_temp="",lByte,lCount;
        for (lCount = 0;lCount<=3;lCount++) {
            lByte = (lValue>>>(lCount*8)) & 255;
            WordToHexValue_temp = "0" + lByte.toString(16);
            WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2);
        }
        return WordToHexValue;
    };
 
    function Utf8Encode(string) {
        string = string.replace(/\r\n/g,"\n");
        var utftext = "";
 
        for (var n = 0; n < string.length; n++) {
 
            var c = string.charCodeAt(n);
 
            if (c < 128) {
                utftext += String.fromCharCode(c);
            }
            else if((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            }
            else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }
 
        }
 
        return utftext;
    };
 
    var x=Array();
    var k,AA,BB,CC,DD,a,b,c,d;
    var S11=7, S12=12, S13=17, S14=22;
    var S21=5, S22=9 , S23=14, S24=20;
    var S31=4, S32=11, S33=16, S34=23;
    var S41=6, S42=10, S43=15, S44=21;
 
    string = Utf8Encode(string);
 
    x = ConvertToWordArray(string);
 
    a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;
 
    for (k=0;k<x.length;k+=16) {
        AA=a; BB=b; CC=c; DD=d;
        a=FF(a,b,c,d,x[k+0], S11,0xD76AA478);
        d=FF(d,a,b,c,x[k+1], S12,0xE8C7B756);
        c=FF(c,d,a,b,x[k+2], S13,0x242070DB);
        b=FF(b,c,d,a,x[k+3], S14,0xC1BDCEEE);
        a=FF(a,b,c,d,x[k+4], S11,0xF57C0FAF);
        d=FF(d,a,b,c,x[k+5], S12,0x4787C62A);
        c=FF(c,d,a,b,x[k+6], S13,0xA8304613);
        b=FF(b,c,d,a,x[k+7], S14,0xFD469501);
        a=FF(a,b,c,d,x[k+8], S11,0x698098D8);
        d=FF(d,a,b,c,x[k+9], S12,0x8B44F7AF);
        c=FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);
        b=FF(b,c,d,a,x[k+11],S14,0x895CD7BE);
        a=FF(a,b,c,d,x[k+12],S11,0x6B901122);
        d=FF(d,a,b,c,x[k+13],S12,0xFD987193);
        c=FF(c,d,a,b,x[k+14],S13,0xA679438E);
        b=FF(b,c,d,a,x[k+15],S14,0x49B40821);
        a=GG(a,b,c,d,x[k+1], S21,0xF61E2562);
        d=GG(d,a,b,c,x[k+6], S22,0xC040B340);
        c=GG(c,d,a,b,x[k+11],S23,0x265E5A51);
        b=GG(b,c,d,a,x[k+0], S24,0xE9B6C7AA);
        a=GG(a,b,c,d,x[k+5], S21,0xD62F105D);
        d=GG(d,a,b,c,x[k+10],S22,0x2441453);
        c=GG(c,d,a,b,x[k+15],S23,0xD8A1E681);
        b=GG(b,c,d,a,x[k+4], S24,0xE7D3FBC8);
        a=GG(a,b,c,d,x[k+9], S21,0x21E1CDE6);
        d=GG(d,a,b,c,x[k+14],S22,0xC33707D6);
        c=GG(c,d,a,b,x[k+3], S23,0xF4D50D87);
        b=GG(b,c,d,a,x[k+8], S24,0x455A14ED);
        a=GG(a,b,c,d,x[k+13],S21,0xA9E3E905);
        d=GG(d,a,b,c,x[k+2], S22,0xFCEFA3F8);
        c=GG(c,d,a,b,x[k+7], S23,0x676F02D9);
        b=GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);
        a=HH(a,b,c,d,x[k+5], S31,0xFFFA3942);
        d=HH(d,a,b,c,x[k+8], S32,0x8771F681);
        c=HH(c,d,a,b,x[k+11],S33,0x6D9D6122);
        b=HH(b,c,d,a,x[k+14],S34,0xFDE5380C);
        a=HH(a,b,c,d,x[k+1], S31,0xA4BEEA44);
        d=HH(d,a,b,c,x[k+4], S32,0x4BDECFA9);
        c=HH(c,d,a,b,x[k+7], S33,0xF6BB4B60);
        b=HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);
        a=HH(a,b,c,d,x[k+13],S31,0x289B7EC6);
        d=HH(d,a,b,c,x[k+0], S32,0xEAA127FA);
        c=HH(c,d,a,b,x[k+3], S33,0xD4EF3085);
        b=HH(b,c,d,a,x[k+6], S34,0x4881D05);
        a=HH(a,b,c,d,x[k+9], S31,0xD9D4D039);
        d=HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);
        c=HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);
        b=HH(b,c,d,a,x[k+2], S34,0xC4AC5665);
        a=II(a,b,c,d,x[k+0], S41,0xF4292244);
        d=II(d,a,b,c,x[k+7], S42,0x432AFF97);
        c=II(c,d,a,b,x[k+14],S43,0xAB9423A7);
        b=II(b,c,d,a,x[k+5], S44,0xFC93A039);
        a=II(a,b,c,d,x[k+12],S41,0x655B59C3);
        d=II(d,a,b,c,x[k+3], S42,0x8F0CCC92);
        c=II(c,d,a,b,x[k+10],S43,0xFFEFF47D);
        b=II(b,c,d,a,x[k+1], S44,0x85845DD1);
        a=II(a,b,c,d,x[k+8], S41,0x6FA87E4F);
        d=II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);
        c=II(c,d,a,b,x[k+6], S43,0xA3014314);
        b=II(b,c,d,a,x[k+13],S44,0x4E0811A1);
        a=II(a,b,c,d,x[k+4], S41,0xF7537E82);
        d=II(d,a,b,c,x[k+11],S42,0xBD3AF235);
        c=II(c,d,a,b,x[k+2], S43,0x2AD7D2BB);
        b=II(b,c,d,a,x[k+9], S44,0xEB86D391);
        a=AddUnsigned(a,AA);
        b=AddUnsigned(b,BB);
        c=AddUnsigned(c,CC);
        d=AddUnsigned(d,DD);
    }
 
    var temp = WordToHex(a)+WordToHex(b)+WordToHex(c)+WordToHex(d);
 
    return temp.toLowerCase();
}

// --------------------------------------------
// ---------- account menu option -------------
// --------------------------------------------


// Charon's code
function buildPrefs() {
    if (!document.querySelector('#privacy'))
        return;
    if (!document.querySelector('#scripts')) {
        //scripts tab is not built, do it here
        var scripts = document.querySelector('ul').appendChild(document.createElement('li'));
        scripts.id = 'scripts';
        var a = scripts.appendChild(document.createElement('a'));
        a.href = '#';
        var img = a.appendChild(document.createElement('img'));
        img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAACOElEQVRIibWXu9HsIAyFCQkpgCbUiFpRO2qFBiiAAkgVEjo8N7gjxvZi7/P3jGZfhs96HbEBH1y9dxARiAilFPTeMcZ4a4/wCZSZkVKCiICZQURg5r8Dt9YQY0QIASGEt2Efg5l5Qt1U9W/B27Yh54wQAnLOM9wxxrfz+xa41oqcM1QVtVZs2wZVnfkVEdRafws2M4jINFWFmYGZp+f+2lr7DdjMZusQEcYY6L1DVQ8e+30i8huwt0wpBTlnpJRmjpl5fkdECCG8HO6n4FLKbCERQe/94Z7WGkRktti2bd+DVRUpJZRSlhv23iEiyDkfCu0rsFdyjHEWkKoeFCvGiBjjhKkqYoxP+/sSrKrIOUNEZtF4OB3MzLPQiGhGZ69sV2Ffgkspc7GHkIhQa0UI4dDD/j6EgJTSAe5FaGbPwWOMqVBnc8l0jx3mv6nqUlZXOX8A+9OvNNnz6q3jHnlPr9a5nb0+gPd6vDdXJM/x2XLOMw376XU3TA5gM7sMMYDp6Qp89dBXI/QAvgqX5+gODOAyIk/BrbXbMD0D77vhbER0X1yrzR185VFKCWZ2C77N8eqp9yp0V7mttbn2XGArIbkUkPPk2bYNInJQpjNYRJbQlwRkde3FfwVOKU1ddxgz347Il8DMjBjjHBir4tqr2k/GYu/9Abb6HGN8qNyPwWZ2mdO76v3aY5fBO/PRue/Xrw8CZjbDSkTLHKeUDlHxI/BXYOB/a7mouDf+R83MMMaYk8sr/5UD/j/2nAi155cMxQAAAABJRU5ErkJggg==';
        img.align = 'absmiddle';
        img.border = '0';
        img.style.paddingRight = '10px';
        a.appendChild(document.createTextNode('Scripts'));
        a.addEventListener('click', function (e) {
                //make our new tab active when clicked, clear out the #guts div and add our settings to it
                e.stopPropagation();
                document.querySelector('.active').className = '';
                document.querySelector('#scripts').className = 'active';
                document.querySelector('#guts').innerHTML = '<div class="scaffold"></div>';
                document.querySelector('#guts').appendChild(getSettings());
            }, false);
    } else {
        //script tab already exists
         document.querySelector('#scripts').firstChild.addEventListener('click', function (e) {
                //some other script is doing the activation work, just add our settings
                e.stopPropagation();
                document.querySelector('#guts').appendChild(getSettings());
            }, false);
    }
}

function getSettings() {
    //build our settings and return them for appending
    var contents = document.createElement('div');
    contents.id = 'recipecounterprefs';
    var fieldset = contents.appendChild(document.createElement('fieldset'));
    fieldset.setAttribute('style', 'width:33%; margin-top:20px');
    var legend = fieldset.appendChild(document.createElement('legend'));
    legend.className = 'subhead';
    legend.textContent = 'Recipe Counter';
    var section = fieldset.appendChild(document.createElement('div'));
    section.className = 'indent';
    section.appendChild(buildSettings());
    return contents;
}

function buildSettings() {
    //var ul = document.createElement('ul');
    //var li = document.createElement('li');
    var ar = document.createElement('a');
    ar.setAttribute('href','#');
    ar.appendChild(document.createTextNode('Update all recipe lists'));
    ar.addEventListener('click',openAll,false);
    ar.setAttribute('title','Note that this opens up 6 new windows.');
    //li.appendChild(ar);
    //ul.appendChild(li);
    return ar;
}

function openAll() {
    window.open('http://kol.coldfront.net/thekolwiki/index.php/Cocktailcrafting_Discoveries','Cocktailcrafting Discoveries');
    window.open('http://kol.coldfront.net/thekolwiki/index.php/Cooking_Discoveries','Cooking Discoveries');
    window.open('http://kol.coldfront.net/thekolwiki/index.php/Meat-Pasting_Discoveries','Meat-Pasting Discoveries');
    window.open('http://kol.coldfront.net/thekolwiki/index.php/Meatsmithing_Discoveries','Meatsmithing Discoveries');
    window.open('http://kol.coldfront.net/thekolwiki/index.php/Miscellaneous_Discoveries','Miscellaneous Discoveries');
}

if (window.location.href.indexOf('http://kol.coldfront.net/thekolwiki/index.php/')>=0) {    
    gather(getPageMD5(document.body.innerHTML));
} else if (window.location.pathname.indexOf('/account.php')==0) {
    buildPrefs();
} else {
    checkDiscoveries();
    doPage();
}