// peeks the last value in the array (to "pop" without actually popping)
if (!Array.peek) {
    Array.prototype.peek = function() {
        if (this.length > 0) return this[this.length - 1];
        else return null;
    };
}

// tightly-typed inArray() function
if (!Array.inArray) {
    Array.prototype.inArray = function(value) {
        for (var i = 0; i < this.length; i++) if (this[i] === value) return i;
        return false;
    };
}

// loosely-typed inArray() function
if (!Array.inArrayLoose) {
    Array.prototype.inArrayLoose = function(value) {
        for (var i = 0; i < this.length; i++) if (this[i] == value) return i;
        return false;
    };
}

// PHP-like date formatting
if (!Date.formatDate) {
    // v. 7/10/2008
    Date.prototype.formatDate = function(format) {
        var str = "";
        var nth = new Array("th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th");
        var dShort = new Array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
        var dLong = new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" );
        for (var i = 0; i < format.length; i++) {
            switch (format.charAt(i)) {
                case 'm': str += '' + ((this.getMonth() < 9) ? '0' : '') + (this.getMonth() + 1); break;
                case 'n': str += '' + (this.getMonth() + 1); break;
                case 'd': str += '' + ((this.getDate() < 10) ? '0' : '') + this.getDate(); break;
                case 'j': str += '' + this.getDate(); break;
                case 'Y': str += '' + this.getFullYear(); break;
                case 'y': str += '' + this.getYear(); break;
                case 'H': str += '' + ((this.getHours() < 10) ? '0' : '') + this.getHours(); break;
                case 'h': var th = this.getHours() % 12; th = (th == 0) ? 12 : th; str += '' + ((th < 10) ? '0' : '') + th; break;
                case 'G': str += '' + this.getHours(); break;
                case 'g': str += '' + ((this.getHours() > 12) ? (this.getHours() - 12) : ((this.getHours() == 0) ? '12' : this.getHours())); break;
                case 'i': str += '' + ((this.getMinutes() < 10) ? '0' : '') + this.getMinutes(); break;
                case 's': str += '' + ((this.getSeconds() < 10) ? '0' : '') + this.getSeconds(); break;
                case 'a': str += '' + ((this.getHours() < 12) ? "am" : "pm"); break;
                case 'A': str += '' + ((this.getHours() < 12) ? "PM" : "PM"); break;
                case 'S': var ind = this.getDate(); if (ind > 9 && ind < 21) ind = 0; ind %= 10; str += nth[ind]; break;
                case 'D': str += dShort[this.getDay()]; break;
                case 'l': str += dLong[this.getDay()]; break;
                default:
                    str += format.charAt(i);
                    break;
            }
        }
        return str;
    };
}

function timeStamp() { return new Date().getTime(); }

function openNewWindow(url, params) {
    if (!params) params = "width=800,height=600,scrollbars=1,resizable=1,toolbar=1,status=1,menubar=1";
    return window.open(url, 'new_window_' + timeStamp(), params);
}

function jitterScrollBar() {
    // this is the stupidest (and only current) solution to a stupid browser...IE, this one's for you.  @#$!
    document.body.scrollTop++;
    document.body.scrollTop--;
    var orig_overflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    document.body.style.overflow = 'scroll';
    document.body.style.overflow = orig_overflow;
}

function execEmbeddedScript(content) {
    // thank you http://www.html.com/forums/javascript/59366-run-javascript-part-ajax-response.html
    var re = /<script\b.*?>([\s\S]*?)<\/script/ig;
    var match;
    while (match = re.exec(content)) {
        try { eval(match[1]); } catch(e) { alert("Imported script failed evaluation:\n\n" + match[1]); }
    }
}

function stopClickPropagation(e) {
    if (typeof(window.event) != "undefined") {
        // IE
        e = window.event;
        if (!e) return false;
        e.cancelBubble = true;
    } else {
        // Firefox
        e.stopPropagation();
    }
}

function parseFloatTypecast(v) {
    if (typeof v == 'string') return (v == "") ? 0 : parseFloat(v.replace(/[^0-9\.\-]/g, ""));
    if (typeof v == 'number') return parseFloat(v);
    return 0;
}

function isAlien(a) {
   return isObject(a) && typeof a.constructor != 'function';
}

function isArray(a) {
    return isObject(a) && a.constructor == Array;
}

function isBoolean(a) {
    return typeof a == 'boolean';
}

function isEmpty(o) {
    var i, v;
    if (isObject(o)) {
        for (i in o) {
            v = o[i];
            if (isUndefined(v) && isFunction(v)) {
                return false;
            }
        }
    }
    return true;
}

function isFunction(a) {
    return typeof a == 'function';
}

function isNull(a) {
    return typeof a == 'object' && !a;
}

function isNumber(a) {
    return typeof a == 'number' && isFinite(a);
}

function isObject(a) {
    return (a && typeof a == 'object') || isFunction(a);
}

function isString(a) {
    return typeof a == 'string';
}

function isUndefined(a) {
    return typeof a == 'undefined';
}

// matches A-Z, a-z (no spaces)
function isvAlpha(str) {
    var re = /[^a-zA-Z]/g;
    return !re.test(str);
}

// matches 0-9 (no periods)
function isvNumeric(str){
    var re = /[\D]/g;
    return !re.test(str);
}

// matches A-Z, a-z, 0-9 (no spaces)
function isvAlphaNumeric(str){
    var re = /[^a-zA-Z0-9]/g;
    return !re.test(str);
}

// matches zip codes
function isvZip(str) {
    var re = /\D{5}(-\D{4})?/;
    return re.test(str);
}

// matches $17.23 or $14,281,545.45 or ...
function isvCurrency(str) {
    var re = /\$\d{1,3}(,\d{3})*\.\d{2}/;
    return re.test(str);
}

// matches 5:04 or 12:34 but not 75:83
function isvTime12(str) {
    var re = /^([1-9]|1[0-2]):[0-5]\d$/;
    return re.test(str);
}

// matches 15:04 or 12:34 but not 75:83
function isvTime24(str) {
    var re = /^([1-9]|1[0-9]|2[0-3]):[0-5]\d$/;
    return re.test(str);
}

//matches email
function isvEmail(str) {
    var re = /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?)$/;
    return re.test(str);
}

// matches phone ###-###-####
function isvPhoneUS(str) {
    var re = /^\(?\d{3}\)?\s|-\d{3}-\d{4}$/;
    return re.test(str);
}

// International Phone Number
function isvPhoneIntl(str) {
    var re = /^\d(\d|-){7,20}/;
    return re.test(str);
}

// IP Address
function isvIP(str) {
    var re = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
    return re.test(str);
}

// Date xx/xx/xxxx or xx-xx-xxxx or xx.xx.xxxx
function isvDate(str) {
    var re = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{4}$/;
    return re.test(str);
}

// Date xx/xx/xxxx only
function isvDateSlashes(str) {
    var re = /^\d{1,2}(\/)\d{1,2}\1\d{4}$/;
    return re.test(str);
}

// State Abbreviation
function isvState2(str) {
    var re = /^(AK|AL|AR|AZ|CA|CO|CT|DC|DE|FL|GA|HI|IA|ID|IL|IN|KS|KY|LA|MA|MD|ME|MI|MN|MO|MS|MT|NB|NC|ND|NH|NJ|NM|NV|NY|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VA|VT|WA|WI|WV|WY)$/i;
    return re.test(str);
}

// Social Security Number (matches 123-45-6789 or 123456789)
function isvSSN(str) {
    var re = /^(\d{3}\-\d{2}\-\d{4}|\d{9})$/;
    return re.test(str);
}

function smartEval(content) {
    //clearMCEInstances();
    if (content == "_USERX") {
        if (!document.sessionExpireAlert) {
            document.sessionExpireAlert = true;
            alert("Your session has expired.  Please log in again.");
        }
        return true;
    }
    try {
        eval(content);
    } catch (e) {
        if (e.message != "") {
            if (confirm("Javascript evaluation failed!\n\nError name: " + e.name + "\nError message: " + e.message + "\n\nClick OK to view failed script content, or Cancel to dismiss.")) {
                jPopup(content, "Javascript content");
            }
            /*var lines = content.split("\n");
            for (i = 0; i < lines.length; i++) {
                try {
                    eval(lines[i]);
                } catch (e) {
                    if (confirm("AJAX Javascript evaluation failed!\n\nError name: " + e.name + "\nError message: " + e.message + "\nContent line: #" + (i + 1) + "\nSource code: " + lines[i] + "\n\nClick OK to view entire content, or Cancel to dismiss."))
                        alert(content);
                    return false;
                }
            }*/
            return false;
        }
    }
    smartScriptUpdate();
    return true;
}

