Greasy Fork 还支持 简体中文。

JR Mturk Panda Crazy

My own Panda master for mturk with zing and queue smart

As of 04.05.2016. See ბოლო ვერსია.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name        JR Mturk Panda Crazy
// @version     0.1.4
// @description My own Panda master for mturk with zing and queue smart
// @include     http*://www.allbyjohn.com/mturk/pandacrazy.html
// @include     http*://www.mturk.com/mturk/welcome?pandacrazy=on*
// @require     http://code.jquery.com/jquery-2.1.4.min.js
// @require     http://code.jquery.com/ui/1.11.4/jquery-ui.min.js
// @require     https://cdnjs.cloudflare.com/ajax/libs/jquery-layout/1.3.0-rc-30.79/jquery.layout.min.js
// @resource    jQueryUICSS          http://code.jquery.com/ui/1.11.4/themes/pepper-grinder/jquery-ui.css
// @resource    jQueryLayoutCSS      https://cdnjs.cloudflare.com/ajax/libs/jquery-layout/1.3.0-rc-30.79/layout-default.css
// @connect     allbyjohn.com
// @connect     mturk.com
// @connect     tiny.cc
// @connect     ibotta.com
// @connect     *
// @grant       GM_getValue
// @grant       GM_setValue
// @grant       GM_deleteValue
// @grant       GM_addStyle
// @grant 		GM_xmlhttpRequest 
// @grant       GM_getResourceText
// @grant       GM_setClipboard
// @namespace   https://greasyfork.org/users/6406
// ==/UserScript==

var gDatabaseVersion = "JRAPR16-1.1-1.1.1"; // JR[Date]-[requesters DB Reset].[Alarms DB reset]-[requesters DB Version].[Options DB Version].[Tabs DB Version]
var gResetDBVersion = gDatabaseVersion.split("-")[1];
var gDefaultDBVersion = gDatabaseVersion.split("-")[2];
var gDelayedSave = false;
var gScriptStatus = "normal";
var gNotification = true;
var gMyLayout = null, gAcceptedLogTab = null, gStatusLogTab = null, mCoinSound = [];
var gMainData = {"hitCollection":{},"displayInfo":"1",
                 "accepted":0,"skipped":0,"errors":0,"searched":0,"noHits":0,"fullQueue":0,"orphan":0,"tooFast":0,
                 "hitsInQueue":0,"queueStatus":null,"notQual":0,"lastElapsed":0,"jobs":0,"payCounter":0};
var gMainMenu = [{"name":"Main","theobject":null}];
var gDefaultRequestersOptions = {};
var gDefaultLayout = {};
var gDefaultSounds = {};
var gHitBgColor="#AFEEEE", gFilteredHitBgColor="#D1E5E5", gSearchesHitBgColor="#AED2D2", gButtonOffBgColor="#FFFFF0", gButtonOnBgColor="#008000"; 
var gButtonDelayHamBgColor="#00A3CC", gButtonDisabledBgColor="#D3D3D3", gHitMutedColor="#8B4513";
var gTitleColor="#000080", gButtonOffColor="black", gButtonOnColor="white", gButtonDisabledColor="#808080";
var gHitMutedBorderStyle="dotted", gHitBorderStyle="solid";
var gZingOptions = {
    "0.01":{"SearchGroupAllowed":1,"TallyCountTotalAllowed":0,"MaxProductsSearch":0,"AcceptCodesSearching":false,"MaxReceiptImages":3},
    "0.03":{"SearchGroupAllowed":2,"TallyCountTotalAllowed":0,"MaxProductsSearch":2,"AcceptCodesSearching":true,"MaxReceiptImages":3},
    "0.05":{"SearchGroupAllowed":3,"TallyCountTotalAllowed":0,"MaxProductsSearch":4,"AcceptCodesSearching":true,"MaxReceiptImages":4},
    "0.07":{"SearchGroupAllowed":7,"TallyCountTotalAllowed":0,"MaxProductsSearch":5,"AcceptCodesSearching":true,"MaxReceiptImages":8}
};
var gZingFuncOptions = {
    "1":{"filterName":"Parse Zing Hit Page","functionName":parseZingHitPage}
};
var gAlarmSounds = {
    "less2":{"nameVar":"JR_PANDA_Soundless2","default":"http://tiny.cc/c6c1ay","audio":null,"desc":"Hits paying less than $0.02: "},
    "less2Short":{"nameVar":"JR_PANDA_Soundless2Short","default":"http://tiny.cc/kyh1ay","audio":null,"desc":"Hits paying less than $0.02 with a short timer: "},
    "less5":{"nameVar":"JR_PANDA_Soundless5","default":"http://tiny.cc/g7h1ay","audio":null,"desc":"Hits paying less than $0.05: "},
    "less5Short":{"nameVar":"JR_PANDA_Soundless5Short","default":"http://tiny.cc/99h1ay","audio":null,"desc":"Hits paying less than $0.05 with a short timer: "},
    "less15":{"nameVar":"JR_PANDA_Soundless15","default":"http://tiny.cc/qai1ay","audio":null,"desc":"Hits paying less than $0.15: "},
    "less15Short":{"nameVar":"JR_PANDA_Soundless15Short","default":"http://tiny.cc/uai1ay","audio":null,"desc":"Hits paying less than $0.15 with a short timer: "},
    "less99":{"nameVar":"JR_PANDA_Soundless99","default":"http://tiny.cc/gbi1ay","audio":null,"desc":"Hits paying MORE than $0.15: "},
};
var gSoundFile = null;
var gTabIndex = 0;
var gMouseDownTimeoutId = null;
var gPressAndHold = false;
var gGroupings = {};
var gGroupingsSort = [];
var gGroupingData = {"JR First":{"theNumber":"0","description":"First grouping by default.","grouping":[],"delayed":[]}};
var gTabsData = [];
var gDefaultTabsData = [{"tabName":"Main","tabNumber":"1","positions":null},{"tabName":"Daily Hits","tabNumber":"2","positions":null},{"tabName":"Rare Hits","tabNumber":"3","positions":null}];
var gMainOptions = {};
var gDefaultMainOptions = {"cycleNumber":970,"HamCycleNumber":700,"autoSlowDown":true,"cycleAutoIncrease":5,"alarmVolume":80,cycleIncrease:5,cycleDecrease:5,cycleAdding:650,queueTimer:60000,hamDelayTimer:0};
var gRequestersData = {};
var gDefaultRequestersData = { 
    "0":{"requesterName":gDatabaseVersion,"requesterId":28,"action":"","groupId":"","pay":"","qual":"","title":"","queueLimit":0,"duration":"0","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":"0","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":0},
    "4":{"requesterName":"Zing","requesterId":"AGVV5AWLJY7H2","action":"Panda","groupId":"30B721SJLR5BYYBNQJ0CVKJESN00OC","pay":"0.01","qual":"ibotta","title":"Are these the same?","queueLimit":15,"duration":"0","audioforce":"less2","dailyLimit":0,"mute":false,"position":null,"tabNumber":"2","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":0},
    "5":{"requesterName":"Zing","requesterId":"AGVV5AWLJY7H2","action":"Panda","groupId":"30B721SJLR5BYYBNQJ0CVKJEQOZ0OB","pay":"0.01","qual":"","title":"Are these the same?","queueLimit":15,"duration":"0","audioforce":"less2","dailyLimit":0,"mute":false,"position":null,"tabNumber":"2","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":0},
    "6":{"requesterName":"Zing","requesterId":"AGVV5AWLJY7H2","action":"Panda","groupId":"3ZXRRTK2NDCB5NW5M24C9P2OWG41OF","pay":"0.01","qual":"ibotta","title":"Does this receipt contain the following products?","queueLimit":4,"duration":"0","audioforce":"less2","dailyLimit":0,"mute":false,"position":null,"tabNumber":"2","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":0},
    "7":{"requesterName":"Zing","requesterId":"AGVV5AWLJY7H2","action":"Panda","groupId":"3NYGPW9OTYRQLJTE9DQJQJRQJ2IZPS","pay":"0.01","qual":"","title":"Does this receipt contain the following products?","queueLimit":4,"duration":"0","audioforce":"less2","dailyLimit":0,"mute":false,"position":null,"tabNumber":"2","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":0},
    "8":{"requesterName":"Zing","requesterId":"AGVV5AWLJY7H2","action":"Panda","groupId":"3R35RPFD7JUTQN8612HRYP7E6LZ1PV","pay":"0.03","qual":"ibotta","title":"Does this receipt contain the following products?","queueLimit":6,"duration":"0","audioforce":"less2","dailyLimit":0,"mute":false,"position":null,"tabNumber":"2","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":0},
    "9":{"requesterName":"Zing","requesterId":"AGVV5AWLJY7H2","action":"Panda","groupId":"3ZXRRTK2NDCB5NW5M24C9P2OVF61OE","pay":"0.03","qual":"","title":"Does this receipt contain the following products?","queueLimit":6,"duration":"0","audioforce":"less2","dailyLimit":0,"mute":false,"position":null,"tabNumber":"2","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":0},
    "10":{"requesterName":"Zing","requesterId":"AGVV5AWLJY7H2","action":"Panda","groupId":"3CRC4NO2BIQQWQ3GX0HLFPTFOD30SA","pay":"0.05","qual":"ibotta","title":"Does this receipt contain the following products?","queueLimit":12,"duration":"60 minutes","audioforce":"less2","dailyLimit":0,"mute":false,"position":null,"tabNumber":"2","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":0},
    "11":{"requesterName":"Zing","requesterId":"AGVV5AWLJY7H2","action":"Panda","groupId":"3787DLY3Y49RIF1DIJQB3Z8BUNP1T2","pay":"0.05","qual":"","title":"Does this receipt contain the following products?","queueLimit":12,"duration":"0","audioforce":"less2","dailyLimit":0,"mute":false,"position":null,"tabNumber":"2","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":0},
    "13":{"requesterName":"Viral Mturk","requesterId":"A2UFLDVZ75JD9M","action":"Panda","groupId":"3ZXEP6UEGGA75UPGRQ2UPK3XA4YO8B","pay":"0.25","qual":"","title":"Rate the quality of ads on YouTube","queueLimit":0,"duration":"0","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":"0","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":0},
    "14":{"requesterName":"MyLikes","requesterId":"A239M0XNXTKQZ7","action":"Panda","groupId":"3EGCY5R6XY0PS57S4R2H1KZW7LSAYC","pay":"0.01","qual":"","title":"Identify Images with Mature Content","queueLimit":0,"duration":"0","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":"0","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":0},
    "15":{"requesterName":"MyLikes","requesterId":"A239M0XNXTKQZ7","action":"Panda","groupId":"3USMLONC9E5D7T4TWRD6UWVBJLN85E","pay":"0.03","qual":"","title":"Identify Images with Mature Content","queueLimit":0,"duration":"0","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":"0","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":0},
    "16":{"requesterName":"MyLikes","requesterId":"A239M0XNXTKQZ7","action":"Panda","groupId":"37G59K9AEU0BNMXNCLOH5POEZUC9YI","pay":"0.03","qual":"","title":"Identify Videos with Mature Content","queueLimit":0,"duration":"15 minutes","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":"0","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":0},
    "17":{"requesterName":"Steven Snow","requesterId":"A3GAVAUPTHM0B8","action":"Panda","groupId":"3X19M43Z4VULD73G1I2N3GGRYF10D8","pay":"0.06","qual":"","title":"steven snow search 3X..D8","queueLimit":0,"duration":"0","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":3,"once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":0},
    "18":{"requesterName":"Steven Snow","requesterId":"A3GAVAUPTHM0B8","action":"Panda","groupId":"3TJJ8HSJVIVGSMA3ZXVL0CV5EGV28D","pay":"0.05","qual":"","title":"steven snow url 3T..8D","queueLimit":0,"duration":"0","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":"3","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":0},
    "19":{"requesterName":"Venue Quality","requesterId":"A14AT838CPSKA6","action":"Panda","groupId":"3EM4DVSA8U8J6KF08Q5EM8I2NYE308","pay":"0.01","qual":"","title":"locations same","queueLimit":0,"duration":"0","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":"0","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":0},
    "20":{"requesterName":"Venue Quality","requesterId":"A14AT838CPSKA6","action":"Panda","groupId":"3D8O2NKTAGFJD90I499E0D26RON13W","pay":"0.01","qual":"","title":"locations adult","queueLimit":0,"duration":"5 minutes","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":"0","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":0},
    "21":{"requesterName":"Venue Quality","requesterId":"A14AT838CPSKA6","action":"Panda","groupId":"ZZAWVTYW3Z9ZTAX43ZD0","pay":"0.01","qual":"","title":"locations family","queueLimit":0,"duration":"0","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":"0","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":0},
    "22":{"requesterName":"Annabel","requesterId":"A3HB3KPJ2RZ2K8","action":"Panda","groupId":"3CVHT3IKTXQR8KSLQHD2N8KOQZPR06","pay":"0.50","qual":"","title":"Comparing two statements with each other","queueLimit":0,"duration":"60 minutes","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":"0","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":0},
    "23":{"requesterName":"Rob Grady","requesterId":"AM07BBZNC6UTQ","action":"Panda","groupId":"33X7UBO5WUFB78Y5WJ3MVC35LFMU05","pay":"0.03","qual":"","title":"Transcribe Waffle House Guest Check","queueLimit":0,"duration":"5 minutes","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":"0","once":false,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":0},
    "24":{"requesterName":"PredictWallStreet.com","requesterId":"A17T7LCJF0818V","action":"Search","groupId":"329HSLC9WDXX9F2DN54ARF87CMFHGG","pay":"0.80","qual":"","title":"Predict 100 Stocks - Up or Down?","queueLimit":0,"duration":"60 minutes","audioforce":"","dailyLimit":0,"mute":false,"position":null,"tabNumber":"0","once":true,"dailyDone":0,"day":0,"filterMode":0,"hamTimer":0}
};
var gExcludeIds = ["38FT9G80DL83PUCSQBVANJBIKGSLHM"];
var jqUI_CssSrc = GM_getResourceText("jQueryUICSS");
var jqLayout_CssSrc = GM_getResourceText("jQueryLayoutCSS");

Date.prototype.stdTimezoneOffset = function() {
    var jan = new Date(this.getFullYear(), 0, 1);
    var jul = new Date(this.getFullYear(), 6, 1);
    return Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset());
}

Date.prototype.dst = function() {
    return this.getTimezoneOffset() < this.stdTimezoneOffset();
}
function formatAMPM(theFormat,theDate,theTimeZone) {
    var d = (theDate) ? theDate : new Date();
    if (theTimeZone == "mturk") {
        var mturkTZOffset = -8;
        var today = new Date();
        if (today.dst()) mturkTZOffset++;
        var utc = d.getTime() + (d.getTimezoneOffset() * 60000);
        var MturkTime = utc + (3600000 * mturkTZOffset);
        d = new Date(MturkTime);
    }
    var minutes = d.getMinutes().toString().length == 1 ? '0'+d.getMinutes() : d.getMinutes(),
        hours = d.getHours().toString().length == 1 ? '0'+d.getHours() : d.getHours(),
        ampm = d.getHours() >= 12 ? 'pm' : 'am',
        months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
        days = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
    if (theFormat=="short") return ('0' + (d.getMonth()+1)).slice(-2) + '-' + ('0' + d.getDate()).slice(-2) + '-' + d.getFullYear() + '(' + hours + ':' + minutes + ampm + ')';
    else if (theFormat=="onlydate") return ('0' + (d.getMonth()+1)).slice(-2) + '-' + ('0' + d.getDate()).slice(-2) + '-' + d.getFullYear();
    else return days[d.getDay()]+' '+months[d.getMonth()]+' '+d.getDate()+' '+d.getFullYear()+' '+hours+':'+minutes+ampm;
}
function formatTimeZone(theFormat,theDate,theTimeZone) {
    return formatAMPM(theFormat,theDate,theTimeZone);
}
function checkNotifications() {
  // Let's check if the browser supports notifications
  if (!("Notification" in window)) return false;
  else if (Notification.permission === "granted") return true;
  else if (Notification.permission !== 'denied') {
    Notification.requestPermission(function (permission) {
      if (permission === "granted") return true;
    });
  }
  return false;
}
function showNotification( title, message, tag ) {
    var n = new Notification(title, {
        body: message,
        icon: "http://www.allbyjohn.com/mturk/Messaging-Online-icon.png",
        tag: tag});
    if (navigator.userAgent.search("Chrome") >= 0) n.onshow = function () { setTimeout(n.close.bind(n), 20000); }
}

// Database using setValue and getValue
function convertDatabase(theDataBase,resetDBVersion,defaultDBVersion) {
    var newDataBase = {};
    $.each(theDataBase, function( index, value ) {
        newDataBase[index] = value;
    });
    newDataBase[0].requesterName = gDatabaseVersion;
    return newDataBase;
}
function getBase64Audio(theData) {
    var base64AudioData = new Uint8Array(theData);
    var i = base64AudioData.length;
    var binaryString = new Array(i);
    while (i--) { binaryString[i] = String.fromCharCode(base64AudioData[i]); }
    var data = binaryString.join('');
    return(window.btoa(data));
}
function loadSoundFiles(soundNumber,keyArray,resetDBVersion) {
    if (soundNumber < keyArray.length) {
        if (gResetDBVersion.split(".")[1] > resetDBVersion.split(".")[1]) GM_deleteValue(gAlarmSounds[keyArray[soundNumber]].nameVar);
        console.log("JR reset version: " + resetDBVersion + " | new reset version: " + gResetDBVersion);
        var gotBase64 = GM_getValue(gAlarmSounds[keyArray[soundNumber]].nameVar,null);
        this.firstTime = this.firstTime || false;
        if (gotBase64 === null) {
            if (!this.firstTime) $("#JRWaitDialog").append(createDiv("For your first time this might take a few seconds.<br>Loading Alarms ").attr({"class":"alarmsLoad"}));
            this.firstTime = true;
            requestUrl(gAlarmSounds[keyArray[soundNumber]].default,0,function(theResult,theNumber,data1,data2) {
                $("#JRWaitDialog .alarmsLoad").append(createSpan(" ."));
                var base64 = getBase64Audio(theResult.response);
                GM_setValue(gAlarmSounds[keyArray[soundNumber]].nameVar,JSON.stringify(base64));
                gAlarmSounds[keyArray[soundNumber]].audio = new Audio("data:audio/wav;base64," + base64);
                loadSoundFiles(soundNumber+1,keyArray,resetDBVersion);
            },function() { errorRequest(); }, "", "", "arraybuffer");
        } else {
            gAlarmSounds[keyArray[soundNumber]].audio = new Audio("data:audio/wav;base64," + JSON.parse(gotBase64));
            loadSoundFiles(soundNumber+1,keyArray,resetDBVersion);
        }
    } else continueLoading();
}

