/* vim: set expandtab tabstop=4 shiftwidth=4: */

/**
* JavaScript container. Useful for rendering any Clearspring widget -- 
* Flash widgets get rendered into object tags; blobs get document.written.
* In other words, it doubles as our straight JS container and as our
* general purpose widget renderer on the widget.bs page. 
*
* cf. http://widgets.clearspring.com/c/widget.bs?wid=472b633e7225b6e3
* 
* For a JS widget, we write a relatively complicated series of nested
* divs to manage everything.
*
* div id="D" - the container of all 
*   div id="F" - F is for Frame; all the widget content goes in here
*        div id="O" - O is for Object; the widget content is here
*            div id="I" - iframe container
*                iframe
*        div id="B" - B is for Background; on Windows, we have to completely hide the widget when showing our menu because the Flash player plugin cannot composite Flash over iframes
*            div id="BGI" - Background Image - in the old days we had a simple image here
*                background object (flash) - now we have a tiling widget templated by the pawns
*    div id="PM" - service menu container
*        menu object (flash)
*
*
* All CS widgets on a page share a single Clearspring Manager object
* (CSM) with common static functions. 
*
* Each individual widget has its own CSO object, templated by the pawn with
* standard TLAs. For an example, see
* http://widgets.clearspring.com/o/472b633e7225b6e3/-/widget.js
*
* Note that there is some nasty shit in here. Hopefully JavaScript won't
* get the short end of the stick forever....
* 
* @author soa
* @author mjk
*
* @see http://twiki/DeveloperResources/WidgetAPI/JavaScriptContainer
*/
if (CSM && CSM.proto) var _CSM = CSM;
if (!CSM || !CSM.nsetup)
{
    if (CSM) var __CSM = CSM;
    var ua = navigator.userAgent.toLowerCase();
    var CSM = {
        /* constants for device environments */
        DASHB : '1',
        VISTA : '2',
        YAHOO : '3',
        /* service menu dimensions */
        SHD : 2, // shadow on a side
        DH : 20,
        MW : 160,
        MH : 150,
        MXW : 450,
        MXH : 450,
        /* are we in an iframe? */
        iframe : (self!=top&&_CSM==undefined),

        /** true iff. os is windows */
        IWN : navigator.appVersion.toLowerCase().indexOf("win")!=-1,

        /** true iff. browser is IE */
        IIE : !!(window.attachEvent && !window.opera),

        /** true iff. browser is Firefox 3*/
        FX3 : ua.indexOf('Firefox/3'),

        DEF : function (o)
        {
            return (o && typeof(o) != 'undefined' && o != 'undefined');
        },

        DEL : function(object, method)
        {
            return function() { method.apply(object, arguments); };
        },

        GPR : function () { 
                            var rv = '';
                            try 
                            {
                                //CSM.debug('cspur to: ' + typeof(_cs_pur));
                                if (CSM.DEF(window._cs_pur))
                                {
                                    //CSM.debug('had cs_pur: ' + _cs_pur);
                                    rv = window._cs_pur;
                                } 
                                rv = (rv.split("?"))[0];
                            }
                            catch (e)
                            {
                                return;
                            }
                            //CSM.debug('rv : ' + rv);
                            return rv;
                          },
                          
		BLR : function (targetObj) {
			if (!CSM.IIE) return;
			 
			//Hidden element to focus
			var _el = document.createElement('a'); _el.style.width = _el.style.height = 0;
			
			document.body.appendChild(_el); 
			_el.focus(); 
            if (targetObj && targetObj.focus) targetObj.focus();
            else window.focus();
			document.body.removeChild(_el);
        },                          

        /** true iff. browser is safari */
        ISF : (ua.indexOf("safari") > -1),

        /** true iff. browser is a gecko variant */
        IGK : (ua.indexOf("gecko") > -1 && !this.ISF),

        /** true iff. browser is firefox */
        IFX : (ua.indexOf("firefox") > -1),

        /** true iff. browser is operatic */
        IOP : (typeof(window.opera) != "undefined"),
        IST : (document.documentElement && document.documentElement.clientHeight),
        IAL : (this.IGK || this.IOP || this.IIE),

        /** shorthand for document.getElementById */
        GEL : function(id) { return document.getElementById(id); },

        /** cleans weird characters out of pids; needed for people doing arbitrary pid overrides  */
        clean : function (pid) {
            return pid.replace(/[^0-9a-zA-Z_]/g,"_");
        },
   
        /** convenience method for adding a variable to a url-encoded kvpair string */ 
        AVR : function (vars, name, value)
        {
           vars +=  (vars==''?'':'&') + name +'='+ value;
           return vars;
        },

        /** getframewidth */
        GFW : function () {
            if (self.innerWidth) {
                return self.innerWidth;
            } else if (document.documentElement && document.documentElement.clientWidth) {
                return document.documentElement.clientWidth;
            } else if (document.body) {
                return document.body.clientWidth;
            }
            return 0;
        },

        /** getframeheight */
        GFH : function () {
            if (self.innerWidth) {
                return self.innerHeight;
            } else if (document.documentElement && document.documentElement.clientWidth) {
                return document.documentElement.clientHeight;
            } else if (document.body) {
                return document.body.clientHeight;
            }
            return 0;
        },

        /** generate flash object tag */
        OBJ : function(id,w,h,url,ie,max,wmode,fsm,scalemode) {
            var wx = max ? '100%' : w;
            var hy = max ? '100%' : h;
            if (!wmode || wmode === undefined) wmode = "transparent";
            switch (wmode)
            {
                case "1":
                case 1:
                    wmode = (CSO.TWM == "1" || CSO.TWM == 1) ? 'opaque' : 'transparent';
                    break;
                case "2":
                case 2:
                    wmode = 'window';
                    break;
                case "0":
                case 0:
                default:
                    wmode = 'transparent';
                    break;
            }            
            
            if (CSM.args && CSM.args._cs_cnf) url += (url.indexOf("?") > -1 ? "&" : "?") + "_cs_cnf="+CSM.args._cs_cnf;
            if (max) url += (url.indexOf("?") > -1 ? "&" : "?") + "_cs_max=1";
            return '<object id="W'+id+'" width="'+wx+'" height="'+hy+'" quality="best" '+(ie?'':' data="'+url+'" ')+
            'pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash">' +
            '<param name="scalemode" value="'+((scalemode && scalemode !== '' ? scalemode : "showAll")) +'"/><param name="menu" value="false"/><param name="wmode" value="'+wmode+'"/><param name="allowNetworking" value="all" /><param name="allowScriptAccess" value="always"/>'+
            ((fsm+'')=='1'?'<param name="allowFullScreen" value="true"/>':'')+
            (ie?'<param name="movie" value="'+url+'" />':'')+' </object>';
        },

        debug : function (t) {
            try {
                //if (console) console.debug(t);
                //else alert(t); 
            } catch (e) {
            }
        },

        /** 
        * TMR = toggle manager 
        * Adjusts z-index of service menu, and, for certain browsers, toggles the visibility of the iframe and background image (important because
        * not all browsers properly display Flash above iframes).
        */
        TMR : function (cid, status, service) {
          // Service menu div:
          var m = this.GEL('PM'+cid);
          // Content div:
          var c = this.GEL('I'+cid);
          // Background div
          var b = this.GEL('B'+cid);
          var mgr = this.GEL('W'+cid);
          status =  (status == "true" || status === true);
          //CSM.debug('tmr: c=' + cid + ' s='+status+' svc='+service + ' m=' + m + ' iwn='+this.IWN);

          if (status) {
              m.style.zIndex = 999;

              // Steal focus for the service menu if necessary
              CSM.BLR(mgr);
          } else {
              m.style.zIndex = 0;
              CSM.BLR();
          }

          // We have to actually hide the iframe due to
          // problems with layering flash above other objects
          // that might be on the web page
          
          //CSM.debug('status: ' + status + ' margintop: ' + c.style.marginTop);
          if (status) {
              //c.style.marginTop = '-100000px';
              //b.style.marginTop = '0px';
              b.style.visibility = 'visible';
              b.style.display = 'block';
          } else {
              //c.style.marginTop = '0px';
              //b.style.marginTop = '-10000000px';
              //b.style.display = 'none';
              b.style.visibility = 'hidden';
          }
          c.style.display = status ? 'none' : 'block'; 
        },

        /**
        * Encodes URL. Returns null if no URL given.
        */
        EUR : function (url) {
            //console.debug('url='+url+' encodedUrl='+encodedUrl);
            if (url) {
                var encodedUrl = encodeURIComponent(url);
                if (CSM.DEF(encodedUrl))
                    return encodedUrl;
            }
            return;
        },
        
        /**
        * generates HTML for a tracking bug
        */
        BUG : function (id,sid,override,d,p,ie,fpid) {
            return CSM.OBJ(id,1,1,'http://'+d+p+override+'/-W/1/-H/1/-TRK/1/lib.as2.swf',ie);
        },

        /**
        * generates HTML for a service menu
        */
        MGR : function (id,override,w,h,d,p,ie,fpid,flvoverride) {
            return CSM.OBJ(id,w,h,'http://'+d+p+override+'/-W/'+(w-0)+'/-H/'+(h-0)+'/'+'-TRK/1/-DSW/0/m.template.v3.as3.swf?_cs_ontoggle=CSM.TMR&_cs_onclosetoggle=CSM.TMR' + (fpid ? '&_cs_fpid='+fpid : '') + (flvoverride ? '&'+flvoverride : ''),ie);
        },

        /**
        * generates HTML for a script tag or object tag for a widget in our system
        */
        GEN : function(id,override,w,h,d,p,ie,ijs,max,fwm,fsm,smo) {
            return ijs ?
                '<script type="text/javascript" src="http://'+d+p+override+'"> </script>' :
                CSM.OBJ(id,w,h,'http://'+d+p+override,ie,max,fwm,fsm,smo);
        }
    };

    if (_CSM) CSM.set = _CSM.set;
}
//CSM.debug('csm built');
// Clearspring Standard Object
var NCSO = {
    /** background color */
    BGC : this.FWM && (this.FWM=="opaque"||this.FWM=="1") ? this.FWM="#"+parseInt(this.BGC,16) : "transparent",

    /** 
    * getDimensionsBreakdown()
    *
    * object DimensionBreakdown := {
    *   name: String, // name of the section, ex. Shadow, Widget, Dock, etc.
    *   size: Number  // size in pixels of the section
    * }
    * 
    * @return object {width: DimensionBreakdown Array, height: DimensionBreakdown Array }
    */
    GDB : function () {
        var width = [];
        var height = [];

        var createDimBreakdown = function (name, size) { return {name: name, size: size};};
        this.SHD = CSM.SHD;
        var addShadow = CSM.DEL(this, function (obj) { obj.push(createDimBreakdown('Shadow', this.SHD));});

        var isFlash = (this.TYP===0||this.TYP=='0');
        var doShadow = isFlash && (this.DSW===1||this.DSW=='1');
        var doDock = (this.DBL===1||this.DBL=='1') && this.EMH >= CSM.MH && this.EMW >= CSM.MW;
        var dockHeight = CSM.DH;

        if (isFlash)
        {
            switch (this.SMO) 
            {
                case 'exactFit':
                case 'showAll':
                    dockHeight = (this.EMH / this.H) * CSM.DH;
                    this.SHD = (this.EMH / this.H) * CSM.SHD;
                    break;
            }
        }
                
        if (doShadow) {
            addShadow(width);
            addShadow(height);
        }

        width.push(createDimBreakdown('Widget', this.EMW - (doShadow ? 4 : 0)));
        height.push(createDimBreakdown('Widget', this.EMH - (doDock ? dockHeight : 0) - (doShadow ? 4 : 0)));

        if (doShadow) {
            addShadow(width);
            addShadow(height);
        }
       
        // Is this a dock-style template?
        //if (!isFlash || this.TFN.indexOf('template2')===0) {
            if (doDock) height.push(createDimBreakdown('Dock', dockHeight));
        //}

        return {width: width, height: height};
    },

    /** IE workaround for object tags to prevent multiple loads */
    ICF : function(id) {
        var w=window;
        var d=document; var ol=w.onload;
        w.onload=function() {
            if (typeof(ol)=="function") {try{ol();} catch(e){}}
            var o=d.getElementById(id); var h=o.outerHTML,params="";
            for (var j=0;j<o.childNodes.length;j++) { var p=o.childNodes[j]; if (p.tagName.toUpperCase()=="PARAM") params+=p.outerHTML; }
            var newO=h.split(">")[0]+">"+params+o.innerHTML+" </OBJECT>"; 
            o.outerHTML = newO;
        }
    },

    /** generates inline overrides for internal and widget variables */
    GOVR: function (includeTFN) {
        var override = "", i;
        var hasPur = false;
        var opr = CSM.EUR(CSM.GPR()); // from _cs_pur
        if (opr) {
            override += '/-PUR/'+opr;
            hasPur = true;
        }
        var tfn = '';

        if (this.IOV) {
            for (i=0;i<this.IOV.length;i++) {
                var key = this.IOV[i];
                // If GPR() returned something, we don't want to use our previous PUR override
                if (key == 'PUR') {
                    if (hasPur) continue;

                    if (this[key].indexOf("http%3A") === 0) {
                        this[key] = unescape(this[key]);
                    }
                    hasPur = true;
                } 

                if (this[key]!=null)
                {
                    var val = escape(this[key]).replace(/\//g,'%2f');
                    if (val == false || val == 'false') val = 0;
                    if (key == 'TFN')
                    {
                        tfn = "/"+val;
                    } 
                    else
                    {
                        override += "/-" + key + "/" + val;
                    }
                }
            }
        }
        if (this.FOV) {
            for (i=0;i<this.FOV.length;i++) {
                var key = this.FOV[i];
                override += "/" + key + "/" + escape(this.FLV[key]).replace(/\//g,'%2f');
            }
        }

        if (!hasPur) {
            var wpur;
            try 
            {
                if (!CSM.FX3 && top!=self && top.window.location.href) 
                {
                    //CSM.debug('href: ' + top.window.location.href);
                    wpur = ''+top.window.location.href;    
                } else {
                    wpur = ''+window.location.href;
                }
                wpur = (wpur.split("?"))[0];
            }
            catch (e)
            {
                // probably permissions error with location.href 
            }
            if (wpur) {
                var opr = CSM.EUR(wpur);
                override += (opr ? '/-PUR/'+opr : '');
            }
        }

        if (includeTFN === true) override += tfn;

        return override;
    },

    GFLV : function () {
        var override = '';

        // For console only:
        try  {
            if (CSM.args && CSM.DEF(CSM.args._cs_flv)) {
                var flvs = CSM.args._cs_flv.split("&");
                for (var i = 0; i < flvs.length; i++) {
                    override += (i ? "&" : "") + unescape(flvs[i]);
                }
            }

            if (CSM.args && CSM.DEF(CSM.args._cs_pwid)) {
                override += '_cs_pwid='+CSM.args._cs_pwid;
            }
        } catch (e) {}

        return override;
    },

    defaults : function(attrs) {
        for (var k in attrs) {
            if (!this[k]) { this[k] = attrs[k]; }
            if (typeof(attrs[k]) == 'number') {
                this[k] = parseInt(this[k],10);
            }
        }
    },
              
    /** write background */ 
    WBG : function () {
        return '<div id="BGI'+this.CID+'" style="position:absolute;top:0px;left:0px;z-index:1;width:100%;height:100%">'+
                ((this.MSW && this.MSW != this.EMW) || (this.MSH && this.MSH != this.EMH) ? this.WBI() : '') +
                '</div>';
    },

    /** write background image */ 
    WBI : function () {
        //return    '<img src="http://widgetimages2.clearspring.com/images/'+this.WID+'/img'+this.EMW+'x'+this.EMH+'.png" width="'+this.EMW+'" height="'+this.EMH+'" style="z-index:2"/>';
        return CSM.OBJ('BI'+this.CID,this.EMW,this.EMH-(this.DBL ? CSM.DH : 0),'http://'+this.TPH+'/o/'+this.WID+'/-/-/-/-W/'+this.EMW+'/-H/'+(this.EMH-(this.DBL ? CSM.DH : 0))+'/-TRK/0/back.swf',CSM.IIE,false,'transparent',false,'noScale');
    },

    /** 
    * Generate widget context.
    *
    * For sending to server with content request.
    */
    GWC : function (iaf) {
        var flvs = '';
        if (iaf & 0x1 && this.GEO) {
           flvs = CSM.AVR(flvs, '_cs_geo', this.GEO.substr(0, 26));
        }
        if (iaf & 0x2 && this.GEO) {
           flvs = CSM.AVR(flvs, '_cs_net', this.GEO.substr(26));
        }
        if (iaf & 0x4) {
           flvs = CSM.AVR(flvs, '_cs_dom', this.DOM);
        }
        if (iaf & 0x8) {
           flvs = CSM.AVR(flvs, '_cs_pur', this.PUR);
        }
        if (iaf & 0x10) {
           flvs = CSM.AVR(flvs, '_cs_ptc', this.KPP);
        }
        if (iaf & 0x20) {
           flvs = CSM.AVR(flvs, '_cs_wtc', this.KWP);
        }
        if (iaf & 0x40) {
        }
        if (iaf & 0x80) {
        }
        if (iaf & 0x100) flvs = CSM.AVR(flvs, '_cs_wid', this.WID);
        if (iaf & 0x200) flvs = CSM.AVR(flvs, '_cs_pid', this.PID);
        if (this.DWE) flvs = CSM.AVR(flvs, '_cs_dwe', this.DWE);
        return flvs;
    },

	/** 
    *   @returns full content url with args
	*   @note used separately in dashboard and mobile -- please do not fold back into WWT
	*/
	FCU : function() {
        var flvs = this.GWC(this.IAF);
        for (var key in this.FLV) {
            if (typeof(this.FLV[key])!="function") {
                flvs += (flvs.length?"&":"")+key+"="+(escape(this.FLV[key]).replace(/\//g,'%2f'));
            }
        }
        return flvs.length ? (this.CTU.indexOf("?")>-1? "&"+flvs : "?"+flvs) : "";
	},

    /** generates widget div/iframe html 
    *   <div id=O(WID+PID)      -- o for 'object'
    *       script | iframe
    *   </div>
    *   <div id=B(WID+PID)  -- b for 'background'
    *       <background color div>
    *       <background image div>
    *   </div>
    */ 
    WWT : function (wbs) {
        var flv = this.FCU();
        return '<div id="O'+this.CID+'" class="cs-js-o" '+
               'style="position:'+((this.DYN === true || this.DYN == '1') ? 'relative' : 'absolute')+';left:'+this.OFX+'px;top:'+this.OFY+'px;width:100%;height:100%;">'+
                ((this.PJS === true || this.PJS == "1") && !wbs ?  '<div id="I'+this.CID+'" class="cs-js-i">'+this.SCR(flv)+'</div>' : this.IFR(flv, wbs))+'</div>'+
               '<div id="B'+this.CID+'" class="cs-js-b" style="position:absolute;left:'+this.OFX+'px;top:'+this.OFY+'px;width:100%;height:100%;border:0px;display:none;z-index:2">'+
               /*
                    foo's idea:
                    '<h3 style="position: absolute;top: 0px;left: 0px;display: block;width: 100%;background: #666;padding: 6px 12px;margin: 0px;font-size: 14px;border-bottom:2px solid #000;color: #fff;z-index: 4;font-family:Helvetica,Sans;">(sharing widget)</h3>' +
                */
               '<div style="position:absolute;top:0px;left:0px;width:100%;height:100%;z-index:3;"></div>'+
                this.WBG() +
               '</div>';
    },

    /**
    * adds script tag to container built in WWT(); needed because IE6 won't respect placement of document.writes otherwise
    */
    SCR : function (flv) {
            return '<script type="text/javascript" src="'+this.CTU+flv+'"></script>';

            var scriptDiv = CSM.GEL('I'+this.CID);
            if (!flv) flv = this.FCU();
            //scriptDiv.innerHTML = '<script type="text/javascript" src="'+this.CTU+flv+'"></script>';
            if (scriptDiv) {
                //CSM.debug('got I'+this.CID+';f=' + scriptDiv.appendChild);
                var scriptObj = document.createElement("script");
                scriptObj.setAttribute("type", "text/javascript");
                scriptObj.setAttribute("charset", "utf-8");
                scriptDiv.appendChild(scriptObj);
                scriptObj.setAttribute("src", this.CTU + flv);
                //CSM.debug('created script element');
            }
    },

	/** writes the actual content iframe */
    IFR : function(flv, wbs) {
            var ctu = wbs ? "http://"+this.TPH+"/c/widget.bs?wid="+this.WID+'&opt=/-DBL/0'+CS.PAGES.SETUP.getURLOverrides() : this.CTU + flv;
            return '<iframe id="I'+this.CID+'" src="'+ctu+'" frameborder="0" scrolling="no" style="margin:0px;padding:0px;width:100%;height:100%;border:0px;z-index:60;overflow:hidden;overflow-x: hidden; overflow-y: hidden;" allowtransparency="true">'+this.ADN+'</iframe>';
    },

    /** generates widget manager in a nice containing div; called by WJS and WBL */
    GMR : function (write) {
        var div = '<div id="PM'+this.CID+'" class="cs-js-pm"';
        var mw=parseInt(this.MSW||"0") ? this.MSW : this.EMW;
        var mh=parseInt(this.MSH||"0") ? this.MSH : this.EMH;
        return div + (write !== false ? ' style="line-height:0px !important;z-index:0;position:absolute;left:'+(this.EMW/2-mw/2)+'px;bottom:0px">'
                                         + CSM.MGR(this.CID,this.GOVR(),mw,mh,this.TPH,this.URL,CSM.IIE,this.FPID == this.PID ? null : this.FPID,this.GFLV()) 
                                      : '>' + CSM.BUG(this.CID,this.SID,this.GOVR(),this.TPH,this.URL,CSM.IIE)) +'</div>';
    },

    /**    
    * CHM = can have manager? 
    * @returns true iff. containing div is tall enough for a manager
    * @todo modify for supporting dynamically-sized widgets -- perhaps in that case we should have a generic div container which floats the service menu after their content,
    *                                                          or else give them a callback for replacing the dock 
    */
    CHM : function () {
        var container = CSM.GEL('D'+this.CID);
        return ((this.DBL && this.DBL !== "0") && (this.EMW >= CSM.MW) && (this.EMH >= CSM.MH) && (!container || (container.offsetWidth >= CSM.MW && container.offsetHeight >= CSM.MH)));
    },

    /**     
    * AMR = attach manager
    * Attaches service menu to container based on its current size; used by WMC since the container can change size; 
    */
    AMR : function () {
        var mw=parseInt(this.MSW||"0") ? this.MSW : this.EMW;
        var mh=parseInt(this.MSH||"0") ? this.MSH : this.EMH;
        var parent = CSM.GEL('PM'+this.CID);
        var menu = (this.CHM()) ? CSM.MGR(this.CID,this.GOVR(),mw,mh,this.TPH,this.URL,CSM.IIE,this.FPID == this.PID ? null : this.FPID,this.GFLV()) 
                                : ''; 
        //if (CSM.IFX) {
            //var container = CSM.GEL('D'+this.CID);
            parent.innerHTML = menu;
            parent.style.zIndex = 0;
            parent.style.position = "absolute";
            //parent.style.marginTop = (this.EMH+this.OFY - CSM.MH) + 'px';
            parent.style.left = (this.EMW/2-mw/2)+'px';
            parent.style.bottom = '0px';
        //} else {
           //parent.innerHTML = menu;
        //}
    },

    /**     
    * RSZ = resize: 
    * for widget console only 
    */
    RSZ : function (emw, emh) {
        this.EMW = emw;
        this.EMH = emh;

        var container = CSM.GEL('D'+this.CID);
        var iframeWrapper = CSM.GEL('F'+this.CID);
        iframeWrapper.style['width'] = container.style['width'] = (emw + this.OFX) + 'px';
        iframeWrapper.style['height'] = container.style['height'] = (emh + this.OFY - (this.DBL ? CSM.DH : 0)) + 'px';

        //var imageContainer = CSM.GEL('BGI'+this.CID); 
        //imageContainer.innerHTML = this.WBI();  // not compatible with all browsers

        this.AMR();
    },

	/** add javascript;
        cyrus calls this to stuff the provided div with html for editing */
    AJS : function (div, isDebugMode) {
        this.URL = "/o/"+this.WID+"/-/-/-"+(isDebugMode===true?'/-DBG/1':'');
        var npjs = (this.PJS != '1' && this.PJS !== true);
        div.innerHTML = this.WJS(false, true, !npjs);
        if (!npjs) this.SCR();

        this.AMR(); 
    },

    /** recenter 
    RCR : function(id) {

        var dyn=this.DYN == '1' || this.DYN === 1;
        if (!dyn)
        {
            var w=window; var d=document;
            var emw=parseInt(this.EMW,10);
            var fw = CSM.GFW();
            var n=d.getElementById('F'+id);
            var pm=d.getElementById('PM'+id);
            var p=n.parentNode || n.parent;
            //alert(fw);
            if (emw > fw) emw = fw; 
            n.style.width = emw + 'px';
            //n.style['left'] = (fw / 2 - emw / 2) + 'px'; 
            //alert(fw + ' > ' + emw);
            n.style['left'] = (fw / 2 - emw / 2) + 'px'; 
            pm.style['left'] = ((fw / 2 - emw /2) + ((emw-CSM.MW)/2)) + 'px';
            //alert(n.style.left);
        }
    }, 
    */

    /** reveal hanging chad */
    RHC : function(id) {
        var w=window; var d=document; var ol=w.onload;
        var emw=parseInt(this.EMW,10);
        var mw=parseInt(this.MSW||"0") ? this.MSW : this.EMW;
        w.onload=function() {
            if (typeof(ol)=="function") {try{ol();} catch(e){}}
            var n=d.getElementById('F'+id);
            var p=n.parentNode || n.parent;
            
            if (n && n.style && p && p.style['height'] == '100%') {
                var dyn=this.DYN == '1' || this.DYN === 1;
                if (!dyn)
                {
                    var fw = CSM.GFW();
                    var pm=d.getElementById('PM'+id);
                    if (emw > fw) emw = fw; 
                    n.style.width = emw + 'px';
                    n.style['left'] = (fw / 2 - emw / 2) + 'px'; 
                    pm.style['left'] = ((fw / 2 - emw /2) + ((emw-mw)/2)) + 'px';
                }
            }
        }
    },


    /** write blob 
    *
    * <div id=D(WID+PID)> -- d for 'div'
    *   <div id=O(WID+PID)> -- o for 'object'
    *       blob
    *   </div>
    *   <tracking kernel>
    * </div>
    */
    WBL : function () {
        var blob = undefined;
        var utfdecode = function (utftext) {
            var string = "";
            var i = 0;
            var c = c1 = c2 = 0;

            while ( i < utftext.length ) {

                c = utftext.charCodeAt(i);

                if (c < 128) {
                    string += String.fromCharCode(c);
                    i++;
                } else if((c > 191) && (c < 224)) {
                    c2 = utftext.charCodeAt(i+1);
                    string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                    i += 2;
                } else {
                    c2 = utftext.charCodeAt(i+1);
                    c3 = utftext.charCodeAt(i+2);
                    string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                    i += 3;
                }
            }

            return string;
        }

        if (this.BLB) {
            blob = unescape(this.BLB);
            blob = blob.replace(/\+/g, " ");
            blob = utfdecode(blob);
            blob = blob.replace(/{{_CS_WID}}/g, this.WID);
            blob = blob.replace(/{{_CS_PID}}/g, this.PID);
           
            var FLV = this.FLV;
           
            var flvReplacer = function (str, prefix, flv) 
            {
                //CSM.debug('s='+str+' flv='+flv);
                return (FLV[flv] ? FLV[flv] : str);
            } 
            blob = blob.replace(/\{\{(flv_)(.+?)\}\}/g, flvReplacer);
        }

        return '<div id="D'+this.CID+'" class="cs-js-d"><div id="F'+this.CID+'" class="cs-js-f">' + (blob && blob != ' ' ? blob : 'No content defined') + '</div>' + 
               ((this.BUG == '1' || this.BUG === 1) ? this.GMR(false) : '') + '</div>';
    },

    /** write javascript widget
    * <div id=D(WID+PID)>     -- d for 'dock'
    *   <div id="F(WID+PID)"> -- f for 'frame'
    *       WWT()
    *   </div>
    *   <service menu OR bug>  -- if dnw == true, we get bug instead of service menu
    * </div>
    */
    WJS : function(max, dnw, wbs, onlyOpen) {
        /*if (max)
        {
            var gfw = CSM.GFW();
            max = ((CSO.TYP === 0 || CSO.TYP == '0') || gfw < this.EMW);
            //alert(max + ' - ' + gfw + ' < ' + this.EMW);
        }*/
        var wx = max && !this.IJS ? '100%' : (this.EMW+this.OFX)+'px';
        var wxb = max ? '100%' : (this.EMW+this.OFX)+'px';
        var hy = max && !this.IJS ? '100%' : (this.EMH+this.OFY-(this.DBL ? CSM.DH : 0))+'px';
        var hyb = max ? '100%' : (this.EMH+this.OFY)+'px';
        var wh = this.DYN === true || this.DYN == '1' ? "" : "width:"+wx+";height:"+hy;
        var whb = this.DYN === true || this.DYN == '1' ? "" : "width:"+wxb+";height:"+hyb;

        return (onlyOpen !== false ? '<div id="D'+this.CID+'" class="cs-js-d" style="position:relative;'+whb+';text-align:left;overflow:hidden">'+
                    '<div id="F'+this.CID+'" class="cs-js-f" style="position:'+((this.DYN===true||this.DYN=='1')?'relative':'absolute')+';'+(this.PJS===true||this.PJS=='1'?'overflow:hidden':'')+';'+wh+';z-index:5">'+
                        this.WWT(wbs) : '') +
                (onlyOpen === true ? '' : '</div>'+(this.GMR(!dnw && this.CHM()))+'</div>');
    },

    WST : function() {
		if (this.TYP === 1 || this.TYP == '1') {
			return CSE.iframe;
		} else {
			return CSE.oembed;
		}
    }
}
//CSM.debug('ncso built');

if (!CSM.nsetup) {
	CSM.nsetup = 1;
    if (__CSM) {
        for (var k in __CSM)
        {
            //CSM.debug('ncsm : copying over ' + k);
            CSM[k] = __CSM[k]; 
        }
    }    
}
//CSM.debug('csm fixed');
if (typeof(CSO) == "undefined" || !CSO) var CSO = NCSO;
NCSO.set = CSM.set ? CSM.set : function(k,v) { }
for (var k in NCSO) {
    if (typeof(NCSO[k])=='function') {
        //CSM.debug('ncso : copying over '+ k);
        CSO[k] = NCSO[k];
    }
}
//CSM.debug('ncso copied');
CSO.defaults({EMW:640, W:640, EMH:640, H:480, CSS:3, OFX:0, OFY:0, FLV:{}, ADN:"", MAX:0});
//CSM.debug('cso defaulted: ' + CSO.WID);
if (CSO.XXX) {
    CSO.CTU = "";
    CSO.TYP = 1;
}
if (!CSO.PID) {
    CSO.PID = CSO.WID;
}
if (CSM.GPR())
{
    CSO.PUR = CSM.GPR();
}
if (CSO.CTU && CSO.CTU.toUpperCase().indexOf('HTTP%3A') === 0) { 
    // CTU starts with an encoded HTTP://; we can infer the need to decode
    CSO.CTU = unescape(CSO.CTU); 
} 
if (CSO.WID) {
    /* 
        CPID = cleaned PID
        A customer using a custom-made PID could have non-alphanumeric characters in it, which aren't valid
        for all our purposes (i.e., in object IDs). We replace them with underscores.
    */
    CSO.CPID = CSM.clean(CSO.PID); // xxx should this happen at the pawn instead? what should the real pid be?
	CSO.NID = CSO.UR0.split("/")[3];

    /*
        CSM stores CSO objects in a few places.

        1. Hash of hashes

            CSM[WID] -> hash of all PIDs belonging to that wid 
            
            Since PIDs COULD be duplicated, the PID entry is itself not a leaf node, but rather an array of CSOs.
            e.g. CSM[CSO.WID] = {pid0: [CSO0, CSO1....]; pid1: [CSO0]; ....}

        2. Quick CID lookup

            e.g. CSM[WID+PID] = CSO

    */
	if (!CSM[CSO.WID]) {
        CSM[CSO.WID] = {};
    }

    if (!CSM[CSO.WID][CSO.CPID]) {
        CSM[CSO.WID][CSO.CPID] = [CSO];
        CSO.FPID = CSO.CPID; // see below
    } else {
        /* 
            FPID = fake PID; if we have a duplicate pid, as in this branch,
            we have to create a fake distinct PID so that the objects don't collide
        */
        CSO.FPID = CSO.CPID + (CSM[CSO.WID][CSO.CPID].length - 1);
        CSM[CSO.WID][CSO.CPID].push(CSO);
    }

    /*
        CID = combined ID, WID + FPID
    */
	CSO.CID = CSO.WID+CSO.FPID;

    // this seemingly-redundant object is for proto.js access
    CSM[CSO.CID] = CSO; 

    if (CSM.args === undefined) 
    {
        CSM.args = new Object();
        var src = window.location.search;
        src.replace(
                new RegExp( "([^?=&]+)(=([^&]*))?", "g" ),

                // For each matched query string pair, add that
                // pair to the URL struct using the pre-equals
                // value as the key.
                function( $0, $1, $2, $3 ){
                CSM.args[ $1 ] = $3;
                });
    }
        
    CSO.DBL = CSO.DBL === 1 || CSO.DBL == '1';

    var max = CSO.MAX === 1 || CSO.MAX == '1';
    var ijs = CSO.TYP === 1 || CSO.TYP == '1';
    CSO.IJS = ijs;
    var ilp = CSO.TYP === 4 || CSO.TYP == '4';

    //For #8648
    var w = CSO.EMW;// - ((CSO.DSW && CSO.DSW != '0') ? 0 : CSM.SHD*2);
    var h = CSO.EMH;// - ((CSO.DSW && CSO.DSW != '0') ? 0 : CSM.SHD*2) - ((CSO.DBL && CSO.DBL != '0') ? 0 : CSM.DH);
    //if (CSO.IOV == undefined) CSO.IOV = []; 
    //CSO.IOV.push('W'); CSO.IOV.push('H');
    //CSO.W = w; CSO.H = h;

    var override = CSO.GOVR(true);
    var gflv = CSO.GFLV();
    gflv = (override && override.indexOf("?") != -1 ? "&" : "?") + gflv;


	// Clearspring Standard Embed; used by clients and us 
	var CSE = {
		oembed: ijs ? null : CSM.GEN(CSO.WID+CSO.FPID, override + gflv, w, h, CSO.TPH, CSO.URL, CSM.IIE, 0, max, CSM.args._cs_fwm||CSO.FWM||null,CSO.FSM||false,CSO.SMO||''),
		oplace: CSM.GEN(CSO.WID+CSO.NID,override,w,h,CSO.TPH,CSO.UR0,CSM.IIE,ijs,max,CSO.FWM,CSO.FSM||false,CSO.SMO||''),
        blob: ilp ? CSO.WBL() : null,
		iframe: ijs ? CSO.WJS(max) : null,
        iopen : ijs ? CSO.WJS(max, null, null, true) : null,
        iclose : ijs ? CSO.WJS(max, null, null, false) : null
	}
	CSO.CSE = CSE;

    var needRulers = CSM.args._cs_rulers;
	// to write to the page or to not write to the page
	if (!CSO.DNW) {
        if (needRulers) document.write('<script type="text/javascript" src="'+CSO.JHO+'/'+CSO.VJS+'/rulers.js"></script>');
		if (ijs) {
            var id = 'W' + CSO.CID;
            window[id] = "";
            if (CSM.IIE && (CSO.PJS===1||CSO.PJS=='1')) {
                document.write(CSE.iopen);
                CSM.closetag = CSE.iclose;
                document.write('<script type="text/javascript" src="'+CSO.JHO+'/'+CSO.VJS+'/close.cache.js"></script>');
            } else {
			    document.write(CSE.iframe);
            }
            window[id] = CSM.GEL(id);
            // for start pages where width/height 100%, we need JS to fix the parent div 
            CSO.RHC(CSO.CID);
        } else if (ilp) {
            document.write(CSE.blob);
        } else {
            var id = 'W' + CSO.CPID;
			var e = CSM.GEL(id);
			if (e && e.parentNode) { 
                if (CSM.IIE == 1) {
                     CSO.ICF(id);
                } 
            } else { 
                try {
                    document.write(CSE.oembed); 
                } catch (e) {
                    // weird flash bug. it attempts to access Location, possibly for security purposes.
                    // if there's a permission error of some kind (e.g., in ffx3), the script fails silently.
                }
            }
            window[id] = CSM.GEL(id);
		}
	}
}


//var CSO2 = CSO;

//Handle issue on google homepage with focusing
if (CSM.IIE && CSO.DOM && CSO.DOM.indexOf('google') != -1) {
  	//timeout variable
	var to = undefined;

	document.attachEvent('onmouseover', function() { to = setTimeout(CSM.BLR, 100); });
	document.attachEvent('onmouseout', function() { clearTimeout(to); });
}

//CSM.debug('finished');