function smartScriptUpdate(selector) {
    if (!selector) selector = document;
    jQuery(selector).find("input[type=text][prmFormat=date]").dateField().datePicker({startDate:'01/01/2000'});
    jQuery(selector).find(".autoCurrencyField").currencyField();
    jQuery(selector).find(".autoTimeField").timeField();
    jQuery(selector).find(".autoDecimalField").decimalField();
    jQuery(selector).find(".box.error:not(.autoModified)").prepend('<div class="floatLeft paddingRight8" style="margin-top: -2px;"><img src="/images/icons/cross.png" /></div>').addClass("autoModified");
    jQuery(selector).find(".box.notice:not(.autoModified)").prepend('<div class="floatLeft paddingRight8" style="margin-top: -2px;"><img src="/images/icons/exclamation.png" /></div>').addClass("autoModified");
    jQuery(selector).find(".box.success:not(.autoModified)").prepend('<div class="floatLeft paddingRight8" style="margin-top: -2px;"><img src="/images/icons/tick.png" /></div>').addClass("autoModified");
    jQuery(selector).find(".fillParent").fillParent();
    jQuery(selector).find(".autoDropShadow").jDropShadow({ thickness: 5, opacity: 0.1, color: "#666666" });
    jQuery(selector).find("input[type=button]:not(.fbutton), input[type=submit]:not(.fbutton)").addClass("fbutton").hover(function() { jQuery(this).addClass("fbutton_hover"); }, function() { jQuery(this).removeClass("fbutton_hover"); });
    jQuery(selector).find("input[type=text]:not(.ftext), input[type=password]:not(.ftext), textarea:not(.ftext)").addClass("ftext").focus(function() { jQuery(this).addClass("ftext_focus"); }).blur(function() { jQuery(this).removeClass("ftext_focus"); });
    jQuery(selector).find("input[type=text][prmGhost]").each(function(i) {
        var t = jQuery(this);
        if (t.val() == "") t.addClass("ghost").val(t.attr("prmGhost"));
        t.focus(function() { var z = jQuery(this); if (z.val() == z.attr("prmGhost") && z.hasClass("ghost")) z.removeClass("ghost").val(""); if (z.hasClass("ghost")) z.removeClass("ghost"); });
        t.blur(function() { var z = jQuery(this); if (z.val() == "") z.addClass("ghost").val(z.attr("prmGhost")); else if (z.val() != z.attr("prmGhost")) z.removeClass("ghost"); });
        t.mouseleave(function() { var z = jQuery(this); if (z.val() != z.attr("prmGhost")) z.removeClass("ghost"); });
    });
    jQuery(selector).find("a:not(.noAjaxLoading, .flagAJLSetup)").click(function() { jQuery(".ajaxLoading").show(); }).addClass("flagAJLSetup");
    jQuery(selector).find("[prmTip]:not([prmTipoptions]):not(.flagTipSetup)").hover(function() { Tip(jQuery(this).attr("prmTip")); }, function() { UnTip(); }).addClass("flagTipSetup");
    jQuery(selector).find("[prmTip][prmTipoptions]:not(.flagTipSetup)").hover(function() { eval('Tip(jQuery(this).attr("prmTip"), ' + jQuery(this).attr("prmTipoptions") + ');'); }, function() { UnTip(); }).addClass("flagTipSetup");
    jQuery(selector).find("[prmTagtip]:not([prmTipoptions]):not(.flagTipSetup)").hover(function() { TagToTip(jQuery(this).attr("prmTagtip")); }, function() { UnTip(); }).addClass("flagTipSetup");
    jQuery(selector).find("[prmTagtip][prmTipoptions]:not(.flagTipSetup)").hover(function() { eval('TagToTip(jQuery(this).attr("prmTagtip"), ' + jQuery(this).attr("prmTipoptions") + ');'); }, function() { UnTip(); }).addClass("flagTipSetup");
    //jQuery(selector).find(".tinyMCEeditor, .tinyMCEeditorLimited").each(function(i) { if (!tinyMCE.get(this.id)) tinyMCE.execCommand('mceAddControl', false, this.id); });
}

function clearMCEInstances(selector) {
    if (!selector) selector = document;
    //jQuery(selector).find(".tinyMCEeditor").each(function(i) { if (tinyMCE.get(this.id)) tinyMCE.execCommand('mceRemoveControl', false, this.id); });
}

// *****************************************************************************************
// *****************************************************************************************
// COMMON JQUERY EXTENSION OR RELATED FUNCTIONS
// *****************************************************************************************
// *****************************************************************************************

jQuery.formatDate = function(str) {
    if (str != "") {
        str = str.toString();
        var parts = str.split(/[-\/]/);
        if (parts.length == 3) {
            // month/day/year
            var m = parseInt(parts[0], 10);
            var d = parseInt(parts[1], 10);
            var y = parseInt(parts[2], 10);
            if (m > 12 || m < 1) {
                // alternate form YYYY-mm-dd
                y = parseInt(parts[0], 10);
                m = parseInt(parts[1], 10);
                d = parseInt(parts[2], 10);
            }
            if (!isNaN(m) && !isNaN(d) && !isNaN(y) && m >= 1 && m <= 12 && d >= 1 && d <= 31) {
                if (y < 100 && y >= 70) {
                    y += 1900;
                } else if (y < 70) {
                    y += 2000;
                } else if (y < 1900) {
                    y = (y % 100) + 2000;
                }
                return (m + "/" + d + "/" + y);
            } else {
                return "";
            }
        } else if (parts.length == 2) {
            // only month/day (OR month/year)
            var m = parseInt(parts[0], 10);
            var d = parseInt(parts[1], 10);
            if ((parts[1].length == 2 && parts[1][0] == '0') || parts[1].length == 4) {
                if (!isNaN(m) && !isNaN(d) && m >= 1 && m <= 12) {
                    if (d < 10) d += 2000;
                    return (m + "/1/" + d); // d is actually y in this case
                } else {
                    return "";
                }
            } else {
                if (!isNaN(m) && !isNaN(d) && m >= 1 && m <= 12 && d >= 1 && d <= 31) {
                    var y = new Date().getYear();
                    if (y < 1900) y += 1900;
                    return (m + "/" + d + "/" + y);
                } else {
                    return "";
                }
            }
        } else {
            // unknown...reset
            return "";
        }
    } else return "";
};

jQuery.fn.dateField = function() {
    return this.each(function() {
        if (jQuery(this).attr("autoDateFieldEnabled")) return; // already enabled
        jQuery(this).attr("autoDateFieldEnabled", true);
        //jQuery(this).after("<img src=\"images/cal.gif\" id=\"datetrigger" + this.id + "\" align=\"absmiddle\" style=\"cursor: pointer; border: 1px solid black; margin-right: 8px;\" title=\"Date selector\" />");
        //Calendar.setup({inputField: this.id, ifFormat: "%m/%d/%Y", button: "datetrigger" + this.id, align:"bR", singleClick:true});
        //jQuery("#datetrigger" + this.id).mouseover(function() { this.style.borderColor="#FF0000"; }).mouseout(function() { this.style.borderColor="#000000"; });
        jQuery(this).change(function() {
            if (jQuery(this).attr("prmDateFormat")) {
                var tD = new Date(jQuery.formatDate(jQuery(this).val()));
                jQuery(this).val(tD.formatDate(jQuery(this).attr("prmDateFormat")));
            } else {
                jQuery(this).val(jQuery.formatDate(jQuery(this).val()));
            }
        });
    });
};

jQuery.formatDecimal = function(str, places, zerofill) {
    if (typeof str != 'string' || str.length > 0) {
        str = str.toString();
        var number = parseFloat(str.replace(/[^0-9\.\-]/g, ''));
        var dec = 0;
        if (isNaN(number)) number = 0;
        if (!places || isNaN(places) || places < 0) places = 2;
        var sign = (Math.abs(number) == number);
        number = Math.abs(number);
        dec = Math.round(number * Math.pow(10, places)) - (Math.floor(number) * Math.pow(10, places));
        if (dec >= Math.pow(10, places)) { number++; dec -= Math.pow(10, places); }
        if (!zerofill) while (dec != 0 && dec / 10 == Math.floor(dec / 10) && dec.toString().length > places) dec /= 10;
        if (zerofill && dec == 0) {
            dec = "";
            for (var z = 0; z < places; z++) dec += "" + "0";
        }
        while (dec.toString().length < places) dec = "0" + "" + dec;
        number = Math.floor(number).toString();
        for (var i = 0; i < Math.floor((number.length - (1 + i)) / 3); i++)
            number = number.substring(0, number.length - (4 * i + 3)) + ',' + number.substring(number.length - (4 * i + 3));
        return ((sign ? "" : "-") + (number + ((dec != 0 || zerofill) ? ("." + dec) : "")));
    } else return "";
};

jQuery.fn.decimalField = function() {
    return this.each(function() {
        if (jQuery(this).attr("decimalFieldEnabled")) return; // already enabled
        jQuery(this).attr("decimalFieldEnabled", true);
        jQuery(this).change(function() {
            jQuery(this).val(jQuery.formatDecimal(jQuery(this).val(), parseInt(jQuery(this).attr("tag"))));
        }).css("text-align", "right");
    });
};

jQuery.formatCurrency = function(str, minimum, maximum) {
    if (typeof str != 'string' || str.length > 0) {
        str = str.toString();
        var amount = parseFloatTypecast(str);
        if (isNaN(amount)) amount = 0;
        var sign = (amount == Math.abs(amount));
        return (((sign) ? '' : '-') + '$' + jQuery.formatDecimal(Math.abs(amount), 2, true));
    } else return "";
};

jQuery.fn.currencyField = function() {
    return this.each(function() {
        if (jQuery(this).attr("autoCurrencyFieldEnabled")) return; // already enabled
        jQuery(this).attr("autoCurrencyFieldEnabled", true);
        jQuery(this).change(function() {
            jQuery(this).val(jQuery.formatCurrency(jQuery(this).val()));
        }).css("text-align", "right");
    });
};