function fillInGroupings() {
    $.each(gGroupingData, function( index, value ) {
        if (!value.grouping) value.grouping = [];
        gGroupings[index] = {"data":value,"collecting":false};
        gGroupingsSort.push(index);
    });
}
function loadSettings() {
    var tempData = JSON.parse(GM_getValue("JR_PANDA_RequestersData",JSON.stringify(gDefaultRequestersData)));
    var savedDBVersion = tempData[0].requesterName;
    var resetDBVersion = savedDBVersion.split("-")[1];
    var defaultDBVersion = savedDBVersion.split("-")[2];
    if (gResetDBVersion.split(".")[0] > resetDBVersion.split(".")[0]) {
        GM_deleteValue("JR_PANDA_RequestersData");
        tempData = JSON.parse(GM_getValue("JR_PANDA_RequestersData",JSON.stringify(gDefaultRequestersData)));
    }
    gRequestersData = convertDatabase(tempData,resetDBVersion,defaultDBVersion);
    GM_deleteValue("JR_PANDA_MainOptions");
    gMainOptions = JSON.parse(GM_getValue("JR_PANDA_MainOptions",JSON.stringify(gDefaultMainOptions)));
    gTabsData = JSON.parse(GM_getValue("JR_PANDA_TabsData",JSON.stringify(gDefaultTabsData)));
    //GM_deleteValue("JR_PANDA_GroupingData");
    gGroupingData = JSON.parse(GM_getValue("JR_PANDA_GroupingData",JSON.stringify(gGroupingData)));
    fillInGroupings();
    loadSoundFiles(0,Object.keys(gAlarmSounds),resetDBVersion);
}
function saveSettings(doAfter) {
    GM_setValue("JR_PANDA_RequestersData",JSON.stringify(gRequestersData));
    GM_setValue("JR_PANDA_MainOptions",JSON.stringify(gMainOptions));
    GM_setValue("JR_PANDA_TabsData",JSON.stringify(gTabsData));
    GM_setValue("JR_PANDA_GroupingData",JSON.stringify(gGroupingData));
    if (doAfter) setTimeout( function() { doAfter(); },200);
}
function checkDelayedSave() { if (gDelayedSave) saveSettings(); }

function toggleButton(thisButton,doThisOn,doThisOff,mode,modeStatus) {
    var theStatus = $(thisButton).data("status");
    var doStatus = (modeStatus) ? modeStatus : (theStatus != "on" && theStatus!=mode) ? "on" : "off";
    if (mode && theStatus!=mode) $(thisButton).data("status",mode);
    else $(thisButton).data("status",doStatus);
    if (doStatus=="on" && doThisOn) doThisOn($(thisButton).data("theNumber"),thisButton,mode);
    if (doStatus=="off" && doThisOff) doThisOff($(thisButton).data("theNumber"),thisButton,mode);
    updateHitColors($(thisButton).data("theNumber"),thisButton);
}
function toggleButtonOff(thisButton,doThisOn,doThisOff) {
    $(thisButton).data("status","off");
    updateHitColors($(thisButton).data("theNumber"),thisButton);
    if (doThisOff) doThisOff($(thisButton).data("theNumber"),thisButton);
}
function toggleButtonOn(thisButton,doThisOn,doThisOff) {
    $(thisButton).data("status","on");
    updateHitColors($(thisButton).data("theNumber"),thisButton);
    if (doThisOn) doThisOn($(thisButton).data("theNumber"),thisButton);
}
function checkButtonsStatus() {
    if (gScriptStatus == "normal") return true;
    else return false;
}
function createDiv(theHtml) { var inner = (theHtml) ? theHtml : ""; return $('<div>').html(inner); }
function createSpan(theHtml) { var inner = (theHtml) ? theHtml : ""; return $('<span>').html(inner); }
function createTextInput(theValue) { return $("<input>").attr({ "type": "text", "value": theValue }); }
function createCheckbox(theValue) { return $("<input>").attr({ "type": "checkbox", "value": theValue }); }
function createLink(theText,theUrl,theTarget,theTitle) { return $('<a>',{text: theText,target: theTarget,title: theTitle,href: theUrl}); }
function createSpanButton(toDo,theHtml,theBackgroundColor,theColor,theFontSize) {
    var backgroundColor = (theBackgroundColor) ? theBackgroundColor : "initial";
    var textColor = (theColor) ? theColor : "initial";
    var fontSize = (theFontSize) ? theFontSize : "9px";
    var theButton = createSpan(theHtml).data("status","off")
        .data("backgroundColor",backgroundColor)
        .data("textColor",textColor)
        .data("htmlText",theHtml)
        .disableSelection()
        .dblclick(function(e) { e.stopPropagation(); })
        .css({"font-size":fontSize,
            "padding":"0px 2px",
            "background-color":backgroundColor,
            "color":textColor,
            "border":"2px groove red",
            "cursor":"default",
            "margin":"0px 1px"});
    if (toDo) theButton.click( function(e) {
        if (checkButtonsStatus()) {toDo(e);}
    });
    return theButton;
}
function createContainer() {
    var containerDiv = createDiv();
    containerDiv.css({"padding-left":"3px", "padding-right":"3px","padding-top":"0px","padding-bottom":"1px"});
    return containerDiv;
}
function createPanels(goAppend) {
    var panelContainer = createContainer()
        .attr("id","panelContainer")
        .appendTo(goAppend);
    return panelContainer;
}
function createPanel(goAppend) {
    var panel = createContainer().appendTo(goAppend);
    return panel;
}
function createTabs(goAppend,isSortable,idName) {
    var tabList = $("<ul>");
    var tabsContainer = createContainer()
        .attr("id",idName)
        .css({"height":"99%"})
        .appendTo(goAppend);
    tabList.appendTo(tabsContainer);
    tabsContainer.tabs().delegate( "span.ui-icon-close", "click", function() {
      console.log("JR removing this tab");
      $("#JRMainTabs").tabs( "refresh" );
    });
    if (isSortable) tabList.sortable({placeholder:"sortable-placeholder",delay:300,"items":"li:not(.ui-not-sortable)",dropOnEmpty: true});
    return tabsContainer;
}
function createTab(tabContainer,theTitle,isSortable,theID,tabData,appendClose) {
    var theClasses = (!appendClose) ? "ui-not-sortable" : "";
    var theTabDiv = createContainer().attr("id","tabs-" + (++gTabIndex));
    var theTabLi = $("<li>").html("<a href='#tabs-" + gTabIndex + "'>" + theTitle + "</a>")
        .attr({"id":theID,"class":theClasses})
        .css({"font-size":"10px"})
        .data({"tabData":tabData})
        .appendTo( tabContainer.find("ul") );
    if (appendClose) theTabLi.append(createSpan("Remove Tab").attr({"class":"ui-icon ui-icon-close","role":"presentation"}));
    theTabDiv.data({"tabData":tabData}).appendTo(tabContainer);
    if (isSortable) {
        theTabLi.click( function() { $(this).focus(); $(this).find(".tabContents").focus(); })
            .droppable({
                tolerance: 'pointer',
                over: function( event, ui ) {
                    $("#JRMainTabs").tabs("option", "active", $(event.target).index());
                    $(event.target).focus(); $(event.target).find(".tabContents").focus();
                }
            });
        theTabDiv.html("<br clear='all' class='cleartab'></br>");
    }
    tabContainer.tabs("refresh");
    return theTabDiv;
}
function playThisSound( keyName ) {
    gAlarmSounds[keyName].audio.pause();
    gAlarmSounds[keyName].audio = gAlarmSounds[keyName].audio;
    gAlarmSounds[keyName].audio.currentTime = 0;
    gAlarmSounds[keyName].audio.volume = gMainOptions.alarmVolume/100;
    gAlarmSounds[keyName].audio.play();
}
function playNewSound( AudioObject ) {
    if (gSoundFile) gSoundFile.pause();
    gSoundFile = AudioObject;
    gSoundFile.currentTime = 0;
    gSoundFile.volume = gMainOptions.alarmVolume/100;
    gSoundFile.play();
}

var theCycler = (function() {
    var privateVars = {
        _timers: [],
        _theQueue: [],
        _theFrontOfTheLineQueue: [],
        _theFrontOfTheLineTimer: [],
        _before: new Date(),
        _theCycle: 500,
        _realCycle: 500,
        _theCycleElapsed: 0,
        _theCycleSkipping: 0,
        _paused: false,
        _hamNumber: 0,
        _timeoutVar: null
    }

    var privateFunctions = {
        _getInTimer: function(theNumber) {
             for (var i=0, len=privateVars._timers.length; i<len; i++) {
                 if (privateVars._timers[i].theNumber == theNumber) return(privateVars._timers[i]);
            }
            return null;
       },
        _checkInQueue: function(theNumber) {
            for (var i=0, len=privateVars._theQueue.length; i<len; i++) {
                if (privateVars._theQueue[i].theNumber == theNumber) return(i);
            }
            return -1;
        },
        _removeFromQueue: function(theNumber) {
            var foundNumber = privateFunctions._checkInQueue(theNumber);
            if (foundNumber != -1) return privateVars._theQueue.splice(foundNumber, 1)[0];
            else return null;
        },
        _goFrontOfTheLineTimer: function() {
            var frontOfTheLineNumber = privateVars._theFrontOfTheLineTimer.shift();
            var frontOfTheLineItem = privateFunctions._getInTimer(frontOfTheLineNumber);
            if (frontOfTheLineItem) {
                frontOfTheLineItem.runFunction.apply("frontoftheline",[frontOfTheLineItem.elapsed,frontOfTheLineItem.theNumber] );
                return true;
            } else return false;
        },
        _goFrontOfTheLine: function() {
            var frontOfTheLineNumber = privateVars._theFrontOfTheLineQueue.shift();
            var frontOfTheLineItem = privateFunctions._removeFromQueue(frontOfTheLineNumber);
            if (frontOfTheLineItem) {
                privateVars._theQueue.push(frontOfTheLineItem);
                frontOfTheLineItem.runFunction.apply("frontoftheline",[privateVars._theCycleElapsed,frontOfTheLineItem.theNumber] );
                return true;
            } else return false;
        },
        _goHam: function() {
            var hamCalled = false;
            var foundNumber = privateFunctions._checkInQueue(privateVars._hamNumber);
            if (foundNumber != -1) {
                hamCalled = privateVars._theQueue[foundNumber].runFunction.apply("goham",[privateVars._theCycleElapsed,privateVars._hamNumber] );
            }
            return hamCalled;
        },
        _doTimers: function() {
            var timerCalled = false;
            for(var i=0, len=privateVars._timers.length; i<len; i++) {
                privateVars._timers[i].elapsed += privateVars._theCycleElapsed;
                if (privateVars._timers[i].elapsed >= privateVars._timers[i].miliSeconds) {
                    var returnStatus = privateVars._timers[i].runFunction.apply("timer",[privateVars._timers[i].elapsed,privateVars._timers[i].theNumber] );
                    privateVars._timers[i].elapsed = 0;
                    if (returnStatus && privateVars._timers[i].cycleTimer) timerCalled = true;
                }
            }
            return timerCalled;
        },
        _doQueue: function() {
            var skipThis = true;
            var firstTime = true;
            var firstNumber = privateVars._theQueue[0].theNumber;
            do {
                var queueItem = privateVars._theQueue.shift();
                privateVars._theQueue.push(queueItem);
                skipThis = !queueItem.runFunction.apply("queue",[privateVars._theCycleElapsed,queueItem.theNumber] );
            } while (privateVars._theQueue.length > 0 && skipThis && firstNumber != privateVars._theQueue[0].theNumber);
        },
        _theLoop: function() {
            var continueCheck = true;
            var elapsed = new Date().getTime() - privateVars._before.getTime();
            if (elapsed >= privateVars._realCycle) {
                privateVars._theCycleElapsed = elapsed;
                privateVars._before = new Date();
                if (privateVars._theFrontOfTheLineTimer.length > 0) continueCheck = !privateFunctions._goFrontOfTheLineTimer();
                if (privateVars._theFrontOfTheLineQueue.length > 0) continueCheck = !privateFunctions._goFrontOfTheLine();
                if (continueCheck && privateVars._timers.length>0) continueCheck = !privateFunctions._doTimers();
                if (continueCheck && privateVars._hamNumber != 0) { continueCheck = false; privateFunctions._goHam(); }
                if (continueCheck && privateVars._theQueue.length>0) {
                    privateFunctions._doQueue();
                }
            }
            privateVars._timeoutVar = setTimeout(privateFunctions._theLoop, 0);
        }
    }
    var output = {
        addJob: function(func, theNumber, miliSeconds, cycleTimer) {
            if (typeof func === 'function' && !isNaN(miliSeconds)) {
                if (privateFunctions._checkInQueue(theNumber)!=-1) return;
                for(var i=0, len=privateVars._timers.length; i<len; i++) {
                    if (privateVars._timers[i].theNumber == theNumber) return;
                }
                var jobData = {'theNumber': theNumber, 'runFunction': func, 'miliSeconds': miliSeconds, 'cycleCounter': 0, 'elapsed': miliSeconds, 'cycleTimer': cycleTimer};
                if (miliSeconds == 0) privateVars._theQueue.push(jobData);
                else if (miliSeconds > 0) privateVars._timers.push(jobData);
            }
            if (privateVars._timeoutVar===null) privateFunctions._theLoop();
        },
        removeJob: function(theNumber) {
            var returnValue = false;
            privateFunctions._removeFromQueue(theNumber);
            for (var i=0, len=privateVars._timers.length; i<len; i++) {
                if (privateVars._timers[i].theNumber == theNumber) {
                    privateVars._timers.splice(i, 1);
                    returnValue=true;
                    break;
                }
            }
            if (privateVars._theQueue.length == 0 && privateVars._timers.length == 0) privateVars._timeoutVar = null;
            return returnValue;
        },
        pause: function() {
            privateVars._paused = true;
            clearTimeout(privateVars._timeoutVar);
        },
        isPaused: function() { return privateVars._paused; },
        unpause: function() {
            privateVars._paused = false;
            if (privateVars._timers.length>0 || privateVars._theQueue.length>0) 
                privateVars._timeoutVar = setTimeout(privateFunctions._theLoop, 0);
        },
        frontOfTheLineTimer: function( theNumber ) { privateVars._theFrontOfTheLineTimer.push(theNumber); },
        frontOfTheLine: function( theNumber ) { privateVars._theFrontOfTheLineQueue.push(theNumber); },
        hamOn: function( theNumber ) { privateVars._hamNumber = theNumber; },
        hamOff: function() { privateVars._hamNumber = 0; },
        isHamOn: function() { return (privateVars._hamNumber>0) ? true : false; },
        jobs: function() { return privateVars._theQueue.length; },
        skippingReset: function() { privateVars._theCycleSkipping = 0; privateVars._realCycle = privateVars._theCycle; },
        cycleIncrease: function(increaseNumber) { 
            increaseNumber = increaseNumber || gMainOptions.cycleIncrease;
            privateVars._theCycleSkipping += increaseNumber; 
            privateVars._realCycle += increaseNumber;
        },
        cycleDecrease: function() {
            privateVars._theCycleSkipping = (privateVars._theCycleSkipping > 0)
                ? privateVars._theCycleSkipping -= gMainOptions.cycleDecrease : 0;
            privateVars._realCycle = privateVars._theCycle + privateVars._theCycleSkipping;
        },
        cycle: function() { return privateVars._theCycle; },
        cycleSkipping: function() { return privateVars._theCycleSkipping; },
        cycleChange: function(newSkipping) { 
            privateVars._theCycleSkipping = newSkipping; privateVars._realCycle = privateVars._theCycle + privateVars._theCycleSkipping;
        },
        cycleAdd: function(newSkipping) { 
            privateVars._theCycleSkipping += newSkipping; privateVars._realCycle = privateVars._theCycle + privateVars._theCycleSkipping;
        },
        cycleResetChange: function(newCycle) { 
            privateVars._theCycle = newCycle; privateVars._theCycleSkipping = 0; privateVars._realCycle = newCycle;
        }
    };
    return output;
})();

function displayMainStatus() {
    var statusText = "", theMode="";
    var theJobs = (gMainData.jobs==0) ? "-- No Jobs to Search. " : "-- Running: " + gMainData.jobs + " jobs ";
    $("#JrMainStatus .JRJobsArea").html(theJobs);
    theMode = $("#JrMainStatus .JRCycleInfoArea").data("mode");
    var theCycle = (theMode=="Elapsed") ? "[ Elapsed Time: " + gMainData.lastElapsed + "ms | " : 
        (theMode=="Cycle") ? "[ Cycling every: " + theCycler.cycle() + "ms | " :
        (theMode=="CycleSkipping") ? "[ Cycling Slowed: " + theCycler.cycleSkipping() + "ms | " : 
        (theMode=="Hamcycle") ? "[ Min Ham Cycle: " + gMainOptions.HamCycleNumber + "ms | " : "";
    if (isActiveMenu(gMainMenu,"Cycle")) { 
        theCycle = "[ Elapsed Time: " + gMainData.lastElapsed + "ms | Cycling every: " + theCycler.cycle() + "ms | Cycling Slowed: " + 
            theCycler.cycleSkipping() + "ms | Min Ham Cycle: " + gMainOptions.HamCycleNumber + "ms ]";
        $("#JrMainStatus .JRCycleInfoArea").html(theCycle);
        $("#JrMainStatus .JRResultAccSkipArea").html("");
        $("#JrMainStatus .JRErrorArea").html("");
        $("#JrMainStatus .JRMturkQueueArea").html("");
        $("#JrMainStatus .JRSearchedArea").html("");
        $("#JrMainStatus .JRPayArea").html("");
    } else {
        $("#JrMainStatus .JRCycleInfoArea").html(theCycle);
        theMode = $("#JrMainStatus .JRResultAccSkipArea").data("mode");
        var theAccSkip = (theMode=="Accepted") ? "Accepted: " + gMainData.accepted + " | " : 
            (theMode=="Skipped") ? "Skipped: " + gMainData.skipped + " | " : "";
        $("#JrMainStatus .JRResultAccSkipArea").html(theAccSkip);
        theMode = $("#JrMainStatus .JRErrorArea").data("mode");
        var theErrors = (theMode=="Errors") ? "Errors: " + gMainData.errors + " | " : 
            (theMode=="TooFast") ? "Too Fast: " + gMainData.tooFast + " | " : "";
        $("#JrMainStatus .JRErrorArea").html(theErrors);
        $("#JrMainStatus .JRMturkQueueArea").html("Mturk Queue: " + gMainData.hitsInQueue + " | ");
        $("#JrMainStatus .JRSearchedArea").html("Searched: " + gMainData.searched + " | ");
        $("#JrMainStatus .JRPayArea").html("Pay Accepted: " + gMainData.payCounter.toFixed(2) + " ]");
    }
}
function displayControlsStatus() {
}
function displayHitStatus( theNumber ) {
    var hitInfo = gMainData.hitCollection[theNumber];
    var hitStatus = hitInfo.status;
    var statusText = "";
    statusText += "[ Acc: " + hitStatus.accepted + " | Skip: " + hitStatus.skipped + " | Srch: " + hitStatus.searched + " ] ";
    $("#JRCellStatus_" + theNumber).html( statusText );
    displayMainStatus();
}
function processResults( theNumber, result ) {
    var hitInfo = (theNumber>0) ? gMainData.hitCollection[theNumber] : null;
    var hitData = (hitInfo) ? hitInfo.data : null;
    var hitStatus = (hitInfo) ? hitInfo.status : null;
    switch(result) {
        case "NOTQUALIFIED":
            if (hitStatus) hitStatus.notQual++;
            gMainData.notQual++;
            break;
        case "NOMORE":
        case "NOACCEPT":
            if (hitStatus) hitStatus.noHits++;
            gMainData.noHits++;
            break;
        case "TOOFAST":
            if (hitStatus) hitStatus.tooFast++;
            gMainData.tooFast++;
            theCycler.cycleIncrease(gMainOptions.cycleAutoIncrease);
            break;
        case "LOGGEDOFF":
            theCycler.pause();
            $("#JRPauseButton").html("Resume").css({"background-color":"red","color":"white"});
            alert("You are logged out of Amazon. Can't accept hits. Please log back in");
            break;
        case "DAILYLIMIT":
            theCycler.pause();
            $("#JRPauseButton").html("Resume").css({"background-color":"red","color":"white"});
            alert("Congratulations!! You have reached your daily limit. Wait for tomorrow.");
            break;
        case "NOTCOMPLETED":
        case "ERROR":
            if (hitStatus) hitStatus.error++;
            gMainData.error++;
            break;
        case "QUEUEMAX":
            if (hitStatus) hitStatus.fullQueue++;
            gMainData.fullQueue++;
            break;
        case "SKIPPED":
            if (hitStatus) hitStatus.skipped++;
            gMainData.skipped++;
            break;
        case "ACCEPTED":
            if (hitStatus) hitStatus.accepted++;
            if (hitData.hamTimer > 0) hitInfo.lastAccept = new Date();
            var newDate = new Date().setHours(0,0,0,0);
            if (hitData.dailyLimit && hitData.dailyLimit>0) hitData.dailyDone = (newDate == hitData.day) ? hitData.dailyDone + 1 : 1;
            if (hitData.once) hitData.dailyDone = 1;
            hitData.day = newDate;
            gMainData.accepted++;
            gMainData.hitsInQueue++;
            var hitPay = parseFloat(hitData.pay);
            gMainData.payCounter = Math.round( (gMainData.payCounter + hitPay) * 100) / 100;
            var theDuration = hitInfo.minutes;
            if (theDuration==0 && hitData.duration!="0") {
                theDuration = (hitData.duration.indexOf("weeks")!=-1) ? 5000 : (hitData.duration.indexOf("day")!=-1) ? 1500 : (hitData.duration.indexOf("hours")!=-1) ? 200 : 
                    (hitData.duration.indexOf("hour")!=-1) ? 60 : (hitData.duration.indexOf("minutes")!=-1) ? parseInt(hitData.duration.split("minutes")[0]) : 1;
                hitInfo.minutes = theDuration;
            }
            var theSoundFile = "less99";
            var notificationTitle = "Accepted Hit From: " + hitData.requesterName;
            var notificationMessage = "Pay: " + hitData.pay + "\nDuration: " + hitData.duration + "\nTitle: " + hitData.title;
            if (!hitData.mute) {
                if ( hitPay < 0.02 ) { theSoundFile = (theDuration != 0 && theDuration<=2) ? "less2Short" : "less2"; }
                else if ( hitPay <= 0.05 ) { theSoundFile =  (theDuration != 0 && theDuration<=5) ? "less5Short" : "less5"; }
                else if ( hitPay <= 0.15 ) { theSoundFile = (theDuration != 0 && theDuration<=15) ? "less15Short" : "less15"; }
                else if ( hitPay < 0.99 ) { theSoundFile = "less99"; }
                if (hitData.audioforce != "") theSoundFile = hitData.audioforce;
                playThisSound(theSoundFile);
            }
            $("#JRCellNum_" + theNumber).stop(true,true);
            $("#JRCellNum_" + theNumber).css({"background-color":"yellow"});
            $("#JRCellNum_" + theNumber).animate({backgroundColor: $("#JRCellNum_" + theNumber).data("backgroundColor")}, 40000);
            if (gNotifications) showNotification( notificationTitle, notificationMessage, "accepted");
            if ( hitInfo.ham == "paused" ) toggleButton($("#JRHamB_" + theNumber),hamOn,hamOff);
            addToAcceptedLog( hitData.requesterName + " - <a href='" + pandaLink(hitData.groupId) + "' target='_blank' style='color:cyan;'>" + hitData.groupId + "</a> - " + hitData.title );
            updateHitCell(theNumber);
            break;
    }
    if (theNumber > 0) displayHitStatus(theNumber);
}

