/**

 * SWFAddress 2.0: Deep linking for Flash and Ajax - http://www.asual.com/swfaddress/

 *

 * SWFAddress is (c) 2006-2007 Rostislav Hristov and is released under the MIT License:

 * http://www.opensource.org/licenses/mit-license.php

 *

 */



if (typeof com == "undefined") var com = {};

if (typeof com.asual == "undefined") com.asual = {};

if (typeof com.asual.util == "undefined") com.asual.util = {};

   

/**

 * @class Utility class that provides detailed browser information.

 * @static

 * @ignore

 */

com.asual.util.Browser = new function() {



    var _supported = false;

    var _version = -1;



    var _agent = navigator.userAgent;

    var _ie = false;

    var _camino = false;

    var _safari = false;

    var _opera = false;

    var _mozilla = false;



    if (/MSIE/.test(_agent)) {

        _ie = true;

        _version = parseFloat(_agent.substring(_agent.indexOf('MSIE') + 4));

        _supported = _version >= 6;

    } else if (/AppleWebKit/.test(_agent)) {

        _safari = true;

        _version = parseFloat(_agent.substring(_agent.indexOf('Safari') + 7));

        _supported = _version >= 312;

    } else if (/Opera/.test(_agent)) {

        _opera = true;

        _version = parseFloat(navigator.appVersion);

        _supported = _version >= 9.02;

    } else if (/Camino/.test(_agent)) {

        _camino = true;

        _version = parseFloat(_agent.substring(_agent.indexOf('Camino') + 7));

        _supported = _version >= 1;

    } else if (/Firefox/.test(_agent)) {

        _mozilla = true;

        _version = parseFloat(_agent.substring(_agent.indexOf('Firefox') + 8));

        _supported = _version >= 1;

    } else if (/Netscape/.test(_agent)) {

        _mozilla = true;

        _version = parseFloat(_agent.substring(_agent.indexOf('Netscape') + 9));

        _supported = _version >= 8;

    } else if (/Mozilla/.test(_agent) && /rv:/.test(_agent)) {

        _mozilla = true;

        _version = parseFloat(_agent.substring(_agent.indexOf('rv:') + 3));

        _supported = _version >= 1.8;

    }



    /**

     * Detects if the browser is supported.

     * @return {Boolean}

     * @static

     */

    this.isSupported = function() {

        return _supported;

    }



    /**

     * Detects the version of the browser.

     * @return {Number}

     * @static

     */

    this.getVersion = function() {

        return _version;

    }



    /**

     * Detects if the browser is Internet Explorer.

     * @return {Boolean}

     * @static

     */

    this.isIE = function() {

        return _ie;

    }



    /**

     * Detects if the browser is Safari.

     * @return {Boolean}

     * @static

     */

    this.isSafari = function() {

        return _safari;

    }



    /**

     * Detects if the browser is Opera.

     * @return {Boolean}

     * @static

     */

    this.isOpera = function() {

        return _opera;

    }



    /**

     * Detects if the browser is Camino.

     * @return {Boolean}

     * @static

     */

    this.isCamino = function() {

        return _camino;

    }



    /**

     * Detects if the browser is Mozilla.

     * @return {Boolean}

     * @static

     */

    this.isMozilla = function() {

        return _mozilla;

    }

}



/**

 * @class Utility class that provides event helpers.

 * @static

 * @ignore

 */