jQuery.formatTime = function(str) {
    if (str != "") {
        var parts = jQuery.trim(str.replace(/\s+/, " ")).split(/[: ]/);
        var num, h = 0, m = 0, s = 0, assumePM = false, detail = 0, timeStr = "", pmStr = "";
        if (parts[0] > 99 && parts[0] < 2400) { // for lazy people
            m = parts % 100;
            h = (parts - m) / 100
            parts[0] = m;
            parts.unshift(h);
        } else if (parts[0] < 100 && parts[0] > 12 && parts.length == 1) { // for EXTRA lazy people
            m = parts % 10;
            h = (parts - m) / 10;
            m *= 10;
            if (m < 60) { parts[0] = m; parts.unshift(h); }
        }
        for (var i = 0; i < parts.length; i++) {
            num = parseInt(parts[i]);
            if (i == 0) {           // hours first
                if (isNaN(num) || num < 0 || num > 23) { timeStr = ""; break; }
                else if (num > 12) { h = num - 12; pmStr = " PM"; }
                else if (num == 0) { h = 12; pmStr = " AM"; }
                else h = num;
                timeStr += (h + 0);
                if (h < 8 || h == 12) assumePM = true;
                detail++;
            } else if (i == 1) {    // then minutes, if supplied
                if (isNaN(num) || num < 0 || num > 59) break;
                else m = num;
                timeStr += ":" + ((m < 10) ? "0" : "") + m;
                detail++;
            } else if (i == 2) {    // then seconds, if supplied
                if (isNaN(num) || num < 0 || num > 59) break;
                else s = num;
                timeStr += ":" + ((s < 10) ? "0" : "") + s;
                detail++;
            }
        }
        if (timeStr != "") {
            if (detail < 2) timeStr += ":00";   // add minutes
            //if (detail < 3) timeStr += ":00";   // add seconds
            if (pmStr != "") timeStr += pmStr;
            else timeStr += (str.match(/(pm|p)/i) || (assumePM && !str.match(/(am|a)/i))) ? " PM" : " AM";
        }
        return timeStr;
    } else return "";
};

jQuery.fn.timeField = function() {
    return this.each(function() {
        if (jQuery(this).attr("autoTimeFieldEnabled")) return; // already enabled
        jQuery(this).attr("autoTimeFieldEnabled", true);
        jQuery(this).change(function() {
            jQuery(this).val(jQuery.formatTime(jQuery(this).val()));
        });
    });
};

jQuery.fn.fillParent = function() {
    return this.each(function() {
        var ph = jQuery(this).parent().height();
        var th = jQuery(this).height();
        var pt = jQuery(this).parent().offset().top;
        var tt = jQuery(this).offset().top;
        var height = ph - (pt - tt);
        jQuery(this).height(height);
        alert(ph + "\n" + th + "\n" + pt + "\n" + tt);
    });
};

jQuery.fn.jDropShadow = function(args) {
    if (!args) args = new Object();
    if (!args.opacity) args.opacity = 0.1;
    if (!args.thickness) args.thickness = 5;
    if (!args.color) args.color = "#000000";
    return this.each(function(i) {
        var d = jQuery(this);
        var x = d.offset().left, y = d.offset().top, w = d.outerWidth(), h = d.outerHeight();
        var tx, ty, tw, th, id;
        var thick = 4;
        for (var j = 0; j < args.thickness; j++) {
            id = "ddshadowx_" + new Date().getTime() + "_" + j + "_" + i;
            jQuery("body").append('<div id="' + id + 'b" class="appliedDropShadowX"></div>');
            tx = x + j + 3; ty = y + h; tw = w - 2; th = j;
            //if (jQuery.browser.msie) tx--;
            tx--;
            jQuery("#" + id + "b").css("left", tx + "px").css("top", ty + "px").width(tw).height(th);
            jQuery("body").append('<div id="' + id + 'r" class="appliedDropShadowX"></div>');
            tx = x + w + 1; ty = y + j + 2; tw = j; th = h - j - 2;
            //if (jQuery.browser.msie) tx--;
            tx--;
            jQuery("#" + id + "r").css("left", tx + "px").css("top", ty + "px").width(tw).height(th);
        }
        jQuery(".appliedDropShadowX").css("position", "absolute").css("background-color", args.color).css("z-index", 5).css("opacity", args.opacity);
    });
};

var jDropShadowTimeout = false;
jQuery(window).resize(function() {
    if (jDropShadowTimeout) clearTimeout(jDropShadowTimeout);
    jDropShadowTimeout = setTimeout('jQuery(".appliedDropShadowX").remove(); jQuery(".autoDropShadow").jDropShadow({ thickness: 5, opacity: 0.1, color: "#666666" });', 50);
});

jQuery.combineJSON = function(json1, json2) {
    var newJSON = json1;
    for (i in json2) newJSON[i] = json2[i];
    return newJSON;
};

jQuery.buildSmartInput = function(selector, ignoreParams) {
    var json = { };
    var ed = false;
    var s = jQuery(selector);
    var obj;
    for (var z = 0; z < s.length; z++) {
        obj = s.eq(z).find("input[type!=button], select, textarea");
        for (var i = 0; i < obj.length; i++) {
            with (obj[i]) {
                if (type == "select-multiple") {
                    var sel = Array();
                    for (j = 0; j < options.length; j++) {
                        if (options[j].selected) sel.push(options[j]);
                    }
                    json[id] = sel;
                } else if (type == "textarea") {
                    if (!((ed = tinyMCE.get(id)) && (json[id] = ed.getContent()))) json[id] = jQuery(obj[i]).val();
                } else if (type == "checkbox") {
                    if (checked) json[id] = value;
                    else json[id] = "";
                } else if (type == "radio") {
                    if (!json[name] && checked) json[name] = value;
                } else {
                    json[id] = value;
                }
            }
            if (!ignoreParams && !jQuery(obj[i]).attr("disabled")) {
                if (jQuery(obj[i]).attr("prmRequired") == "yes" && json[obj[i].id] == "") {
                    try {
                        obj[i].focus();
                        var label = jQuery("label[for=" + obj[i].id + "]");
                        var title = jQuery(obj[i]).attr("prmTitle");
                        if (!title) title = label.length > 0 ? label.text() : "current";
                        alert("Please enter a value for the '" + title + "' field.");
                        return false;
                    } catch(e) {
                        // invisible... TODO: special handling?
                    }
                }
                if (jQuery(obj[i]).attr("prmMinimum") && parseFloatTypecast(json[obj[i].id]) < jQuery(obj[i]).attr("prmMinimum")) {
                }
                if (jQuery(obj[i]).attr("prmMaximum") && parseFloatTypecast(json[obj[i].id]) > jQuery(obj[i]).attr("prmMaximum")) {
                }
            }
        }
    }
    return json;
};

// returns an array of all of the val() data values from the jQuery applied object array
jQuery.fn.valueArray = function() {
    var a = new Array();
    for (var i = 0; i < this.length; i++) a.push(jQuery(this[i]).val());
    return a;
};

jQuery.fn.modal = function(args) {
    if (!args) args = { centerHoriz: 0, centerVert: 0 };
    return this.each(function() {
        if (jQuery(".JQModalCover").length == 0) jQuery("body").append('<div id="jqModalCoverLayer" class="JQModalCover"></div>');
        var w = jQuery(document).width(), h = jQuery(document).height();
        if (jQuery(window).width() > w) w = jQuery(window).width();
        if (jQuery(window).height() > h) h = jQuery(window).height();
        var vpw = jQuery(window).width(), vph = jQuery(window).height();
        var c = jQuery(".JQModalCover").css("opacity", 0.01).show().width(w).height(h).fadeTo("slow", 0.75);
        if (!args.fixed) {
            var t = jQuery(this).css("position", "absolute");
            if (parseInt(args.centerHoriz) != NaN) { var left = Math.round(vpw/2 - t.width()/2) + args.centerHoriz + jQuery(window).scrollLeft(); t.css("left", (left < 0 ? 0 : left) + "px"); }
            if (parseInt(args.centerVert) != NaN) { var top = Math.round(vph/2 - t.height()/2) + args.centerVert + jQuery(window).scrollTop(); t.css("top", (top < 0 ? 0 : top) + "px"); }
            t.addClass("JQModalPosition").fadeIn("fast");
        }
    });
};

jQuery.fn.unmodal = function(args) {
    return this.each(function() {
        jQuery(this).hide().removeClass("JQModalPosition");
        if (jQuery(".JQModalPosition").length == 0) jQuery(".JQModalCover").hide();
    });
};

jQuery.fn.clickToggle = function(toggle, showText, hideText) {
    return this.each(function() {
        jQuery(this).attr("clickToggleSelector", toggle);
        jQuery(this).attr("clickToggleShowText", showText);
        jQuery(this).attr("clickToggleHideText", hideText);
        jQuery(this).click(function() {
            jQuery(jQuery(this).attr("clickToggleSelector")).toggle();
            jQuery(this).html(jQuery(this).attr(jQuery(jQuery(this).attr("clickToggleSelector")).css("display") == "none" ? "clickToggleShowText" : "clickToggleHideText"));
        });
    });
};

// *****************************************************************************************
// *****************************************************************************************
// JPOPUP FUNCTIONS
// *****************************************************************************************
// *****************************************************************************************

