﻿/*
* jQuery jclock - Clock plugin - v 2.2.1
* http://plugins.jquery.com/project/jclock
*
* Copyright (c) 2007-2009 Doug Sparling <http://www.dougsparling.com>
* Licensed under the MIT License:
* http://www.opensource.org/licenses/mit-license.php
*/
(function($) {

    $.fn.jclock = function(options) {
        var version = '2.2.1';

        // options
        var opts = $.extend({}, $.fn.jclock.defaults, options);

        return this.each(function() {
            $this = $(this);
            $this.timerID = null;
            $this.running = false;

            // Record keeping for seeded clock
            $this.increment = 0;
            $this.lastCalled = new Date().getTime();

            var o = $.meta ? $.extend({}, opts, $this.data()) : opts;

            $this.format = o.format;
            $this.utc = o.utc;
            // deprecate utc_offset (v 2.2.0)
            $this.utcOffset = (o.utc_offset != null) ? o.utc_offset : o.utcOffset;
            $this.seedTime = o.seedTime;
            $this.timeout = o.timeout;

            $this.css({
                fontFamily: o.fontFamily,
                fontSize: o.fontSize,
                backgroundColor: o.background,
                color: o.foreground
            });

            // %a
            $this.daysAbbrvNames = new Array(7);
            $this.daysAbbrvNames[0] = "Dom";
            $this.daysAbbrvNames[1] = "Seg";
            $this.daysAbbrvNames[2] = "Ter";
            $this.daysAbbrvNames[3] = "Qua";
            $this.daysAbbrvNames[4] = "Qui";
            $this.daysAbbrvNames[5] = "Sex";
            $this.daysAbbrvNames[6] = "Sáb";

            // %A
            $this.daysFullNames = new Array(7);
            $this.daysFullNames[0] = "Domingo";
            $this.daysFullNames[1] = "Segunda";
            $this.daysFullNames[2] = "Terça";
            $this.daysFullNames[3] = "Quarta";
            $this.daysFullNames[4] = "Quinta";
            $this.daysFullNames[5] = "Sexta";
            $this.daysFullNames[6] = "Sábado";

            // %b
            $this.monthsAbbrvNames = new Array(12);
            $this.monthsAbbrvNames[0] = "Jan";
            $this.monthsAbbrvNames[1] = "Fev";
            $this.monthsAbbrvNames[2] = "Mar";
            $this.monthsAbbrvNames[3] = "Abr";
            $this.monthsAbbrvNames[4] = "Mai";
            $this.monthsAbbrvNames[5] = "Jun";
            $this.monthsAbbrvNames[6] = "Jul";
            $this.monthsAbbrvNames[7] = "Ago";
            $this.monthsAbbrvNames[8] = "Set";
            $this.monthsAbbrvNames[9] = "Out";
            $this.monthsAbbrvNames[10] = "Nov";
            $this.monthsAbbrvNames[11] = "Dez";

            // %B
            $this.monthsFullNames = new Array(12);
            $this.monthsFullNames[0] = "Janeiro";
            $this.monthsFullNames[1] = "Fevereiro";
            $this.monthsFullNames[2] = "Março";
            $this.monthsFullNames[3] = "Abril";
            $this.monthsFullNames[4] = "Maio";
            $this.monthsFullNames[5] = "Junho";
            $this.monthsFullNames[6] = "Julho";
            $this.monthsFullNames[7] = "Agosto";
            $this.monthsFullNames[8] = "Setembro";
            $this.monthsFullNames[9] = "Outubro";
            $this.monthsFullNames[10] = "Novembro";
            $this.monthsFullNames[11] = "Dezembro";

            $.fn.jclock.startClock($this);

        });
    };

    $.fn.jclock.startClock = function(el) {
        $.fn.jclock.stopClock(el);
        $.fn.jclock.displayTime(el);
    }

    $.fn.jclock.stopClock = function(el) {
        if (el.running) {
            clearTimeout(el.timerID);
        }
        el.running = false;
    }

    $.fn.jclock.displayTime = function(el) {
        var time = $.fn.jclock.getTime(el);
        el.html(time);
        el.timerID = setTimeout(function() { $.fn.jclock.displayTime(el) }, el.timeout);
    }

    $.fn.jclock.getTime = function(el) {
        if (typeof (el.seedTime) == 'undefined') {
            // Seed time not being used, use current time
            var now = new Date();
        } else {
            // Otherwise, use seed time with increment
            el.increment += new Date().getTime() - el.lastCalled;
            var now = new Date(el.seedTime + el.increment);
            el.lastCalled = new Date().getTime();
        }

        if (el.utc == true) {
            var localTime = now.getTime();
            var localOffset = now.getTimezoneOffset() * 60000;
            var utc = localTime + localOffset;
            var utcTime = utc + (3600000 * el.utcOffset);
            now = new Date(utcTime);
        }

        var timeNow = "";
        var i = 0;
        var index = 0;
        while ((index = el.format.indexOf("%", i)) != -1) {
            timeNow += el.format.substring(i, index);
            index++;

            // modifier flag
            //switch (el.format.charAt(index++)) {
            //}

            var property = $.fn.jclock.getProperty(now, el, el.format.charAt(index));
            index++;

            //switch (switchCase) {
            //}

            timeNow += property;
            i = index
        }

        timeNow += el.format.substring(i);
        return timeNow;
    };

    $.fn.jclock.getProperty = function(dateObject, el, property) {

        switch (property) {
            case "a": // abbrv day names
                return (el.daysAbbrvNames[dateObject.getDay()]);
            case "A": // full day names
                return (el.daysFullNames[dateObject.getDay()]);
            case "b": // abbrv month names
                return (el.monthsAbbrvNames[dateObject.getMonth()]);
            case "B": // full month names
                return (el.monthsFullNames[dateObject.getMonth()]);
            case "d": // day 01-31
                return ((dateObject.getDate() < 10) ? "0" : "") + dateObject.getDate();
            case "H": // hour as a decimal number using a 24-hour clock (range 00 to 23)
                return ((dateObject.getHours() < 10) ? "0" : "") + dateObject.getHours();
            case "I": // hour as a decimal number using a 12-hour clock (range 01 to 12)
                var hours = (dateObject.getHours() % 12 || 12);
                return ((hours < 10) ? "0" : "") + hours;
            case "m": // month number
                return ((dateObject.getMonth() < 10) ? "0" : "") + (dateObject.getMonth() + 1);
            case "M": // minute as a decimal number
                return ((dateObject.getMinutes() < 10) ? "0" : "") + dateObject.getMinutes();
            case "p": // either `am' or `pm' according to the given time value,
                // or the corresponding strings for the current locale
                return (dateObject.getHours() < 12 ? "am" : "pm");
            case "P": // either `AM' or `PM' according to the given time value,
                return (dateObject.getHours() < 12 ? "AM" : "PM");
            case "S": // second as a decimal number
                return ((dateObject.getSeconds() < 10) ? "0" : "") + dateObject.getSeconds();
            case "y": // two-digit year
                return dateObject.getFullYear().toString().substring(2);
            case "Y": // full year
                return (dateObject.getFullYear());
            case "%":
                return "%";
        }

    }

    // plugin defaults (24-hour)
    $.fn.jclock.defaults = {
        format: '%H:%M:%S',
        utcOffset: 0,
        utc: false,
        fontFamily: '',
        fontSize: '',
        foreground: '',
        background: '',
        seedTime: undefined,
        timeout: 1000 // 1000 = one second, 60000 = one minute
    };

})(jQuery);