function requestUrl(theUrl, theNumber, theFunction, errorFunction, data1, data2, theResponseType) {
    var theResponseType = theResponseType || "";
    console.log("JR going to get: " + theUrl);
    GM_xmlhttpRequest({
        method: "GET",
        url: theUrl,
        responseType: theResponseType,
        onload: function(response) { if (typeof theFunction == 'function') theFunction(response,theNumber,data1,data2); },
        onerror: function(response) { if (typeof errorFunction == 'function') errorFunction(response,theNumber); }
    });
}

function pandaLink(thegroupId) { return "https://www.mturk.com/mturk/previewandaccept?groupId=" + thegroupId; }
function previewLink(thegroupId) { return "https://www.mturk.com/mturk/preview?groupId=" + thegroupId; }
function requesterSearch(theRequester) { return "https://www.mturk.com/mturk/searchbar?selectedSearchType=hitgroups&qualifiedFor=on&sortType=Reward%3A1&requesterId=" + theRequester; }
function acceptLink(theHitData) { return "https://www.mturk.com/mturk/accept?hitId=" + theHitData.hitId + "&prevHitSubmitted=" + theHitData.prevHitSubmitted +
    "&prevRequester=" + theHitData.prevRequester + "&prevReward=" + theHitData.prevReward + "&requesterId=" + theHitData.requesterId + "&groupId=" + 
    theHitData.groupId + "&signature=" + theHitData.signature;
}
function checkLimits(theNumber) {
    //console.log("JR checking " + theNumber + " for their limits.");
    var hitInfo = gMainData.hitCollection[theNumber];
    var hitData = hitInfo.data;
    var returnValue = false;
    if (hitData.queueLimit == 0 && hitData.dailyLimit == 0 && !hitData.once) returnValue = true;
    else if (hitData.once && hitData.dailyDone>0) {
        if (hitInfo.hitCell.data("status")=="on") hitInfo.hitCell.data("status","off");
        toggleButtonOff( hitInfo.hitCell.find(".JRCollectButton"),startCollecting,stopCollecting);
        console.log("JR found 1 so turning off.");
        returnValue = false;
    } else if (hitData.dailyLimit > 0 && hitData.dailyLimit < gMainData.dailyDone) returnValue = false;
    else if (hitData.queueLimit > 0 && hitData.queueLimit <= gMainData.hitsInQueue) returnValue = false;
    else returnValue = true;
    return returnValue;
}
function searchRequestersInfo( theNumber, hitNumber, requestersInfo ) {
    var hitInfo = gMainData.hitCollection[hitNumber];
    var hitData = hitInfo.data;
    if (hitInfo.collecting != "off") {
        hitInfo.status.searched++;
        displayHitStatus(hitNumber);
        for (var i=0, len=requestersInfo.data.length; i<len; i++) {
            if ( requestersInfo.data[i].groupId == hitData.groupId ) {
                //console.log("JR found something");
                return i;
            }
        }
    }
    return -1;
}
function parseHitSearchPage(theResult,theNumber) {
    var hitInfo = (theNumber>0) ? gMainData.hitCollection[theNumber] : null;
    var hitData = (hitInfo) ? hitInfo.data : null;
    var parser = new DOMParser();
    var xmlDoc = parser.parseFromString(theResult.responseText,"text/html");
    var errorTitle_Array = xmlDoc.getElementsByClassName("error_title");
    var errorTitle = (errorTitle_Array.length) ? errorTitle_Array[0] : null;
    if (errorTitle && errorTitle.innerHTML.indexOf("You have exceeded the maximum allowed page request rate") != -1) {
        processResults( theNumber, "TOOFAST" );
        return;
    } else if (errorTitle && errorTitle.innerHTML.indexOf("Your search did not match any HITs") != -1) {
        return;
    } else {
        //console.log("JR HitsearchPage : might have something");
        var tempNode = $(xmlDoc).find("#sortresults_form");
        if ($(tempNode).length) {
            //console.log("JR HitsearchPage : checking something");
            var requestersInfo = {"counter":0,"data":[]};
            $(tempNode).next("table").find("tbody:first").children("tr").each( function() {
                //console.log("JR HitsearchPage : checking a hit");
                requestersInfo.data[requestersInfo.counter] = {};
                var capsuleNode = $(this).find("a#capsule" + requestersInfo.counter + "-0");
                if (capsuleNode) {
                    //console.log("JR HitsearchPage : hit capsuleNode found");
                    var title = $(capsuleNode).html().split("<span")[0];
                    var playerClass = $(this).find('a[id^="private_hit.view_a_HIT_in_group.tooltip"]');
                    var groupIdNumber = (playerClass.length) ? "" : $(capsuleNode).closest("tr").find("a:contains('View a HIT in this group')")
                        .attr("href").replace("/mturk/preview?groupId=","");
                    console.log("JR HitsearchPage : I found this groupID: " + groupIdNumber);
                    var requesterIdentity = $(this).find("span.requesterIdentity");
                    var requesterName = $(requesterIdentity).html().trim();
                    var capsuleFieldTextIdentity = $(requesterIdentity).closest(".capsule_field_text").find("a");
                    var requesterIdNumber = (capsuleFieldTextIdentity.length) ? $(capsuleFieldTextIdentity).attr("href")
                        .replace("/mturk/searchbar?selectedSearchType=hitgroups&requesterId=","") : "";
                    var rewardNode = $(this).find("#reward\\.tooltip--" + requestersInfo.counter);
                    var thePay = ( $(rewardNode).length ) ? $(rewardNode).parent().next().find("span").html().replace("$","").trim() : "";
                    if (gExcludeIds.indexOf(groupIdNumber)==-1) {
                        console.log("JR HitsearchPage : found a hit");
                        requestersInfo.data[requestersInfo.counter].requesterName = requesterName;
                        requestersInfo.data[requestersInfo.counter].hitTitle = title;
                        requestersInfo.data[requestersInfo.counter].requesterId = requesterIdNumber;
                        requestersInfo.data[requestersInfo.counter].groupId = groupIdNumber;
                    } else console.log("JR excluded hit");
                    requestersInfo.counter++;
                }
            });
            var foundTheNumber = -1;
            if (requestersInfo.data.length > 0) {
                console.log("JR HitsearchPage : I found some hits: " + requestersInfo.data.length);
                var goUrl = ""; console.log("HitsearchPage : Number=" + theNumber);
                if (theNumber<=0) {
                    $.each(gMainData.hitCollection, function( index, value ) {
                        foundTheNumber = searchRequestersInfo(index, index, requestersInfo);
                        if (foundTheNumber != -1) {
                            console.log("HitsearchPage : I found a matching hit for a panda: " + requestersInfo.data[foundTheNumber].groupId);
                            goUrl = (value.data.action=="SearchAndFilter") ? previewLink(requestersInfo.data[foundTheNumber].groupId) : pandaLink(requestersInfo.data[foundTheNumber].groupId);
                            gMainData.hitCollection[0].goToUrl.push({"url":goUrl,"theNumber":i});
                        }
                    });
                } else {
                    for (var i=0, len=requestersInfo.data.length; i<len; i++) {
                        goUrl = (hitData.action=="SearchAndFilter") ? previewLink(requestersInfo.data[i].groupId) : pandaLink(requestersInfo.data[i].groupId);
                        hitData.groupId = requestersInfo.data[i].groupId; console.log("HitsearchPage : GroupID=" + requestersInfo.data[i].groupId);
                        hitInfo.newTitle = requestersInfo.data[i].hitTitle
                        hitInfo.goToUrl.push({"url":goUrl,"theNumber":theNumber});
                        updateHitCell(theNumber);
                    }
                    if (hitData.maxHam!="" && hitData.maxHam!="0" && hitInfo.ham=="on") hamOn(theNumber);
                    theCycler.frontOfTheLine(theNumber);
                }
            }
        }
    }
}
function parseQueuePage(theResult,theNumber) {
    var parser = new DOMParser();
    var xmlDoc = parser.parseFromString(theResult.responseText,"text/html");
    var alertBoxHeader = $(xmlDoc).find("#alertboxHeader");
    if ($(xmlDoc).find("td.error_title:contains('There are currently no HITs assigned to you.')").length > 0) {
        //addToStatusLog("---- nothing in queue");
        gMainData.hitsInQueue = 0;
    } else {
        var numberQueueText = $(xmlDoc).find("td.title_orange_text").html();
        if (numberQueueText) {
            var words = numberQueueText.trim().split(' ');
            if ($.isNumeric(words[words.length - 2])) gMainData.hitsInQueue = parseInt(words[words.length - 2]);
        }
    }
}
function errorRequest(res,theNumber) {
    console.log("error: " + res.statusText);
    if (res.statusText == "Forbidden") processResults( theNumber, "LOGGEDOFF" );
    //setStatusText(theNumber,"...... Searching - Error .....","errors");
}
function parseZingHitPage(theResult,theNumber,formData) {
    var parser = new DOMParser();
    var xmlDoc = parser.parseFromString(theResult.responseText,"text/html");
    var hitInfo = gMainData.hitCollection[theNumber];
    var hitData = hitInfo.data;
    
    var thisZingOptions = gZingOptions[hitData.pay];
    thisZingOptions = (gZingOptions[hitData.pay]) ? gZingOptions[hitData.pay] : gZingOptions["0.01"];
    
    var goAccept = false;
    var theSearching = $(xmlDoc).find(".row-fluid .span6").eq(0);
    var receiptItemsCount = $(theSearching).find(".receipt_items .fieldswrapper").length;
    var inputCount = $(theSearching).find("input[type=text]").length;
    var multipleQuantityCount = $(theSearching).find("input[type=text].multiple_quantity").length;
    var codesCount = inputCount - 1 - multipleQuantityCount;
    var thePicturesCount = $(xmlDoc).find(".receipt_images").eq(0).find("img").length; //console.log("pictures: " + thePicturesCount);
    
    var limitReceptItems = thisZingOptions.SearchGroupAllowed;
    var limitTallyCount = thisZingOptions.TallyCountTotalAllowed;
    var limitCodes = (thisZingOptions.AcceptCodesSearching) ? 10 : 0;
    var limitImages = thisZingOptions.MaxReceiptImages;
    if (receiptItemsCount <= limitReceptItems && multipleQuantityCount <= limitTallyCount && codesCount <= limitCodes && thePicturesCount <= limitImages) goAccept = true;
    if ( goAccept ) {
        if (checkLimits(theNumber)) {
            var acceptHitURL = acceptLink(formData);
            hitInfo.goToUrl.push({"url":acceptHitURL,"theNumber":theNumber});
            theCycler.frontOfTheLine(theNumber);
        } else {
            $("#JRCellNum_" + theNumber).stop(true,true);
            $("#JRCellNum_" + theNumber).css({"background-color":"#FF9999"});
            $("#JRCellNum_" + theNumber).animate({backgroundColor: $("#JRCellNum_" + theNumber).data("backgroundColor")}, 40000);
        }
    } else processResults( theNumber, "SKIPPED" );
}
function parseMturkHitPage(theResult,theNumber) {
    var hitInfo = gMainData.hitCollection[theNumber];
    var hitData = hitInfo.data;
    var parser = new DOMParser();
    var xmlDoc = parser.parseFromString(theResult.responseText,"text/html");
    var alertBoxHeader = xmlDoc.getElementById("alertboxHeader");
    var dailyLimit = false;
    if (alertBoxHeader) {
        var alertHeaderHTML = alertBoxHeader.innerHTML;
        if (alertHeaderHTML.indexOf("There are no more available HITs") != -1 || alertHeaderHTML.indexOf("There are no HITs in this group") != -1) {
            processResults( theNumber, "NOMORE" );
            return;
        } else if (alertHeaderHTML.indexOf("You have accepted the maximum number of HITs allowed") != -1) {
            processResults( theNumber, "QUEUEMAX" );
            return;
        } else if (alertHeaderHTML.indexOf("The HIT you were viewing could not be accepted") != -1) {
            processResults( theNumber, "NOACCEPT" );
            return;
        } else if (alertHeaderHTML.indexOf("You are not qualified to accept") != -1 || alertHeaderHTML.indexOf("Your Qualifications do not meet the") != -1) {
            processResults( theNumber, "NOTQUALIFIED" );
            return;
        }
        dailyLimit = (alertHeaderHTML.indexOf("There are no HITs available for you at this time") != -1);
    }
    var loggedOff1 = xmlDoc.getElementById("ap_signin_custom_message");
    var loggedOff3 = xmlDoc.getElementById("signin-slot");
    if (loggedOff1 || loggedOff3) {
        processResults( theNumber, "LOGGEDOFF" );
        return;
    }
    var errorTitle = $(xmlDoc).find("td.error_title").eq(0);
    var hitAccepted = $(xmlDoc).find("img[src$='/media/return_hit.gif']");
    var notAccepted = $(xmlDoc).find("input[src$='/media/accept_hit.gif']");
    if (errorTitle.length && errorTitle.html().indexOf("You have exceeded the maximum allowed page request rate") != -1) {
        processResults( theNumber, "TOOFAST" );
    } else if (errorTitle.length && errorTitle.html().indexOf("Your request was not completed successfully") != -1) {
        processResults( theNumber, "NOTCOMPLETED" );
    } else if (dailyLimit) {
        processResults( theNumber, "DAILYLIMIT" );
    } else if (hitAccepted.length) {
        var updated = false;
        var hitGroupId = ($(xmlDoc).find("form[name='hitForm']").length) ? $(xmlDoc).find("form[name='hitForm']").eq(0).find("input[name='groupId']").eq(0).val() : "";
        hitData.groupId = hitGroupId;
        var capsuleNode = $(xmlDoc).find("td.capsulelink_bold:first div").eq(0);
        var theTitle = (capsuleNode.length) ? $(capsuleNode).html().trim() : hitData.title;
        if (hitData.title != theTitle) { hitData.title = theTitle; updated=true; }
        var timeLeft = $(xmlDoc).find("a#time_left\\.tooltip");
        var theDuration = (timeLeft.length) ? timeLeft.parent().next().html().trim() : hitData.duration;
        if (hitData.duration != theDuration) { hitData.duration = theDuration; updated=true; }
        var requesterTip = $(xmlDoc).find("#requester\\.tooltip");
        var requesterNameNode = (requesterTip.length) ? $(requesterTip).eq(0).parent().next() : null;
        var theRequesterName = ($(requesterNameNode)) ? ( ($(requesterNameNode).find("a").length) ? $(requesterNameNode).find("a").html().trim() : $(requesterNameNode).html().trim() ) : "";
        theRequesterName = (theRequesterName) ? theRequesterName : hitData.requesterName;
        if (hitData.requesterName != theRequesterName) { hitData.requesterName = theRequesterName; updated=true; }
        var numberHitsTip = $(xmlDoc).find("#number_of_hits\\.tooltip");
        var theNumberHits = (numberHitsTip.length) ? numberHitsTip.parent().next().html().trim() : hitInfo.numberHits;
        hitInfo.numberHits = theNumberHits;
        var rewardTip = $(xmlDoc).find("#reward\\.tooltip");
        var theReward = (rewardTip.length) ? rewardTip.parent().next().find("span").html().replace("$","").trim() : hitData.pay;
        if (hitData.pay != theReward) { hitData.pay = theReward; updated=true; }
        processResults( theNumber, "ACCEPTED" );
        if (updated) gDelayedSave = true;
        console.log("accepted: " + theNumber + " | updated: " + updated + " | groupId: " + hitGroupId);
    } else if (notAccepted.length) {
        var formData = {};
        formData.hitId = $(xmlDoc).find("input[name='hitId']").eq(0).val();
        formData.prevHitSubmitted = $(xmlDoc).find("input[name='prevHitSubmitted']").eq(0).val();
        formData.prevRequester = $(xmlDoc).find("input[name='prevRequester']").eq(0).val();
        formData.requesterId = $(xmlDoc).find("input[name='requesterId']").eq(0).val();
        formData.prevReward = $(xmlDoc).find("input[name='prevReward']").eq(0).val();
        formData.groupId = $(xmlDoc).find("input[name='groupId']").eq(0).val();
        formData.signature = $(xmlDoc).find("input[name='signature']").eq(0).val();
        var iframeSrc = $(xmlDoc).find("iframe").attr("src");
        var acceptHitURL = acceptLink(formData);
        if (iframeSrc) {
            if (formData.requesterId=="AGVV5AWLJY7H2") {
                if (hitData.filterMode>0 && hitData.filterMode <= Object.keys(gZingFuncOptions).length) {
                    requestUrl(iframeSrc, theNumber, gZingFuncOptions[hitData.filterMode].functionName, errorRequest, formData, "");
                } else {
                    console.log("Filter Mode is off");
                    hitInfo.goToUrl.push({"url":acceptHitURL,"theNumber":theNumber});
                    theCycler.frontOfTheLine(theNumber);
                }
            }
        }
    } else { processResults( theNumber, "ERROR" ); }
}