// jPopup and jMessage, v1.0
// Pretty ways to alert the user to stuff that's going on
// Jeff Rowberg <jeff@rowberg.net> - April 6, 2008
// http://www.sectorfej.net/jpopup

// Use it, have fun with it, modify it...just don't say you
// wrote it unless you actually totally do rewrite it.

// NOTE: Requires jQuery >= 1.2 (built around 1.2.1)
// http://www.jquery.com/

// ********************************************************

// Behavioral settings located at bottom of file

// ============-------------------
// CONSTANTS - DON'T CHANGE THESE!
// ============-------------------
var JPOPUP_BTN_OK = 0, JPOPUP_BTN_OKCANCEL = 1, JPOPUP_BTN_YESNO = 2, JPOPUP_BTN_YESNOCANCEL = 3, JPOPUP_BTN_CUSTOM = 10;
var JPOPUP_ICON_QUESTION = 0, JPOPUP_ICON_ALERT = 1, JPOPUP_ICON_ERROR = 2, JPOPUP_ICON_INFO = 3;
var JPOPUP_RESPONSE_OK = 0, JPOPUP_RESPONSE_CANCEL = 1, JPOPUP_RESPONSE_YES = 2, JPOPUP_RESPONSE_NO = 3;
var JMESSAGE_UPDATE = 0, JMESSAGE_ERROR = 1, JMESSAGE_SUCCESS = 2, JMESSAGE_NOTICE = 3;
var JMESSAGE_POS_TOPLEFT = 0, JMESSAGE_POS_TOPRIGHT = 1, JMESSAGE_POS_BOTTOMLEFT = 2, JMESSAGE_POS_BOTTOMRIGHT = 3;

// ====================
// ON TO THE GOOD STUFF
// ====================
var jPopupZIndex = 1000;
var jPopupRef = new Array();
var jMessageOffset = 0;
var jMessageRef = new Array();
var jMessageScrollTimeout = false;
var jMessageResizeTimeout = false;

jQuery(window).scroll(function() {
    if (jMessageScrollTimeout) clearTimeout(jMessageScrollTimeout);
    jMessageScrollTimeout = setTimeout("jPopupScrollAssist();", 180);
});

jQuery(window).resize(function() {
    if (jMessageResizeTimeout) clearTimeout(jMessageResizeTimeout);
    jMessageResizeTimeout = setTimeout("jPopupResizeAssist();", 180);
});

function jPopupScrollAssist() {
    if (jPopupRef.length > 0)
        for (var i = 0; i < jPopupRef.length; i++)
            if (!jPopupRef[i].left && !jPopupRef[i].top) jPosition.windowCenter(jQuery("#" + jPopupRef[i].id), 0, -32, jPopupScrollSpeed);
    if (jMessageRef.length > 0)
        for (var i = 0; i < jMessageRef.length; i++)
            jMessagePositionFunction(jQuery("#" + jMessageRef[i].id), jMessagePadHoriz, jMessageRef[i].top, jMessageScrollSpeed);
    jMessageScrollTimeout = null;
}

function jPopupResizeAssist() {
    if (jPopupRef.length > 0)
        for (var i = 0; i < jPopupRef.length; i++) {
            if (!jPopupRef[i].left && !jPopupRef[i].top)
                jPosition.windowCenter(jQuery("#" + jPopupRef[i].id), 0, -32, jPopupScrollSpeed);
            var fullWidth = jQuery(document).width();
            var fullHeight = jQuery(document).height();
            if (jQuery(window).width() > fullWidth) fullWidth = jQuery(window).width();
            if (jQuery(window).height() > fullHeight) fullHeight = jQuery(window).height();
            jQuery("#" + jPopupRef[i].id + "_fade").width(fullWidth).height(fullHeight);
        }
    if (jMessageRef.length > 0)
        for (var i = 0; i < jMessageRef.length; i++)
            jMessagePositionFunction(jQuery("#" + jMessageRef[i].id), jMessagePadHoriz, jMessageRef[i].top, jMessageScrollSpeed);
    jMessageResizeTimeout = null;
}

function jPopup(body, title, type, callback, width, left, top) {
    d = new Date();
    var id = "jpopup" + Math.floor(Math.random(10000)) + "" + d.getTime();

    if (!title) title = jPopupDefaultTitle;
    if (!type) type = jPopupDefaultType;
    if (!callback) callback = jPopupDefaultCallback;
    if (!width) width = jPopupDefaultWidth;

    jQuery("body").append("<div id=\"" + id + "\" class=\"jPopupDiv\" style=\"display: none;\"></div>");
    jQuery("body").append("<div id=\"" + id + "_fade\" class=\"jPopupFade\" style=\"display: none;\"></div>");

    var p = jQuery("#" + id).css("z-index", jPopupZIndex + 2).css("opacity", 0).show(); // show required for auto-width

    p.append("<div id=\"" + id + "_title\" class=\"jPopupTitle\">" + title + "</div>");
    p.append("<div id=\"" + id + "_body\" class=\"jPopupBody\"><div id=\"" + id + "_bodyspan\">" + body + "</div></div>");

    var b = jQuery("#" + id + "_body");
    var s = jQuery("#" + id + "_bodyspan");

    // use 75% of window if 0 passed
    if (width == 0) width = -Math.floor(parseInt(jPosition.o().innerWidth) * .75);

    if (width < 0) { // autosize up to maximum -width
        if (s.paddedWidth() + 40 < -width) width = s.paddedWidth() + 40;
        else width = -width;
    }
    p.width(width);

    var btnDiv = '<div class="jPopupButtonContainer">';
    var focus = "";
    switch (type) {
        case JPOPUP_BTN_OK:
            btnDiv += '<input id="' + id + '_btnOK" type="button" class="jPopupButton" value="OK" />';
            focus = "_btnOK";
            break;
        case JPOPUP_BTN_OKCANCEL:
            btnDiv += '<input id="' + id + '_btnOK" type="button" class="jPopupButton" value="OK" />';
            btnDiv += '<input id="' + id + '_btnCancel" type="button" class="jPopupButton" value="Cancel" />';
            focus = "_btnOK";
            break;
        case JPOPUP_BTN_YESNO:
            btnDiv += '<input id="' + id + '_btnYes" type="button" class="jPopupButton" value="Yes" />';
            btnDiv += '<input id="' + id + '_btnNo" type="button" class="jPopupButton" value="No" />';
            focus = "_btnYes";
            break;
        case JPOPUP_BTN_YESNOCANCEL:
            btnDiv += '<input id="' + id + '_btnYes" type="button" class="jPopupButton" value="Yes" />';
            btnDiv += '<input id="' + id + '_btnNo" type="button" class="jPopupButton" value="No" />';
            btnDiv += '<input id="' + id + '_btnCancel" type="button" class="jPopupButton" value="Cancel" />';
            focus = "_btnYes";
            break;
        case JPOPUP_BTN_CUSTOM:
            if (options.customButtons) {
                for (var item in options.customButtons) {
                    alert(item + "=" + fieldData[item]);
                }
            } else {
                // failsafe
                btnDiv += '<input id="' + id + '_btnOK" type="button" class="jPopupButton" value="OK" />';
                focus = "_btnOK";
            }
            break;
    }
    btnDiv += '</div>';
    b.append(btnDiv);

    if (p.height() > (jQuery(window).height() * 0.8)) {
        p.height(parseInt(jQuery(window).height() * 0.8));
        //b.height(parseInt(jQuery(window).height() * 0.8));
    }

    if (!left && !top) {
        jPosition.windowCenter(p, 0, -32);
    } else {
        if (!top) top = 30;
        if (!left) left = 40;
        p.css("left", left).css("top", top);
    }

    jPopupRef.push({ id: id, left: left, top: top });

    if (jPopupEnableSmooth) {
        jQuery("#" +  id + "_btnOK").click(function() { if (callback(JPOPUP_RESPONSE_OK)) jQuery("#" + id + ", #" + id + "_fade").fadeOut(jPopupFadeOutSpeed, function() { jQuery(this).remove(); jPopupZIndex -= 10; }); }).hover(function() { jQuery(this).addClass("jPopupButtonHover"); }, function() { jQuery(this).removeClass("jPopupButtonHover"); }).css("disabled", false);
        jQuery("#" +  id + "_btnCancel").click(function() { if (callback(JPOPUP_RESPONSE_CANCEL)) jQuery("#" + id + ", #" + id + "_fade").fadeOut(jPopupFadeOutSpeed, function() { jQuery(this).remove(); jPopupZIndex -= 10; }); }).hover(function() { jQuery(this).addClass("jPopupButtonHover"); }, function() { jQuery(this).removeClass("jPopupButtonHover"); }).css("disabled", false);
        jQuery("#" +  id + "_btnYes").click(function() { if (callback(JPOPUP_RESPONSE_YES)) jQuery("#" + id + ", #" + id + "_fade").fadeOut(jPopupFadeOutSpeed, function() { jQuery(this).remove(); jPopupZIndex -= 10; }); }).hover(function() { jQuery(this).addClass("jPopupButtonHover"); }, function() { jQuery(this).removeClass("jPopupButtonHover"); }).css("disabled", false);
        jQuery("#" +  id + "_btnNo").click(function() { if (callback(JPOPUP_RESPONSE_NO)) jQuery("#" + id + ", #" + id + "_fade").fadeOut(jPopupFadeOutSpeed, function() { jQuery(this).remove(); jPopupZIndex -= 10; }); }).hover(function() { jQuery(this).addClass("jPopupButtonHover"); }, function() { jQuery(this).removeClass("jPopupButtonHover"); }).css("disabled", false);
    } else {
        jQuery("#" +  id + "_btnOK").click(function() { if (callback(JPOPUP_RESPONSE_OK)) { jQuery("#" + id + ", #" + id + "_fade").remove(); jPopupZIndex -= 10; }}).hover(function() { jQuery(this).addClass("jPopupButtonHover"); }, function() { jQuery(this).removeClass("jPopupButtonHover"); }).css("disabled", false);
        jQuery("#" +  id + "_btnCancel").click(function() { if (callback(JPOPUP_RESPONSE_CANCEL)) { jQuery("#" + id + ", #" + id + "_fade").remove(); jPopupZIndex -= 10; }}).hover(function() { jQuery(this).addClass("jPopupButtonHover"); }, function() { jQuery(this).removeClass("jPopupButtonHover"); }).css("disabled", false);
        jQuery("#" +  id + "_btnYes").click(function() { if (callback(JPOPUP_RESPONSE_YES)) { jQuery("#" + id + ", #" + id + "_fade").remove(); jPopupZIndex -= 10; }}).hover(function() { jQuery(this).addClass("jPopupButtonHover"); }, function() { jQuery(this).removeClass("jPopupButtonHover"); }).css("disabled", false);
        jQuery("#" +  id + "_btnNo").click(function() { if (callback(JPOPUP_RESPONSE_NO)) { jQuery("#" + id + ", #" + id + "_fade").remove(); jPopupZIndex -= 10; }}).hover(function() { jQuery(this).addClass("jPopupButtonHover"); }, function() { jQuery(this).removeClass("jPopupButtonHover"); }).css("disabled", false);
    }

    var fullWidth = jQuery(document).width();
    var fullHeight = jQuery(document).height();
    if (jQuery(window).width() > fullWidth) fullWidth = jQuery(window).width();
    if (jQuery(window).height() > fullHeight) fullHeight = jQuery(window).height();
    var c = jQuery("#" + id + "_fade").width(fullWidth).height(fullHeight).css("z-index", jPopupZIndex + 1).css("opacity", 0).show();

    jPopupZIndex += 10;
    if (jPopupEnableSmooth) {
        c.fadeTo(jPopupFadeInSpeed, 0.5);
        p.fadeTo(jPopupFadeInSpeed, 1);
    } else {
        c.css("opacity", 0.5);
        p.css("opacity", 1);
    }
    jQuery("#" + id + focus).focus();
    return p;
}