com.asual.util.Events = new function() {



    var _cache = [];

    var _browser = com.asual.util.Browser;

    var _dcl = 'DOMContentLoaded';



    if (_browser.isIE() || _browser.isSafari()) {

        (function(){

            try {

                if (_browser.isIE() || !/loaded|complete/.test(document.readyState))

                    document.documentElement.doScroll('left');

            } catch(e) {

                return setTimeout(arguments.callee, 0);

            }

            for (var i = 0, e; e = _cache[i]; i++) {

                if (e.t == _dcl) e.l.call(null);

            }

        })();

    }



    /**

     * Adds an event listener to an object.

     * @param {Object} obj The object that provides events.

     * @param {String} type The type of the event.

     * @param {Function} listener The event listener function.

     * @return {void}

     * @static

     */

    this.addListener = function(obj, type, listener) {

        _cache.push({o: obj, t: type, l: listener});

        if (type == _dcl && (_browser.isIE() || _browser.isSafari()))

            return;

        if (obj.addEventListener){

            obj.addEventListener(type, listener, false);

        } else if (obj.attachEvent){

            obj.attachEvent('on' + type, listener);

        }

    }



    /**

     * Removes an event listener from an object.

     * @param {Object} obj The object that provides events.

     * @param {String} type The type of the event.

     * @param {Function} listener The event listener function.

     * @return {void}     

     * @static

     */

    this.removeListener = function(obj, type, listener) {

        for (var i = 0, e; e = _cache[i]; i++) {

            if (e.o == obj && e.t == type && e.l == listener) {

                _cache.splice(i, 1);

                break;

            }

        }

        if (type == _dcl && (_browser.isIE() || _browser.isSafari()))

            return;

        if (obj.removeEventListener){

            obj.removeEventListener(type, listener, false);

        } else if (obj.detachEvent){

            obj.detachEvent('on' + type, listener);

        }

    }



    var _unload = function() {

        for (var i = 0, evt; evt = _cache[i]; i++) {

            if (evt.t != _dcl)

                com.asual.util.Events.removeListener(evt.o, evt.t, evt.l);

        }

    }



    this.addListener(window, 'unload', _unload);

}



/**

 * Creates a new SWFAddress event.

 * @class Event class for SWFAddress.

 * @param {String} type Type of the event.

 */

SWFAddressEvent = function(type) {

    

    /**

     * String representation of this object.

     * @ignore

     */

    this.toString = function() {

        return '[object SWFAddressEvent]';

    }



    /**

     * The type of this event.

     * @type String

     */

    this.type = type;



    /**

     * The target of this event.

     * @type Function

     */

    this.target = [SWFAddress][0];



    /**

     * The value of this event.

     * @type String

     */

    this.value = SWFAddress.getValue();



    /**

     * The path of this event.

     * @type String

     */

    this.path = SWFAddress.getPath();



    /**

     * The parameters of this event.

     * @type Object

     */

    this.parameters = {};



    var _names = SWFAddress.getParameterNames();

    for (var i = 0, n; n = _names[i]; i++) {

        this.parameters[n] = SWFAddress.getParameter(n);

    }

}



/**

 * Init event.

 * @type String

 * @memberOf SWFAddressEvent

 * @static

 */

SWFAddressEvent.INIT = 'init';



/**

 * Change event.

 * @type String

 * @memberOf SWFAddressEvent

 * @static 

 */

SWFAddressEvent.CHANGE = 'change';



/**

 * @class The SWFAddress class can be configured with query parameters using the following format:

 * swfaddress.js?html=false&history=1&tracker=pageTracker._trackPageview&strict=1.<br /> 

 * The list of supported options include:<br /><br />

 * <code>history:Boolean</code> - Enables or disables the creation of history entries.<br />

 * <code>html:Boolean</code> - Enables or disables the usage of swfaddress.html.<br />

 * <code>strict:Boolean</code> - Enables or disables the strict mode.<br />

 * <code>tracker:String</code> - Sets a function for page view tracking.<br />

 * @static 

 */ 