function makeStatus() { return {"accepted":0,"skipped":0,"errors":0,"tooFast":0,"noHits":0,"fullQueue":0,"hitsStreak":0,"noHitsStreak":0,"searched":0,"orphan":0,"hitsResults":0,"notQual":0}; }
function buttonStatus(buttonName,theData,buttonChange) {
    if (buttonName=="collect") {
    } else if (buttonName=="ham") {
    }
}
function addHitCollection(theData,theNumber,tabIndex) {
    var pandaUrl = pandaLink(theData.groupId);
    var previewUrl = previewLink(theData.groupId);
    var filterFuncData = (theData.action.indexOf("Filter") != -1) ? ((theData.requesterId=="AGVV5AWLJY7H2") ? gZingFuncOptions : null) : null;
    gMainData.hitCollection[theNumber] =
        {"collecting":"off","pandaUrl":pandaUrl,"previewUrl":previewUrl,"goToUrl":[],"theNumber":theNumber,"data":theData,"status":makeStatus(),"specialOptions":null,"hitCell":null,"ham":"off","minutes":0,"newTitle":"","numberHits":"0","once":false,"filterFuncData":filterFuncData,"searching":"off","lastAccept":null,"tabIndex":tabIndex};
    return theNumber;
}
function findHitsPageOff(thisButton) {
    $(thisButton).data("useHitSearch","off");
    theCycler.removeJob(-10);
    theCycler.hamOff();
}
function findHitsPageOn( thisButton ) {
    var theHitNumber = null, hitInfo = null, hitData = null, okToPanda = false;  
    if ( theCycler.isHamOn ) hamOff();
    $(thisButton).data("useHitSearch","on");
    theCycler.addJob( function( elapsed, theNumber ) {
        if (gMainData.hitCollection[0].goToUrl.length) {
            var theGoToUrl = gMainData.hitCollection[0].goToUrl.shift();
            var hitInfo = gMainData.hitCollection[theGoToUrl.theNumber];
            var hitData = hitInfo.data;
            if (checkLimits(theGoToUrl.theNumber)) {
                gMainData.lastElapsed = elapsed;
                requestUrl(theGoToUrl.url,theGoToUrl.theNumber,parseMturkHitPage, errorRequest);
            }
        } else {
            gMainData.searched++;
            gMainData.lastElapsed = elapsed;
            requestUrl("https://www.mturk.com/mturk/sortsearchbar?searchSpec=HITGroupSearch%23T%231%2310%23-1%23T%23!only_available_hits!0!rO0ABXQABHRydWU-!keyword_list!2!rO0ABXQAAA--!Reward!6!rO0ABXQABDAuMDA-!%23!LastUpdatedTime!1!%23!&selectedSearchType=hitgroups&searchWords=&sortType=LastUpdatedTime%3A1&%2Fsort.x=14&%2Fsort.y=9", -10 ,parseHitSearchPage,errorRequest, "" );
        }
        displayMainStatus();
        return true;
    }, -10, 0, true);
    theCycler.hamOn(-10);
}
function addQueueCheck() {
    theCycler.addJob( function( elapsed, theNumber ) {
        gMainData.queueStatus.searched++;
        requestUrl("https://www.mturk.com/mturk/myhits",1,function(theResult,theNumber,data1,data2) {
            //console.log("checking queue number");
            return parseQueuePage(theResult);
        },function() { errorRequest(); } );
        displayMainStatus();
        return true;
    }, -1, gMainOptions.queueTimer, true);
}
function startCollecting(theNumber,thisButton) {
    var hitInfo = gMainData.hitCollection[theNumber], theGoToUrl = null;
    var hitData = hitInfo.data;
    if (hitData.once) hitData.dailyDone = 0;
    hitInfo.collecting = "on";
    console.log("Turning on " + theNumber);
    theCycler.addJob( function( elapsed, theNumber ) {
        var hitInfo = gMainData.hitCollection[theNumber];
        var hitData = hitInfo.data;
        if (hitInfo.ham == "ontimed") { 
            if (hitData.hamTimer > 0 && hitInfo.lastAccept) {
                var nowTime = new Date();
                var elapsedTime = nowTime - hitInfo.lastAccept;
                var theSeconds = elapsedTime / 1000;
                var theMinutes = Math.floor(theSeconds / 60);
                var offHamMode = (hitInfo.ham == "ontimed") ? "paused" : "off";
                if (theSeconds >= hitData.hamTimer) {
                    toggleButton($("#JRHamB_" + theNumber),hamOn,hamOff,offHamMode);
                    hitInfo.lastAccept = null;
                }
            }
        }
        //console.log("going to checklimits for " +theNumber+ " hitInfo status = " + hitInfo.hitCell.data("status"));
        if ( checkLimits(theNumber) ) {
            hitInfo.status.searched++;
            if (hitInfo.goToUrl.length) {
                console.log("Found a gotoUrl so I must do Url");
                if ( (hitInfo.data.action.substring(0,6) == "Search" || hitInfo.data.action == "FilterPanda") && !hitInfo.hitCell.data("firstPanda") )
                    theGoToUrl = hitInfo.goToUrl.shift();
                else theGoToUrl = hitInfo.goToUrl[0];
                var theUrl=theGoToUrl.url;
            } else {
                var theUrl = ( hitInfo.data.action == "Panda" ) ? hitInfo.pandaUrl : (hitInfo.data.action.substring(0,6) == "Search") ? requesterSearch(hitData.requesterId) : hitInfo.previewUrl;
            }
            gMainData.searched++;
            gMainData.lastElapsed = elapsed;
            //console.log("Doing Number: " + theNumber + " | going to: " + theUrl);
            if (theUrl.indexOf("selectedSearchType=hitgroups")!=-1) requestUrl(theUrl,theNumber,parseHitSearchPage, errorRequest, hitInfo.status.searched, "");
            else requestUrl(theUrl,theNumber,parseMturkHitPage, errorRequest, hitInfo.status.searched, "");
            displayHitStatus(theNumber);
            return true;
        } else {
            $("#JRCellNum_" + theNumber).stop(true,true);
            $("#JRCellNum_" + theNumber).css({"background-color":"#FF9999"});
            $("#JRCellNum_" + theNumber).animate({backgroundColor: $("#JRCellNum_" + theNumber).data("backgroundColor")}, 40000);
            return false;
        }
    }, theNumber, 0, true);
    gMainData.jobs++;
    addQueueCheck();
}
function stopCollecting(theNumber,thisButton) {
    //console.log("turning off " + theNumber);
    if (gMainData.hitCollection[theNumber].collecting == "on") { 
        gMainData.hitCollection[theNumber].collecting = "off";
        gMainData.hitCollection[theNumber].goToUrl.splice(0,gMainData.hitCollection[theNumber].goToUrl.length);
        theCycler.removeJob(theNumber); 
        gMainData.jobs--;
    }
    if (theCycler.jobs() == 0) theCycler.removeJob(-1); // Stop mturk queue checking. Doesn't matter how many hits now.
    displayHitStatus(theNumber);
}
function stopAll() {
    $.each(gMainData.hitCollection, function( index, value ) {
        if (value.collecting == "on") {
            toggleButton( $("#JRCollectB_" + index),startCollecting,stopCollecting);
            if (value.collecting=="off" && value.ham != "off") toggleButtonOff($("#JRHamB_" + index),hamOn,hamOff);
        }
    });
}
function hamOn(theNumber,thisButton) {
    var onMode = "on";
    $(".JRHamButton").each( function() {
        if ( $(this).data("theNumber") != theNumber ) $(this).data("disabled",true);
        updateHitColors($(this).data("theNumber"));
    });
    if (gMainData.hitCollection[theNumber].ham == "paused") onMode = "ontimed";
    gMainData.hitCollection[theNumber].ham = onMode;
    theCycler.hamOn(theNumber);
    theCycler.skippingReset();
    theCycler.cycleResetChange(gMainOptions.HamCycleNumber);
}
function hamOff(theNumber,thisButton,theMode) {
    var passedMode = theMode || "off";
    var hitInfo = gMainData.hitCollection[theNumber];
    if (hitInfo.ham.substring(0,2) == "on") {
        $(".JRHamButton").each( function() {
            if ( $(this).data("disabled") ) $(this).data("disabled",false);
            updateHitColors($(this).data("theNumber"));
        });
    }
    if (hitInfo.ham == "ontimed") passedMode = "paused";
    gMainData.hitCollection[theNumber].ham = passedMode;
    $("#JRCellNum_" + theNumber).data("firstPanda",false);
    theCycler.hamOff();
    theCycler.skippingReset();
    theCycler.cycleResetChange(gMainOptions.cycleNumber);
}
function muteJob(theNumber) {
    var hitInfo = gMainData.hitCollection[theNumber];
    hitInfo.data.mute = !hitInfo.data.mute;
    hitInfo.hitCell.data("mute",hitInfo.data.mute);
    updateHitColors( theNumber );
    saveSettings();
}
function addTab(tabContainer,theTitle,isSortable,theID,tabData,appendClose) {
    var theTab = createTab(tabContainer,theTitle,isSortable,theID,tabData,appendClose)
        .data({"tabData":tabData});
    createDiv().insertBefore(theTab.find("br.cleartab"))
        .data({"tabData":tabData})
        .attr({"class":"tabContents connectedSortable"})
        .css({"overflow":"auto"})
        .sortable({dropOnEmpty: true,delay:400,connectWith: ".connectedSortable",tolerance: "pointer","items":".JRHitCell:not(.ui-not-sortable)",
            helper:"clone",opacity: 0.9,appendTo:"body",
            start: function( event, ui ) {
                //$(".hasTooltip").tooltip("disable");
                ui.item.addClass('noclick');
                ui.item.data("oldPosition",ui.item.index());
                ui.item.data("received",false);
            },
            receive: function( event, ui ) {
                ui.item.data("received",true);
                $(event.target).find(".JRHitDummy").remove();
                gTabsData[ui.item.data("hitInfo").tabIndex].positions.splice(ui.item.data("oldPosition"), 1);
                $(event.target).data("tabData").positions.splice(ui.item.index(), 0, ui.item.data("theNumber"));
                ui.item.data("hitInfo").tabIndex = $(gTabsData).index($(event.target).data("tabData"));
                ui.item.data("hitData").tabNumber = $(event.target).data("tabData").tabNumber;
                $(event.target).append(createDiv("&nbsp;").attr("class","JRHitCell JRHitDummy").data("hitInfo",{"tabIndex":0}));
                saveSettings();
            },
            stop: function( event, ui ) {
                if (ui.item.data("hitInfo") && !ui.item.data("received")) {
                    $(event.target).find(".JRHitDummy").remove();
                    var thePositions = gTabsData[ui.item.data("hitInfo").tabIndex].positions;
                    console.log("JR positions before: " + JSON.stringify(thePositions));
                    thePositions.splice(ui.item.index(), 0, thePositions.splice(ui.item.data("oldPosition"), 1)[0]);
                    console.log("JR positions after: " + JSON.stringify(thePositions));
                    $(event.target).append(createDiv("&nbsp;").attr("class","JRHitCell JRHitDummy").data("hitInfo",{"tabIndex":0}));
                    saveSettings();
                }
                $(".hasTooltip").tooltip("enable");
            }
        });
    return theTab;
}
function dataEdited(thisArea,theValue) {
    $("#JREditDialog").data("edited",true);
    $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Save')").button().show();
    var inputEdit = createTextInput(theValue).css({"width":"300px"});
    $(inputEdit).focus( function() { $(this).select(); });
    $(thisArea).find("span").replaceWith(inputEdit);
    $(inputEdit).focus();
}
function dataTrueFalse(thisArea,theValue) {
    $("#JREditDialog").data("edited",true);
    $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Save')").button().show();
    if (theValue) returnValue=false;
    else returnValue=true;
    $(thisArea).find("span").html(returnValue.toString());
    return returnValue;
}
function dataPandaSearch(thisArea,theValue) {
    $("#JREditDialog").data("edited",true);
    $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Save')").button().show();
    if (theValue) returnValue=false;
    else returnValue=true;
    $(thisArea).find("span").html(returnValue.toString());
    return returnValue;
}
function saveAlarmsData() {
    $.each(gAlarmSounds, function( index, value ) {
        var importFileID = "importFileInput-" + index;
        value.audio = $("#" + importFileID).data("audio");
        var base64 = $("#" + importFileID).data("base64");
        if (base64) GM_setValue(value.nameVar,JSON.stringify(base64));
    });
    saveSettings();
}
function saveTimersData() {
    var cycleEdit = $("#JREditDialog #timersCycleEdit input");
    if (cycleEdit.length) gMainOptions.cycleNumber = parseInt($(cycleEdit).eq(0).val());
    var goHamEdit = $("#JREditDialog #timersGoHamEdit input");
    if (goHamEdit.length) gMainOptions.HamCycleNumber = parseInt($(goHamEdit).eq(0).val());
    var hamDelayEdit = $("#JREditDialog #timersHamDelayEdit input");
    if (hamDelayEdit.length) gMainOptions.hamDelayTimer = parseInt($(hamDelayEdit).eq(0).val());
    var checkQueueEdit = $("#JREditDialog #timersCheckQueueEdit input");
    if (checkQueueEdit.length) {
        gMainOptions.queueTimer = parseInt($(checkQueueEdit).eq(0).val());
        if (theCycler.jobs() > 0) { theCycler.removeJob(-1); addQueueCheck(); };
    }
    var cycleIncreaseEdit = $("#JREditDialog #timersCycleIncreaseEdit input");
    if (cycleIncreaseEdit.length) gMainOptions.cycleIncrease = parseInt($(cycleIncreaseEdit).eq(0).val());
    var cycleDecreaseEdit = $("#JREditDialog #timersCycleDecreaseEdit input");
    if (cycleDecreaseEdit.length) gMainOptions.cycleDecrease = parseInt($(cycleDecreaseEdit).eq(0).val());
    var cycleAddingEdit = $("#JREditDialog #timersCycleAddingEdit input");
    if (cycleAddingEdit.length) {
        gMainOptions.cycleAdding = parseInt($(cycleAddingEdit).eq(0).val());
        $("#JrCycleAddingButton").find("span").html("Add " + gMainOptions.cycleAdding);
    }
    var cycleAutoIncreaseEdit = $("#JREditDialog #timersCycleAutoIncreaseEdit input");
    if (cycleAutoIncreaseEdit.length) gMainOptions.cycleAutoIncrease = parseInt($(cycleAutoIncreaseEdit).eq(0).val());
    saveSettings();
    theCycler.cycleResetChange(gMainOptions.cycleNumber);
    displayMainStatus();
}
function saveJobData() {
    var theNumber = $("#JREditDialog").data("theNumber");
    var hitInfo = gMainData.hitCollection[theNumber];
    var hitData = hitInfo.data;
    var requesterNameEdit = $("#JREditDialog #requesterNameEdit input");
    if (requesterNameEdit.length) hitData.requesterName = $(requesterNameEdit).eq(0).val();
    var requesterIdEdit = $("#JREditDialog #requesterIdEdit input");
    if (requesterIdEdit.length) hitData.requesterId = $(requesterIdEdit).eq(0).val();
    var actionEdit = $("#JREditDialog #actionEdit input");
    if (actionEdit.length) hitData.action = $(actionEdit).eq(0).val();
    var groupIdEdit = $("#JREditDialog #groupIdEdit input");
    if (groupIdEdit.length) {
        hitData.groupId = $(groupIdEdit).eq(0).val();
        hitInfo.pandaUrl = pandaLink(hitData.groupId);
        hitInfo.previewUrl = previewLink(hitData.groupId);
    }
    var payEdit = $("#JREditDialog #payEdit input");
    if (payEdit.length) hitData.pay = $(payEdit).eq(0).val();
    var qualEdit = $("#JREditDialog #qualEdit input");
    if (qualEdit.length) hitData.qual = $(qualEdit).eq(0).val();
    var titleEdit = $("#JREditDialog #titleEdit input");
    if (titleEdit.length) hitData.title = $(titleEdit).eq(0).val();
    var durationEdit = $("#JREditDialog #durationEdit input");
    if (durationEdit.length) hitData.duration = $(durationEdit).eq(0).val();
    var queueLimitEdit = $("#JREditDialog #queueLimitEdit input");
    if (queueLimitEdit.length) hitData.queueLimit = Number($(queueLimitEdit).eq(0).val());
    var dailyLimitEdit = $("#JREditDialog #dailyLimitEdit input");
    if (dailyLimitEdit.length) hitData.dailyLimit = Number($(dailyLimitEdit).eq(0).val());
    var onceEdit = $("#JREditDialog #onceEdit input");
    if (onceEdit.length) hitData.once = $(onceEdit).eq(0).val();
    var hamTimerEdit = $("#JREditDialog #hamTimerEdit input");
    if (hamTimerEdit.length) hitData.hamTimer = $(hamTimerEdit).eq(0).val();
    var dailyDoneEdit = $("#JREditDialog #dailyDoneEdit input");
    if (dailyDoneEdit.length) hitData.dailyDone = $(dailyDoneEdit).eq(0).val();
    var audioforceEdit = $("#JREditDialog #audioforceEdit input");
    if (audioforceEdit.length) hitData.audioforce = $(audioforceEdit).eq(0).val();
    var filterModeEdit = $("#JREditDialog #filterModeEdit select");
    if (filterModeEdit.length) hitData.filterMode = $(filterModeEdit).eq(0).val();
    updateHitCell(theNumber);
    saveSettings();
    updateHitColors( theNumber );
}
function saveEditedData() {
    if ( $("#JREditDialog").data("edited") ) {
        if ($("#JREditDialog").data("editing") == "job") saveJobData();
        else if ($("#JREditDialog").data("editing") == "timers") saveTimersData();
        else if ($("#JREditDialog").data("editing") == "alarms") saveAlarmsData();
        else if ($("#JREditDialog").data("editing") == "groupingCreate") saveGroupingCreateData();
        else if ($("#JREditDialog").data("editing") == "groupingHitsEdit") saveGroupingHitsData();
    }
}
function saveToFile(theData) {
    var blob = new Blob( [JSON.stringify(theData)], {type: "text/plain"});
    var dl = document.createElement("A");
    dl.href = URL.createObjectURL(blob);
    console.log(dl.href);
    dl.download = "PandaCrazy_" + formatAMPM("short") + ".json";
    document.body.appendChild(dl);
    dl.click();
    dl.remove();
}
function exportJobs() {
    //load from database to temp data variable
    $("#JRWaitDialog").html("");
    $("#JRWaitDialog").dialog("open");
    saveToFile({"Requesters":gRequestersData,"Options":gMainOptions,"Tabsdata":gTabsData,"Grouping":gGroupingData});
    $("#JRWaitDialog").dialog("close");
}
function importJobs(theFile) {
    //load json text and verify it's correct data for the database
    $("div[aria-describedby='JRWaitDialog'] .ui-dialog-buttonpane button:contains('Cancel') span").html("Close");
    $("#JRWaitDialog").data("closeme",function() { saveSettings(); });
    $("#JRWaitDialog").html("");
    $("#JRWaitDialog").dialog("open");
    $("#JRWaitDialog").dialog("option", "title", "Please wait for importing data");
    if (window.File && window.FileReader && window.FileList && window.Blob) {
        var reader = new FileReader();
        reader.onload = function() {
            $("#JRWaitDialog").append(createDiv("Loaded file in memory."))
            var textData = reader.result;
            setTimeout( function() {
                try {
                    $("#JRWaitDialog").append(createDiv("Parsing the imported Data."))
                    var theData = JSON.parse(textData);
                    $("#JRWaitDialog").append(createDiv("Stopping all Jobs"))
                    stopAll();
                    setTimeout( function() {
                        $("#JRWaitDialog").append(createDiv("Removing all Job Cells"))
                        $("#JRMainTabs").find(".ui-tabs-panel").each( function() {
                            $(this).find(".JRHitCell").each( function() {
                                $(this).remove();
                            });
                        });
                        setTimeout( function() {
                            $("#JRWaitDialog").append(createDiv("Removing all Tabs"))
                            $.each(gTabsData, function( index, value ) {
                                var panelId = $("#JRTab_" + value.tabNumber).closest( "li" ).remove().attr( "aria-controls" );
                                $( "#" + panelId ).remove();
                                $("#JRMainTabs").tabs( "refresh" );
                            });
                            setTimeout( function() {
                                $("#JRWaitDialog").append(createDiv("Deleting Collection Data"))
                                $.each(gMainData.hitCollection, function( index, value ) {
                                    delete gMainData.hitCollection[index];
                                });
                                setTimeout( function() {
                                    $("#JRWaitDialog").append(createDiv("Deleting Requesters Data"))
                                    $.each(gRequestersData, function( index, value ) { delete gRequestersData[index]; });
                                    $("#JRWaitDialog").append(createDiv("Deleting Grouping Data"))
                                    $.each(gGroupingData, function( index, value ) { delete gGroupingData[index]; });
                                    $.each(gGroupings, function( index, value ) { delete gGroupings[index]; });
                                    gGroupingsSort.splice(0,gGroupingsSort.length);
                                    setTimeout( function() {
                                        $("#JRWaitDialog").append(createDiv("Deleting Tabs"))
                                        $.each(gTabsData, function( index, value ) {
                                            delete gTabsData[index];
                                        });
                                        setTimeout( function() {
                                            $("#JRWaitDialog").append(createDiv("Adding imported data in the database."))
                                            gRequestersData = convertDatabase(theData["Requesters"]);
                                            gTabsData = theData["Tabsdata"];
                                            gGroupingData = theData["Grouping"];
                                            fillInGroupings();
                                            $.each(gTabsData, function( index, value ) {
                                                addTab($("#JRMainTabs"),value.tabName,true,"JRTab_" + value.tabNumber,value,true).css({"overflow":"visible"});
                                            });
                                            fillTabs();
                                            setTimeout( function() {
                                                $("#JRMainTabs").tabs("option", "active", 0);
                                                $("#JRWaitDialog").append(createDiv("Importing is finished."))
                                                $("#JRWaitDialog").dialog("option", "title", "Importing data is now done.");
                                                $("div[aria-describedby='JRWaitDialog'] .ui-dialog-buttonpane button:contains('Close')").show();
                                            },1);
                                        },1);
                                    },1);
                                },1);
                            },1);
                        },1);
                    },1);
                } catch(e) {
                    console.log("Could not parse text in file. Sorry.");
                }
            },50);
        }
        reader.readAsBinaryString(theFile);
        reader.onerror = function() {
            alert('Unable to read ' + file.fileName);
        };
        return true;
    } else {
        alert('The File APIs are not fully supported by your browser. Fallback required.');
        return false;
    }
}
function checkGroupings(groupingData) {
    if (!groupingData.data) return false;
    if (!groupingData.data.grouping) return false;
    for (var i=0; i<groupingData.data.grouping.length; i++) {
        if ( !gRequestersData[groupingData.data.grouping[i]] ) { groupingData.data.grouping.splice(i, 1); i--; }
        else groupingData.data.grouping[i] = "" + groupingData.data.grouping[i]
    };
    if (groupingData.data.grouping.length==0) return false;
    return true;
}
function saveGroupingHitsData() {
    var tempGrouping = [];
    $("#JREditDialog .groupingHitCell").each( function() {
        if (!$(this).data("removeMe")) tempGrouping.push("" + $(this).data("theNumber"));
    });
    gGroupingData[$("#JREditDialog").data("theNumber")].grouping = tempGrouping;
    showGroupingDialog("view",$("#JREditDialog").data("button"));
}
function saveGroupingCreateData(theName,theDescription) { console.log("ok creating");
    theDescription = theDescription || "";
    if ( !(gGroupingData[theName]) ) {
        gGroupingData[theName] = {"theNumber":++gGroupingData["JR First"].theNumber,
            "description":theDescription,"grouping":$("#JREditDialog").data("theGrouping")};
        gGroupings[theName] = {"data":gGroupingData[theName],"collecting":false};
        gGroupingsSort.push(theName);
        saveSettings();
        return true;
    } else {
        return false;
    }
}
function formatDialog(idName,theHeight,theWidth,theTitle,theButton,editing,theModal) {
    $("#" + idName).dialog("option","height",theHeight);
    $("#" + idName).dialog("option","width",theWidth);
    $("#" + idName).dialog("option", "title", theTitle);
    $("#JREditDialog").dialog("option", "position", { my: "center", at: "center", of: $("body") });
    $("#" + idName).data({"edited":false,"editing":editing,"theNumber":null,"button":theButton,"closeme":null,"yesFunction":null,"NOCloseDialog":false});
    $("#" + idName).dialog("option","modal",theModal);
    $(".ui-dialog-titlebar").show();
    $("div[aria-describedby='" + idName + "'] .ui-dialog-buttonpane button:contains('Yes')").hide();
    $("div[aria-describedby='" + idName + "'] .ui-dialog-buttonpane button:contains('No')").hide();
    $("div[aria-describedby='" + idName + "'] .ui-dialog-buttonpane button:contains('Create Group')").hide();
    $("div[aria-describedby='" + idName + "'] .ui-dialog-buttonpane button:contains('Save')").hide();
    $("div[aria-describedby='" + idName + "'] .ui-dialog-buttonpane button:contains('Close') span").html("Cancel");
    $("div[aria-describedby='" + idName + "'] .ui-dialog-buttonpane button:contains('Cancel')").show();
    $("#JREditDialog").html("");
}
function createGroup() {
    var creating = $("#JREditDialog").data("creating");
    $("#JREditDialog").dialog( "close");
    $(".ui-dialog-titlebar").show();
    gScriptStatus = "normal";
    $(".JRHitCell .JRButton").removeClass("ui-state-disabled");
    $(".JRHitCell").each( function() { updateHitColors($(this).data("theNumber")); });
    $("div[aria-describedby='JREditDialog']").removeClass("notmodal");
    var theGrouping = [];
    $(".JRHitCell:not('.JRHitDummy')").each( function() {
        if (creating=="selection") {
            if ($(this).data("selected")) theGrouping.push("" + $(this).data("theNumber"));
        } else {
            if ($(this).data("hitInfo").collecting != "off") theGrouping.push("" + $(this).data("theNumber"));
        }
        $(this).data("selected",false);
    });
    showGroupingCreateDialog($("#JREditDialog").data("button"),theGrouping,"grouping");
}
function showGroupingCreateDialog(theButton,theGrouping,creating) {
    if (creating=="selection" || creating=="collecting") {
        formatDialog("JREditDialog",106,600,"Select jobs to your group",theButton,"groupingCreate",false);
        gScriptStatus = "creating groupings";
        $("#JREditDialog").data({"creating":creating});
        $(".JRHitCell:not('.JRHitDummy')").css({"background-color":"#E0EEEE"});
        $(".JRHitCell .myFloater").css({"background-color":"#E0EEEE"});
        $(".JRHitCell .JRButton:not('.JRCollectButton')").addClass("ui-state-disabled");
        $("div[aria-describedby='JREditDialog']").addClass("notmodal");
        $("#JREditDialog").data("closeme",function() { 
            gScriptStatus = "normal"; 
            $(".JRHitCell .JRButton").removeClass("ui-state-disabled");
            $(".JRHitCell").each( function() { updateHitColors($(this).data("theNumber")); });
        });
        $("#JREditDialog").dialog("option", "position", { my: "center top", at: "center top", of: $("body") });
        var infoArea = createDiv().attr("class","infoArea").css({"margin":"15px 15px"}).appendTo($("#JREditDialog"));
        $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Create Group')").show();
        if (creating=="selection") {
            createDiv().html("Click on the jobs you want in this group below:")
                .css({"font-size":"14px","text-align":"center"}).appendTo(infoArea);
        } else {
            if (gMainData.jobs==0) {
                createDiv().html("Sorry. You need to start collecting hits to create a grouping instantly.")
                    .css({"font-size":"14px","text-align":"center"}).appendTo(infoArea);
                $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Create Group')").hide();
                $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Cancel') span").html("Close");
            } else {
                createDiv().html("Do you really want to create an instant grouping for all the hits collecting now?")
                    .css({"font-size":"14px","text-align":"center"}).appendTo(infoArea);
                $("#JREditDialog").data({"creating":"created"});
            }
        }
        $(".ui-dialog-titlebar").hide();
        $("#JREditDialog").dialog("open");
    } else if ($("#JREditDialog").data("creating") == "created") {
        $("#JREditDialog").data({"theGrouping":theGrouping});
        saveGroupingCreateData("Instantly Created #" + (gGroupingData["JR First"].theNumber + 1),"Grouping instantly made so no description");
        $("#JREditDialog").data("button",null);
        toggleButton(theButton,null,null);
        $("#JREditDialog").dialog("close");
    } else if (theGrouping.length>0) {
        formatDialog("JREditDialog",300,620,"Name your grouping to create it:",theButton,"groupingCreate",true);
        $("#JREditDialog").data({"theGrouping":theGrouping});
        var groupingArea = createDiv().attr("class","groupingArea").css({"margin":"15px 15px"}).appendTo($("#JREditDialog"));
        createDiv().html("").css({"margin":"15px 0 0 20px","font-size":"14px","color":"red","height":"30px"})
            .attr("class","groupingCreateError").appendTo(groupingArea);
        createDiv().html("Type in the name of this grouping:").css({"font-size":"15px"}).appendTo(groupingArea);
        createDiv().append(createTextInput("").attr("class","groupName").css({"width":"200px","margin":"5px 0 0 30px","height":"25px"})).appendTo(groupingArea);
        createDiv().html("Type in the description of this grouping:").css({"font-size":"15px","margin-top":"5px"}).appendTo(groupingArea);
        createDiv().append(createTextInput("").attr("class","groupDesc").css({"width":"350px","margin":"5px 0 0 30px","height":"25px"})).appendTo(groupingArea);
        var addGroupingButtonArea = createDiv().append(createSpanButton( function(e) {
            var theName = $("#JREditDialog").find(".groupName").val().toString();
            var theDescription = $("#JREditDialog").find(".groupDesc").val().toString();
            if (theName!=="") {
                if (saveGroupingCreateData(theName,theDescription)) {
                    $("#JREditDialog").data("button",null);
                    toggleButton(theButton,null,null);
                    $("#JREditDialog").dialog("close");
                } else {
                    $("#JREditDialog .groupingCreateError:first").html("Error: Found another grouping with this name. Type in a UNIQUE name.");
                }
            } else {
                $("#JREditDialog .groupingCreateError:first").html("Error: You must type in a unique grouping name.");
            }
        },"Create This Named Group",gButtonOffBgColor,gButtonOffColor,"12px"))
            .css({"margin":"10px 0 0 35px"}).appendTo(groupingArea);
        $("#JREditDialog").dialog("open");
    } else {
        var realCreating = $("#JREditDialog").data("creating");
        formatDialog("JREditDialog",106,600,"No groupings selected!",theButton,"groupingCreate",true);
        $("#JREditDialog").data("yesFunction",function() { 
            $("#JREditDialog").dialog( "close"); showGroupingCreateDialog($("#JREditDialog").data("button"),[],$("#JREditDialog").data("creating"));
        });
        $("#JREditDialog").dialog("option", "position", { my: "center top", at: "center top", of: $("body") });
        var infoArea = createDiv().attr("class","infoArea").css({"margin":"15px 15px"}).appendTo($("#JREditDialog"));
        if (realCreating == "selection") {
            createDiv().html("You forgot to select hits for the group. Try again?").css({"font-size":"14px","text-align":"center"}).appendTo(infoArea);
            $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Yes')").show();
            $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('No')").show();
            $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Cancel')").hide();
        } else { 
            createDiv().html("There are no hits currently being collected. Start one first.").css({"font-size":"14px","text-align":"center"}).appendTo(infoArea);
        }
        $(".ui-dialog-titlebar").hide();
        $("#JREditDialog").dialog("open");
    }
}
function refreshGroupingHitsDialog(theKey,groupingViewArea) {
    var theGrouping = gGroupings[theKey].data.grouping;
    console.log(JSON.stringify(theGrouping));
    for (var i=0,len=theGrouping.length; i<len; i++) {
        createDiv().attr("class","groupingHitCell")
            .css({"border-color":"MidnightBlue", "border-width":"3px", "border-style":"groove", "margin":"2px 4px","width":"180px","height":"40px",
                "background-color":gHitBgColor, "font-size":"10px", "overflow":"hidden", "float":"left", "white-space":"nowrap", "padding":"3px 3px"})
            .data({"theNumber":theGrouping[i],"removeMe":false})
            .append(createDiv(gRequestersData[theGrouping[i]].requesterName))
            .append(createDiv(gRequestersData[theGrouping[i]].pay))
            .append(createDiv(gRequestersData[theGrouping[i]].title).css({"font-size":"8px"}))
            .click( function(e) {
                $("#JREditDialog").data("edited",true);
                $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Save')").show();
                $(e.target).data("removeMe",!$(e.target).data("removeMe"));
                $(e.target).closest(".groupingHitCell").css("background-color",($(e.target).data("removeMe")) ? "#F08080" : gHitBgColor);
            }).appendTo(groupingViewArea);
    }
    $("<br clear='all' class='cleartab'>").appendTo(groupingViewArea);
}
function refreshGroupingsDialog(groupingViewArea) {
    var returnValue = {"noGrouping":false,"collecting":false};
    $(groupingViewArea).find(".groupingLine").each( function() {
        $(this).remove();
    });
    $.each(gGroupingsSort, function( index, theKey ) {
        var value = gGroupings[theKey];
        if (theKey != "JR First") {
            var theBackground = "#F1EDC2";
            if (value.collecting) { theBackground = "#66CD00"; returnValue["collecting"] = true; }
            if (!checkGroupings(value)) { theBackground = "#F08080"; returnValue["noGrouping"] = true; }
            if (value.data.grouping.length==0) { theBackground = "#F08080"; returnValue["noGrouping"] = true; }
            var groupingLine = createDiv()
                .css({"margin-top":"2px","background-color":theBackground,"padding":"2px 3px 2px 3px","height":"17px","border":"2px ridge black","cursor":"pointer"})
                .attr({"class":"groupingLine"}).data({"theKey":theKey,"theIndex":index})
                .click( function() {
                    if (value.data.grouping.length>0) {
                        value.collecting = !value.collecting;
                        for (var i=0,len=value.data.grouping.length; i<len; i++) {
                            if ($("#JRCollectB_" + value.data.grouping[i]).length) {
                                if (value.collecting) toggleButtonOn( $("#JRCollectB_" + value.data.grouping[i]),startCollecting,stopCollecting);
                                else toggleButtonOff( $("#JRCollectB_" + value.data.grouping[i]),startCollecting,stopCollecting);
                            } else console.log("bad button");
                        };
                        if (value.collecting) gGroupingsSort.splice(0, 0, gGroupingsSort.splice(index, 1)[0]);
                        refreshGroupingsDialog($("#JREditDialog .groupingViewArea"));
                    }
                }).appendTo(groupingViewArea);
            createSpan().html(theKey + " - " + value.data.description).appendTo(groupingLine);
            var addGroupingButtonArea = createSpanButton( function(e) {
                e.stopPropagation();
                $("#JRYesNoDialog").html("");
                $("#JRYesNoDialog").data("theNumber",$(e.target).data("theKey"));
                $("#JRYesNoDialog").data("theIndex",$(e.target).data("theIndex"));
                $("#JRYesNoDialog").data("yesFunction",function(theKey) {
                    console.log("the key = " + theKey);
                    delete gGroupings[theKey];
                    delete gGroupingData[theKey];
                    gGroupingsSort.splice($("#JRYesNoDialog").data("theIndex"), 1);
                    saveSettings( function() {
                        refreshGroupingsDialog($("#JREditDialog .groupingViewArea"))
                        $("#JRYesNoDialog").dialog( "close");
                    });
                });
                createDiv("Are you sure you want me to delete this job?<br>" + $(e.target).data("theKey")).attr("class","questionArea")
                    .css({"margin":"15px 8px 0 8px","font-size":"19px","text-align":"center","line-height":"20px"}).appendTo($("#JRYesNoDialog"));
                $("#JRYesNoDialog").dialog("open");
            },"Del",gButtonOffBgColor,gButtonOffColor,"12px").data({"theKey":theKey,"theIndex":index})
                .css({"float":"right"}).appendTo(groupingLine);
            var addGroupingButtonArea = createSpanButton( function(e) {
                e.stopPropagation();
            },"Add",gButtonOffBgColor,gButtonOffColor,"12px").data({"theKey":theKey,"theIndex":index})
                .css({"float":"right"}).appendTo(groupingLine);
            var addGroupingButtonArea = createSpanButton( function(e) {
                e.stopPropagation();
                var theKey = $(e.target).data("theKey");
                formatDialog("JREditDialog",600,815,"Groupings Edit:",$("#JREditDialog").data("button"),"groupingHitsEdit",true);
                $("#JREditDialog").data("theNumber",theKey);
                $("#JREditDialog").data("closeme",function() { showGroupingDialog("view",$("#JREditDialog").data("button")); });
                $("#JREditDialog").data("NOCloseDialog",true);
                var groupingViewArea = createDiv().attr("class","groupingViewArea").css({"border":"1px solid grey","margin":"15px 1px","padding":"5px 1px"})
                    .appendTo($("#JREditDialog"));
                refreshGroupingHitsDialog(theKey,groupingViewArea);
            },"Edit",gButtonOffBgColor,gButtonOffColor,"12px").data({"theKey":theKey,"theIndex":index})
                .css({"float":"right"}).appendTo(groupingLine);
        }
    });
    if (returnValue["collecting"]) $("#JREditDialog .JRCollectingInstr").html("Groupings which are collecting are in green color.");
    else $("#JREditDialog .JRCollectingInstr").html("");
    if (returnValue["noGrouping"]) $("#JREditDialog .JREmptyInstr").html("Groupings which have NO hits grouped are in red.");
    else $("#JREditDialog .JREmptyInstr").html("");
}
function showGroupingDialog(doThis,theButton) {
    formatDialog("JREditDialog",600,780,"Groupings List:",theButton,"grouping " + doThis,true);
    $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Cancel') span").html("Close");
    var infoArea = createDiv().attr("class","infoArea").css({"margin":"15px 15px","text-align":"center"}).appendTo($("#JREditDialog"));
    createDiv().html("Click on the Grouping Name you want to start or stop.").css("font-size","14px").appendTo(infoArea);
    createDiv().html("").attr({"class":"JRCollectingInstr"}).css("font-size","14px").appendTo(infoArea);
    createDiv().html("").attr({"class":"JREmptyInstr"}).css("font-size","14px").appendTo(infoArea);
    var groupingViewArea = createDiv().attr("class","groupingViewArea").css({"border":"1px solid grey","margin":"15px 15px","padding":"5px 3px"})
        .appendTo($("#JREditDialog"));
    refreshGroupingsDialog(groupingViewArea);
    $("#JREditDialog").dialog("open");
}
function showExportImportDialog(porting,theButton) {
    formatDialog("JREditDialog",200,300,porting + " data",theButton,"export and importing",true);
    var exportImportArea = createDiv().attr("class","exportImportArea").css("margin","15px 15px").appendTo($("#JREditDialog"));
    if (porting=="Export") {
        createSpanButton( function(e) { 
            var theButton = $("#JREditDialog").data("button");
            $("#JREditDialog").data("button",null);
            toggleButton(theButton,null,null);
            $("#JREditDialog").dialog("close");
            exportJobs();
        },"Export to File",gButtonOffBgColor,gButtonOffColor,"12px").appendTo(exportImportArea);
        createSpanButton( null,"Copy Exported Data",gButtonOffBgColor,gButtonOffColor,"12px").appendTo(exportImportArea);
    } else {
        createDiv().css({"margin":"5px 0 10px 0"}).append($("<input>").attr({"type":"file","id":"importFileInput"})
            .change( function(event) { $("#importFromFileButton").data("disabled",false).css({"background-color":gButtonOffBgColor}); } )).appendTo(exportImportArea);
        createSpanButton( function(e) { 
                if ( !$(e.target).data("disabled") ) importJobs( $("#importFileInput").prop("files")[0] );
                var theButton = $("#JREditDialog").data("button");
                $("#JREditDialog").data("button",null);
                toggleButton(theButton,null,null);
                $("#JREditDialog").dialog("close");
            },"Import From File",gButtonDisabledBgColor,gButtonOffColor,"12px").appendTo(exportImportArea)
            .attr({"id":"importFromFileButton"})
            .data("disabled",true);
    }
    $("#JREditDialog").dialog("open");
}
function showAddJobsDialog(theButton) {
    formatDialog("JREditDialog",250,600,"Add a new PANDA!",theButton,"add job",true);
    var addJobArea = createDiv().attr("class","addJobArea").css("margin","15px 15px").appendTo($("#JREditDialog"));
    createDiv().html("Below enter the preview or the previewandaccept url.<br>You may enter just the groupID number too. This is needed for panda jobs.<br>")
        .append(createTextInput("").attr("class","groupIdInput").css({"width":"400px","margin-left":"30px"})
            .keypress(function(e) {
                if(e.which == 13) $("#JREditDialog .JRAddPanda:first span").click();
            }))
        .append(createDiv()
            .append(createCheckbox().attr("class","collectNow").prop('checked', true).css("margin-left","70px")).append(createSpan("Start Collecting"))
            .append(createCheckbox().attr("class","onlyOnce").css("margin-left","20px")).append(createSpan("Collect only once"))).appendTo(addJobArea);
    var addGroupIDButtonArea = createDiv().append(createSpanButton( function(e) {
        var theValue = $("#JREditDialog .groupIdInput:first").val();
        var collectNow = $("#JREditDialog .collectNow:first").prop('checked');
        var onlyOnce = $("#JREditDialog .onlyOnce:first").prop('checked');
        $("#JREditDialog .groupIDError").html("");
        var parsedGroupID = "";
        if (theValue=="") { $("#JREditDialog .groupIDError").html("Please Enter a url or GroupID first."); }
        else if (theValue.indexOf("groupId=")!=-1) {
            parsedGroupID = theValue.split("groupId=")[1];
            if (parsedGroupID.indexOf("&")!=-1) parsedGroupID = parsedGroupID.split("&")[0];
        } else if (theValue.indexOf("mturk.com")==-1) {
            parsedGroupID = theValue;
        } else { $("#JREditDialog .groupIDError").html("Please Enter a url or GroupID first."); }
        if (parsedGroupID!="") {
            console.log("found GroupID: " + parsedGroupID);
            var newHitData = jQuery.extend(true, {}, gRequestersData[0]);
            newHitData.requesterName = parsedGroupID; newHitData.requesterId = ""; newHitData.action = "Panda"; newHitData.groupId = parsedGroupID;
            newHitData.pay = "0.00"; newHitData.qual = ""; newHitData.title = parsedGroupID; newHitData.queueLimit = 0; newHitData.duration = "";
            newHitData.audioforce = ""; newHitData.hitlimit = ""; newHitData.mute = false; newHitData.position = null;
            newHitData.tabNumber = gTabsData[0].tabNumber; newHitData.once = onlyOnce; newHitData.hamTimer = gMainOptions.hamDelayTimer;
            var newCell = addHitData(newHitData,0);
            updateHitCell(newCell.data("theNumber"));
            if (collectNow) {
                newCell.data("status","on");
                toggleButton( newCell.find(".JRCollectButton"),startCollecting,stopCollecting );
            }
            $("#JRMainTabs").tabs("option", "active", 0);
            var theButton = $("#JREditDialog").data("button");
            toggleButton(theButton,null,null);
            $("#JREditDialog").dialog("close");
        }
    },"Add Panda for Group ID hit",gButtonOffBgColor,gButtonOffColor,"12px")).attr("class","JRAddPanda")
        .css({"margin":"6px 0 0 35px"}).appendTo(addJobArea);
    createSpan("").attr("class","groupIDError").css({"color":"red","margin-left":"10px"}).appendTo(addGroupIDButtonArea);
    $("#JREditDialog .groupIDError")
    $("#JREditDialog").dialog("open");
}
function alarmReaderEditor(fileInput) {
    $("#JREditDialog").data("edited",true);
    $("div[aria-describedby='JREditDialog'] .ui-dialog-buttonpane button:contains('Save')").show();
    console.log("JR " + fileInput.prop("files")[0].name + " : " + fileInput.prop("files")[0].size);
    if (fileInput.prop("files")[0].size > 150000) console.log("JR sorry this is too big");
    var reader = new FileReader();
    reader.onload = function() {
        var readerContents = reader.result;
        var base64Audio = btoa(readerContents);
        var newAudio = new Audio("data:audio/wav;base64," + base64Audio);
        playNewSound( newAudio );
        fileInput.data("base64",base64Audio);
        fileInput.data("audio",newAudio);
    }
    reader.readAsBinaryString(fileInput.prop("files")[0]);
    reader.onerror = function() {
        alert('Unable to read ' + file.fileName);
    };
}
function showAlarmsDialog( theNumber, theButton ) {
    formatDialog("JREditDialog",700,650,"Edit your alarms according to what you like:",theButton,"alarms",true);
    var alarmsArea = createDiv().attr("class","alarmsArea").css({"margin":"15px 15px"}).appendTo($("#JREditDialog"));
    createDiv().html("")
        .css({"font-size":"15px","text-align":"center"}).appendTo(alarmsArea);
    $.each(gAlarmSounds, function( index, value ) {
        var importFileID = "importFileInput-" + index; console.log(importFileID);
        createDiv().attr("class","alarmInputEdits")
            .append(createDiv().append(createSpanButton(function(e) { playNewSound($("#" + importFileID).data("audio")); }
                    ,"- Play -","ivory","black","13px").css({"margin-right":"20px"}))
                .append(createSpan(value.desc).css({"font-weight":"bolder","textDecoration":"underline"}))
                .css({"margin-top":"10px"}))
            .append(createDiv().html("Change to: ").append($("<input>").attr({"type":"file","id":importFileID,"accept":"audio/*"}).data("audio",value.audio).data("base64",null)
                .change( function() { alarmReaderEditor($(this)); })).css({"margin":"8px 0 0 80px"})).appendTo(alarmsArea);
    });
    $("#JREditDialog").dialog("open");
}
function showEditTimersDialog( theNumber, theButton ) {
    formatDialog("JREditDialog",610,650,"Edit this hit:",theButton,"timers",true);
    var timersArea = createDiv().attr("class","timersArea").css({"margin":"15px 15px"}).appendTo($("#JREditDialog"));
    createDiv().html("All the timers on this page is measured in Milliseconds.<br>1000 Milliseconds is equal to 1 second.<br>Click on numbers to edit.")
        .css({"font-size":"15px","text-align":"center"}).appendTo(timersArea);
    createDiv().html("Cycle Timer: ").append(createSpan(gMainOptions.cycleNumber.toString())).css("margin-top","30px")
        .attr({"class":"timersLine","id":"timersCycleEdit"}).appendTo(timersArea)
        .click( function() { dataEdited($(this),gMainOptions.cycleNumber); });
    createDiv().html("GoHam Cycle Timer: ").append(createSpan(gMainOptions.HamCycleNumber.toString())).css("margin-top","10px")
        .attr({"class":"timersLine","id":"timersGoHamEdit"}).appendTo(timersArea)
        .click( function() { dataEdited($(this),gMainOptions.HamCycleNumber); });
    createDiv().html("Default GoHam Delay Timer: ").append(createSpan(gMainOptions.hamDelayTimer.toString())).css("margin-top","10px")
        .attr({"class":"timersLine","id":"timersHamDelayEdit"}).appendTo(timersArea)
        .click( function() { dataEdited($(this),gMainOptions.hamDelayTimer); });
    createDiv().html("Check Queue Timer Every: ").append(createSpan(gMainOptions.queueTimer.toString())).css("margin-top","10px")
        .attr({"class":"timersLine","id":"timersCheckQueueEdit"}).appendTo(timersArea)
        .click( function() { dataEdited($(this),gMainOptions.queueTimer); });
    var AdvancedArea = createDiv().attr("class","advancedArea").css({"border":"1px solid grey","margin":"20px 0 0 0","padding":"5px 3px"}).appendTo(timersArea);
    createDiv().html("Advanced Options:").css({"font-size":"15px","text-align":"center"}).appendTo(AdvancedArea);
    createDiv().html("Cycle Increase Button: ").append(createSpan(gMainOptions.cycleIncrease.toString())).css("margin-top","15px")
        .attr({"class":"timersLine","id":"timersCycleIncreaseEdit"}).appendTo(AdvancedArea)
        .click( function() { dataEdited($(this),gMainOptions.cycleIncrease); });
    createDiv().html("Cycle Decrease Button: ").append(createSpan(gMainOptions.cycleDecrease.toString())).css("margin-top","10px")
        .attr({"class":"timersLine","id":"timersCycleDecreaseEdit"}).appendTo(AdvancedArea)
        .click( function() { dataEdited($(this),gMainOptions.cycleDecrease); });
    createDiv().html("Cycle Add Time Button: ").append(createSpan(gMainOptions.cycleAdding.toString())).css("margin-top","10px")
        .attr({"class":"timersLine","id":"timersCycleAddingEdit"}).appendTo(AdvancedArea)
        .click( function() { dataEdited($(this),gMainOptions.cycleAdding); });
    createDiv().html("Cycle Auto Slowdown Increase: ").append(createSpan(gMainOptions.cycleAutoIncrease.toString())).css("margin-top","10px")
        .attr({"class":"timersLine","id":"timersCycleAutoIncreaseEdit"}).appendTo(AdvancedArea)
        .click( function() { dataEdited($(this),gMainOptions.cycleAutoIncrease); });
    $("#JREditDialog").dialog("open");
}
function showEditHitDialog( theNumber, theButton ) {
    formatDialog("JREditDialog",640,600,"Edit this hit:",theButton,"job",true);
    $("#JREditDialog").data("theNumber",theNumber);
    var hitInfo = gMainData.hitCollection[theNumber];
    var hitData = hitInfo.data;
    var requesterArea = createDiv().attr("class","requesterArea").css("margin","15px 8px").appendTo($("#JREditDialog"));
    createDiv().html("Details of hit. All can be edited except for details in red.<br>Click on details to edit.")
        .css({"font-size":"15px","text-align":"center"}).appendTo(requesterArea);
        
    createDiv().html("Queue Limit: ").append(createSpan( hitData.queueLimit.toString() )).css({"margin-top":"10px"})
        .attr({"class":"requesterLine","id":"queueLimitEdit"}).appendTo(requesterArea)
        .click( function() { dataEdited($(this),hitData.queueLimit.toString()); });
    createDiv().html("Daily Limit: ").append(createSpan( hitData.dailyLimit.toString() ))
        .attr({"class":"requesterLine","id":"dailyLimitEdit"}).appendTo(requesterArea)
        .click( function() { dataEdited($(this),hitData.dailyLimit.toString()); });
    createDiv().html("Daily Done: ").append(createSpan(hitData.dailyDone.toString()))
        .attr({"class":"requesterLine","id":"dailyDoneEdit"}).appendTo(requesterArea)
        .click( function() { dataEdited($(this),hitData.dailyDone.toString()); });
    createDiv().html("Ham Timer (seconds): ").append(createSpan( hitData.hamTimer.toString() ))
        .attr({"class":"requesterLine","id":"hamTimerEdit"}).appendTo(requesterArea)
        .click( function() { dataEdited($(this),hitData.hamTimer.toString()); });
    createDiv().html("Once: ").append(createSpan( hitData.once.toString() ))
        .attr({"class":"requesterLine","id":"onceEdit"}).appendTo(requesterArea)
        .click( function() { hitData.once=dataTrueFalse($(this),hitData.once); });
    var advancedArea = createDiv().attr("class","advancedArea").css({"border":"1px solid grey","margin":"20px 0 0 0","padding":"5px 3px"}).appendTo(requesterArea);
    createDiv().html("Advanced Options most are changed by the script automatically:").css({"font-size":"15px","text-align":"center"}).appendTo(advancedArea);
    createDiv().html("The Number: ").append(createSpan(theNumber)).appendTo(advancedArea).css({"margin-top":"5px","color":"red"});
    createDiv().html("Action: ").append(createSpan(hitData.action))
        .attr({"class":"requesterLine","id":"actionEdit"}).appendTo(advancedArea)
        .click( function() { dataEdited($(this),hitData.action); });
    createDiv().html("Requester Name: ").append(createSpan(hitData.requesterName))
        .attr({"class":"requesterLine","id":"requesterNameEdit"}).appendTo(advancedArea)
        .click( function() { dataEdited($(this),hitData.requesterName); });
    createDiv().html("Requester ID: ").append(createSpan(hitData.requesterId))
        .attr({"class":"requesterLine","id":"requesterIdEdit"}).appendTo(advancedArea)
        .click( function() { dataEdited($(this),hitData.requesterId); });
    createDiv().html("Group ID: ").append(createSpan(hitData.groupId))
        .attr({"class":"requesterLine","id":"groupIdEdit"}).appendTo(advancedArea)
        .click( function() { dataEdited($(this),hitData.groupId); });
    createDiv().html("Pay: ").append(createSpan(hitData.pay))
        .attr({"class":"requesterLine","id":"payEdit"}).appendTo(advancedArea)
        .click( function() { dataEdited($(this),hitData.pay); });
    createDiv().html("Qualifications: ").append(createSpan(hitData.qual)).css("color","red") // Can not be edited.
        .attr({"class":"requesterLine","id":"qualEdit"}).appendTo(advancedArea);
    createDiv().html("Title: ").append(createSpan(hitData.title))
        .attr({"class":"requesterLine","id":"titleEdit"}).appendTo(advancedArea)
        .click( function() { dataEdited($(this),hitData.title); });
    createDiv().html("Duration: ").append(createSpan(hitData.duration))
        .attr({"class":"requesterLine","id":"durationEdit"}).appendTo(advancedArea)
        .click( function() { dataEdited($(this),hitData.duration); });
    createDiv().html("Force Audio: ").append(createSpan(hitData.audioforce))
        .attr({"class":"requesterLine","id":"audioforceEdit"}).appendTo(advancedArea)
        .click( function() { dataEdited($(this),hitData.audioforce); });
    if (hitData.action.indexOf("Filter") != -1) {
        var filterModeArea = createDiv().html("Filter Mode: ")
            .attr({"class":"requesterLine","id":"filterModeEdit"}).appendTo(advancedArea)
            .change( function() { dataEdited($(this),hitData.filterMode.toString()); });
        var filterSelection = $("<select>").attr("name","filterMode").appendTo(filterModeArea);
        var selected = "";
        for (var i=0,len=Object.keys(hitInfo.filterFuncData).length; i<len; i++) {
            selected = (hitData.filterMode==i+1) ? " selected='selected'" : "";
            filterSelection.append("<option value=" + Object.keys(hitInfo.filterFuncData)[i] + selected + ">" + hitInfo.filterFuncData[i+1].filterName + "</option>");
        }
        var selected = (hitData.filterMode==0) ? " selected='selected'" : "";
        filterSelection.append("<option value=0 " + selected + ">Off</option>");
    }
    var buttonJobArea = createDiv().css({"margin-top":"35px"}).appendTo(requesterArea);
    var muteJobButton = createSpanButton( function(e) {
            muteJob(theNumber);
            $(this).html( (hitData.mute) ? "Turn on Alarm" : "Mute Alarm" );
        },(hitData.mute) ? "Turn on Alarm" : "Mute Alarm",gButtonOffBgColor,gButtonOffColor,"13px")
        .css({"border-color":"blue"})
        .attr({"class":"requesterLine","id":"muteJobButton"}).appendTo(buttonJobArea);
    var deleteJobButton = createSpanButton( function(e) {
            $("#JRYesNoDialog").html("");
            $("#JRYesNoDialog").data("theNumber",theNumber);
            $("#JRYesNoDialog").data("yesFunction",function(theNumber) {
                $("#JRCellNum_" + theNumber).remove();
                stopCollecting(theNumber);
                delete gMainData.hitCollection[theNumber];
                delete gRequestersData[theNumber];
                saveSettings( function() { $("#JREditDialog").dialog( "close"); $("#JRYesNoDialog").dialog( "close");} );
            });
            createDiv("Are you sure you want me to delete this job?").attr("class","questionArea")
                .css({"margin":"15px 8px","font-size":"19px","text-align":"center"}).appendTo($("#JRYesNoDialog"));
            $("#JRYesNoDialog").dialog("open");
        },"Delete Job",gButtonOffBgColor,gButtonOffColor,"13px")
        .attr({"class":"requesterLine","id":"deleteJobButton"}).css({"margin-left":"80px"}).appendTo(buttonJobArea);
    $("#JREditDialog").dialog("open");
}
function releaseButton(thisDialog) {
    if ($(thisDialog).data("button")) {
        toggleButton($(thisDialog).data("button"),null,null);
        $(thisDialog).data("button",null);
    }
}
function createADialog(idName,theTitle,theHeight,theWidth,isModal,saveFunction,theNumber) {
    createContainer().attr("id",idName)
        .data({"button":null,"theNumber":theNumber,"NOCloseDialog":false})
        .appendTo("body")
        .dialog({
            dialogClass: "no-close", autoOpen: false, title: theTitle, height: theHeight, width: theWidth, modal: isModal,
            buttons: {
                "Yes": function() {
                    if ($(this).data("yesFunction")) ($(this).data("yesFunction"))($(this).data("theNumber"));
                },
                "No": function() { releaseButton($(this)); $(this).dialog( "close"); },
                "Create Grouping": function() { createGroup(); },
                "Save": function() { 
                    var NOCloseDialog = $(this).data("NOCloseDialog");
                    if (saveFunction) saveFunction();
                    if (!NOCloseDialog) {
                        releaseButton($(this));
                        $(this).dialog( "close");
                    }
                },
                "Cancel": function() {
                    var NOCloseDialog = $(this).data("NOCloseDialog");
                    if ($(this).data("closeme")) ($(this).data("closeme"))();
                    if (!NOCloseDialog) {
                        releaseButton($(this));
                        $(this).dialog( "close");
                    }
                }
            }
        });
    $("div[aria-describedby='" + idName + "'] .ui-dialog-buttonpane button:contains('Save')").hide();
    $("div[aria-describedby='" + idName + "'] .ui-dialog-buttonpane button:contains('Create Group')").hide();
    $("div[aria-describedby='" + idName + "'] .ui-dialog-buttonpane button:contains('Yes')").hide();
    $("div[aria-describedby='" + idName + "'] .ui-dialog-buttonpane button:contains('No')").hide();
}
function createWaitDialog() {
    createADialog("JRWaitDialog","Please Wait",230,300,true);
    $("div[aria-describedby='JRWaitDialog'] .ui-dialog-buttonpane button:contains('Cancel')").hide();
}
function createEditDialog() {
    createADialog("JREditDialog","Job Details",600,500,true,saveEditedData);
}
function createYesNoDialog() {
    createADialog("JRYesNoDialog","Are you sure?",155,560,true,null,"");
    $("div[aria-describedby='JRYesNoDialog'] .ui-dialog-buttonpane button:contains('Yes')").show();
    $("div[aria-describedby='JRYesNoDialog'] .ui-dialog-buttonpane button:contains('No')").show();
    $("div[aria-describedby='JRYesNoDialog'] .ui-dialog-buttonpane button:contains('Cancel')").hide();
}
function shortGroupID( groupId ) { return groupId.slice(0,2) + ".." + groupId.slice(-4); }
function updateHitCell(theNumber) {
    var hitInfo = gMainData.hitCollection[theNumber];
    var hitData = hitInfo.data;
    var hitCell = $("#JRCellNum_" + theNumber).eq(0);
    $(hitCell).find(".myTitle").html(hitData.requesterName).attr({"title":hitData.requesterName + "\n" + hitData.groupId});
    $(hitCell).find(".myfloater").html(".. " + shortGroupID(hitData.groupId));
    if (gMainData.displayInfo==0) {
        $(hitCell).find(".myExtra").html("");
        $(hitCell).find(".myDescription").html("");
    } else if (gMainData.displayInfo==1) {
        $(hitCell).find(".myExtra").html(hitData.pay + ( (hitData.qual=="") ? "" : " (" + hitData.qual + ") " ) + ( (hitInfo.numberHits=="0") ? "" : " [" + hitInfo.numberHits + "] " ));
        $(hitCell).find(".myDescription").html(hitData.title);
    }
}
function updateHitColors(theNumber,thisButton) {
    if (theNumber) {
        var hitInfo = gMainData.hitCollection[theNumber];
        var hitData = hitInfo.data;
        var collectButtonStatus = $("#JRCellNum_" + theNumber).find(".JRCollectButton").data("status");
        $("#JRCellNum_" + theNumber).data("status",collectButtonStatus);
        var gohamButtonStatus = $("#JRCellNum_" + theNumber).find(".JRHamButton").data("status");
        var gohamButtonDisabled = $("#JRCellNum_" + theNumber).find(".JRHamButton").data("disabled");
        var hitCellMute = $("#JRCellNum_" + theNumber).data("mute");
        var hitCellTypeAction = hitData.action;
        var hitBgColor = (hitCellTypeAction.substring(0,6)=="Search") ? gSearchesHitBgColor : (hitCellTypeAction=="FilterPanda") ? gFilteredHitBgColor : gHitBgColor;
        var titleColor = (hitCellMute) ? gHitMutedColor : gTitleColor;
        var borderStyle = (hitCellMute) ? gHitMutedBorderStyle : gHitBorderStyle;
        var collectBgColor = (collectButtonStatus=="off") ? gButtonOffBgColor : gButtonOnBgColor;
        var collectColor = (collectButtonStatus=="off") ? gButtonOffColor : gButtonOnColor;
        var gohamBgColor = (gohamButtonDisabled) ? gButtonDisabledBgColor : (gohamButtonStatus=="off") ? gButtonOffBgColor : (gohamButtonStatus=="paused") ? gButtonDelayHamBgColor : gButtonOnBgColor;
        var goHamColor = (gohamButtonDisabled) ? gButtonDisabledColor : (gohamButtonStatus=="off") ? gButtonOffColor : gButtonOnColor;
        $("#JRCellNum_" + theNumber).css({"background-color":hitBgColor});
        $("#JRCellNum_" + theNumber).css({"border-style":borderStyle});
        $("#JRCellNum_" + theNumber).find(".myTitle").css({"color":titleColor});
        $("#JRCellNum_" + theNumber).find(".JRCollectButton").css({"background-color":collectBgColor});
        $("#JRCellNum_" + theNumber).find(".JRCollectButton").css({"color":collectColor});
        $("#JRCellNum_" + theNumber).find(".JRHamButton").css({"background-color":gohamBgColor});
        $("#JRCellNum_" + theNumber).find(".JRHamButton").css({"color":goHamColor});
        $("#JRCellNum_" + theNumber).find(".myfloater").css({"background-color":hitBgColor});
    } else {
        var buttonStatus = $(thisButton).data("status");
        var buttonBgColor = (buttonStatus=="off") ? gButtonOffBgColor : gButtonOnBgColor;
        var buttonColor = (buttonStatus=="off") ? gButtonOffColor : gButtonOnColor;
        $(thisButton).css({"background-color":buttonBgColor});
        $(thisButton).css({"color":buttonColor});
    }
}
function createHitCell(goAppend,hitData,cellNumber) {
    var theContainer = createContainer();
    var hitInfo = gMainData.hitCollection[cellNumber];
    var backgroundColor = (hitData.action.substring(0,6)=="Search") ? gSearchesHitBgColor : (hitData.action=="FilterPanda") ? gFilteredHitBgColor : gHitBgColor;
    var floaterRight = createDiv()
        .attr({"class":"myfloater"})
        .data({"hitInfo":hitInfo})
        .click(function(e) { GM_setClipboard ($(e.target).data("hitInfo").pandaUrl); e.stopPropagation();})
        .css({"float":"right","margin-right":"-3px","padding":"0 1px 0 3px","font-weight":"900","background-color":backgroundColor,
            "color":"purple","font-size":"7px","z-index":"999","position":"relative"})
        .html(".. " + shortGroupID(hitData.groupId)).appendTo(theContainer);
    var theInfoArea = createDiv();
    var titleColor = (hitData.mute) ? gHitMutedColor : gTitleColor;
    createDiv().html(hitData.requesterName).css({"font-weight":"900","color":titleColor,"font-size":"13px"})
        .attr({"class":"myTitle hasTooltip","title":hitData.requesterName + "\n" + hitData.groupId})
        .tooltip({ show: {delay:1100} }).appendTo(theContainer);
    if (gMainData.displayInfo==0) {
        var htmlDescription = "";
    } else if (gMainData.displayInfo==1) {
        var htmlDescription = hitData.pay + ( (hitData.qual=="") ? "" : " (" + hitData.qual + ") " );
    }
    var htmlTitle = hitData.title;
    createDiv().html(htmlDescription).attr({"class":"myExtra"})
        .css({"font-size":"11px"}).appendTo(theContainer);
    createDiv().html(htmlTitle).css({"font-size":"10px"})
        .attr({"class":"myDescription hasTooltip","title":hitData.title}).tooltip({ show: {delay:1100} }).appendTo(theContainer);
    createDiv().html(" ").attr({"class":"myStatus","id":"JRCellStatus_" + cellNumber})
        .css({"color":"darkred","font-weight":"400","font-size":"10px"}).appendTo(theContainer);
    createCheckbox("testing").css({"float":"right","position":"relative","width":"25px","height":"15px"}).attr("class","myCheckBox").hide()
        .click(function(e) { e.stopPropagation(); }).appendTo(theContainer);
    var theButtonArea = createDiv().css({"padding":"2px"}).appendTo(theContainer);
    createSpanButton( function(e) {
            var thisHitInfo = $(e.target).data("hitInfo");
            toggleButton( $(e.target),startCollecting,stopCollecting);
            if (thisHitInfo.collecting=="off" && thisHitInfo.ham != "off") toggleButtonOff($("#JRHamB_" + $(e.target).data("theNumber")),hamOn,hamOff);
            e.stopPropagation();
        },"Collect",gButtonOffBgColor,gButtonOffColor,"12px")
        .bind("mousedown", function(e) {
            $(e.target).closest(".tabContents").sortable("disable");})
        .bind("mouseup mouseleave", function(e) { 
            $(e.target).closest(".tabContents").sortable("enable");})
        .attr({"id":"JRCollectB_" + cellNumber,"class":"JRCollectButton JRButton"})
        .data({"theNumber":cellNumber,"hitCell":theContainer,"hitInfo":hitInfo,"status":"off","disabled":false}).appendTo(theButtonArea);
    createSpanButton( function(e) {
            if ( !$(e.target).data("disabled") && !gPressAndHold ) {
                var thisHitInfo = $(e.target).data("hitInfo");
                if (thisHitInfo.collecting == "off") toggleButton($("#JRCollectB_" + $(e.target).data("theNumber")),startCollecting,stopCollecting);
                if (thisHitInfo.ham == "paused") toggleButtonOff($(e.target),hamOn,hamOff);
                else toggleButton($(e.target),hamOn,hamOff);
                gPressAndHold=false;
                e.stopPropagation();
            } else if (gPressAndHold) gPressAndHold=false;
        },"GoHam",gButtonOffBgColor,gButtonOffColor,"12px")
        .bind("mousedown", function(e) {
            var thisButton = $(e.target);
            $(e.target).closest(".tabContents").sortable("disable");
            gMouseDownTimeoutId = setTimeout( function() {
                gPressAndHold=true;
                console.log("mousedown timer finished");
                var thisNumber = $(thisButton).data("theNumber");
                if ($(thisButton).data("hitInfo").collecting == "off") toggleButton($("#JRCollectB_" + thisNumber),startCollecting,stopCollecting);
                toggleButton($(thisButton),hamOn,hamOff,"paused","off");
            }, 500);
            e.stopPropagation();
        })
        .bind("mouseup mouseleave", function(e) { 
            clearTimeout(gMouseDownTimeoutId);
            $(e.target).closest(".tabContents").sortable("enable");
            e.stopPropagation();
        })
        .attr({"id":"JRHamB_" + cellNumber,"class":"JRHamButton JRButton"})
        .data({"theNumber":cellNumber,"hitCell":theContainer,"hitInfo":hitInfo,"status":"off","disabled":false}).appendTo(theButtonArea);
    createSpanButton( function(e) {
            showEditHitDialog($(e.target).data("theNumber"),$(e.target));
            e.stopPropagation();
        },"details",gButtonOffBgColor,gButtonOffColor,"9px")
        .bind("mousedown", function(e) {
            $(e.target).closest(".tabContents").sortable("disable");})
        .bind("mouseup mouseleave", function(e) { 
            $(e.target).closest(".tabContents").sortable("enable");})
        .attr({"id":"JRDetailsB_" + cellNumber,"class":"JRDetailsButton JRButton"})
        .data({"theNumber":cellNumber,"hitCell":theContainer,"hitInfo":hitInfo,"status":"off","disabled":false}).appendTo(theButtonArea);
    var borderStyle = (hitData.mute) ? "dotted" : "solid";
    theContainer.width("200px")
        .attr({"id":"JRCellNum_" + cellNumber,"class":"JRHitCell"})
        .data({"backgroundColor":backgroundColor,"borderColor":"MidnightBlue","titleColor":gTitleColor,"theNumber":cellNumber,"status":"off",
                "mute":hitData.mute,"firstPanda":false,"typeAction":hitData.action,"hitData":hitData,"hitInfo":hitInfo,"oldPosition":null,"selected":false})
        .css({"border-color":"MidnightBlue", "border-width":"3px", "border-style":borderStyle, "margin":"2px 4px",
            "background-color":backgroundColor, "font-size":"11px", "cursor":"move", "overflow":"hidden", "float":"left", "white-space":"nowrap"})
        .bind("contextmenu", function(e) {
            if ($(e.target).is(".JRButton")) return;
            e.preventDefault();
            muteJob($(e.target).data("theNumber"));
        })
        .bind("mouseup mouseleave", function(e) {
            if ($(e.target).is(".JRButton")) { e.stopPropagation(); return; }
        })
        .dblclick( function(e) {
            var theHitCell = $(e.target).closest(".JRHitCell");
            var thisHitInfo = theHitCell.data("hitInfo");
            var thisHitData = thisHitInfo.data;
            var newHitData = jQuery.extend(true, {}, gRequestersData[0]);
            newHitData.requesterName = thisHitData.requesterName; newHitData.requesterId = thisHitData.requesterId; newHitData.groupId = thisHitData.groupId;
            newHitData.pay = "0.00"; newHitData.qual = ""; newHitData.title = thisHitData.title; newHitData.queueLimit = 0; newHitData.duration = thisHitData.duration;
            newHitData.audioforce = ""; newHitData.hitlimit = ""; newHitData.mute = false; newHitData.position = null; newHitData.maxHam = "";
            newHitData.tabNumber = gTabsData[0].tabNumber; newHitData.hamTimer = gMainOptions.hamDelayTimer;
            if ( theHitCell.data("typeAction").substring(0,6) != "Search" ) {
                $("#JRMainTabs").tabs("option", "active", 1);
                newHitData.action = "Search";
                var newHitCell = addHitData(newHitData,0);
                gMainData.hitCollection[ $(newHitCell).data("theNumber") ].title = thisHitInfo.newTitle;
            } else if (newHitData.groupId != "") {
                $("#JRMainTabs").tabs("option", "active", 0);
                newHitData.action = "Panda"; newHitData.tabNumber = gTabsData[0].tabNumber; newHitData.title = "Any Hit"; newHitData.pay = "0.00";
                var myDisabled = theCycler.isHamOn();
                var newHitCell = addHitData(newHitData,0);
                $(newHitCell).find(".JRHamButton").data({"disabled":myDisabled});
                updateHitColors(newHitCell.data("theNumber"));
            }
        })
        .click( function(e) {
            if (gScriptStatus == "normal") {
                if ($(e.target).is(".JRButton")) { e.stopPropagation(); return; }
                if ($(e.target).hasClass('noclick')) {
                    $(e.target).removeClass('noclick');
                } else {
                    var theHitCell = $(e.target).closest(".JRHitCell");
                    var thisHitInfo = theHitCell.data("hitInfo");
                    if ( theHitCell.data("typeAction").substring(0,6) == "Search" ) {
                        var firstPanda = !(theHitCell.data("firstPanda"));
                        var borderColor = (firstPanda) ? "red" : theHitCell.data("borderColor");
                        thisHitInfo.goToUrl.splice(0,thisHitInfo.goToUrl.length);
                        theHitCell.css({"border-color":borderColor});
                        theHitCell.data("firstPanda",firstPanda);
                    }
                }
            } else if (gScriptStatus == "creating groupings") {
                console.log("creating groupings");
                var theHitCell = $(e.target).closest(".JRHitCell");
                if (theHitCell.data("selected")) {
                    theHitCell.css({"background-color":"#E0EEEE"});
                    theHitCell.data("selected",false);
                } else {
                    theHitCell.css({"background-color":"#ADFF2F"});
                    theHitCell.data("selected",true);
                }
            }
        });
    theContainer.appendTo(goAppend);
    displayHitStatus(cellNumber);
    return theContainer;
}
function addHitData(newHitData,tabIndex) {
    var inTabId = "#" + $("#JRTab_" + newHitData.tabNumber).attr("aria-controls");
    gRequestersData[gRequestersData[0].requesterId] = newHitData;
    $(inTabId).data("tabData").positions.push(gRequestersData[0].requesterId);
    var theNumber = addHitCollection(newHitData,gRequestersData[0].requesterId,tabIndex);
    gRequestersData[0].requesterId++;
    $(inTabId).find("#.JRHitDummy").remove();
    newHitCell = createHitCell($(inTabId).find(".tabContents"),newHitData,theNumber).data({"removeMe":false,"pandaHam":"off"});
    $(inTabId).append(createDiv("&nbsp;").attr("class","JRHitCell JRHitDummy").data("hitInfo",{"tabIndex":0}));
    gMainData.hitCollection[theNumber].hitCell = newHitCell;
    saveSettings();
    return newHitCell;
}
function addToMenu(theMenuArray,theName,theMenuObject) {
    if (theName=="Main") theMenuArray[0].theobject = theMenuObject;
    else {
        theMenuArray.push({"name":theName,"theobject":theMenuObject});
        $(theMenuObject).hide();
    }
}
function activeMenu(theMenuArray,theName,theNumber) {
    for (var i=0,len=theMenuArray.length; i<len; i++) {
        if (theMenuArray[i].name == theName) $(theMenuArray[i].theobject).show();
        else $(theMenuArray[i].theobject).hide();
    }
    displayMainStatus();
}
function isActiveMenu(theMenuArray,theName) {
    for (var i=0,len=theMenuArray.length; i<len; i++) {
        if (theMenuArray[i].name == theName && $(theMenuArray[i].theobject).is(":visible")) return true;
    }
    return false;
}
function addToLog(addNode,logNode) {
    var logLength = logNode.find(".logDiv").length;
    if (logLength > 3000) logNode.find(".logDiv:first").remove();
    var firstLogDiv = logNode.find(".logDiv:first");
    if (firstLogDiv.length) firstLogDiv.before(createDiv().css({"margin-left":"18px","text-indent":"-15px"}).attr("class","logDiv").append(addNode));
    else logNode.append(createDiv().css({"margin-left":"18px","text-indent":"-15px"}).attr("class","logDiv").append(addNode));
}
function addToStatusLog(theText) { addToLog(createSpan(theText.trim()),$("#JRStatusLog")); }
function addToAcceptedLog(theText) { addToLog(createSpan(theText.trim()),$("#JRAcceptedLog")); }
function addToMturkgrindLog(thisStuff) { 
    $("#JRMTGTab").css("background-color","#DEB887");
    $("#JRMturkgrindLog").one('mouseover', function() { $("#JRMTGTab").css("background-color",""); })
    addToLog(thisStuff,$("#JRMturkgrindLog"));
}
function addToMturkforumLog(theText) { addToLog(createSpan(theText),$("#JRMturkforumLog")); }
function addToHWTFLog(thisStuff) { 
    $("#JRHWTFTab").css("background-color","#DEB887");
    $("#JRHWTFLog").one('mouseover', function() { $("#JRHWTFTab").css("background-color",""); })
    addToLog(thisStuff,$("#JRHWTFLog"));
}
function fillInPositions() { // Initialize positions because they are not set.
    $.each(gRequestersData, function( index, value ) {
        if (index>0) {
            var goInTab = null;
            $.each(gTabsData, function( tabsIndex, tabsValue ) { 
                if (goInTab === null) goInTab = tabsValue;
                if (tabsValue.tabNumber == value.tabNumber) goInTab = tabsValue;
            });
            if (goInTab) {
                if (goInTab.positions === null) goInTab.positions = [];
                goInTab.positions.push(index);
                value.tabNumber = goInTab.tabNumber;
            }
        }
    });
}
function fillTabs() {
    var theNumber=0, newHitCell=null, thisTab=null, thisData=null, thisTabControls=null;
    $.each(gTabsData, function( index, value ) { 
        thisTab = $("#" + ($("#JRTab_" + value.tabNumber).attr("aria-controls")));
        if (value.positions) {
            for (var ii=0; ii<value.positions.length; ii++) {
                var thisPositionNumber = value.positions[ii];
                if (thisPositionNumber in gRequestersData) {
                    thisData = gRequestersData[thisPositionNumber];
                    theNumber = addHitCollection(thisData,thisPositionNumber,index);
                    newHitCell = createHitCell($(thisTab).find(".tabContents"),thisData,theNumber)
                        .data({"removeMe":false,"pandaHam":"off"});
                    gMainData.hitCollection[theNumber].hitCell = newHitCell;
                    gMainData.hitCollection[theNumber].data.tabNumber = value.tabNumber;
                    value.positions[ii] = "" + value.positions[ii];
                } else { 
                    console.log("error: " + thisPositionNumber + " was not in requestersData");
                    value.positions.splice(ii, 1);
                    ii--;
                }
            }
        } else value.posistions = [];
        $(thisTab).find(".tabContents").append(createDiv("&nbsp;").attr("class","JRHitCell JRHitDummy").data("hitInfo",{"tabIndex":index}));
    });
}
function refreshAllCells() {
    $.each(gMainData.hitCollection, function( index, value ) {
        updateHitCell(index);
    });
}
function showButtonUsed(thisButton) {
    thisButton.css({"background-color": "#CCC6B0"});
    thisButton.animate({"background-color": gButtonOffBgColor}, 500);
}
function startPandaCrazy() {
    gMainData.queueStatus = makeStatus();
    var panels = createPanels("body")
        .css({"height":"auto"});

    var northPanel = createPanel("body");
    northPanel.addClass("ui-layout-north");
    var mainControls = createDiv().appendTo(northPanel);
    mainControls.css({"background-color":"aliceblue",
                   "font-size":"10px",
                   "color":"midnightblue",
                   "padding":"5px 4px",
                   "border-color":"black", "border-width":"2px", "border-style":"groove"});
    createSpan("Vol: ").appendTo(mainControls);
    createSpan().attr("id","JRVolumeControl").css({"display":"inline-block","width":"80px","margin":"3px 8px 0px 2px"})
        .slider({range: "min",min: 0,max: 100,value: gMainOptions.alarmVolume,step: 5,
            stop: function(event, ui) {
                gMainOptions.alarmVolume = ui.value;
                gSoundFile.volume = gMainOptions.alarmVolume/100;
                if (gSoundFile.paused == true) {
                    gSoundFile = gAlarmSounds["less2"].audio;
                    gSoundFile.currentTime = 0;
                    gSoundFile.play();
                }
            } 
        })
        .appendTo(mainControls);
    
    $("#JRWaitDialog").append(createDiv("Setting up Menu."));
    setTimeout( function() {
        var theMenuArea = createSpan().attr("id","menuArea").appendTo(mainControls);
        var mainMenuControls = createSpan().appendTo(theMenuArea).attr("id","JrMainMenuControls").css({"margin":"10px 0"});
        addToMenu(gMainMenu,"Main",mainMenuControls);
        var jobsMenuControls = createSpan().appendTo(theMenuArea).attr("id","JrJobsMenuArea").css({"margin":"10px 0"});
        addToMenu(gMainMenu,"Jobs",jobsMenuControls);
        var displayMenuControls = createSpan().appendTo(theMenuArea).attr("id","JrDisplayMenuArea").css({"margin":"10px 0"});
        addToMenu(gMainMenu,"Display",displayMenuControls);
        var groupingMenuControls = createSpan().appendTo(theMenuArea).attr("id","JrGroupingMenuArea").css({"margin":"10px 0"});
        addToMenu(gMainMenu,"Grouping",groupingMenuControls);
        var cycleMenuControls = createSpan().appendTo(theMenuArea).attr("id","JrCycleMenuArea").css({"margin":"10px 0"});
        addToMenu(gMainMenu,"Cycle",cycleMenuControls);
        var optionsMenuControls = createSpan().appendTo(theMenuArea).attr("id","JrOptionsMenuArea").css({"margin":"10px 0"});
        addToMenu(gMainMenu,"Options",optionsMenuControls);
        activeMenu(gMainMenu,"Main");

        createSpan(" | ").appendTo(mainMenuControls);

        createSpan().append(createSpanButton(function(e) { activeMenu(gMainMenu,"Jobs"); },"Jobs","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(mainMenuControls);
        createSpan().append(createSpanButton(function(e) { activeMenu(gMainMenu,"Main"); },"Main","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(jobsMenuControls);
        createSpan(" -Jobs- ").appendTo(jobsMenuControls);
        createSpan().append(createSpanButton(function(e) { 
            toggleButton($(e.target),function(theNumber,thisButton) { showAddJobsDialog(thisButton); },null);
        },"Add","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(jobsMenuControls);
        createSpan().append(createSpanButton(function(e) {
            toggleButton($(e.target),function(theNumber,thisButton) { showExportImportDialog("Export",thisButton); },null);
        },"Export","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(jobsMenuControls);
        createSpan().append(createSpanButton(function(e) {
            toggleButton($(e.target),function(theNumber,thisButton) { showExportImportDialog("Import",thisButton); },null);
        },"Import","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(jobsMenuControls);

        createSpan().append(createSpanButton(function(e) { activeMenu(gMainMenu,"Display"); },"Display","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(mainMenuControls);
        createSpan().append(createSpanButton(function(e) { activeMenu(gMainMenu,"Main"); },"Main","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(displayMenuControls);
        createSpan(" -Display- ").appendTo(displayMenuControls);
        createSpan().append(createSpanButton(function(e) {
            showButtonUsed($(e.target)); gMainData.displayInfo=0; refreshAllCells();
        },"Minimum Info","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(displayMenuControls);
        createSpan().append(createSpanButton(function(e) {
            showButtonUsed($(e.target)); gMainData.displayInfo=1; refreshAllCells();
        },"Extended Info","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(displayMenuControls);

        createSpan().append(createSpanButton(function(e) { activeMenu(gMainMenu,"Grouping"); },"Grouping","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(mainMenuControls);
        createSpan().append(createSpanButton(function(e) { activeMenu(gMainMenu,"Main"); },"Main","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(groupingMenuControls);
        createSpan(" -Grouping- ").appendTo(groupingMenuControls);
        createSpan().append(createSpanButton(function(e) {
            toggleButton($(e.target),function(theNumber,thisButton) { showGroupingDialog("collect",thisButton); },null);
        },"Start/Stop","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(groupingMenuControls);
        createSpan().append(createSpanButton(function(e) {
            toggleButton($(e.target),function(theNumber,thisButton) { showGroupingCreateDialog(thisButton,[],"selection"); },null);
        },"Create By Selection","ivory","black","12px")).css({"margin":"10px 0"}).data("creating","see").appendTo(groupingMenuControls);
        createSpan().append(createSpanButton(function(e) {
            toggleButton($(e.target),function(theNumber,thisButton) { showGroupingCreateDialog(thisButton,[],"collecting"); },null);
        },"Create Instantly","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(groupingMenuControls);
        createSpan().append(createSpanButton(function(e) {  },"Add to..","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(groupingMenuControls);
        createSpan().append(createSpanButton(function(e) {
            toggleButton($(e.target),function(theNumber,thisButton) { showGroupingDialog("view",thisButton); },null);
        },"View all","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(groupingMenuControls);

        createSpan().append(createSpanButton(function(e) { activeMenu(gMainMenu,"Cycle");
            $("#JrMainStatus .JRCycleInfoArea").stop(true,true);
            $("#JrMainStatus .JRCycleInfoArea").css({"color":"red"}); 
        },"Cycler","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(mainMenuControls);
        createSpan().append(createSpanButton(function(e) { 
            activeMenu(gMainMenu,"Main"); $("#JrMainStatus .JRCycleInfoArea").stop(true,true);
            $("#JrMainStatus .JRCycleInfoArea").animate({"color": "#191970"}, 30000);
        },"Main","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(cycleMenuControls);
        createSpan(" -Cycler- ").appendTo(cycleMenuControls);
        createSpan().append(createSpanButton(function(e) {
            showButtonUsed($(e.target)); theCycler.skippingReset(); displayMainStatus();
        },"Reset","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(cycleMenuControls);
        createSpan().append(createSpanButton(function(e) {
            showButtonUsed($(e.target)); theCycler.cycleIncrease(); displayMainStatus();
        },"Increase","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(cycleMenuControls);
        createSpan().append(createSpanButton(function(e) {
            showButtonUsed($(e.target)); theCycler.cycleDecrease(); displayMainStatus();
        },"Decrease","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(cycleMenuControls);
        createSpan().append(createSpanButton(function(e) {
            showButtonUsed($(e.target)); theCycler.cycleAdd(gMainOptions.cycleAdding); displayMainStatus();
        },"Add " + gMainOptions.cycleAdding,"ivory","black","12px")).css({"margin":"10px 0"}).attr("id","JrCycleAddingButton").appendTo(cycleMenuControls);
        createSpan().append(createSpanButton(function(e) { displayMainStatus(); },"Edit Cycle Timers","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(cycleMenuControls);

        createSpan().append(createSpanButton(function(e) { activeMenu(gMainMenu,"Options"); },"Options","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(mainMenuControls);
        createSpan().append(createSpanButton(function(e) { activeMenu(gMainMenu,"Main"); },"Main","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(optionsMenuControls);
        createSpan(" -Options- ").appendTo(optionsMenuControls);
        createSpan().append(createSpanButton(function(e) {
            toggleButton($(e.target),function(theNumber,thisButton) { showEditTimersDialog("Timers",thisButton); },null);
        },"Timers","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(optionsMenuControls);
        createSpan().append(createSpanButton(function(e) {
            toggleButton($(e.target),function(theNumber,thisButton) { showAlarmsDialog("Alarms",thisButton); },null);
        },"Alarms","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(optionsMenuControls);
        createSpan().append(createSpanButton(function(e) { },"General","ivory","black","12px")).css({"margin":"10px 0"}).appendTo(optionsMenuControls);

        var mainStatus = createDiv().appendTo(northPanel).attr("id","JrMainStatus");
        mainStatus.css({"background-color":"aliceblue",
                       "font-size":"12px",
                       "color":"#191970",
                       "font-weight":"bold",
                       "padding":"5px 5px",
                       "border-color":"black", "border-width":"2px", "border-style":"groove"});
        createSpan().attr({"class":"JRJobsArea","title":"Click to Show Number of Panda, Searches or Filtered Jobs."}).data("mode","Jobs").tooltip({ show: {delay:600} }).appendTo(mainStatus);
        createSpan().attr({"class":"JRCycleInfoArea","title":"Click to Show Elapsed Time, Cycle Time, Added Time for Slow Down or Min Ham Cycle Time."}).data("mode","Elapsed")
            .tooltip({ show: {delay:600} })
            .click( function(e) {
                var theMode = $(e.target).data("mode");
                $(e.target).data("mode", (theMode=="Elapsed") ? "Cycle" : (theMode=="Cycle") ? "CycleSkipping" : (theMode=="CycleSkipping") ? "Hamcycle" : "Elapsed")
                    .stop(true,true)
                    .css({"color":"red"})
                    .animate({"color": "#191970"}, 30000);
                displayMainStatus();
            }).css({"cursor":"pointer"}).appendTo(mainStatus);
        createSpan().attr({"class":"JRResultAccSkipArea","title":"Click to Show Accepted or Skipped Hits."}).data("mode","Accepted")
            .tooltip({ show: {delay:600} })
            .click( function(e) {
                var theMode = $(e.target).data("mode");
                $(e.target).data("mode", (theMode=="Accepted") ? "Skipped" : "Accepted")
                    .stop(true,true)
                    .css({"color":"red"})
                    .animate({"color": "#191970"}, 30000);
                displayMainStatus();
            }).css({"cursor":"pointer"}).appendTo(mainStatus);
        createSpan().attr({"class":"JRErrorArea","title":"Click to Show Number of Too Fast or Error Pages."}).data("mode","TooFast")
            .tooltip({ show: {delay:600} })
            .click( function(e) {
                var theMode = $(e.target).data("mode");
                $(e.target).data("mode", (theMode=="TooFast") ? "Errors" : "TooFast")
                    .stop(true,true)
                    .css({"color":"red"})
                    .animate({"color": "#191970"}, 30000);
                displayMainStatus();
            }).css({"cursor":"pointer"}).appendTo(mainStatus);
        createSpan().attr({"class":"JRMturkQueueArea","title":"Number of Hits in Mturk Queue. Only verifies queue after specified time in options."}).data("mode","Queue")
            .tooltip({ show: {delay:600} }).appendTo(mainStatus)
            .click( function() {
                theCycler.frontOfTheLineTimer(-1);
            }).css({"cursor":"pointer"}).appendTo(mainStatus);
        createSpan().attr({"class":"JRSearchedArea","title":"Number of Searched Hits."}).data("mode","Searched").tooltip({ show: {delay:600} }).appendTo(mainStatus);
        createSpan().attr({"class":"JRPayArea","title":"Total Amount for Accepted Hits."}).data("mode","Pay").tooltip({ show: {delay:600} }).appendTo(mainStatus);

        var centerPanel = createPanel("body");
        centerPanel.addClass("ui-layout-center");

        var theControls = createDiv().attr("id","JRTheControls").appendTo(centerPanel);
        theControls.css({"background-color":"aliceblue",
                       "font-size":"10px",
                       "color":"midnightblue",
                       "padding":"5px 4px",
                       "border-color":"black", "border-width":"2px", "border-style":"groove"});
        createSpanButton(function(e) { 
            if (theCycler.isPaused()) { theCycler.unpause(); $(e.target).html("Pause").css({"background-color":"ivory","color":"black"}); }   
            else { theCycler.pause(); $(e.target).html("Resume").css({"background-color":"red","color":"white"}); }
        },"Pause","ivory","black","12px").attr("id","JRPauseButton").appendTo(theControls);
        createSpanButton( function(e) {
            toggleButton($(e.target),function(theNumber,thisButton) { showGroupingDialog("start",thisButton); },null);
        },"Start Group","ivory","black","12px").appendTo(theControls); 
        createSpanButton( function(e) { stopAll(); },"Stop All","ivory","black","12px").appendTo(theControls); 
        createSpanButton( function(e) {
            toggleButton($(e.target),function(theNumber,thisButton) { showAddJobsDialog(thisButton); },null);
        },"Add Job","ivory","black","12px").appendTo(theControls);
        createSpan(" - ").appendTo(theControls);
        createSpanButton( function(e) {
            showButtonUsed($(e.target)); theCycler.skippingReset(); displayMainStatus();
        },"Reset Timer","ivory","black","12px").appendTo(theControls); 
        createSpanButton( function(e) { 
            toggleButton($(e.target),function(theNumber,thisButton) {
                $("#JRWaitDialog").data("button",thisButton);
                $("#JRWaitDialog").html("");
                $("#JRWaitDialog").dialog("open");
                saveSettings();
                createDiv("Database Saved.<br>You may close this dialog.").css({"font-size":"18px","margin-top":"30px","text-align":"center"}).appendTo($("#JRWaitDialog"));
                $("div[aria-describedby='JRWaitDialog'] .ui-dialog-buttonpane button:contains('Close')").button().show();
            },null);
        },"Save","ivory","black","12px").appendTo(theControls); 

        $("#JRWaitDialog").append(createDiv("Setting up tabs."));
        setTimeout( function() {
            var mainTabs = createTabs(centerPanel,true,"JRMainTabs").css({"overflow":"hidden"}).show();
            if (gTabsData[0].positions === null) fillInPositions();
            var firstTab = true;
            $.each(gTabsData, function( index, value ) {
                addTab(mainTabs,value.tabName,true,"JRTab_" + value.tabNumber,value,!firstTab).css({"overflow":"visible"});
                if (firstTab) firstTab = false;
            });

            var southPanel = createPanel("body");
            southPanel.addClass("ui-layout-south");
            var logTabs = createTabs(southPanel,true,"JRStatusTabs");
            gAcceptedLogTab = addTab(logTabs,"Accepted",false,"JRStatusTab_0",null,false);
            gStatusLogTab = addTab(logTabs,"Status log",false,"JRStatusTab_1",null,false);
            createDiv().appendTo(gAcceptedLogTab)
                .attr("id","JRAcceptedLog")
                .css({"background-color":"black","overflow":"auto","color":"white","font-size":"9px"});
            createDiv().appendTo(gStatusLogTab)
                .attr("id","JRStatusLog")
                .css({"background-color":"black","overflow":"auto","color":"white","font-size":"9px"});
            logTabs.tabs("option", "active", 1)

            $("#JRWaitDialog").append(createDiv("Creating Panda Cells."));
            setTimeout( function() {
                fillTabs();
                mainTabs.tabs("option", "active", 0);
                gMyLayout = $('body').layout({
                    center__onresize: function() {
                        var newHeight = $(".ui-layout-south").innerHeight() - 35;       
                        gStatusLogTab.find("div").css({"height":newHeight}); 
                        gAcceptedLogTab.find("div").css({"height":newHeight});
                        $("#JRMainTabs").css({"height":$(".ui-layout-center").innerHeight() - $("#JRTheControls").innerHeight() - 8});
                        $("#JRMainTabs").find(".tabContents").css({"height":$(".ui-layout-center").innerHeight() - $("#JRMainTabs").find(".ui-tabs-nav").innerHeight() - $("#JRTheControls").innerHeight() - 8})
                    },
                });
                gMyLayout.sizePane("north", 65);
                gMyLayout.sizePane("south", 140);
                $("#JRStatusLog").css({"height":$(".ui-layout-south").innerHeight() - 35});
                $("#JRAcceptedLog").css({"height":$(".ui-layout-south").innerHeight() - 35});

                theCycler.cycleResetChange(gMainOptions.cycleNumber);
                gNotifications = checkNotifications();
                displayMainStatus();
                $("#JRWaitDialog").append(createDiv("Display is done.<br>Starting up script."));
                setTimeout( function() {
                    $("#JRWaitDialog").dialog("close");
                },1000);
            },10);
        },10);
    },10);
}
function continueLoading() {
    $("#JRWaitDialog").append(createDiv("Creating UI Display."));
    setTimeout( function() {
        startPandaCrazy();
    },10);
}

$("body").html("").css("height",screen.height-310);
$(function() {
    createEditDialog();
    createWaitDialog();
    createYesNoDialog();
    
    $("#JRWaitDialog").html("Setting up Panda Crazy!");
    $("#JRWaitDialog").dialog("open");
    $("#JREditDialog").dialog("option","height",310);
    $("#JREditDialog").dialog("option","width",320);
    $("#JRWaitDialog").dialog('option', 'position', 'center');
    $("#JRWaitDialog").dialog("option", "title", "Please wait. Loading....");
    setTimeout( function() {
        var nowDate = new Date();
        //console.log(formatTimeZone("onlydate",nowDate,"mturk"));
        $("#JRWaitDialog").append(createDiv("Loading settings in memory."));
        setTimeout( function() {
            loadSettings();
        },10);
    },10);
});

GM_addStyle(jqUI_CssSrc);
GM_addStyle(jqLayout_CssSrc);
GM_addStyle( " \
    body, input, select, td, li, div, textarea, p { \
        font-size:11px; \
        line-height: 14px; \
        font-family:verdana,arial,sans-serif; \
    } \
    .sortable-placeholder { \
        height: 1.5em; line-height: 1.2em; background-color:burlywood; \
    } \
    .ui-state-highlight { \
        height: 1.5em; line-height: 1.2em; \
    } \
    .requesterLine { \
        padding: 2px 0; \
    } \
    .requesterLine span { \
        font-weight: bold; \
    } \
    .ui-tooltip { \
        white-space: pre-line; \
        font-size:16px !important; \
        max-width: 400px; \
        width:400px; \
    } \
    .ui-tooltip-content { \
        max-width: 400px; \
        font-size:16px !important; \
    } \
    .ui-dialog.notmodal { \
        border: 3px solid #000; \
    } \
    .no-close .ui-dialog-titlebar-close { \
        display: none; \
    } \
    .ui-state-hover .ui-icon { \
        background-image: url('https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/themes/pepper-grinder/images/ui-icons_ffffff_256x240.png') !important; \
    } \
    .ui-state-active .ui-icon { \
         background-image: url('https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/themes/pepper-grinder/images/ui-icons_b83400_256x240.png') !important; \
    } \
    .ui-state-default .ui-icon { \
        background-image: url('https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/themes/pepper-grinder/images/ui-icons_b83400_256x240.png'); \
    } \
    .ui-widget-content { \
        background: #eceadf url('https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/themes/pepper-grinder/images/ui-bg_fine-grain_10_eceadf_60x60.png') 50% 50% repeat; \
    } \
    #JRMainTabs li .ui-icon-close { float: left; margin: 0.4em 0.2em 0 0; cursor: pointer; } \
    #JRStatusTabs li .ui-icon-close { float: left; margin: 0.4em 0.2em 0 0; cursor: pointer; } \
");