function jMessage(message, type, duration, width) {
    d = new Date();
    var id = "jmessage" + Math.floor(Math.random(10000)) + "" + d.getTime();
    if (!type) type = jMessageDefaultType;
    if (!duration && duration !== 0) duration = jMessageDefaultDuration;
    if (!width) width = jMessageDefaultWidth;
    var cssClass = "";
    switch (type) {
        case JMESSAGE_UPDATE:  cssClass = "jMessageUpdate"; break;
        case JMESSAGE_ERROR:   cssClass = "jMessageError"; break;
        case JMESSAGE_SUCCESS: cssClass = "jMessageSuccess"; break;
        case JMESSAGE_NOTICE:  cssClass = "jMessageNotice"; break;
        default:               cssClass = "jMessageUpdate"; break;
    }
    jQuery("body").append("<div id=\"" + id + "\" class=\"jMessageDiv " + cssClass + "\" style=\"display: none;\"></div>");
    var m = jQuery("#" + id).css("opacity", 0).show(); // to make auto-width work correctly
    m.append('<span id="' + id + '_closespan" class="jMessageCloseSpan"><a class="jMessageCloseLink" href="javascript:void();" onClick="jMessageOffset -= jQuery(\'#' + id + '\').paddedHeight(); jQuery(\'#' + id + '\').remove(); jMessageShiftUp(\'' + id + '\'); return false;">[X]</a></span>');
    m.append('<span id="' + id + '_span" class="jMessageSpan">' + message + '</span>');
    var cs = jQuery("#" + id + "_closespan");
    var s = jQuery("#" + id + "_span");
    if (width < 0) { // autosize up to maximum -width
        if (s.width() + cs.width() + 16 < -width) width = s.width() + cs.width() + 16;
        else width = -width;
    }
    m.width(width);
    jMessagePositionFunction(m, jMessagePadHoriz, jMessagePadVert + jMessageOffset);
    jMessageRef.push({ id: id, top: jMessagePadVert + jMessageOffset });
    jMessageOffset += m.paddedHeight();
    if (duration == 0) {
        if (jMessageEnableSmooth)
            m.fadeTo(jMessageFadeSpeed, jMessageOpacity);
        else
            m.css("opacity", jMessageOpacity);
    } else {
        if (jMessageEnableSmooth)
            m.fadeTo(jMessageFadeSpeed, jMessageOpacity, function() { setTimeout('jQuery("#' + id + '").fadeOut(jMessageFadeSpeed, function() { jMessageOffset -= jQuery(this).paddedHeight(); jQuery(this).remove(); jMessageShiftUp("' + id + '"); });', duration); });
        else {
            m.css("opacity", jMessageOpacity);
            setTimeout('jMessageOffset -= jQuery("#' + id + '").paddedHeight(); jQuery("#' + id + '").remove(); jMessageShiftUp("' + id + '");', duration);
        }
    }
    return m;
}

// removes a given message (or the top one if not specified) and slides the rest to fit
function jMessageShiftUp(id) {
    if (jMessageRef.length > 1) {
        var old = false, num;
        if (id) {
            for (var i = 0; i < jMessageRef.length; i++) if (jMessageRef[i].id == id) { old = jMessageRef.splice(i, 1); old = old[0]; num = i; break; }
        } else {
            old = jMessageRef.shift(); // take the top one
            num = 0;
        }
        if (num >= jMessageRef.length) return; // no shifting necessary
        var dist = jMessageRef[num].top - old.top;
        for (var i = num; i < jMessageRef.length; i++) {
            jMessageRef[i].top -= dist;
            jMessagePositionFunction(jQuery("#" + jMessageRef[i].id), jMessagePadHoriz, jMessageRef[i].top, jMessageSlideSpeed);
        }
    } else if (jMessageRef.length == 1) {
        jMessageRef.shift(); // just disappear, since it's the last one
    }
}

// returns full width, including padding
jQuery.fn.paddedWidth = function() {
    return jQuery(this).width() + parseInt(jQuery(this).css("padding-left")) + parseInt(jQuery(this).css("padding-right"));
};

// returns full height, including padding
jQuery.fn.paddedHeight = function() {
    return jQuery(this).height() + parseInt(jQuery(this).css("padding-top")) + parseInt(jQuery(this).css("padding-bottom"));
};