/*	
Watermark plugin for jQuery
Version: 2.0

Copyright (c) 2009 Todd Northrop
http://www.speednet.biz/
	
June 2, 2009

Requires:  jQuery 1.2.3+
	
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version, subject to the following conditions:
	
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
	
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
------------------------------------------------------*/

(function($) {

    var 
    // Will speed up references to undefined
	undefined,

    // String constants for data names
	dataFlag = "watermark",
	dataClass = "watermarkClass",
	dataFocus = "watermarkFocus",
	dataFormSubmit = "watermarkSubmit",
	dataMaxLen = "watermarkMaxLength",
	dataPassword = "watermarkPassword",
	dataText = "watermarkText",

    // Includes only elements with watermark defined
	selWatermarkDefined = ":data(" + dataFlag + ")",

    // Includes only elements capable of having watermark
	selWatermarkAble = ":text,:password,textarea";

    // Extends jQuery with a custom selector - ":data(...)"
    // :data(<name>)  Includes elements that have a specific name defined in the jQuery data collection. (Only the existence of the name is checked; the value is ignored.)
    // :data(<name>=<value>)  Includes elements that have a specific jQuery data name defined, with a specific value associated with it.
    // :data(<name>!=<value>)  Includes elements that have a specific jQuery data name defined, with a value that is not equal to the value specified.
    // :data(<name>^=<value>)  Includes elements that have a specific jQuery data name defined, with a value that starts with the value specified.
    // :data(<name>$=<value>)  Includes elements that have a specific jQuery data name defined, with a value that ends with the value specified.
    // :data(<name>*=<value>)  Includes elements that have a specific jQuery data name defined, with a value that contains the value specified.
    $.extend($.expr[":"], {
        "data": function(element, index, matches, set) {
            var data, parts = /^((?:[^=!^$*]|[!^$*](?!=))+)(?:([!^$*]?=)(.*))?$/.exec(matches[3]);
            if (parts) {
                data = $(element).data(parts[1]);

                if (data !== undefined) {

                    if (parts[2]) {
                        data = "" + data;

                        switch (parts[2]) {
                            case "=":
                                return (data == parts[3]);
                            case "!=":
                                return (data != parts[3]);
                            case "^=":
                                return (data.slice(0, parts[3].length) == parts[3]);
                            case "$=":
                                return (data.slice(-parts[3].length) == parts[3]);
                            case "*=":
                                return (data.indexOf(parts[3]) !== -1);
                        }
                    }

                    return true;
                }
            }

            return false;
        }
    });

    $.watermark = {

        // Default class name for all watermarks
        className: "watermark",

        // Hide one or more watermarks by specifying any selector type
        // i.e., DOM element, string selector, jQuery matched set, etc.
        hide: function(selector) {
            $(selector).filter(selWatermarkDefined).each(
			function() {
			    $.watermark._hide($(this));
			}
		);
        },

        // Internal use only.
        _hide: function($input, focus) {

            if ($input.val() == $input.data(dataText)) {
                $input.val("");

                // Password type?
                if ($input.data(dataPassword)) {

                    if ($input.attr("type") === "text") {
                        var $pwd = $input.data(dataPassword), $wrap = $input.parent();
                        $wrap[0].removeChild($input[0]); // Can't use jQuery methods, because they destroy data
                        $wrap[0].appendChild($pwd[0]);
                        $input = $pwd;
                    }
                }

                if ($input.data(dataMaxLen)) {
                    $input.attr("maxLength", $input.data(dataMaxLen));
                    $input.removeData(dataMaxLen);
                }

                if (focus) {
                    $input.attr("autocomplete", "off");  // Avoid NS_ERROR_XPC_JS_THREW_STRING error in Firefox
                    window.setTimeout(
					function() {
					    $input.select();  // Fix missing cursor in IE
					}
				, 0);
                }
            }

            $input.removeClass($input.data(dataClass));
        },

        // Display one or more watermarks by specifying any selector type
        // i.e., DOM element, string selector, jQuery matched set, etc.
        // If conditions are not right for displaying a watermark, ensures that watermark is not shown.
        show: function(selector) {
            $(selector).filter(selWatermarkDefined).each(
			function() {
			    $.watermark._show($(this));
			}
		);
        },

        // Internal use only.
        _show: function($input) {
            var val = $input.val(), text = $input.data(dataText);

            if (((val.length == 0) || (val == text)) && (!$input.data(dataFocus))) {

                // Password type?
                if ($input.data(dataPassword)) {

                    if ($input.attr("type") === "password") {
                        var $wm = $input.data(dataPassword), $wrap = $input.parent();
                        $wrap[0].removeChild($input[0]); // Can't use jQuery methods, because they destroy data
                        $wrap[0].appendChild($wm[0]);
                        $input = $wm;
                    }
                }

                // Ensure maxLength big enough to hold watermark (input of type="text" only)
                if ($input.attr("type") === "text") {
                    var maxLen = $input.attr("maxLength");

                    if ((maxLen > 0) && (text.length > maxLen)) {
                        $input.data(dataMaxLen, maxLen);
                        $input.attr("maxLength", text.length);
                    }
                }

                $input.val(text);
                $input.addClass($input.data(dataClass));
            }
            else {
                $.watermark._hide($input);
            }
        },

        // Hides all watermarks on the current page.
        hideAll: function() {
            $.watermark.hide(selWatermarkAble);
        },

        // Displays all watermarks on the current page.
        showAll: function() {
            $.watermark.show(selWatermarkAble);
        }
    };

    $.fn.watermark = function(text, className) {
        ///	<summary>
        ///		Set watermark text and class name on all input elements of type="text" and textareas within
        /// 	the matched set. If className is not included, the default is "watermark". Within the matched
        /// 	set, only input elements with type="text" and textareas are affected; all other elements are
        /// 	ignored.
        ///	</summary>
        ///	<returns type="jQuery">
        ///		Returns the original jQuery matched set (not just the input and texarea elements).
        /// </returns>
        ///	<param name="text" type="String">
        ///		Text to display as a watermark when the input or textarea element has an empty value and does not
        /// 	have focus. The first time watermark() is called on an element, if this argument is empty (or not
        /// 	a String type), then the watermark will have the net effect of only changing the class name when
        /// 	the input or textarea element's value is empty and it does not have focus.
        ///	</param>
        ///	<param name="className" type="String" optional="true">
        ///		Provides the ability to override the default class name of "watermark" with the supplied class name.
        ///	</param>
        /// <remarks>
        ///		The effect of changing the text and class name on an input element is called a watermark because
        ///		typically light gray text is used to provide a hint as to what type of input is required. However,
        ///		the appearance of the watermark can be something completely different: simply change the CSS style
        ///		pertaining to the supplied class name.
        ///		
        ///		The first time watermark() is called on an element, the watermark text and class name are initialized,
        ///		and the focus and blur events are hooked in order to control the display of the watermark.
        ///		
        ///		Subsequently, watermark() can be called again on an element in order to change the watermark text
        ///		and/or class name, and it can also be called without any arguments in order to refresh the display.
        ///		
        ///		For example, after changing the value of the input or textarea element programmatically, watermark()
        /// 	should be called without any arguments to refresh the display, because the change event is only
        /// 	triggered by user actions, not by programmatic changes to an input or textarea element's value.
        /// 	
        /// 	The one exception to programmatic updates is for password input elements:  you are strongly cautioned
        /// 	against changing the value of a password input element programmatically (after the page loads).
        /// 	The reason is that some fairly hairy code is required behind the scenes to make the watermarks bypass
        /// 	IE security and switch back and forth between clear text (for watermarks) and obscured text (for
        /// 	passwords).  It is *possible* to make programmatic changes, but it must be done in a certain way, and
        /// 	overall it is not recommended.
        /// </remarks>

        var hasText = (typeof (text) === "string"), hasClass = (typeof (className) === "string");

        return this.filter(selWatermarkAble).each(
		function() {
		    var $input = $(this);

		    // Watermark already initialized?
		    if ($input.data(dataFlag)) {

		        // If re-defining text or class, first remove existing watermark, then make changes
		        if (hasText || hasClass) {
		            $.watermark._hide($input);

		            if (hasText) {
		                $input.data(dataText, text);
		            }

		            if (hasClass) {
		                $input.data(dataClass, className);
		            }
		        }
		    }
		    else {
		        $input.data(dataText, hasText ? text : "");
		        $input.data(dataClass, hasClass ? className : $.watermark.className);
		        $input.data(dataFlag, 1); // Flag indicates watermark was initialized

		        // Special processing for password type
		        if ($input.attr("type") === "password") {
		            var $wrap = $input.wrap("<span>").parent();
		            var $wm = $($wrap.html().replace(/type=["']?password["']?/i, 'type="text"'));

		            $wm.data(dataText, $input.data(dataText));
		            $wm.data(dataClass, $input.data(dataClass));
		            $wm.data(dataFlag, 1);

		            $wm.focus(
						function() {
						    $.watermark._hide($wm, true);
						}
					);
		            $input.blur(
						function() {
						    $.watermark._show($input);
						}
					);

		            $wm.data(dataPassword, $input);
		            $input.data(dataPassword, $wm);
		        }
		        else {

		            $input.focus(
						function() {
						    $input.data(dataFocus, 1);
						    $.watermark._hide($input, true);
						}
					).blur(
						function() {
						    $input.data(dataFocus, 0);
						    $.watermark._show($input);
						}
					);
		        }

		        // In order to reliably clear all watermarks before form submission,
		        // we need to replace the form's submit function with our own
		        // function.  Otherwise watermarks won't be cleared when the form
		        // is submitted programmatically.
		        var $form = $(this.form);

		        if (!$form.data(dataFormSubmit)) {
		            $form.data(dataFormSubmit, this.form.submit);
		            $form.submit($.watermark.hideAll);

		            this.form.submit = function() {
		                $.watermark.hideAll();
		                $form.data(dataFormSubmit).apply($form[0], arguments);
		            };
		        }
		    }

		    $.watermark._show($input);
		}
	).end();
    };

})(jQuery);

/**
* Flash (http://jquery.lukelutman.com/plugins/flash)
* A jQuery plugin for embedding Flash movies.
* 
* Version 1.0
* November 9th, 2006
*
* Copyright (c) 2006 Luke Lutman (http://www.lukelutman.com)
* Dual licensed under the MIT and GPL licenses.
* http://www.opensource.org/licenses/mit-license.php
* http://www.opensource.org/licenses/gpl-license.php
* 
* Inspired by:
* SWFObject (http://blog.deconcept.com/swfobject/)
* UFO (http://www.bobbyvandersluis.com/ufo/)
* sIFR (http://www.mikeindustries.com/sifr/)
* 
* IMPORTANT: 
* The packed version of jQuery breaks ActiveX control
* activation in Internet Explorer. Use JSMin to minifiy
* jQuery (see: http://jquery.lukelutman.com/plugins/flash#activex).
*
**/
; (function() {

    var $$;

    /**
    * 
    * @desc Replace matching elements with a flash movie.
    * @author Luke Lutman
    * @version 1.0.1
    *
    * @name flash
    * @param Hash htmlOptions Options for the embed/object tag.
    * @param Hash pluginOptions Options for detecting/updating the Flash plugin (optional).
    * @param Function replace Custom block called for each matched element if flash is installed (optional).
    * @param Function update Custom block called for each matched if flash isn't installed (optional).
    * @type jQuery
    *
    * @cat plugins/flash
    * 
    * @example $('#hello').flash({ src: 'hello.swf' });
    * @desc Embed a Flash movie.
    *
    * @example $('#hello').flash({ src: 'hello.swf' }, { version: 8 });
    * @desc Embed a Flash 8 movie.
    *
    * @example $('#hello').flash({ src: 'hello.swf' }, { expressInstall: true });
    * @desc Embed a Flash movie using Express Install if flash isn't installed.
    *
    * @example $('#hello').flash({ src: 'hello.swf' }, { update: false });
    * @desc Embed a Flash movie, don't show an update message if Flash isn't installed.
    *
    **/
    $$ = jQuery.fn.flash = function(htmlOptions, pluginOptions, replace, update) {

        // Set the default block.
        var block = replace || $$.replace;

        // Merge the default and passed plugin options.
        pluginOptions = $$.copy($$.pluginOptions, pluginOptions);

        // Detect Flash.
        if (!$$.hasFlash(pluginOptions.version)) {
            // Use Express Install (if specified and Flash plugin 6,0,65 or higher is installed).
            if (pluginOptions.expressInstall && $$.hasFlash(6, 0, 65)) {
                // Add the necessary flashvars (merged later).
                var expressInstallOptions = {
                    flashvars: {
                        MMredirectURL: location,
                        MMplayerType: 'PlugIn',
                        MMdoctitle: jQuery('title').text()
                    }
                };
                // Ask the user to update (if specified).
            } else if (pluginOptions.update) {
                // Change the block to insert the update message instead of the flash movie.
                block = update || $$.update;
                // Fail
            } else {
                // The required version of flash isn't installed.
                // Express Install is turned off, or flash 6,0,65 isn't installed.
                // Update is turned off.
                // Return without doing anything.
                return this;
            }
        }

        // Merge the default, express install and passed html options.
        htmlOptions = $$.copy($$.htmlOptions, expressInstallOptions, htmlOptions);

        // Invoke $block (with a copy of the merged html options) for each element.
        return this.each(function() {
            block.call(this, $$.copy(htmlOptions));
        });

    };
    /**
    *
    * @name flash.copy
    * @desc Copy an arbitrary number of objects into a new object.
    * @type Object
    * 
    * @example $$.copy({ foo: 1 }, { bar: 2 });
    * @result { foo: 1, bar: 2 };
    *
    **/
    $$.copy = function() {
        var options = {}, flashvars = {};
        for (var i = 0; i < arguments.length; i++) {
            var arg = arguments[i];
            if (arg == undefined) continue;
            jQuery.extend(options, arg);
            // don't clobber one flash vars object with another
            // merge them instead
            if (arg.flashvars == undefined) continue;
            jQuery.extend(flashvars, arg.flashvars);
        }
        options.flashvars = flashvars;
        return options;
    };
    /*
    * @name flash.hasFlash
    * @desc Check if a specific version of the Flash plugin is installed
    * @type Boolean
    *
    **/
    $$.hasFlash = function() {
        // look for a flag in the query string to bypass flash detection
        if (/hasFlash\=true/.test(location)) return true;
        if (/hasFlash\=false/.test(location)) return false;
        var pv = $$.hasFlash.playerVersion().match(/\d+/g);
        var rv = String([arguments[0], arguments[1], arguments[2]]).match(/\d+/g) || String($$.pluginOptions.version).match(/\d+/g);
        for (var i = 0; i < 3; i++) {
            pv[i] = parseInt(pv[i] || 0);
            rv[i] = parseInt(rv[i] || 0);
            // player is less than required
            if (pv[i] < rv[i]) return false;
            // player is greater than required
            if (pv[i] > rv[i]) return true;
        }
        // major version, minor version and revision match exactly
        return true;
    };
    /**
    *
    * @name flash.hasFlash.playerVersion
    * @desc Get the version of the installed Flash plugin.
    * @type String
    *
    **/
    $$.hasFlash.playerVersion = function() {
        // ie
        try {
            try {
                // avoid fp6 minor version lookup issues
                // see: http://blog.deconcept.com/2006/01/11/getvariable-setvariable-crash-internet-explorer-flash-6/
                var axo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash.6');
                try { axo.AllowScriptAccess = 'always'; }
                catch (e) { return '6,0,0'; }
            } catch (e) { }
            return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
            // other browsers
        } catch (e) {
            try {
                if (navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin) {
                    return (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]).description.replace(/\D+/g, ",").match(/^,?(.+),?$/)[1];
                }
            } catch (e) { }
        }
        return '0,0,0';
    };
    /**
    *
    * @name flash.htmlOptions
    * @desc The default set of options for the object or embed tag.
    *
    **/
    $$.htmlOptions = {
        height: 240,
        flashvars: {},
        pluginspage: 'http://www.adobe.com/go/getflashplayer',
        src: '#',
        type: 'application/x-shockwave-flash',
        width: 320
    };
    /**
    *
    * @name flash.pluginOptions
    * @desc The default set of options for checking/updating the flash Plugin.
    *
    **/
    $$.pluginOptions = {
        expressInstall: false,
        update: true,
        version: '6.0.65'
    };
    /**
    *
    * @name flash.replace
    * @desc The default method for replacing an element with a Flash movie.
    *
    **/
    $$.replace = function(htmlOptions) {
        this.innerHTML = '<div class="alt">' + this.innerHTML + '</div>';
        jQuery(this)
		.addClass('flash-replaced')
		.prepend($$.transform(htmlOptions));
    };
    /**
    *
    * @name flash.update
    * @desc The default method for replacing an element with an update message.
    *
    **/
    $$.update = function(htmlOptions) {
        var url = String(location).split('?');
        url.splice(1, 0, '?hasFlash=true&');
        url = url.join('');
        var msg = '<p>This content requires the Flash Player. <a href="http://www.adobe.com/go/getflashplayer">Download Flash Player</a>. Already have Flash Player? <a href="' + url + '">Click here.</a></p>';
        this.innerHTML = '<span class="alt">' + this.innerHTML + '</span>';
        jQuery(this)
		.addClass('flash-update')
		.prepend(msg);
    };
    /**
    *
    * @desc Convert a hash of html options to a string of attributes, using Function.apply(). 
    * @example toAttributeString.apply(htmlOptions)
    * @result foo="bar" foo="bar"
    *
    **/
    function toAttributeString() {
        var s = '';
        for (var key in this)
            if (typeof this[key] != 'function')
            s += key + '="' + this[key] + '" ';
        return s;
    };
    /**
    *
    * @desc Convert a hash of flashvars to a url-encoded string, using Function.apply(). 
    * @example toFlashvarsString.apply(flashvarsObject)
    * @result foo=bar&foo=bar
    *
    **/
    function toFlashvarsString() {
        var s = '';
        for (var key in this)
            if (typeof this[key] != 'function')
            s += key + '=' + encodeURIComponent(this[key]) + '&';
        return s.replace(/&$/, '');
    };
    /**
    *
    * @name flash.transform
    * @desc Transform a set of html options into an embed tag.
    * @type String 
    *
    * @example $$.transform(htmlOptions)
    * @result <embed src="foo.swf" ... />
    *
    * Note: The embed tag is NOT standards-compliant, but it 
    * works in all current browsers. flash.transform can be
    * overwritten with a custom function to generate more 
    * standards-compliant markup.
    *
    **/
    $$.transform = function(htmlOptions) {
        htmlOptions.toString = toAttributeString;
        if (htmlOptions.flashvars) htmlOptions.flashvars.toString = toFlashvarsString;
        return '<embed ' + String(htmlOptions) + '/>';
    };

    /**
    *
    * Flash Player 9 Fix (http://blog.deconcept.com/2006/07/28/swfobject-143-released/)
    *
    **/
    if (window.attachEvent) {
        window.attachEvent("onbeforeunload", function() {
            __flash_unloadHandler = function() { };
            __flash_savedUnloadHandler = function() { };
        });
    }

})();