SWFAddress = new function() {



    var _browser = com.asual.util.Browser;

    var _supported = _browser.isSupported();

    

    var _d = top.document;

    var _h = top.history;

    var _l = top.location;



    var _iframe, _form, _url, _js = 'swfaddress.js';

    var _title = _d.title;

    var _length = _h.length;

    var _silent = false;

    var _listeners = {};

    var _stack = [];

    var _ids = [];

    var _opts = [];

    _opts['history'] = true;

    _opts['html'] = false;

    _opts['strict'] = true;

    _opts['tracker'] = 'urchinTracker';

    

    if ((!_supported && _l.href.indexOf('#') != -1) || 

        (_browser.isSafari() && _browser.getVersion() < 412 && _l.href.indexOf('#') != -1 && _l.search != '')){

        _d.open();

        _d.write('<html><head><meta http-equiv="refresh" content="0;url=' + 

            _l.href.substr(0, _l.href.indexOf('#')) + '" /></head></html>');

        _d.close();

    }



    var _getHash = function() {

        var index = _l.href.indexOf('#');

        if (index != -1) {

            return _l.href.substring(index).replace(/^#/g, '');

        }

        return '';

    }



    var _value = _getHash();



    var _strictCheck = function(value, force) {

        if (_opts['strict']) {

            if (force) {

                if (value.substr(0, 1) != '/') value = '/' + value;

                value = value.replace(/^([^\?.]*[^\/])(\?|$)/, '$1/$2').replace(/\/\//, '/');

            } else {

                if (value == '') value = '/';

            }

        }

        return value;

    }



    var _titleCheck = function() {

        if (_browser.isIE() && _d.title != _title) {

            SWFAddress.setTitle(_title);

        }

    }



    var _listen = function() {

        if (!_silent) {

            if (_browser.isIE()) {

                if (_value != _getHash()) {

                    if (_browser.getVersion() < 7) {

                        _l.reload();

                    } else {

                        SWFAddress.setValue(_getHash());

                    }

                }

            } else if (_browser.isSafari()) {

                if (_length != _h.length) {

                    _length = _h.length;

                    if (typeof _stack[_length - 1] != 'undefined') {

                        _value = _stack[_length - 1];

                    }

                    _update();

                }

            } else if (_value != _getHash()) {

                _value = _getHash();

                _update();

            }

            _titleCheck();

        }

    }



    var _jsDispatch = function(type) {

        if (SWFAddress.hasEventListener(type)) {

            SWFAddress.dispatchEvent(new SWFAddressEvent(type));

        }

        type = type.substr(0, 1).toUpperCase() + type.substring(1);

        if(typeof SWFAddress['on' + type] == 'function') {

            SWFAddress['on' + type]();

        }

    }



    var _jsInit = function() {

        _jsDispatch('init');

    }



    var _jsChange = function() {

        _jsDispatch('change');

    }



    var _swfChange = function() {

        for (var i = 0, id; id = _ids[i]; i++) {

            var obj = document.getElementById(id);

            if (obj) {

                if (obj.parentNode && typeof obj.parentNode.so != 'undefined') {

                    obj.parentNode.so.call('setSWFAddressValue', SWFAddress.getValue());

                } else {

                    obj = (obj && typeof obj.setSWFAddressValue != 'undefined') ? 

                        obj : ((obj.getElementsByTagName('object')[0] && 

                        typeof obj.getElementsByTagName('object')[0].setSWFAddressValue != 'undefined') ? 

                        obj.getElementsByTagName('object')[0] : ((obj.getElementsByTagName('embed')[0] && 

                        typeof obj.getElementsByTagName('embed')[0].setSWFAddressValue != 'undefined') ? 

                        obj.getElementsByTagName('embed')[0] : null));

                    if (obj) {

                        obj.setSWFAddressValue(SWFAddress.getValue());

                    }

                }

            }

        }

    }



    var _update = function() {

        _swfChange();

        _jsChange();

    }



    var _track = function() {

        if (typeof _opts['tracker'] != 'undefined' && eval('typeof ' + _opts['tracker'] + ' != "undefined"')){

            var fn = eval(_opts['tracker']);

            if (typeof fn == 'function') {

                fn((_l.pathname + SWFAddress.getValue()).replace(/\/\//, '/').replace(/^\/$/, ''));

            }

        }

    }

    

    var _htmlWrite = function() {

        var doc = _iframe.contentWindow.document;

        doc.open();

        doc.write('<script>var swfaddress = "' + _getHash() + '";</script>');

        doc.close();

    }



    var _htmlLoad = function() {

        if (_opts['html']) {

            var src = _iframe.contentWindow.location.href;

            _value = (src.indexOf('?') > -1) ? 

                src.substring(src.indexOf('?') + 1) : '';

        } else {

            _value = (typeof _iframe.contentWindow.swfaddress != 'undefined') ? 

                _iframe.contentWindow.swfaddress : '';

        }

        if (_value != _getHash()) {

            _update();

            _l.hash = _value;

        }

    }



    var _load = function() {



        var attr = 'id="swfaddress" style="position:absolute;top:-9999px;"';

        if (_browser.isIE()) {

            document.body.appendChild(document.createElement('div')).innerHTML = '<iframe ' + attr + ' src="' + 

                (_opts['html'] ? _url.replace(/\.js(\?.*)?$/, '.html') + '?' + _getHash() : 'javascript:false;') + 

                '"></iframe>';

            _iframe = document.getElementById('swfaddress');

            setTimeout(function() {

                if (!_opts['html'] && typeof _iframe.contentWindow.swfaddress == 'undefined') _htmlWrite();

                com.asual.util.Events.addListener(_iframe, 'load', _htmlLoad);

            }, 10);

        } else if (_browser.isSafari()) {

            if (_browser.getVersion() < 412) {

                document.body.innerHTML += '<form ' + attr + ' method="get"></form>';

                _form = document.getElementById('swfaddress');

            }

            if (typeof _l.swfaddress == 'undefined') _l.swfaddress = {};

            if (typeof _l.swfaddress[_l.pathname] != 'undefined') _stack = _l.swfaddress[_l.pathname].split(',');

        } else if (_browser.isOpera() && _ids.length == 0) {

            document.body.innerHTML += '<embed ' + attr + ' src="' + _url.replace(/\.js(\?.*)?$/, '.swf') + 

                '" type="application/x-shockwave-flash" />';

        }

        setTimeout(_jsInit, 1);

        setTimeout(_jsChange, 2);

        setTimeout(_track, 10);

        setInterval(_listen, 50);

    }



    /**

     * Init event.

     * @type Function

     * @event

     * @static

     */

    this.onInit = null;

    

    /**

     * Change event.

     * @type Function

     * @event

     * @static

     */

    this.onChange = null;

    

    /**

     * String representation of this class.

     * @ignore

     */

    this.toString = function() {

        return '[class SWFAddress]';

    }



    /**

     * Loads the previous URL in the history list.

     * @return {void}

     * @static

     */

    this.back = function() {

        _h.back();

    }



    /**

     * Loads the next URL in the history list.

     * @return {void}

     * @static

     */

    this.forward = function() {

        _h.forward();

    }



    /**

     * Loads a URL from the history list.

     * @param {Number} delta An integer representing a relative position in the history list.

     * @return {void}

     * @static

     */

    this.go = function(delta) {

        _h.go(delta);

    }



    /**

     * Opens a new URL in the browser. 

     * @param {String} url The resource to be opened.

     * @param {String} target Target window.

     * @return {void}

     * @static

     */

    this.href = function(url, target) {

        target = typeof target != 'undefined' ? target : '_self';     

        switch(target) {

            case '_self': 

                self.location.href = url; 

                break;

            case '_top': 

                _l.href = url; 

                break;                

            case '_blank':

                window.open(url); 

                break; 

            default:

                top.frames[target].location.href = url; 

                break; 

        }

    }



    /**

     * Opens a browser popup window. 

     * @param {String} url Resource location.

     * @param {String} name Name of the popup window.

     * @param {String} options Options which get evaluted and passed to the window.open() method.

     * @param {String} handler Optional JavaScript code for popup handling.    

     * @return {void}

     * @static

     */

    this.popup = function(url, name, options, handler) {

        var popup = window.open(url, name, eval(options));

        eval(handler);

    }



    /**

     * Registers an event listener..

     * @param {String} type Event type.

     * @param {Function} listener Event listener.

     * @return {void}

     * @static

     */

    this.addEventListener = function (type, listener) {

        if (typeof _listeners[type] == 'undefined') {

            _listeners[type] = [];

        }

        _listeners[type].push(listener);

    }



    /**

     * Removes an event listener.

     * @param {String} type Event type.

     * @param {Function} listener Event listener.

     * @return {void}

     * @static     

     */

    this.removeEventListener = function (type, listener) {

        if (typeof _listeners[type] != 'undefined') {

            for (var i = 0, l; l = _listeners[type][i]; i++) {

                if (l == listener) break;

            }

            _listeners[type].splice(i, 1);

        }

    }



    /**

     * Dispatches an event to all the registered listeners. 

     * @param {Object} event Event object.

     * @return {Boolean}

     * @static

     */

    this.dispatchEvent = function (event) {

        if (typeof _listeners[event.type] != 'undefined' && _listeners[event.type].length) {

            event.target = this;

            for (var i = 0, l; l = _listeners[event.type][i]; i++) {

                l(event);

            }

            return true;           

        }

        return false;

    }



    /**

     * Checks the existance of any listeners registered for a specific type of event. 

     * @param {String} event Event type.

     * @return {Boolean}

     * @static

     */

    this.hasEventListener = function (type) {

        return (typeof _listeners[type] != 'undefined' && _listeners[type].length > 0);

    }



    /**

     * Provides the state of the strict mode setting. 

     * @return {Boolean}

     * @static

     */

    this.getStrict = function() {

        return _opts['strict'];

    }



    /**

     * Enables or disables the strict mode.

     * @param {Boolean} strict Strict mode state.

     * @return {void}

     * @static

     */

    this.setStrict = function(strict) {

        _opts['strict'] = enabled;

    }



    /**

     * Provides the state of the history setting. 

     * @return {Boolean}

     * @static

     */

    this.getHistory = function() {

        return _opts['history'];

    }



    /**

     * Enables or disables the creation of history entries.

     * @param {Boolean} history History state.

     * @return {void}

     * @static

     */

    this.setHistory = function(history) {

        _opts['history'] = history;

    }



    /**

     * Provides the tracker function.

     * @return {String}

     * @static

     */

    this.getTracker = function() {

        return _opts['tracker'];

    }



    /**

     * Sets a function for page view tracking. The default value is 'urchinTracker'.

     * @param {String} tracker Tracker function.

     * @return {void}

     * @static

     */

    this.setTracker = function(tracker) {

        _opts['tracker'] = tracker;

    }



    /**

     * Provides a list of all the Flash objects registered. 

     * @return {Array}

     * @static

     */

    this.getIds = function() {

        return _ids;

    }



    /**

     * Provides the id the first and probably the only Flash object registered. 

     * @return {String}

     * @static

     */

    this.getId = function(index) {

        return _ids[0];

    }



    /**

     * Sets the id of a single Flash object which will be registered for deep linking.

     * @param {String} id ID of the object.

     * @return {void}

     * @static

     */

    this.setId = function(id) {

        _ids[0] = id;

    }



    /**

     * Adds an id to the list of Flash object registered for deep linking.

     * @param {String} id ID of the object.

     * @return {void}

     * @static

     */

    this.addId = function(id) {

        this.removeId(id);

        _ids.push(id);

    }



    /**

     * Removes an id from the list of Flash object registered for deep linking.

     * @param {String} id ID of the object.

     * @return {void}

     * @static

     */

    this.removeId = function(id) {

        for (var i = 0, swfid; swfid = _ids[i]; i++) {

            if (id == swfid) {

                _ids.splice(i, 1);

                break;

            }

        }

    }



    /**

     * Provides the title of the HTML document.

     * @return {String}

     * @static

     */

    this.getTitle = function() {

        return _d.title;

    }



    /**

     * Sets the title of the HTML document.

     * @param {String} title Title value.

     * @return {void}

     * @static

     */

    this.setTitle = function(title) {

        if (!_supported) return null;

        if (typeof title == 'undefined') return;

        if (title == 'null') title = '';

        _title = _d.title = title;

        if (_iframe && _iframe.contentWindow)

            _iframe.contentWindow.document.title = title;

    }



    /**

     * Provides the status of the browser window.

     * @return {String}

     * @static

     */

    this.getStatus = function() {

        return top.status;

    }



    /**

     * Sets the status of the browser window.

     * @param {String} status Status value.

     * @return {void}

     * @static

     */

    this.setStatus = function(status) {

        if (!_supported) return null;

        if (typeof status == 'undefined') return;

        if (!_browser.isSafari()) {

            if (status == 'null') status = '';

            status = _strictCheck(status, true);

            if (status == '/') status = '';

            if (!(/http(s)?:\/\//.test(status))) {

                var index = _l.href.indexOf('#');

                status = (index == -1 ? _l.href : _l.href.substr(0, index)) + '#' + status;

            }

            top.status = status;

        }

    }



    /**

     * Resets the status of the browser window.

     * @return {void}

     * @static

     */

    this.resetStatus = function() {

        top.status = '';

    }



    /**

     * Provides the current deep linking value.

     * @return {String}

     * @static

     */

    this.getValue = function() {

        if (!_supported) return null;

        return _strictCheck(_value, false);

    }



    /**

     * Sets the current deep linking value.

     * @param {String} value A value which will be appended to the base link of the HTML document.

     * @return {void}

     * @static

     */

    this.setValue = function(value) {

        if (!_supported) return null;

        if (typeof value == 'undefined') return;

        if (value == 'null') value = ''

        value = _strictCheck(value, true);

        if (value == '/') value = '';

        if (_value == value) return;

        _value = value;

        _silent = true;

        _update();

        _stack[_h.length] = _value;

        if (_browser.isSafari()) {

            if (_opts['history']) {

                _l.swfaddress[_l.pathname] = _stack.toString();

                _length = _h.length + 1;

                if (_browser.getVersion() < 412) {

                    if (_l.search == '') {

                        _form.action = '#' + _value;

                        _form.submit();

                    }

                } else {

                    var evt = document.createEvent('MouseEvents');

                    evt.initEvent('click', true, true);

                    var anchor = document.createElement('a');

                    anchor.href = '#' + _value;

                    anchor.dispatchEvent(evt);

                }

            } else {

                _l.replace('#' + _value);

            }

        } else if (_value != _getHash()) {

            if (_opts['history']) {

                _l.hash = '#' + _value;

            } else {

                _l.replace('#' + _value);

            }

        }

        if (_browser.isIE() && _opts['history']) {

            if (_opts['html']) {

                _iframe.contentWindow.location.assign(_iframe.contentWindow.location.pathname + 

                    '?' + _getHash());

            } else {

                _htmlWrite();

            }

        }

        setTimeout(_track, 10);

        _silent = false;

    }



    /**

     * Provides the deep linking value without the query string.

     * @return {String}

     * @static

     */

    this.getPath = function() {

        var value = this.getValue();

        if (value.indexOf('?') != -1) {

            return value.split('?')[0];

        } else {

            return value;   

        }

    }



    /**

     * Provides the query string part of the deep linking value.

     * @return {String}

     * @static

     */

    this.getQueryString = function() {

        var value = this.getValue();

        var index = value.indexOf('?');

        if (index != -1 && index < value.length) {

            return value.substr(index + 1);

        }

        return '';

    }



    /**

     * Provides the value of a specific query parameter.

     * @param {String} param Parameter name.

     * @return {String}

     * @static

     */

    this.getParameter = function(param) {

        var value = this.getValue();

        var index = value.indexOf('?');

        if (index != -1) {

            value = value.substr(index + 1);

            var params = value.split('&');

            var p, i = params.length;

            while(i--) {

                p = params[i].split('=');

                if (p[0] == param) {

                    return p[1];

                }

            }

        }

        return '';

    }



    /**

     * Provides a list of all the query parameter names.

     * @return {Array}

     * @static

     */

    this.getParameterNames = function() {

        var value = this.getValue();

        var index = value.indexOf('?');

        var names = [];

        if (index != -1) {

            value = value.substr(index + 1);

            if (value != '' && value.indexOf('=') != -1) {

                var params = value.split('&');

                var i = 0;

                while(i < params.length) {

                    names.push(params[i].split('=')[0]);

                    i++;

                }

            }

        }

        return names;

    }



    if (!_supported) return;

    

    for (var i = 1; i < _length; i++) {

        _stack.push('');

    }

    _stack.push(_l.hash.replace(/^#/g, ''));



    if (_browser.isIE() && _l.hash != _getHash()) {

        _l.hash = '#' + _getHash();

    }



    var scripts = document.getElementsByTagName('script');

    for (var i = 0, s; s = scripts[i]; i++) {

        if (s.src.indexOf(_js) > -1) {

            _url = String(s.src);

            break;

        }

    }

    if ((qi = _url.indexOf('?')) > -1) {

        var param, params = _url.substr(qi + 1).split('&');

        for (var j = 0, p; p = params[j]; j++) {

            param = p.split('=');

            if (/^(history|html|strict)$/.test(param[0])) {

                _opts[param[0]] = (isNaN(param[1]) ? eval(param[1]) : (parseFloat(param[1]) > 0));

            }

            if (/^tracker$/.test(param[0])) {

                _opts[param[0]] = param[1];

            }

        }

    }

    if (/file:\/\//.test(_l.href)) _opts['html'] = false;



    _titleCheck();

    com.asual.util.Events.addListener(document, 'DOMContentLoaded', _load);

}



/* Flash embedding hooks */

if (typeof swfobject != 'undefined') SWFObject = swfobject;

if (typeof FlashObject != 'undefined') SWFObject = FlashObject;

if (typeof SWFObject != 'undefined') {

    if (SWFObject.prototype && SWFObject.prototype.write) {

        com.asual.SWFObjectWrite = SWFObject.prototype.write;

        /**

         * @ignore

         */

        SWFObject.prototype.write = function() {

            if (this.getAttribute('version').major < 8) {

                this.addVariable('$swfaddress', SWFAddress.getValue());

                ((typeof arguments[0] == 'string') ? 

                    document.getElementById(arguments[0]) : arguments[0]).so = this;

            }

            if (success = com.asual.SWFObjectWrite.apply(this, arguments))

                SWFAddress.addId(this.getAttribute('id'));

            return success;

        }

    } else {

        com.asual.SWFObjectRegisterObject = SWFObject.registerObject;

        SWFObject.registerObject = function() {

            com.asual.SWFObjectRegisterObject.apply(this, arguments);

            SWFAddress.addId(arguments[0]);            

        }

        com.asual.SWFObjectCreateSWF = SWFObject.createSWF;

        SWFObject.createSWF = function() {

            com.asual.SWFObjectCreateSWF.apply(this, arguments);

            SWFAddress.addId(arguments[0].id);            

        }

        com.asual.SWFObjectEmbedSWF = SWFObject.embedSWF;

        SWFObject.embedSWF = function() {

            com.asual.SWFObjectEmbedSWF.apply(this, arguments);

            SWFAddress.addId(arguments[8].id);            

        }

    }

}

if (typeof UFO != 'undefined') {

    com.asual.UFOCreate = UFO.create;

    UFO.create = function() {

        com.asual.UFOCreate.apply(this, arguments);

        SWFAddress.addId(arguments[0].id);        

    }

}

if (typeof AC_FL_RunContent != 'undefined') {

    com.asual.AC_FL_RunContent = AC_FL_RunContent;

    AC_FL_RunContent = function() {

        com.asual.AC_FL_RunContent.apply(this, arguments);

        for (var i = 0, a; a = arguments[i]; i++) {

            if (a == 'id') {

                SWFAddress.addId(arguments[i+1]);

                break;

            }

        }

    }

}