// modified and extended from "viewport" object of unknown origin--email me for credit
var jPosition = {
    o: function() {
        if (self.innerHeight) {
            this.pageYOffset = self.pageYOffset;
            this.pageXOffset = self.pageXOffset;
            this.innerHeight = self.innerHeight;
            this.innerWidth = self.innerWidth;
        } else if (document.documentElement && document.documentElement.clientHeight) {
            this.pageYOffset = document.documentElement.scrollTop;
            this.pageXOffset = document.documentElement.scrollLeft;
            this.innerHeight = document.documentElement.clientHeight;
            this.innerWidth = document.documentElement.clientWidth;
        } else if (document.body) {
            this.pageYOffset = document.body.scrollTop;
            this.pageXOffset = document.body.scrollLeft;
            this.innerHeight = document.body.clientHeight;
            this.innerWidth = document.body.clientWidth;
        }
        this.leftEdge = this.pageXOffset;
        this.rightEdge = this.innerWidth + this.pageXOffset;
        this.topEdge = this.pageYOffset;
        this.bottomEdge = this.innerHeight + this.pageYOffset;
        return this;
    },
    windowCenter: function(el, padHoriz, padVert, speed) {
        if (speed && speed !== 0) jQuery(el).animate({
            left: Math.round(jPosition.o().innerWidth / 2) + jPosition.o().pageXOffset - Math.round(jQuery(el).paddedWidth() / 2) + padHoriz,
            top: Math.round(jPosition.o().innerHeight / 2) + jPosition.o().pageYOffset - Math.round(jQuery(el).paddedHeight() / 2) + padVert
            }, speed, "swing");
        else {
            jQuery(el).css("left", Math.round(jPosition.o().innerWidth / 2) + jPosition.o().pageXOffset - Math.round(jQuery(el).paddedWidth() / 2) + padHoriz);
            jQuery(el).css("top", Math.round(jPosition.o().innerHeight / 2) + jPosition.o().pageYOffset - Math.round(jQuery(el).paddedHeight() / 2) + padVert);
        }
    },
    windowTopLeft: function(el, padHoriz, padVert, speed) {
        if (!padHoriz || isNaN(padHoriz)) padHoriz = 0; if (!padVert || isNaN(padVert)) padVert = 0;
        if (speed && speed !== 0) jQuery(el).animate({
            left: jPosition.o().pageXOffset + padHoriz,
            top: jPosition.o().pageYOffset + padVert
            }, speed, "swing");
        else {
            jQuery(el).css("left", jPosition.o().pageXOffset + padHoriz);
            jQuery(el).css("top", jPosition.o().pageYOffset + padVert);
        }
    },
    windowTopRight: function(el, padHoriz, padVert, speed) {
        if (!padHoriz || isNaN(padHoriz)) padHoriz = 0; if (!padVert || isNaN(padVert)) padVert = 0;
        //alert("padHoriz: " + padHoriz + "\npadVert: " + padVert + "\noldTop: " + jQuery(el).css("top") + "\noldLeft: " + jQuery(el).css("left") + "\nXOffset: " + jPosition.o().pageXOffset + "\nYOffset: " + jPosition.o().pageYOffset);
        if (speed && speed !== 0) jQuery(el).animate({
            left: jPosition.o().innerWidth + jPosition.o().pageXOffset - (jQuery(el).paddedWidth() + padHoriz),
            top: jPosition.o().pageYOffset + padVert
            }, speed, "swing");
        else {
            jQuery(el).css("left", jPosition.o().innerWidth + jPosition.o().pageXOffset - (jQuery(el).paddedWidth() + padHoriz));
            jQuery(el).css("top", jPosition.o().pageYOffset + padVert);
        }
    },
    windowBottomLeft: function(el, padHoriz, padVert, speed) {
        if (!padHoriz || isNaN(padHoriz)) padHoriz = 0; if (!padVert || isNaN(padVert)) padVert = 0;
        if (speed && speed !== 0) jQuery(el).animate({
            left: jPosition.o().pageXOffset + padHoriz,
            top: jPosition.o().innerHeight + jPosition.o().pageYOffset - (jQuery(el).paddedHeight() + padVert)
            }, speed, "swing");
        else {
            jQuery(el).css("left", jPosition.o().pageXOffset + padHoriz);
            jQuery(el).css("top", jPosition.o().innerHeight + jPosition.o().pageYOffset - (jQuery(el).paddedHeight() + padVert));
        }
    },
    windowBottomRight: function(el, padHoriz, padVert, speed) {
        if (!padHoriz || isNaN(padHoriz)) padHoriz = 0; if (!padVert || isNaN(padVert)) padVert = 0;
        if (speed && speed !== 0) jQuery(el).animate({
            left: jPosition.o().innerWidth + jPosition.o().pageXOffset - (jQuery(el).paddedWidth() + padHoriz),
            top: jPosition.o().innerHeight + jPosition.o().pageYOffset - (jQuery(el).paddedHeight() + padVert)
            }, speed, "swing");
        else {
            jQuery(el).css("left", jPosition.o().innerWidth + jPosition.o().pageXOffset - (jQuery(el).paddedWidth() + padHoriz));
            jQuery(el).css("top", jPosition.o().innerHeight + jPosition.o().pageYOffset - (jQuery(el).paddedHeight() + padVert));
        }
    }
};

// =================
// BEHAVIOR SETTINGS
// =================
var jPopupEnableSmooth = true;      // whether to animate or just show (disable for slower clients)
var jPopupFadeInSpeed = 150;        // ignored if jPopupEnableSmooth = false
var jPopupFadeOutSpeed = 300;       // ignored if jPopupEnableSmooth = false
var jPopupScrollSpeed = 300;        // ignored if jPopupEnableSmooth = false
var jPopupDefaultTitle = "Alert";
var jPopupDefaultType = JPOPUP_BTN_OK;
var jPopupDefaultCallback = function() { return true; };
var jPopupDefaultWidth = 0;

var jMessageEnableSmooth = true;    // whether to animate or just show (disable for slower clients)
var jMessageOpacity = 0.9;          // between 0 and 1
var jMessagePadHoriz = 28;          // safe for vertical scrollbars
var jMessagePadVert = 8;
var jMessagePosition = JMESSAGE_POS_TOPRIGHT;
var jMessageFadeSpeed = 600;        // ignored if jMessageEnableSmooth = false
var jMessageSlideSpeed = 600;       // ignored if jMessageEnableSmooth = false
var jMessageScrollSpeed = 100;      // ignored if jMessageEnableSmooth = false
var jMessageDefaultType = JMESSAGE_UPDATE;
var jMessageDefaultDuration = 10000; // time to show, in milliseconds (set 0 for indefinite)
var jMessageDefaultWidth = -320;

// ==================
// LAST MODIFICATIONS
// ==================

if (!jPopupEnableSmooth) {
    jPopupScrollSpeed = false;
}

if (!jMessageEnableSmooth) {
    jMessageFadeSpeed = false;
    jMessageSlideSpeed = false;
    jMessageScrollSpeed = false;
}

switch (jMessagePosition) {
    case JMESSAGE_POS_TOPLEFT: jMessagePositionFunction = jPosition.windowTopLeft; break;
    case JMESSAGE_POS_TOPRIGHT: jMessagePositionFunction = jPosition.windowTopRight; break;
    case JMESSAGE_POS_BOTTOMLEFT: jMessagePositionFunction = jPosition.windowBottomLeft; break;
    case JMESSAGE_POS_BOTTOMRIGHT: jMessagePositionFunction = jPosition.windowBottomRight; break;
}

var jajax=function(callURL,postData,timeoutMS,ignoreError){
    var errFunc = null;
    if (!ignoreError) errFunc = function(xmlhr,textStatus,errorThrown){jQuery.prompt("AJAX request error: "+textStatus+"\n\nPlease try again.");};
    if(!timeoutMS)timeoutMS=60000;jQuery.ajax({url:callURL,type:"POST",data:postData,dataType: "script",timeout:timeoutMS,success:function(data, textStatus){return true;},error:errFunc});
};

var formValidate = function(formId, inline, singleId) {
    var $f = jQuery("#" + formId);
    var okay = true;
    if (singleId) {
        // special case because :textarea selector breaks each()
        jQuery("#" + singleId + "[prmRequired=yes]:enabled:visible", $f).each(function(i) {
            if (jQuery(this).val() == "" || jQuery(this).hasClass("ghost")) { formAlert(formId, this.id, "Please enter a value for the \"" + jQuery(this).attr("prmLabel") + "\" field.", inline); okay = false; return false; }
        }); if (!okay) return false;
    } else {
        jQuery("input[prmRequired=yes]:text:enabled:visible, input[prmRequired=yes]:password:enabled:visible, input[prmRequired=yes]:radio:enabled:visible, input[prmRequired=yes]:hidden:enabled, textarea[prmRequired=yes]:enabled:visible, select[prmRequired=yes]:enabled:visible", $f).each(function(i) {
            if (jQuery(this).attr("type") == "radio") {
                if (jQuery("input:radio[name=" + jQuery(this).attr("name") + "]:checked:visible").length < 1)  { formAlert(formId, this.id, "Please select an option for the \"" + jQuery(this).attr("prmLabel") + "\" choice.", inline); okay = false; return false; }
            } else if (this.type.toLowerCase() == "select-multiple") {
                var s = jQuery.map(jQuery(this).find(":selected"), function(e) { return e.value; });
                if (s.length == 0) { formAlert(formId, this.id, "Please select at least one value for the \"" + jQuery(this).attr("prmLabel") + "\" field.", inline); okay = false; return false; }
            } else {
                if (jQuery(this).val() == null || jQuery(this).val() == "" || jQuery(this).hasClass("ghost")) { formAlert(formId, this.id, "Please enter a value for the \"" + jQuery(this).attr("prmLabel") + "\" field.", inline); okay = false; return false; }
            }
        }); if (!okay) return false;
    }
    jQuery("input[prmRequired=yes]:checkbox:enabled:visible:not(:checked)", $f).each(function(i) {
        formAlert(formId, this.id, "Please check the box next to the \"" + jQuery(this).attr("prmLabel") + "\" item.", inline); okay = false; return false;
    }); if (!okay) return false;
    jQuery("input[prmFormat=email][value]:enabled:visible", $f).each(function(i) {
        var re = /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?)$/;
        if (!re.test(jQuery(this).val())) { formAlert(formId, this.id, "Please enter a valid email address in the \"" + jQuery(this).attr("prmLabel") + "\" field.", inline); okay = false; return false; }
    }); if (!okay) return false;
    jQuery("input[prmFormat=ssn][value]:enabled:visible", $f).each(function(i) {
        var re = /^(\d{3}\-\d{2}\-\d{4}|\d{9})$/;
        if (!re.test(jQuery(this).val())) { formAlert(formId, this.id, "Please enter a valid SSN in the \"" + jQuery(this).attr("prmLabel") + "\" field.", inline); okay = false; return false; }
    }); if (!okay) return false;
    jQuery("input[prmFormat=date][value]:enabled:visible", $f).each(function(i) {
        var re = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{4}$/;
        if (!re.test(jQuery(this).val())) { formAlert(formId, this.id, "Please enter a valid date in the \"" + jQuery(this).attr("prmLabel") + "\" field.", inline); okay = false; return false; }
    }); if (!okay) return false;
    jQuery("input[prmFormat=integer][value]:enabled:visible", $f).each(function(i) {
        var re = /[\D]/g;
        if (re.test(jQuery(this).val())) { formAlert(formId, this.id, "Please enter a valid whole number in the \"" + jQuery(this).attr("prmLabel") + "\" field.", inline); okay = false; return false; }
    }); if (!okay) return false;
    jQuery("input[prmFormat=float][value]:enabled:visible", $f).each(function(i) {
        var re = /[^0-9\.\-\+]/g;
        if (re.test(jQuery(this).val()) || parseFloat(jQuery(this).val()) == NaN) { formAlert(formId, this.id, "Please enter a valid decimal number in the \"" + jQuery(this).attr("prmLabel") + "\" field.", inline); okay = false; return false; }
    }); if (!okay) return false;
    jQuery("input[prmFormat=alpha][value]:enabled:visible", $f).each(function(i) {
        var re = /[^a-zA-Z]/g;
        if (re.test(jQuery(this).val())) { formAlert(formId, this.id, "Please enter only alpha characters A-Z in the \"" + jQuery(this).attr("prmLabel") + "\" field.", inline); okay = false; return false; }
    }); if (!okay) return false;
    jQuery("input[prmFormat=alphanumeric][value]:enabled:visible", $f).each(function(i) {
        var re = /[^a-zA-Z0-9]/g;
        if (re.test(jQuery(this).val())) { formAlert(formId, this.id, "Please enter a valid alphanumeric string in the \"" + jQuery(this).attr("prmLabel") + "\" field.", inline); okay = false; return false; }
    }); if (!okay) return false;
    jQuery("input[prmFormat=url][value]:enabled:visible", $f).each(function(i) {
        var re = /https?:\/\/([-\w\.]+)+(:\d+)?(\/([\w/_\.]*(\?\S+)?)?)?/;
        if (!re.test(jQuery(this).val())) { formAlert(formId, this.id, "Please enter a valid URL in the \"" + jQuery(this).attr("prmLabel") + "\" field.", inline); okay = false; return false; }
    }); if (!okay) return false;
    jQuery("input[prmFormat=urlshort][value]:enabled:visible", $f).each(function(i) {
        var re = /(https?:\/\/)?([-\w\.]+)+(:\d+)?(\/([\w/_\.]*(\?\S+)?)?)?/;
        if (!re.test(jQuery(this).val())) { formAlert(formId, this.id, "Please enter a valid URL in the \"" + jQuery(this).attr("prmLabel") + "\" field.", inline); okay = false; return false; }
    }); if (!okay) return false;
    jQuery("input[prmFormat=ipaddress][value]:enabled:visible", $f).each(function(i) {
        var re = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
        if (!re.test(jQuery(this).val())) { formAlert(formId, this.id, "Please enter a valid IP address in the \"" + jQuery(this).attr("prmLabel") + "\" field.", inline); okay = false; return false; }
    }); if (!okay) return false;
    jQuery("input[prmFormat=usphone][value]:enabled:visible", $f).each(function(i) {
        var re = /^\(?\d{3}\)?(\s|-|\.)?\d{3}(\s|-|\.)?\d{4}$/;
        if (!re.test(jQuery(this).val())) { formAlert(formId, this.id, "Please enter a valid phone number in the \"" + jQuery(this).attr("prmLabel") + "\" field.", inline); okay = false; return false; }
    }); if (!okay) return false;
    jQuery("input[prmFormat=intlphone][value]:enabled:visible", $f).each(function(i) {
        var re = /^\d(\d|-){7,20}$/;
        if (!re.test(jQuery(this).val())) { formAlert(formId, this.id, "Please enter a valid international phone number in the \"" + jQuery(this).attr("prmLabel") + "\" field.", inline); okay = false; return false; }
    }); if (!okay) return false;
    jQuery("input[prmFormat=time12][value]:enabled:visible", $f).each(function(i) {
        var re = /^([1-9]|1[0-2]):[0-5]\d$/;
        if (!re.test(jQuery(this).val())) { formAlert(formId, this.id, "Please enter a valid 12-hour time in the \"" + jQuery(this).attr("prmLabel") + "\" field.", inline); okay = false; return false; }
    }); if (!okay) return false;
    jQuery("input[prmFormat=time24][value]:enabled:visible", $f).each(function(i) {
        var re = /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?)$/;
        if (!re.test(jQuery(this).val())) { formAlert(formId, this.id, "Please enter a valid 24-hour time in the \"" + jQuery(this).attr("prmLabel") + "\" field.", inline); okay = false; return false; }
    }); if (!okay) return false;
    jQuery("input[prmFormat=uszip][value]:enabled:visible", $f).each(function(i) {
        var re = /\D{5}(-\D{4})?/;
        if (!re.test(jQuery(this).val())) { formAlert(formId, this.id, "Please enter a valid US ZIP code in the \"" + jQuery(this).attr("prmLabel") + "\" field.", inline); okay = false; return false; }
    }); if (!okay) return false;
    jQuery("input[prmMinimum][value]:enabled:visible", $f).each(function(i) {
        var v = parseFloat(jQuery(this).val()), m = parseFloat(jQuery(this).attr("prmMinimum"));
        if (m == NaN) return true; // bad value specified for minimum, but don't die
        if (v == NaN || v < m)  { formAlert(formId, this.id, "Please enter a value no less than " + m + " in the \"" + jQuery(this).attr("prmLabel") + "\" field.", inline); okay = false; return false; }
    }); if (!okay) return false;
    jQuery("input[prmMaximum][value]:enabled:visible", $f).each(function(i) {
        var v = parseFloat(jQuery(this).val()), m = parseFloat(jQuery(this).attr("prmMaximum"));
        if (m == NaN) return true; // bad value specified for maximum, but don't die
        if (v == NaN || v < m)  { formAlert(formId, this.id, "Please enter a value no greater than " + m + " in the \"" + jQuery(this).attr("prmLabel") + "\" field.", inline); okay = false; return false; }
    }); if (!okay) return false;
    jQuery("input[customvalidate]:enabled:visible", $f).each(function(i) {
        var msg; eval("msg = " + jQuery(this).attr("customvalidate") + ";");
        if (msg != "") { formAlert(formId, this.id, msg, inline); okay = false; return false; }
    }); if (!okay) return false;
    
    return true;
};

var formAlert = function(formId, elementId, message, inline) {
    if (inline) {
        // special inline error/message
    } else {
        // normal error/message
        document.promptCallbackId = elementId;
        jQuery.prompt(message, { callback: function() { jQuery("#" + document.promptCallbackId).focus(); } });
    }
};

var ajaxPost = function(formId) {
    var $f = jQuery("#" + formId);
    var action = $f.attr("ajaxAction");
    if (!action) action = $f.attr("action");
    var json = { };
    var obj = $f.find("input[type!=button][type!=submit][type!=reset], select, textarea");
    for (var i = 0; i < obj.length; i++) {
        with (obj[i]) {
            if (type == "select-multiple") {
                var sel = Array();
                for (j = 0; j < options.length; j++) { if (options[j].selected) sel.push(options[j].value); }
                json[id] = sel;
            } else if (type == "textarea") {
                if (jQuery(obj[i]).hasClass("ghost")) json[id] = "";
                else json[id] = jQuery(obj[i]).val();
            } else if (type == "checkbox") {
                if (checked) json[id] = value;
                else json[id] = "";
            } else if (type == "radio") {
                if (!json[name] && checked) json[name] = value;
            } else {
                if (jQuery(obj[i]).hasClass("ghost")) json[id] = "";
                else json[id] = value;
            }
        }
    }
    jQuery.ajax({ url: action, type: "POST", data: json, dataType: "script", timeout: 30000, success: function() { }, error: function() { } });
    return false; // prevent <form> submission after we've done our AJAX action
};

// CMP-specific on every page

var aContainerSetup = [];
var aContainerTimeout = [];
jQuery(function() {
    jQuery("div.aContainer.rotate").each(function(i) {
        var pId = jQuery(this).parent().attr("id");
        var timeout = jQuery(this).attr("prmTimeout");
        if (!timeout) timeout = 10000;
        if (!aContainerSetup[pId]) {
            aContainerSetup[pId] = true;
            aContainerTimeout[pId] = setTimeout('ar("' + jQuery(this).parent().attr("id") + '", ' + timeout + ');', timeout);
        }
    });
});
var ar = function(id, timeout) {
    var $o = jQuery("#" + id);
    var $c = $o.children();
    var setSize = $o.children("[prmRotation=1]").length;
    var total = $c.length / setSize;
    var current = 1;
    $c.each(function(i) { if (jQuery(this).is(":visible")) current = jQuery(this).attr("prmRotation"); });
    var previous = current;
    current++;
    if (current > total) current = 1;
    $o.children("[prmRotation=" + previous + "]").hide();
    $o.children("[prmRotation=" + current + "]").show();
    aContainerTimeout[id] = setTimeout('ar("' + id + '", ' + timeout + ');', timeout);
};

/**
 * tools.flashembed 1.0.4 - The future of Flash embedding.
 * 
 * Copyright (c) 2009 Tero Piirainen
 * http://flowplayer.org/tools/flash-embed.html
 *
 * Dual licensed under MIT and GPL 2+ licenses
 * http://www.opensource.org/licenses
 *
 * Launch  : March 2008
 * Date: ${date}
 * Revision: ${revision} 
 */ 
(function() {  
        
//{{{ utility functions 
        
var jQ = typeof jQuery == 'function';

var options = {
    
    // very common opts
    width: '100%',
    height: '100%',        
    
    // flashembed defaults
    allowfullscreen: true,
    allowscriptaccess: 'always',
    quality: 'high',    
    
    // flashembed specific options
    version: null,
    onFail: null,
    expressInstall: null, 
    w3c: false,
    cachebusting: false 
};

if (jQ) {
        
    // tools version number
    jQuery.tools = jQuery.tools || {};
    
    jQuery.tools.flashembed = { 
        version: '1.0.4', 
        conf: options
    };        
}


// from "Pro JavaScript techniques" by John Resig
function isDomReady() {
    
    if (domReady.done)  { return false; }
    
    var d = document;
    if (d && d.getElementsByTagName && d.getElementById && d.body) {
        clearInterval(domReady.timer);
        domReady.timer = null;
        
        for (var i = 0; i < domReady.ready.length; i++) {
            domReady.ready[i].call();    
        }
        
        domReady.ready = null;
        domReady.done = true;
    } 
}

// if jQuery is present, use it's more effective domReady method
var domReady = jQ ? jQuery : function(f) {
    
    if (domReady.done) {
        return f();    
    }
    
    if (domReady.timer) {
        domReady.ready.push(f);    
        
    } else {
        domReady.ready = [f];
        domReady.timer = setInterval(isDomReady, 13);
    } 
};    


// override extend opts function 
function extend(to, from) {
    if (from) {
        for (key in from) {
            if (from.hasOwnProperty(key)) {
                to[key] = from[key];
            }
        }
    }
    
    return to;
}    


// JSON.asString() function
function asString(obj) {
     
    switch (typeOf(obj)){
        case 'string':
            obj = obj.replace(new RegExp('(["\\\\])', 'g'), '\\$1');
            
            // flash does not handle %- characters well. transforms "50%" to "50pct" (a dirty hack, I admit)
            obj = obj.replace(/^\s?(\d+)%/, "$1pct");
            return '"' +obj+ '"';
            
        case 'array':
            return '['+ map(obj, function(el) {
                return asString(el);
            }).join(',') +']'; 
            
        case 'function':
            return '"function()"';
            
        case 'object':
            var str = [];
            for (var prop in obj) {
                if (obj.hasOwnProperty(prop)) {
                    str.push('"'+prop+'":'+ asString(obj[prop]));
                }
            }
            return '{'+str.join(',')+'}';
    }
    
    // replace ' --> "  and remove spaces
    return String(obj).replace(/\s/g, " ").replace(/\'/g, "\"");
}


// private functions
function typeOf(obj) {
    if (obj === null || obj === undefined) { return false; }
    var type = typeof obj;
    return (type == 'object' && obj.push) ? 'array' : type;
}


// version 9 bugfix: (http://blog.deconcept.com/2006/07/28/swfobject-143-released/)
if (window.attachEvent) {
    window.attachEvent("onbeforeunload", function() {
        __flash_unloadHandler = function() {};
        __flash_savedUnloadHandler = function() {};
    });
}

function map(arr, func) {
    var newArr = []; 
    for (var i in arr) {
        if (arr.hasOwnProperty(i)) {
            newArr[i] = func(arr[i]);
        }
    }
    return newArr;
}
    
function getHTML(p, c) {
        
    var e = extend({}, p);     
    var ie = document.all;    
    var html = '<object width="' +e.width+ '" height="' +e.height+ '"';
    
    // force id for IE or Flash API cannot be returned
    if (ie && !e.id) {
        e.id = "_" + ("" + Math.random()).substring(9);
    }
    
    if (e.id) {    
        html += ' id="' + e.id + '"';    
    }
    
    // prevent possible caching problems
    if (e.cachebusting) {
        e.src += ((e.src.indexOf("?") != -1 ? "&" : "?") + Math.random());        
    }            
    
    if (e.w3c || !ie) {
        html += ' data="' +e.src+ '" type="application/x-shockwave-flash"';        
    } else {
        html += ' classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"';    
    }
    
    html += '>'; 
    
    if (e.w3c || ie) {
        html += '<param name="movie" value="' +e.src+ '" />';     
    }

    // parameters
    e.width = e.height = e.id = e.w3c = e.src = null;
    
    for (var k in e) {
        if (e[k] !== null) {
            html += '<param name="'+ k +'" value="'+ e[k] +'" />';
        }
    }    

    // flashvars
    var vars = "";
    
    if (c) {
        for (var key in c) {
            if (c[key] !== null) {
                vars += key +'='+ (typeof c[key] == 'object' ? asString(c[key]) : c[key]) + '&';
            }
        }
        vars = vars.substring(0, vars.length -1);
        html += '<param name="flashvars" value=\'' + vars + '\' />';
    }
    
    html += "</object>";    
    
    return html;

}

//}}}


function Flash(root, opts, flashvars) {
    
    var version = flashembed.getVersion(); 
    
    // API methods for callback
    extend(this, {
            
        getContainer: function() {
            return root;    
        },
        
        getConf: function() {
            return opts;    
        },
    
        getVersion: function() {
            return version;    
        },    
        
        getFlashvars: function() {
            return flashvars;    
        }, 
        
        getApi: function() {
            return root.firstChild;    
        }, 
        
        getHTML: function() {
            return getHTML(opts, flashvars);    
        }
        
    });

    // variables    
    var required = opts.version; 
    var express = opts.expressInstall;
    
    
    // everything ok -> generate OBJECT tag 
    var ok = !required || flashembed.isSupported(required);
    
    if (ok) {
        opts.onFail = opts.version = opts.expressInstall = null;
        root.innerHTML = getHTML(opts, flashvars);
        
    // fail #1. express install
    } else if (required && express && flashembed.isSupported([6,65])) {
        
        extend(opts, {src: express});
        
        flashvars = {
            MMredirectURL: location.href,
            MMplayerType: 'PlugIn',
            MMdoctitle: document.title
        };
        
        root.innerHTML = getHTML(opts, flashvars);    
        
    // fail #2. 
    } else { 
    
        // fail #2.1 custom content inside container
        if (root.innerHTML.replace(/\s/g, '') !== '') {
            // minor bug fixed here 08.04.2008 (thanks JRodman)            
        
        // fail #2.2 default content
        } else {            
            root.innerHTML = 
                "<h2>Flash version " + required + " or greater is required</h2>" + 
                "<h3>" + 
                    (version[0] > 0 ? "Your version is " + version : "You have no flash plugin installed") +
                "</h3>" + 
                
                (root.tagName == 'A' ? "<p>Click here to download latest version</p>" : 
                    "<p>Download latest version from <a href='http://www.adobe.com/go/getflashplayer'>here</a></p>");
                
            if (root.tagName == 'A') {    
                root.onclick = function() {
                    location.href= 'http://www.adobe.com/go/getflashplayer';
                };
            }                
        }
    }
    
    // onFail
    if (!ok && opts.onFail) {
        var ret = opts.onFail.call(this);
        if (typeof ret == 'string') { root.innerHTML = ret; }    
    }
    
    // http://flowplayer.org/forum/8/18186#post-18593
    if (document.all) {
        window[opts.id] = document.getElementById(opts.id);
    } 
    
}

window.flashembed = function(root, conf, flashvars) {   
    
//{{{ construction
    
    // root must be found / loaded    
    if (typeof root == 'string') {
        var el = document.getElementById(root);
        if (el) {
            root = el;    
        } else {
            domReady(function() {
                flashembed(root, conf, flashvars);
            });
            return;         
        } 
    }
    
    // not found
    if (!root) { return; }
    
    if (typeof conf == 'string') {
        conf = {src: conf};    
    }
    
    var opts = extend({}, options);
    extend(opts, conf);        
    
    return new Flash(root, opts, flashvars);
    
//}}}
    
    
};


//{{{ static methods

extend(window.flashembed, {

    // returns arr[major, fix]
    getVersion: function() {
    
        var version = [0, 0];
        
        if (navigator.plugins && typeof navigator.plugins["Shockwave Flash"] == "object") {
            var _d = navigator.plugins["Shockwave Flash"].description;
            if (typeof _d != "undefined") {
                _d = _d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
                var _m = parseInt(_d.replace(/^(.*)\..*$/, "$1"), 10);
                var _r = /r/.test(_d) ? parseInt(_d.replace(/^.*r(.*)$/, "$1"), 10) : 0;
                version = [_m, _r];
            }
            
        } else if (window.ActiveXObject) {

            try { // avoid fp 6 crashes
                var _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
                
            } catch(e) {
                
                try { 
                    _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
                    version = [6, 0];
                    _a.AllowScriptAccess = "always"; // throws if fp < 6.47 
                    
                } catch(ee) {
                    if (version[0] == 6) { return version; }
                }
                try {
                    _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
                } catch(eee) {
                
                }
                
            }
            
            if (typeof _a == "object") {
                _d = _a.GetVariable("$version"); // bugs in fp 6.21 / 6.23
                if (typeof _d != "undefined") {
                    _d = _d.replace(/^\S+\s+(.*)$/, "$1").split(",");
                    version = [parseInt(_d[0], 10), parseInt(_d[2], 10)];
                }
            }
        } 
        
        return version;
    },
    
    isSupported: function(version) {
        var now = flashembed.getVersion();
        var ret = (now[0] > version[0]) || (now[0] == version[0] && now[1] >= version[1]);            
        return ret;
    },
    
    domReady: domReady,
    
    // returns a String representation from JSON object 
    asString: asString,
    
    
    getHTML: getHTML
    
});

//}}}


// setup jquery support
if (jQ) {
    
    jQuery.fn.flashembed = function(conf, flashvars) {
        
        var el = null;
        
        this.each(function() { 
            el = flashembed(this, conf, flashvars);
        });
        
        return conf.api === false ? this : el;        
    };

}

})();

