
/**
 * ripllib
 * v0.9.0 (beta)
 * 
 * Core functions and methods for dealing with the RIPL API and rendering RIPL content, user, and event objects.
 * 
 * Copyright (c) 2009 RIPL Corporation.  All Rights reserved.
 * 
 * Authors:  John Green, Adam Eivy - RIPL Corporation
 * 
 * Website: http://www.ripl.com/developer
 * 
 * ripllib contains an inline implementation of the Sizzle CSS selector engine.
 * Please refer to the licensing in that section.
 * 
 */

/**
 * Begin ripllib.js core 
 * 
 */


$ripl = {};
$$ripl = {};
ripl = {
    state:0,
    prefetch:{},
    modals:[],
    pageParams:{},
    play:function ripl_play(contentId)
    {
        var pItem = ripl.cache.content.getItemById(contentId);
        if (pItem)
        {
            return ripl.render(pItem);
        }
        return false;
    },
    render:function ripl_render(contentItem)
    {
        ripl.contentDisplay.current.show();
        ripl.contentDisplay.current.setContentItem(contentItem);
    },
    preinitialize:function()
    {
        ripl.initialization.checkFrameworks(true);
        ripl.initialization.checkSwfObject();
    },
    intializeWithToken:function(postAuthHook,apikey,token)
    {
        if (ripl.state != ripl.enums.STATE_UNINITIALIZED) { return; }
        ripl.state = ripl.enums.STATE_PROCESSING;
        ripl.service.apikey = apikey;

        if (postAuthHook)
        {
            ripl._postIntializeVariable = postAuthHook;
        }

        ripl.apiHandler.next = function(tokenInfo)
        {
            if (tokenInfo.error)
            {
                ripl.auth.token = null;
                ripl._autologin();
                ripl.events.libraryEvents.fire('auth_failed');
            }
            else
            {
                ripl.auth.currentUser = new ripl.coreObjects.User(tokenInfo.user);
                ripl.auth.token = tokenInfo.token;
                ripl.events.libraryEvents.fire('auth_failed');
                ripl._postInitialize();
            }
        };
        ripl.service.methods.ripl.auth.checkToken('ripl.apiHandler.next',{'token':token});
        
    },
    initializeForeign:function(postAuthHook,apikey,foreignId,emailHash,timestamp,signature)
    {
        if (ripl.state != ripl.enums.STATE_UNINITIALIZED) { return; }

        ripl.state = ripl.enums.STATE_PROCESSING;
        ripl.service.apikey = apikey;

        if (postAuthHook)
        {
            ripl._postIntializeVariable = postAuthHook;
        }
        if (signature)
        {
            ripl.apiHandler.next=function(foreignInfo)
            {
                if (foreignInfo.error)
                {
                    ripl.auth.token = null;
                    ripl._autologin();
                    ripl.events.libraryEvents.fire('auth_failed');
                }
                else
                {
                    ripl.auth.currentUser = new ripl.coreObjects.User(foreignInfo.user);
                    ripl.auth.token = foreignInfo.token;
                    ripl.events.libraryEvents.fire('authed');
                    ripl._postInitialize();
                }
            };
            ripl.service.methods.ripl.auth.fromForeignToken('ripl.apiHandler.next',{'foreign_id':foreignId,'email_hash':emailHash,'timestamp':timestamp,'signature':signature});
        }
    },
    _autologin:function()
    {
        ripl.auth.checkCookie(ripl._postInitialize);    
    },
    hideModal:function(){
    	ripl.modals.pop().hide();
    },
    createModal:function(config){
    	/*
    	if(ripl.modals[config.name]){
    		return ripl.modals[config.name];
    	}*/
    	
    	var pBody = $ripl.getElementsByTagName('body')[0];
 	    var pOverlay = $ripl.create('div',{className:'ripl_overlay',id:'ripl_'+config.name});
 	    var pElement = $ripl.create('div',{className:'ripl_popWindow ripl_'+config.name});
 	    var pClose = $ripl.create('div',{className:'ripl_closeBtn'});
 	    pClose.listen('click', ripl.hideModal);     
 	    
	    var pLoader = $ripl.create('img',{src:ripl.environment.jslib + 'images/ajax-loader.gif',style:'display:none',className:'ripl_loaderImage'});  

 	    var pTitle = $ripl.create('h1',{className:'ripl_windowTitle'});
 	    pTitle.update(config.title);

 	    var pTarget = $ripl.create('div',{
 	    	id:'ripl_'+config.name+'_dynamicFrame',
 	    	style:'z-index:2;position:absolute;left:10px'
 	    });

	    pTarget.add([config.content,pLoader]);
	    pElement.add([pClose,pTitle,pTarget]);
	    pOverlay.add(pElement);
	    pBody.add(pOverlay);
	    
	    ripl.modals[ripl.modals.length] = pOverlay;
	    return pOverlay;
    },
    showLogin:function(){
    	if(ripl.auth.dialog){
        	ripl.modals[ripl.modals.length] = ripl.auth.dialog;
    	}else{	
    	    var pForm = $ripl.create('form',{
    	    	id:'ripl_signin_form',
    	    	action:'ripl.auth.login',
    	    	method:'post'
    	    });

    	    pForm.update('<div><label for="ripl_username">username/email</label>\
				   <input type="text" class="txtInput" name="login" id="ripl_login" /></div>\
				   <div><label for="ripl_password">password</label>\
				   <input type="password" class="txtInput" id="ripl_password" name="password" /></div>\
				   <div><input type="checkbox" name="rememberMe" id="ripl_rememberMe" style="margin-left:0" />\
				   <label for="ripl_rememberMe">remember me</label></div>\
				   <div class="ripl_error" style="display:none" id="ripl_auth_error"></div>');

    	    var pForgotBlock = $ripl.create('div',{className:'ripl_submitBlock'});
    	    var pForgotBtn = $ripl.create('a',{href:'#'});
    	    pForgotBtn.update('forgot password');
    	    pForgotBtn.listen('click', function(){
            	if(ripl.auth.forgotDialog) {
                	ripl.modals[ripl.modals.length] = ripl.auth.forgotDialog;
            	}else{
	            	var pForm = $ripl.create('form',{
	        	    	id:'ripl_forgot_form',
	        	    	action:'ripl.user.forgotAuth',
	        	    	method:'post'
	        	    });
	            	pForm.update('<div><label for="ripl_forgot_email">email</label><input type="text" class="txtInput" name="email" id="ripl_forgot_email" /></div><div class="ripl_error" style="display:none" id="ripl_forgot_error"></div>');
		    	    var pSubmitBlock = $ripl.create('div',{className:'ripl_submitBlock'});
		    	    var pSubmitBtn = $ripl.create('input',{type:'button',value:'send it'});
		    	    pSubmitBtn.listen('click',function(){
		    	    	ripl.auth.forgot($ripl.getElementById('ripl_forgot_email').value);
		    	    });
	        		pSubmitBlock.add([pSubmitBtn]);
	    		    pForm.add([pSubmitBlock]);
	            	ripl.auth.forgotDialog = ripl.createModal({name:'popForgotAuth',title:'Forgot Password',content:pForm});
            	}
        		ripl.auth.forgotDialog.show();
            });
    	    var pSubmitBlock = $ripl.create('div',{className:'ripl_submitBlock'});
    	    var pSubmitBtn = $ripl.create('input',{type:'button',value:'sign in'});
    	    
    	    var doLogin = function(){
            	var remember = 'no';
            	var login = $ripl.getElementById('ripl_login').value;
            	var pass = escape($ripl.getElementById('ripl_password').value);
            	if(login=='' || pass==''){
            		$ripl.getElementById('ripl_auth_error').update('Please fill in all fields').show();
            		return;
            	}
            	if($ripl.getElementById('ripl_rememberMe').checked){
            		remember = 'yes';
            	}
            	ripl.auth.login(login,pass,remember);
    	    }
    	    pSubmitBtn.listen('click',doLogin);

            pForgotBlock.add([pForgotBtn]);
            pForm.add([pForgotBlock]);
            pSubmitBlock.add([pSubmitBtn]);
            pForm.add([pSubmitBlock]);

    		ripl.auth.dialog = ripl.createModal({name:'popAuth',title:'Sign in to RIPL',content:pForm});
    		$ripl.getElementById('ripl_password').listen('click',function(e){
                if( window.event ? window.event.keyCode : e.which == 13 ){
                	doLogin();
                }
    		});
    	}
    	ripl.auth.dialog.show();
    },    
    setPostAuth:function(postAuthHook)
    {
        ripl._postIntializeVariable = postAuthHook;
    },
    initialize:function()
    {
        if (ripl.state != ripl.enums.STATE_UNINITIALIZED) { return; }
        if (!ripl.initialization.frameworksLoaded) { return; }
        if (!ripl.auth.token) { ripl._autologin(); }
        else { ripl._postInitialize(); }
    },
    _postInitialize:function ripl_postInitialize()
    {
        ripl.initialization.addStyle();
        ripl.initialization.autodiscoverPage();
        ripl.events.listen('scriptless_complete', function(){ripl.initialization.reinstate()}); 
        ripl.state = ripl.enums.STATE_READY;
        ripl._postIntializeVariable();
    },
    _postIntializeVariable:function()
    {
    }
};

ripl.adapters = {
    setCurrent:function(adapter)
    {
        ripl.adapters.current = adapter;
        $ripl = adapter;
    }
};
ripl.adapters.baseAdapter = function(){};
ripl.adapters.not_implemented = function(){throw 'Adapter incomplete';};

/**
 * RIPL Core Adapter
 * You may create adapters for other libraries (Prototype/JQuery) by following this
 * as a framework.
 */
$ripl = function(object)
{
    if (!object) return null;
    if (object['objectType'] == 'riplElement')
    {
        return object;
    }
    var pElement;

    if (typeof object == "string")
    {
        pElement = $ripl.getElementById(object);
        $ripl._idHash[object] = pElement;
        return pElement;
    }
    else
    {
        pElement = $ripl.riplElement(object);
        return pElement;
    }
}



$ripl.riplElement = function(obj, params)
{
    obj.objectType = 'riplElement';
    obj.show = function(){ return $ripl.show(obj);};
    obj.hide = function(){ return $ripl.hide(obj);};

    obj.empty = function(){ return $ripl.empty(obj);};
    obj.add = function(object, ref){ return $ripl.add(obj,object, ref);};
    obj.update = function(object){ return $ripl.update(obj,object);};
    obj.remove = function(){ return $ripl.removeElement(obj);};
    
    obj.readAttribute = function(attName){ return $ripl.readAttribute(obj,attName);};
    obj.writeAttribute = function(attName, attValue){ return $ripl.writeAttribute(obj,attName, attValue);};

    obj.addClass = function(className){ return $ripl.addClassName(obj,className);};
    obj.removeClass = function(className){ return $ripl.removeClassName(obj,className);};
    obj.hasClass = function(className){ return $ripl.hasClass(obj,className);};

    obj.visible = function(){ return $ripl.visible(obj); };

    obj.next = function(){ return $ripl.next(obj); };
    obj.previous = function(){ return $ripl.previous(obj); };
    obj.up = function(selector) {return $ripl.up(obj, selector); };
    obj.down = function(selector) {return $ripl.down(obj, selector); };

    obj._events = new ripl.events.eventManagerBase(obj);
    obj._hasDomListeners = false;
    obj._addDomListeners = function(inThis) 
    {
        obj._hasDomListeners = true;
        ripl.events.addDomListener(new ripl.events.eventObj('click',obj._handleDomEvent,obj,obj));
        ripl.events.addDomListener(new ripl.events.eventObj('focus',obj._handleDomEvent,obj,obj));
        ripl.events.addDomListener(new ripl.events.eventObj('blur',obj._handleDomEvent,obj,obj));
        ripl.events.addDomListener(new ripl.events.eventObj('mouseover',obj._handleDomEvent,obj,obj));
        ripl.events.addDomListener(new ripl.events.eventObj('mouseout',obj._handleDomEvent,obj,obj));
        ripl.events.addDomListener(new ripl.events.eventObj('keyup',obj._handleDomEvent,obj,obj));
        ripl.events.addDomListener(new ripl.events.eventObj('keypress',obj._handleDomEvent,obj,obj));
        ripl.events.addDomListener(new ripl.events.eventObj('keydown',obj._handleDomEvent,obj,obj));
        ripl.events.addDomListener(new ripl.events.eventObj('change',obj._handleDomEvent,obj,obj));
        ripl.events.addDomListener(new ripl.events.eventObj('submit',obj._handleDomEvent,obj,obj));
    };
    
    obj.listen = function(inType,inClosure, inThis)
    {
        if (!obj._hasDomListeners) obj._addDomListeners();
        obj._events.listen(inType,inClosure, inThis);
    }
    obj.unlisten = function(inType,inClosure)
    {
        obj._events.unlisten(inType,inClosure);
    }
    obj._handleDomEvent = function(event)
    {
        obj._events.fire(event.type,this,event);    
    }
    
    obj.list = false;
    
    
    obj.getBounds = function() { return $ripl.getBounds(obj); };

    obj.selectedValue = function()
    {
    	var radioGroup;
        if ((obj.tagName.toLowerCase() == 'input') && (obj.type =='radio'))
        {
            radioGroup = obj.name;
        }
        else
        {
            return false;
        }
        var pQuery = document.getElementsByName(radioGroup);
        for (var i=0; i < pQuery.length; i++)
        {
            if (pQuery[i].checked) 
            {
                return pQuery[i].value;
            }
        }
        return null;
    };

    return obj;
};




$ripl.getElementById = function(elId)
{
    if ($ripl._idHash[elId]) { return $ripl._idHash[elId]; }
    var pEl = document.getElementById(elId);
    pEl = $ripl(pEl);
    $ripl._idHash[elId] = pEl;
    return pEl;
};
$ripl.getElementsByTagName = function(tagName, start)
{
    var pQuery = document.getElementsByTagName(tagName), pReturnVal=[];
    for (var i=0; i < pQuery.length; i++)
    {
        pReturnVal[i] = $ripl(pQuery[i]);
    }
    
    return pReturnVal;//pReturnVal;
};

$ripl.getElementsByClassName = function(className, startElement)
{
    var pQuery = ripl.Sizzle(className,startElement), pReturnVal=[];

    for (var i=0; i < pQuery.length; i++)
    {
        pReturnVal[i] = $ripl(pQuery[i]);
    }

    return pReturnVal;
};
$ripl.create = function(tag,attributes,innerText)
{
    var pElement = $ripl(document.createElement(tag));
    for (var i in attributes)
    {
        if (i == 'className')
        {
            pElement.className = attributes[i];
        }
        else if (i == 'style')
        {
            pElement.style.cssText = attributes[i];
        }
        else
        {
            pElement.writeAttribute(i,attributes[i]);
        }
    }
    if (innerText) { pElement.add(innerText); }
//    if (attributes['id']) $ripl._idHash[attributes['id']] = pElement;
    return pElement;
};
$ripl.empty = function(element)
{
    element = $ripl(element);
    if (!element) return element;
    while (element.hasChildNodes()) 
    {
        element.removeChild(element.firstChild);
    }    
    return element;
}
$ripl.update = function(element,text)
{
    element = $ripl(element);
    $ripl.empty(element);
    $ripl.add(element,text);
    return element;
};
$ripl.removeElement = function(element)
{
    element = $ripl(element);
    if (!element) return element;
    element.parentNode.removeChild(element);
    return element;
};
$ripl.add = function(container,element,pRef)
{
    if (!element) return;
    container = $ripl(container);
    if ($ripl._isElement(element))
    {
        container.appendChild(element);
    }
    else if (ripl.utilities.isArray(element))
    {
        for (var i=0; i < element.length; i++)
        {
            if (element[i])
            {
                container.appendChild(element[i]);
            }
        }
    }
    else
    {
        if (container.innerHTML) container.innerHTML += element;
        else container.innerHTML = element;
    }
    return container;
};

$ripl.readAttribute = function(element,attName)
{
    element = $ripl(element);
    return element.getAttribute(attName);
}
$ripl.writeAttribute = function(element,attName,attValue)
{
    element = $ripl(element);
    element.setAttribute(attName, attValue);
    return element;
};

$ripl.show = function(element)
{    
    element = $ripl(element);
    if (!element) { return; }
    element.style.display='';
    if ($ripl.hasClass(element,'ripl_renderer'))
    {
        ripl.scriptless.processDeferred(element);
    }
    return element;
};
$ripl.hide = function(element)
{
    element = $ripl(element);
    if (element) element.style.display='none';
    return element;
};
$ripl.addClassName = function(element,className)
{
    element = $ripl(element);
    if (!$ripl.hasClass(element,className)) element.className += " "+className;
    return element;
};
$ripl.removeClassName = function(element,className)
{
    element = $ripl(element);
    if ($ripl.hasClass(element,className)) 
    {
        var reg = new RegExp('(\\s|^)'+className+'(\\s|$)');
        element.className = element.className.replace(reg,' ');
    }    
    return element;
};
$ripl.hasClass = function(element,className)
{
    element = $ripl(element);
    return element.className.match(new RegExp('(\\s|^)'+className+'(\\s|$)'));
}
$ripl._isElement = function(object)
{
    return !!(object && object.nodeType == 1);
}
$ripl.visible = function(element)
{
    return (element.style.display != 'none');
}

$ripl.next = function(element)
{
    return $ripl(element.nextSibling);
}
$ripl.previous = function(element)
{
    return $ripl(element.previousSibling);
}

$ripl.up = function(element, selector)
{
    var pPar = element.parentNode;
    if (pPar)
    {
        pPar = $ripl(pPar);
    }
    else
    {
        return null;
    }
    if (!selector)
    {
        return pPar;
    }
    
    var pQuery = ripl.Sizzle(selector, pPar);
    for (var i=0; i < pQuery.length; i++)
    {
        if (pQuery[i] != element)
        {
            return $ripl(pQuery[i]);
        }
    }
    return pPar.up(selector);
}

$ripl.down = function(element,selector)
{
    if (!selector)
    {
        return $ripl(element.firstChild);
    }
    var pQuery = ripl.Sizzle(selector, element);
    if (pQuery.length > 0) return $ripl(pQuery[0]);
    return null;
}


$ripl._idHash = {};

$ripl.objects = {};

$ripl.objects.bounds = function(x,y,width,height)
{
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
}

$ripl.getBounds = function(element)
{
    var pBounds = new $ripl.objects.bounds();
    var offsetX = 0, offsetY = 0, parent;
    element = $ripl(element);

    for (parent = element; parent; parent = parent.offsetParent) 
    {
        if (parent.offsetLeft) 
        {
            offsetX += parent.offsetLeft;
        }

        if (parent.offsetTop) 
        {
            offsetY += parent.offsetTop;
        }
    }
    pBounds.x = offsetX;
    pBounds.y = offsetY;
    pBounds.width = element.offsetWidth;
    pBounds.height = element.offsetHeight;
    return pBounds;
}



/*
 * END RIPL Core Adapter
 */

/**
 * RIPL Initialization
 */

ripl.initialization = {
    styleAdded:false,
    autodiscover:true,
    frameworksLoaded:false,
    usesSwf:true,
    checkFrameworks:function(ispreload)
    {
        ripl.adapters.setCurrent($ripl);
        ripl.initialization.frameworksLoaded = true;
        return true;
    },
    checkSwfObject:function()
    {
        if (ripl.initialization.usesSwf)
        {
            if (ripl.utilities.isDefined('SWFObject')) { return true; }
            else if ((ripl.utilities.isDefined('google')) && (google['load']))
            {
                google.load("swfobject", "2.2");
                return true;                
            }
            else
            {
                var script = $ripl.create('script',{src:'http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js'}),
                head   = $ripl.getElementsByTagName('head')[0];
                head.add(script);
//                $ripl.add(head,script);
                return true;
            }
        }
        return false;
    },
    reinstate:function(){
        // get query params for loading previous state
        var pairs = document.location.search.replace(/^\?/, "").split("&"); 
        for (var i = 0; i < pairs.length; i++) { 
            var pair = pairs[i].split("="); 
            ripl.pageParams[unescape(pair[0])] = (pair.length > 1) ? unescape(pair[1]) : ""; 
        } 
        // auto load content (returned) 
        if(ripl.pageParams.ripl_contentid){ 
            // auto load content  
            ripl.play(ripl.pageParams.ripl_contentid); 
            if(ripl.pageParams.ripl_shareMode){ 
	            // auto load share 
	            ripl.sharing.share(ripl.pageParams.ripl_shareMode); 
            } 
        }
    },
    addStyle:function ripl_initialization_addStyle()
    {
        if (ripl.initialization.styleAdded) { return; }
        var pStylesheet = ripl.environment.styleBase + 'ripllib.css';
        
        var links = $ripl.getElementsByTagName('link');
        for (var i = 0; i < links.length; i++)
        {
            
            if (links[i].readAttribute('href').indexOf('ripllib.css') > -1)
            {
                ripl.initialization.styleAdded = true;
                return; 
            }
        }
        
        if (document.createStyleSheet) 
        {
            document.createStyleSheet(pStylesheet);
        } 
        else 
        {
            var newSS = $ripl.create('link',{rel:'stylesheet',href:'data:text/css,'+escape('@import url('+pStylesheet+');')}),
                pNode = $ripl.getElementsByTagName('head')[0];
//            pNode.add(newSS, pNode.firstChild);
            //.add(newSS,p)
            pNode  = document.getElementsByTagName("head")[0];
            pNode.insertBefore(newSS,pNode.firstChild);
        }     
        ripl.initialization.styleAdded = true;
        
    },
    autodiscoverPage:function ripl_intialization_autodiscoverPage()
    {
        ripl.scriptless.processPage();
    }
};

ripl.scriptless = {
    pageCalls:0,
    deferredElements:[],
    refresh:function(element)
    {
        ripl.scriptless.processElement(element,true);
    },
    processPage:function()
    {
        var i, riplAreas = $ripl.getElementsByClassName('.ripl_renderer');
        riplAreas.ripl_each(ripl.scriptless.processElement);

        riplAreas = [];
        riplAreas = $ripl.getElementsByClassName('.ripl_control');
        for (i = 0; i < riplAreas.length; i++)
        {
            for (var j in ripl.controls.types)
            {
                if (riplAreas[i].hasClass(j))
                {
                    new ripl.controls.types[j](riplAreas[i]);
                }
            }
        }

        ripl.events.libraryEvents.fire('scriptless_processed');
        ripl.scriptless.checkPageCalls();
    },
    checkPageCalls:function()
    {
        if (ripl.scriptless.pageCalls == 0)
        {
            ripl.events.libraryEvents.fire('scriptless_complete');
        }
    },
    processReturnUserList:function(data)
    {
        ripl.apiHandler.renderUserList(data);
        ripl.scriptless.pageCalls--;
        ripl.scriptless.checkPageCalls();
    },
    processReturnContentList:function(data)
    {
        ripl.apiHandler.renderContentList(data);
        ripl.scriptless.pageCalls--;
        ripl.scriptless.checkPageCalls();
    }, 
    processReturnEventList:function(data)
    {
        ripl.apiHandler.renderEventList(data);
        ripl.scriptless.pageCalls--;
        ripl.scriptless.checkPageCalls();
    },       
    processReturnCommentList:function(data)
    {
        ripl.apiHandler.renderCommentList(data);
        ripl.scriptless.pageCalls--;
        ripl.scriptless.checkPageCalls();
    },    
    processValue:function(value,isArray)
    {
        if (value == 'true') return true;
        if (value == 'false') return false;
        if (isArray) return value.split(',');
        if (parseInt(value,10).toString() == value) return parseInt(value,10);
        return value;
    },
    processDeferred:function(element)
    {
        for (var i=ripl.scriptless.deferredElements.length-1; i>=0; i--)
        {
            if (element == ripl.scriptless.deferredElements[i])
            {
                ripl.scriptless.processElement(element);
                ripl.scriptless.deferredElements.splice(i,1);
            }
        }
    },
    processElement:function(element,ignorePf)
    {
        var pAttributes, pParameters,pDisplayOptions,pChildOptions,pEventOptions, pMethod, pBehavior,pKind, prefetchKey, pDeferred = false;
        pParameters ={};
        pDisplayOptions = {renderTarget:element};
        pChildOptions = {};
        pEventOptions = {};
        
        for (var i=0; i < element.attributes.length;i++)
        {
            var pKey = element.attributes[i].name;
            var pValue = element.attributes[i].value;
            
            if (pKey.indexOf('ripl:deferred') > -1)
            {
                if (!element.visible())
                {
                    pDeferred = ripl.scriptless.processValue(pValue);
                    if (pDeferred)
                    {
                        ripl.scriptless.deferredElements.push(element);
                    }
                }
            }
            else if (pKey.indexOf('ripl:display_') >-1)
            {
                var pName = pKey.split('_')[1];
                if (pName == 'typefilters')
                {
                    pDisplayOptions['typeFilters'] = ripl.scriptless.processValue(pValue,true);
                }
                else
                {
                    pDisplayOptions[pName] = ripl.scriptless.processValue(pValue);
                }
            }
            else if (pKey.indexOf('ripl:child_') > -1)
            {
                pChildOptions[pKey.split('_')[1]] = ripl.scriptless.processValue(pValue);                
            }
            else if (pKey.indexOf('ripl:event_') > -1)
            {
                pEventOptions[pKey.split('_')[1]] = ripl.behaviors.types[pValue];
            }
            else if (pKey.indexOf('ripl:kind') > -1)
            {
                pKind = pValue;
            }
            else if (pKey.indexOf('ripl:prefetch') > -1)
            {
                prefetchKey = pValue;
            }            
            else if (pKey.indexOf('ripl:') > -1)
            {
                pParameters[pKey.substring(5,pKey.length)] = ripl.scriptless.processValue(pValue);
            }
        }
        if (prefetchKey && !(ignorePf))
        {
            if (pKind == 'userlist')
            {
                pData = new ripl.coreObjects.UserList(pDisplayOptions,pChildOptions,pEventOptions);
                pData.addObjects(ripl.prefetch[prefetchKey]);
                pData.render();
                element.list = pData;
            }
            else if (pKind == 'contentlist')
            {
                pData = new ripl.coreObjects.ContentList(pDisplayOptions,pChildOptions,pEventOptions);
                pData.addObjects(ripl.prefetch[prefetchKey]);
                pData.render();
                element.list = pData;
            }
            else if (pKind == 'eventlist')
            {
                pData = new ripl.coreObjects.EventList(pDisplayOptions,pChildOptions,pEventOptions);

                pData.addObjects(ripl.prefetch[prefetchKey].feedItems);
                pData._contentItems.addObjects(ripl.prefetch[prefetchKey].content);
                pData._userItems.addObjects(ripl.prefetch[prefetchKey].users);
                pData.render();
                element.list = pData;
            }
            else if (pKind == 'html')
            {
                pData = new ripl.coreObjects.HtmlObject(ripl.prefetch[prefetchKey],pDisplayOptions);
                pData.render();
                element.list = pData;
            }
            else if (pKind == 'commentslist')
            {
                pData = new ripl.coreObjects.CommentList(pDisplayOptions,pChildOptions,pEventOptions);
                pData.addObjects(ripl.prefetch[prefetchKey].comments);
                pData.addUsers(ripl.prefetch[prefetchKey].users);
                pData.link();
                pData.render();
                element.list = pData;
            }
        }
        else if (pDeferred)
        {
            return;
        }
        else
        {
            pMethod = ripl.service.getMethodByKey(pParameters['method']);
            if (!pMethod) return;
            delete (pParameters['method']);
    
            ripl.utilities.cleanObject(pParameters);
            var cb = ripl.service.getDefaultCallback(pMethod);
            switch(cb){
            	case 'ripl.apiHandler.renderUserList':
                    pParameters.callback = 'ripl.scriptless.processReturnUserList';
                    ripl.scriptless.pageCalls++;
            		break;
            	case 'ripl.apiHandler.renderContentList':
                    pParameters.callback = 'ripl.scriptless.processReturnContentList';
                    ripl.scriptless.pageCalls++;
            		break;
            	case 'ripl.apiHandler.renderEventList':
                    pParameters.callback = 'ripl.scriptless.processReturnEventList';
                    ripl.scriptless.pageCalls++;
            		break;
            	case 'ripl.apiHandler.renderCommentList':
                    pParameters.callback = 'ripl.scriptless.processReturnCommentList';
                    ripl.scriptless.pageCalls++;
            		break;
            	default:
            		break;
            }
            ripl.utilities.cleanObject(pDisplayOptions);
            pMethod.call(pParameters,pDisplayOptions,pChildOptions,pEventOptions);
        }
    }
}

ripl.enums = {
    STATE_UNINITIALIZED:0,
    STATE_PROCESSING:1,
    STATE_READY:2,
    CLICK_TO_PLAY:'click_to_play',
    CLICK_TO_LINK:'click_to_link',
    
    TYPE_CONTENT_LIST:'ContentList',
    TYPE_USER_LIST:'UserList',
    TYPE_CONTENT_ITEM:'ContentItem',
    TYPE_USER_ITEM:'User',
    TYPE_EVENT_LIST:'EventList',
    API_USAGE_DISALLOWED:1,
    API_USAGE_REQUIRED:2,
    API_USAGE_OPTIONAL:3,
    
    API_RESPONSE_USERITEM: 1,
    API_RESPONSE_USERLIST:2,
    API_RESPONSE_CONTENTITEM:3,
    API_RESPONSE_CONTENTLIST:4,
    API_RESPONSE_EVENTLIST:5,
    API_RESPONSE_HTML:6,
    API_RESPONSE_SUCCESS:7,
    API_RESPONSE_BOOLEAN:8,
    API_RESPONSE_COMMENTSLIST:9,
    API_RESPONSE_RATINGSTREE :10,
    API_RESPONSE_ARRAY:11,
    API_RESPONSE_INDEXEDCONTENTLIST:12,
    API_RESPONSE_RATEDCONTENTLIST:13,
    API_RESPONSE_RANKEDUSERLIST :14,
    API_RESPONSE_RANKEDCONTENTLIST:15,
    API_RESPONSE_AUTHINFO:16,
    contentChains:{NOT_LOGGED:0,
        MANUAL_FORWARD:1,
        RECOMMENDATIONS_AREA:2,
        FEATURED:3, 
        PROFILE:4,
        TAGS:5, 
        SHARING: 6, 
        FRIEND_UPDATES: 7, 
        FEEDS: 8, 
        MY_CONTENT:9
    }
};


ripl.behaviors = {
    types:{gotoUrl:null},
    addBehavior:function(key,closure)
    {
        ripl.behaviors.types[key] = closure;
    }
};

ripl.behaviors.addBehavior('popup',function _ripl_behaviors_showPopupPlayer()
{
    if (this.objectType=='ContentItem')
    {
        ripl.play(this.pid);
    }
});

ripl.dataservices = {
    callSerial:10000,
    callbacks:[],
    getJSONP:function _ripl_dataservices_getJSONP(url)
    {
        var script = $ripl.create('script',{type:'text/javascript',src:url.replace(/\?(&|$)/, '__jsonp' + ripl.dataservices.callSerial + '$1')}),
            head   = $ripl.getElementsByTagName('head')[0];
        script.onload = function() 
        {
//            script.remove();
            script = null;
        };
        head.add(script);
        ripl.dataservices.callSerial++;
        return ripl.dataservices.callSerial - 1;
    }
        
};

ripl.bridges = {};

ripl.events = {};
ripl.events.serial = 0;
ripl.events.eventObj = function(evtName,closure,thisObj,element,bind)
{
    this.data ={};
    this.data.type = evtName;
    this.data.closure = closure;
    this.data.thisObj = thisObj;
    this.data.element = element;
    this.data.bind = bind;
    this.data.serial = ripl.events.serial++;
};
ripl.events.eventObj.prototype.getName = function()
{
    return this.data.type + '_' + this.data.closure + '_' + this.data.element;
};
ripl.events.eventObj.prototype.callAsDomEvent = function(event)
{
    return this.data.closure.call(this.data.thisObj,event,this);
};

ripl.events.eventManagerBase = function(parent)
{
    this.eventListeners = [];
    this.parent = parent;
};
ripl.events.eventManagerBase.prototype.listen = function(inType,inClosure, inThis)
{
    for (var i=this.eventListeners.length-1; i >=0; i--)
    {
        if ((this.eventListeners[i].type == inType) && (this.eventListeners[i].closure == inClosure))
        {
            this.eventListeners.splice(i,1);
        }
    }    
    this.eventListeners.push({type:inType, closure:inClosure, thisObj:inThis});
};
ripl.events.eventManagerBase.prototype.unlisten = function(inType,inClosure)
{
    for (var i=0; i < this.eventListeners.length; i++)
    {
        if ((this.eventListeners[i].type== inType) && (this.eventListeners[i].closure == inClosure))
        {
            this.eventListeners.splice(i,1);
        }        
    }
};
ripl.events.eventManagerBase.prototype.fire = function(type,thisObj,data)
{
    for (var i=0; i < this.eventListeners.length; i++)
    {
        if (this.eventListeners[i].type == type)
        {
            if (this.eventListeners[i].thisObj)
            {
                thisObj = this.eventListeners[i].thisObj;
            }
            this.eventListeners[i].closure.call(thisObj,data);
        }
    }
};
ripl.events.libraryEvents= new ripl.events.eventManagerBase(ripl.events);
ripl.events.listen = function(inType,inClosure)
{
    ripl.events.libraryEvents.listen(inType,inClosure);
}
ripl.events.unlisten = function(inType,inClosure)
{
    ripl.events.libraryEvents.unlisten(inType,inClosure);
}


ripl.events.addDomListener = function (riplEvtObj) //element, type, handler) 
{
    var element = riplEvtObj.data.element,
        type    = riplEvtObj.data.type,
        handlers= null;
    // assign each event handler a unique ID
    if (!riplEvtObj.$$guid) { riplEvtObj.$$guid = ripl.events.addDomListener.guid++; }
    // create a hash table of event types for the element
    if (!element.events) { element.events = {}; }
    // create a hash table of event handlers for each element/event pair
    handlers = element.events[type];
    if (!handlers) 
    {
        handlers = element.events[type] = {};
        // store the existing event handler (if there is one)
        if (element["on" + type]) 
        {
            handlers[0] = element["on" + type];
        }
    }
    // store the event handler in the hash table
    handlers[riplEvtObj.$$guid] = riplEvtObj;
    // assign a global event handler to do all the work
    element["on" + type] = ripl.events.handleDomEvent;
};
  // a counter used to create unique IDs
ripl.events.addDomListener.guid = 1;

ripl.events.removeDomListener = function(riplEvtObj) 
{
    var element = riplEvtObj.data.element,
        type    = riplEvtObj.data.type;
    // delete the event handler from the hash table
    if (element.events && element.events[type]) 
    {
        delete element.events[type][riplEvtObj.$$guid];
    }
};

ripl.events.handleDomEvent = function(event) 
{
    var returnValue = true;
    // grab the event object (IE uses a global event object)
    event = event || ripl.events.fixDomEvent(window.event);
    // get a reference to the hash table of event handlers
    var handlers = this.events[event.type];
    // execute each event handler
    for (var i in handlers) 
    {
        this.$$handleEvent = handlers[i];
        if (this.$$handleEvent.callAsDomEvent(event) === false) 
        {
            returnValue = false;
        }
    }
    return returnValue;
};

ripl.events.fixDomEvent = function(event)
{
    // add W3C standard event methods
    event.preventDefault = ripl.events.fixDomEvent.preventDefault;
    event.stopPropagation = ripl.events.fixDomEvent.stopPropagation;
    return event;
};
ripl.events.fixDomEvent.preventDefault = function() 
{
    this.returnValue = false;
};
ripl.events.fixDomEvent.stopPropagation = function() 
{
    this.cancelBubble = true;
};



ripl.events.domReadyEvent = {
        name: "domReadyEvent",
        // Array of DOMContentLoaded event handlers.
        events: {},
        domReadyID: 1,
        bDone: false,
        DOMContentLoadedCustom: null,

        // Function that adds DOMContentLoaded listeners to the array.
        add: function(handler) {
            // Assign each event handler a unique ID. If the handler has an ID, it
            // has already been added to the events object or been run.
            if (!handler.$$domReadyID) {
                handler.$$domReadyID = this.domReadyID++;

                // If the DOMContentLoaded event has happened, run the function.
                if(this.bDone){
                    handler();
                }

                // store the event handler in the hash table
                this.events[handler.$$domReadyID] = handler;
            }
        },

        remove: function(handler) {
            // Delete the event handler from the hash table
            if (handler.$$domReadyID) {
                delete this.events[handler.$$domReadyID];
            }
        },

        // Function to process the DOMContentLoaded events array.
        run: function() {
            // quit if this function has already been called
            if (this.bDone) {
                return;
            }

            // Flag this function so we don't do the same thing twice
            this.bDone = true;
            ripl.events.libraryEvents.fire('dom:loaded');
            // iterates through array of registered functions 
            for (var i in this.events) 
            {
                this.events[i]();
            }
      
        },

        schedule: function() {
            // Quit if the init function has already been called
            if (this.bDone) {
                return;
            }
        
            // First, check for Safari or KHTML.
            if(/KHTML|WebKit/i.test(navigator.userAgent)) {
                if(/loaded|complete/.test(document.readyState)) {
                    this.run();
                } else {
                    // Not ready yet, wait a little more.
                    setTimeout(this.name + ".schedule()", 100);
                }
            } else if(document.getElementById("__ie_onload")) {
                // Second, check for IE.
                return true;
            }

            // Check for custom developer provided function.
            if(typeof this.DOMContentLoadedCustom === "function") {
                //if DOM methods are supported, and the body element exists
                //(using a double-check including document.body, for the benefit of older moz builds [eg ns7.1] 
                //in which getElementsByTagName('body')[0] is undefined, unless this script is in the body section)
                if(typeof document.getElementsByTagName !== 'undefined' && (document.getElementsByTagName('body')[0] !== null || document.body !== null)) {
                    // Call custom function.
                    if(this.DOMContentLoadedCustom()) {
                        this.run();
                    } else {
                        // Not ready yet, wait a little more.
                        setTimeout(this.name + ".schedule()", 250);
                    }
                }
            }

            return true;
        },

        init: function() {
            // If addEventListener supports the DOMContentLoaded event.
            if(document.addEventListener) {
                document.addEventListener("DOMContentLoaded", function() { ripl.events.domReadyEvent.run(); }, false);
            }

            // Schedule to run the init function.
            setTimeout("ripl.events.domReadyEvent.schedule()", 100);

            function run() {
                ripl.events.domReadyEvent.run();
            }
            
            // Just in case window.onload happens first, add it to onload using an available method.
            if(typeof addEvent !== "undefined") {
                addEvent(window, "load", run);
            } else if(document.addEventListener) {
                document.addEventListener("load", run, false);
            } else if(typeof window.onload === "function") {
                var oldonload = window.onload;
                window.onload = function() {
                    ripl.events.domReadyEvent.run();
                    oldonload();
                };
            } else {
                window.onload = run;
            }


            /* for Internet Explorer */
            /*@cc_on
                @if (@_win32 || @_win64)
                document.write("<script id=__ie_onload defer src=\"//:\"><\/script>");
                var script = document.getElementById("__ie_onload");
                script.onreadystatechange = function() {
                    if (this.readyState == "complete") {
                        ripl.events.domReadyEvent.run(); // call the onload handler
                    }
                };
                @end
            @*/
        }
};
ripl.events.domReady = function(handler) { ripl.events.domReadyEvent.add(handler); };
ripl.events.domReadyEvent.init();


ripl.envBase = 'http://www.ripl.com/';
ripl.environment ={
    site:ripl.envBase,
    jslib:ripl.envBase+ 'api/1/jslib/',
    endpoint:ripl.envBase+'api/1/rest/',
    endpointHelper:ripl.envBase+'api/1/social/',        
    styleBase:ripl.envBase+'styles/',
    imageBase:ripl.envBase+'images/',
    ugcBase:ripl.envBase,
    userBase:ripl.envBase,
    contentBase:ripl.envBase + 'contentDetailView.php'
};

ripl.renderers = {
    options:{width:640, height:408},
    types:{},
    userTypes:{},
    contentThumbnailTypes:{},
    collectionRenderers:{},
    location:null,
    addCollectionRenderer:function(collectionKey,renderer)
    {
        ripl.renderers.collectionRenderers[collectionKey] = renderer;
    },
    addContentRenderer:function _ripl_renderers_addContentRenderer(typeName,serviceName,renderer)
    {
        if (!ripl.renderers.types[typeName])
        {
            ripl.renderers.types[typeName] = new ripl.renderers._typeBase(typeName);
        }
        var pTypeHandler = ripl.renderers.types[typeName];
        pTypeHandler.serviceRenderers[serviceName] = renderer;
    },
    _typeBase:function _ripl_renderers__typeBase(groupName)
    {
        this.groupName=groupName;
        this.serviceRenderers = {};
    },
    addUserRenderer:function(key, renderer)
    {
    	ripl.renderers.userTypes[key] = renderer;
    },
    getUserRenderer:function(key)
    {
    	return userTypes[key];
    },
    addContentThumbnailRenderer:function(typeName,providerName,cssClass,foregroundImage,noThumbnail)
    {
        var pRenderer = new ripl.renderers._contentThumbnailBase(typeName,providerName,cssClass,foregroundImage,noThumbnail);
        if (!ripl.renderers.contentThumbnailTypes[typeName])
        {
            ripl.renderers.contentThumbnailTypes[typeName] = {};
        }
        ripl.renderers.contentThumbnailTypes[typeName][providerName] = pRenderer;
    },
    getContentThumbnailRenderer:function(inContentItem)
    {
        var typeName = inContentItem.base_type;
        var providerName = inContentItem.provider_id;
        
        if (!ripl.renderers.contentThumbnailTypes[typeName]) { return new ripl.renderers._contentThumbnailBase(); }
        var pRenderer = ripl.renderers.contentThumbnailTypes[typeName][providerName];
        if (!pRenderer) { pRenderer = ripl.renderers.contentThumbnailTypes[typeName]['default']; }
        if (!pRenderer) { return new ripl.renderers._contentThumbnailBase(); }
        if (pRenderer.fn)
        {
            return pRenderer.fn(inContentItem);
        }
        else
        {
            return pRenderer;
        }           
    },
    _contentThumbnailBase:function(typeName,providerName,cssClassOrFunction,foregroundImage,noThumbnail)
    {
        this.typeName = (!typeName) ? 'default' : typeName;
        this.providerName = (!providerName) ? 'default' : providerName;
        if (typeof cssClassOrFunction == 'function')
        {
            this.fn = cssClassOrFunction;
        }
        else
        {
            this.cssClass=  (!cssClassOrFunction) ? 'ripl_contentItem_default':cssClassOrFunction;
            this.foregroundImage = (!foregroundImage) ? '' : foregroundImage;
            this.noThumbnail = (!noThumbnail) ? '' : noThumbnail;
        }
    },
    setDisplayLocation:function _ripl_renderers_setDisplayLocation(locationName)
    {
    }
};


ripl.renderers.addUserRenderer('standard',function(userItem) 
	{
	
	
});

$$ripl = ripl.renderers.addContentThumbnailRenderer;
$$ripl('Photo','default','ripl_contentitem ripl_contentitem_photo','picFrameRipl.png');
$$ripl('Photo','Flickr','ripl_contentitem ripl_contentitem_photo','picFrameFlickr.png');
$$ripl('Photo','Facebook','ripl_contentitem ripl_contentitem_photo','picFrameFacebook.png');
$$ripl('Photo','MySpace','ripl_contentitem ripl_contentitem_photo','picFrameMySpace.png');
$$ripl('Photo','Picasa','ripl_contentitem ripl_contentitem_photo','picFrame_picasa.png');

$$ripl('Video','default','ripl_contentitem ripl_contentitem_video','videoFrame.png');
$$ripl('Video','YouTube','ripl_contentitem ripl_contentitem_video','videoFrame_youTube.png');
$$ripl('Video','MySpace','ripl_contentitem ripl_contentitem_video','videoFrame_mySpace.png');
$$ripl('Video','Vimeo','ripl_contentitem ripl_contentitem_video','videoFrame_vimeo.png');
$$ripl('Video','Hulu','ripl_contentitem ripl_contentitem_video','videoFrame_hulu.png');

$$ripl('Music','default','ripl_contentitem ripl_contentitem_music','musicFrame.png','no_art.gif');

$$ripl('PhotoAlbum','default',function(contentObject)
    {
            var pConvertedCount = 1;
            if (contentObject.item_count <= 20)
            {
                pConvertedCount = contentObject.item_count;
            }
            else if (contentObject.item_count <= 50)
            {
                pConvertedCount = Math.floor(contentObject.item_count/10)*10 + '_plus';            
            }
            else if (contentObject.item_count < 100)
            {
                pConvertedCount = '50_plus';
            }
            else
            {
                pConvertedCount = '100_plus';
            }
            return new ripl.renderers._contentThumbnailBase('PhotoAlbum','default','ripl_contentitem ripl_contentitem_photoalbum','cr/photoAlbum/'+pConvertedCount + '.png');
});


$$ripl = ripl.renderers.addContentRenderer;

$$ripl('video','youtube',function(contentItem) 
    {
        if (!ripl.renderers.location) { return; }
        var params = { allowScriptAccess: "always", wmode:'transparent' };
        var atts = { id: "ripl_youTubePlayer" };

        var pChild = $ripl.create('div',{id:'dynamicFrameChild'});
        $ripl(ripl.renderers.location).update(pChild);
//        $ripl.update(ripl.renderers.location,pChild);
        swfobject.embedSWF(contentItem.content_location_url + "&enablejsapi=1&showinfo=0&autoplay=1&color2=0x444444", 'dynamicFrameChild', ripl.renderers.options.width, ripl.renderers.options.height, "9.0.0", null,null,params,atts);
});
$$ripl('video','myspace',function(contentItem)
    {
        if (!ripl.renderers.location) { return; }
        var params = { allowScriptAccess: "always", wmode:'transparent' };

        var pChild = $ripl.create('div',{id:'dynamicFrameChild'});
        $ripl.update(ripl.renderers.location,pChild);
        var atts = { id: "ripl_mySpacePlayer" };
        swfobject.embedSWF(contentItem.content_location_url, 'dynamicFrameChild', ripl.renderers.options.width, ripl.renderers.options.height, "9.0.0", null,null,params,atts);
});
$$ripl('video','vimeo',function(contentItem)
    {
        ripl.bridges.vimeo1 = function(clips){
            var clipUrl = 'http://www.vimeo.com/api/oembed.json?url=' + encodeURIComponent(clips[0].url) + '&portrait=false&byline=false&title=false&width=640&callback=ripl.bridges.vimeo2';
            var js = $ripl.create('script', {type:'text/javascript',src:clipUrl});
            $ripl.getElementsByTagName('head')[0].add(js);
        };
        ripl.bridges.vimeo2 = function(video)
        {
            var videoEmbedCode = video.html;
            // change the width & height to match our playback.
            videoEmbedCode= videoEmbedCode.replace(/width="..."/gi, "width="+ripl.renderers.options.width);
            videoEmbedCode= videoEmbedCode.replace(/height="..."/gi, "height="+ripl.renderers.options.height);
            $ripl.update(ripl.renderers.location,unescape(videoEmbedCode));
        };
        $ripl(ripl.renderers.location).update();
        
        var pUrl = 'http://www.vimeo.com/api/clip/' + contentItem.foreign_provider_guid + '.json?callback=ripl.bridges.vimeo1';
        $ripl.getElementsByTagName('head')[0].add($ripl.create('script', {type:'text/javascript',src:pUrl}));        
});
$$ripl('video','hulu',function(contentItem)
    {
        ripl.bridges.hulu = function(video)
        {
      	
            var videoEmbedCode = video.html;
            // change the width & height to match our playback.
            videoEmbedCode= videoEmbedCode.replace(/width="..."/gi, "width="+ripl.renderers.options.width);
            videoEmbedCode= videoEmbedCode.replace(/height="..."/gi, "height="+ripl.renderers.options.height);
            $ripl.update(ripl.renderers.location,unescape(videoEmbedCode));
//            $ripl.update(ripl.renderers.location,pString);
        };
        
        var pKey = contentItem.foreign_provider_guid;
		if (pKey.indexOf('hulu.com')  == -1) pKey = 'http://www.hulu.com/watch/'+pKey+'/';

        var pUrl = ripl.environment.endpointHelper + 'hulu/hulu_proxy.php?url=' + encodeURIComponent(unescape(pKey)) + '&callback=ripl.bridges.hulu';
        $ripl.update(ripl.renderers.location);
        ripl.dataservices.getJSONP(pUrl);
});

ripl.renderers.genericPhotoRenderer = function(contentItem)
{
    var pElement = $ripl(ripl.renderers.location);
    pElement.style.textAlign="center";

    var pImage = $ripl.create('img', {style:'position:relative; display:none;margin:auto'});    

    pImage.onload=function(evt)
    {
        var actualAspect = ripl.renderers.options.width*1.0 / ripl.renderers.options.height*1.0,
            pAspect      = (pImage.width *1.0) / (pImage.height*1.0),
            pScale       = 1,
            targetHeight = pImage.height,
            targetWidth  = pImage.width;
        if ((evt) && (evt.target))
        {
            targetHeight = evt.target.height;
            targetWidth = evt.target.width;
            pAspect = (targetWidth *1.0) / (targetHeight*1.0);
        }
        if (actualAspect > pAspect)
        {
            if (ripl.renderers.options.height < targetHeight)
            {
                pImage.style.height="100%";
                pScale = (ripl.renderers.options.height*1.0) / (targetHeight*1.0);
            }
            
            pImage.style.top = "50%";
            pImage.style.marginTop = (-targetHeight*pScale/2 ) + 'px';
            
        }
        else
        {
            pImage.style.top = "50%";

            pScale = (ripl.renderers.options.height*1.0) / (targetHeight*1.0);
            if (ripl.renderers.options.width < targetWidth)
            {
                var pScaledHeight =targetHeight / pScale;
                pImage.style.width="100%";
                pImage.style.marginTop = (-targetHeight/2 ) + 'px';
            }
            else
            {
                pScale = 1;
                pImage.style.marginTop = (-targetHeight/2 ) + 'px';
            }
            
        }
        pImage.style.display="block";
    };
    pImage.src = contentItem.preview_image_url;
    pElement.update(pImage);
};

$$ripl('photo','ripl',ripl.renderers.genericPhotoRenderer);
$$ripl('photo','flickr',ripl.renderers.genericPhotoRenderer);
$$ripl('photo','picasa',ripl.renderers.genericPhotoRenderer);
$$ripl('photo','myspace',ripl.renderers.genericPhotoRenderer);

ripl.renderers.genericPhotoAlbumRenderer = function(contentItem)
{
	// show initial photo while loading album
	ripl.renderers.genericPhotoRenderer(contentItem);
	// get full album (with children)
	ripl.service.methods.ripl.content.getAlbum.call({
		detail:3,
		content_id:contentItem.pid,
		callback: 'ripl.apiHandler.renderPhotoAlbum'
	});
}

$$ripl('photoalbum','default',ripl.renderers.genericPhotoAlbumRenderer);
$$ripl('photoalbum','ripl',ripl.renderers.genericPhotoAlbumRenderer);
$$ripl('photoalbum','flickr',ripl.renderers.genericPhotoAlbumRenderer);
$$ripl('photoalbum','picasa',ripl.renderers.genericPhotoAlbumRenderer);
$$ripl('photoalbum','myspace',ripl.renderers.genericPhotoAlbumRenderer);

$$ripl('music','ripl',function(contentItem)
{
    ripl.bridges.next= function(lookupInfo)
    {
        if ((lookupInfo) && (lookupInfo.foreign_id) && (lookupInfo.foreign_id > 0))
        {
            var pHtml = '<iframe name="napsterPlayer" id="napsterPlayer" allowtransparency="true" src="http://free.napster.com/player/?play_id=';
            pHtml += lookupInfo.foreign_id;
            pHtml += '&type=track" scrolling="no" frameborder="0" height="408" width="640"></iframe>';
            $ripl.add(ripl.renderers.location,pHtml);
        }
        else
        {
            $ripl.add(ripl.renderers.location,'<div class="ripl_contentrender_music">'+
                    '<div class="ripl_contentrender_music_frame">'+
                    '<div class="ripl_contentrender_music_container">'+
                        '<img class="ripl_contentrender_music_preview_bg" src="'+((contentItem.preview_image_url != null)?contentItem.preview_image_url : ripl.environment.imageBase+'music/no_art_large.jpg')+'" alt="" />'+
                        '<img class="ripl_contentrender_music_preview" src="'+ripl.environment.imageBase+'music/frame_large.png" alt="" />'+
                    '</div>'+
                '</div>'+
                '<div class="ripl_contentrender_music_text">'+
                    '<span class="ripl_contentrender_music_title ripl_colors_normal">' + contentItem.title + '</span><br /><span class="ripl_contentrender_music_artist ripl_colors_midemphasis">' + contentItem.artist + '</span><br /><span class="ripl_contentrender_music_album ripl_colors_midemphasis">' + contentItem.album + '</span>'+
                '</div>'+
            '</div>');            
        }
        var pItems = $ripl.getElementsByClassName('.ripl_loaderImage');
        for (var i =0; i < pItems.length; i++)
        {
	            pItems[i].hide();
	        }
	    };
	    $ripl.update(ripl.renderers.location);
			ripl.bridges.next();
//	    ripl.service.getNapsterId(contentItem,'ripl.bridges.next');
	});

$$ripl = ripl.renderers.addCollectionRenderer;


$$ripl('collection_helper_pageChanger',function (contentList) {
    var options = contentList.displayOptions;
    if (options.currentpagenumber < 1) { options.currentpagenumber = 1; }

    var pPagination = $ripl.create('div',{'className':'ripl_collection_pageChanger'});

    var totalPages = Math.ceil(contentList._availableItems.length/(options.itemsperpage));
    var pageMax = (options.currentpagenumber < totalPages) ? false : true;
    var pageMin =(options.currentpagenumber != 1) ? false : true;
    var pLeft;
    var pRight;
    
    if (!pageMin)
    {
        pLeft= $ripl.create('div',{className:'ripl_collection_pageChanger_prevStepper'});
        pLeft.listen('click', contentList.prevPage, contentList);
    }
    else
    {
        pLeft= $ripl.create('div',{className:'ripl_collection_pageChanger_prevStepper_disabled'});        
    }

    if (!pageMax)
    {
        pRight = $ripl.create('div',{className:'ripl_collection_pageChanger_nextStepper'});
        pRight.listen('click', contentList.nextPage, contentList);
    }
    else
    {
        pRight = $ripl.create('div',{className:'ripl_collection_pageChanger_nextStepper_disabled'});
    }
    var pPageText = $ripl.create('div',
            {className:'ripl_colors_normal ripl_collection_pageChanger_text'},
            '&nbsp;page&nbsp;' + options.currentpagenumber + '&nbsp;of&nbsp;' + totalPages + '&nbsp;');
    pPagination.add([pPageText,pRight,pLeft]);
    
    pPagination.listen('mousedown',function(e) {
            if (!e) e = window.event;
            e.cancelBubble = true;
            if (e.stopPropagation) e.stopPropagation();
            return false;
        });
    return pPagination;
});

$$ripl('contentlist_helper_typeSelector',function (contentList) {
    var pPagination = $ripl.create("div",{'className':'ripl_colors_normal ripl_collection_typeChanger'},'content types:');
    var pVideoChk = $ripl.create('input',{'id':'chkVideo','type':'checkbox','value':'Video','checked':'checked' });
    var pPhotoChk = $ripl.create('input',{'id':'chkPhoto','type':'checkbox','value':'Photo','checked':'checked' });
    var pMusicChk = $ripl.create('input',{'id':'chkMusic','type':'checkbox','value':'Music','checked':'checked' });
    var pBlogChk = $ripl.create('input',{'id':'chkBlog','type':'checkbox','value':'Blog','checked':'checked' });

    var pVideoLabel = $ripl.create('label',{'className':'ripl_typeselector_label','for':'chkVideo'},'Video');
    var pPhotoLabel = $ripl.create('label',{'className':'ripl_typeselector_label','for':'chkPhoto'},'Photo');
    var pMusicLabel = $ripl.create('label',{'className':'ripl_typeselector_label','for':'chkMusic'},'Music');
    var pBlogLabel = $ripl.create('label',{'className':'ripl_typeselector_label','for':'chkBlog'},'Blog');
    pPagination.add([pVideoChk,pVideoLabel,pPhotoChk,pPhotoLabel,pMusicChk,pMusicLabel,pBlogChk,pBlogLabel]);

    var pFn = function(e,riplEvtObj)
    {        
        var el = $ripl((e.target) ? e.target : e.srcElement);
        
        var pChecked = el.checked;
        var pKey = el.value;
        var pFilters = [].concat(this.displayOptions.typeFilters);
        var pFound = false;
        for (var i =pFilters.length -1; i >=0; i--)
        {
            if (pFilters[i] == pKey)
            {
                pFound = true;
                if (!pChecked)
                {
                    pFilters.splice(i,1);
                }
            }
        }
        if ((!pFound) && (pChecked))
        {
            pFilters.push(pKey);
        }
        this.setTypeFilters(pFilters,true);      
    };
    pVideoChk.listen('click', pFn, contentList);
    pPhotoChk.listen('click', pFn, contentList);
    pMusicChk.listen('click', pFn, contentList);
    pBlogChk.listen('click', pFn, contentList);

    pVideoChk.checked = contentList.displayOptions.typeFilters.ripl_InArray('Video');
    pPhotoChk.checked = contentList.displayOptions.typeFilters.ripl_InArray('Photo');
    pMusicChk.checked = contentList.displayOptions.typeFilters.ripl_InArray('Music');
    pBlogChk.checked = contentList.displayOptions.typeFilters.ripl_InArray('Blog');

    return pPagination;

});
$$ripl('pagination_helper',function (riplList) {
    var pLen = riplList._availableItems.length,
        pStart = (riplList.displayOptions.currentpagenumber -1) * riplList.displayOptions.itemsperpage;
        pMax = Math.min(pStart + riplList.displayOptions.itemsperpage, pLen);
    
    if (pStart > pMax)
    {
        riplList.displayOptions.currentpagenumber = Math.ceil(pMax / riplList.displayOptions.itemsperpage);
        pStart = (riplList.displayOptions.currentpagenumber -1) * riplList.displayOptions.itemsperpage;
        pMax = Math.min(pStart + riplList.displayOptions.itemsperpage, pLen);
    }
   
    if (riplList.displayOptions.itemsperpage <= 0)
    {
        pStart = 0;
        pMax = pLen;
    }
    if (pStart > pMax) { pStart = pMax; }
    pStart = Math.max(0,pStart); 
    return {'start':pStart,'max':pMax};
});
        
$$ripl('title_helper', function (riplList)
{
    var pTitle;
    if (riplList.displayOptions.title)
    {
        pTitle = $ripl.create('div',
                {className:'ripl_displaytitle'},
                riplList.parseString(riplList.displayOptions.title)
            );
    }
    return pTitle;
});

$$ripl('bottombar_helper', function (riplList, listlength, ignoreLeft)
{
    var pBottomLeft, pShowLeft, pBottomRight, pBottomBar = $ripl.create('div',{className:"ripl_displayoptions"});
    
    pShowLeft = (riplList.displayOptions.displaytypeselector) ? ((ignoreLeft==true) ? false : true) : false;
    if (pShowLeft)
    {
        pBottomLeft = ripl.renderers.collectionRenderers.contentlist_helper_typeSelector(riplList);
    }    
    if ((riplList.displayOptions.itemsperpage < listlength) && (riplList.displayOptions.itemsperpage > 0))
    {
        pBottomRight = ripl.renderers.collectionRenderers.collection_helper_pageChanger(riplList);  
    }
    pBottomBar.add([pBottomLeft, pBottomRight])
    return pBottomBar;
});


$$ripl('mixedlist_default',function (mixedlist) {
    if (!mixedlist.displayOptions.renderTarget) { return; }
    
    var pTitle, pContent, i,
        pLen = mixedlist._availableItems.length,    
        pageInfo, pBottomLeft, pBottomRight, pBottomBar,
        pDiv = $ripl.create('div',{
            className:'ripl_displayObject'
            });
    
    pTitle = ripl.renderers.collectionRenderers.title_helper(mixedlist);

    pContent = $ripl.create('div',{className:'ripl_contentcontainer'});    
    if (pLen == 0) 
    {
        pContent.add(mixedlist.displayOptions.noitems);
    }
    else
    {
        pageInfo = ripl.renderers.collectionRenderers.pagination_helper(mixedlist);
        for (i = pageInfo.start; i < pageInfo.max; i++)
        {
            mixedlist._availableItems[i].addToContainer(pContent);
        }
    }
    
    pBottomBar = ripl.renderers.collectionRenderers.bottombar_helper(mixedlist,pLen);
    pDiv.add([pTitle, pContent, pBottomBar]);

    $ripl.update(mixedlist.displayOptions.renderTarget,pDiv);
});

$$ripl('eventlist_default',function (eventList) {
    if (!eventList.displayOptions.renderTarget) { return; }
    var i    = 0,
        pTitle,
        pContent,
        pBottomBar,
        pText ='',
        pLen = eventList._availableItems.length,    
        pageInfo, pBottomLeft, pBottomRight, 
        pDiv = $ripl.create('div',{
            className:'ripl_displayObject'
        }),
        pItemContainer, pUserEl, pContentEl,pDivChildren=[];
    
    pContent = $ripl.create('div',{className:'ripl_contentcontainer'});    
    if (pLen == 0) 
    {
        pDiv.add(eventList.displayOptions.noitems);
    }
    else
    {
        pageInfo = ripl.renderers.collectionRenderers.pagination_helper(eventList);
        for (i = pageInfo.start; i < pageInfo.max; i++)
        {
            eventList._availableItems[i].contentObject.addToContainer(pDiv); 
            eventList._availableItems[i].actorObject.addToContainer(pDiv); 
            pDiv.add(eventList._availableItems[i].toString());
        }
    }
    pBottomBar = ripl.renderers.collectionRenderers.bottombar_helper(eventList,pLen);
    pDiv.add([pTitle, pContent, pBottomBar]);
    
    $ripl.update(eventList.displayOptions.renderTarget,pDiv);
});


$$ripl('usereventlist_cards_users',function (eventList) {
    if (!eventList.displayOptions.renderTarget) { return; }

    var pTitle, pContent, pBottomBar,pBottomRight,
        pLen = eventList._availableItems.length;
    var pChildren = [];
    var pContainer = $ripl.create('div', {className:'ripl_displayObject'});

    pTitle = ripl.renderers.collectionRenderers.title_helper(eventList);
    pContent = $ripl.create('div',{className:'ripl_contentcontainer'});

    if (pLen == 0) 
    {
        pContent.add(eventList.displayOptions.noitems);
    }
    else
    {
        var pageInfo = ripl.renderers.collectionRenderers.pagination_helper(eventList);

        for (var i = pageInfo.start; i < pageInfo.max; i++)
        {
            var eventItem = eventList._availableItems[i];
            var c = eventItem.contentObject;
            
            var pDiv = $ripl.create('div',{className:'ripl_contentitem_render_card ripl_colors_normal'});

            var pTextCell = $ripl.create('div',{className:'ripl_contentitem_render_card_info'});
            var pItemTitle = c.getAnchor({'className':'ripl_contentitem_render_card_title ripl_link ripl_colors_link'},c.title.ripl_truncate(40));
            
            var pTextCellData = $ripl.create('div');
            if (c.base_type == 'Music')
            {
                pTextCellData.update(c.artist.ripl_truncate(26) + '<br />'+ c.album.ripl_truncate(26) + '<br />');
            }
            var pInfoCell = $ripl.create('div',{className:'ripl_contentitem_render_card_updated ripl_colors_deemphasis'});
            // TODO: genericize user information (and profile link) to allow 3rd party hosting
            pInfoCell.add('<img src="'+eventItem.actorObject.avatarurl+'" style="width:30px; height:30px; float:left; margin-right:5px; border:1px solid #000000" /><div style="float:left;width:110px"><a class="ripl_link ripl_colors_link" href="http://www.ripl.com/'+eventItem.actorObject.login+'">'+eventItem.actorObject.displayName+'</a> '+eventItem.actionType+' '+eventItem.actionTime.ripl_formatSince());
            
            pTextCell.add([pItemTitle,pTextCellData,pInfoCell]);
            
            c.addToContainer(pDiv);
//            eventItem.actorObject.addToContainer(pDiv);
            pDiv.add(pTextCell);
            pChildren.push(pDiv);
        }
        pContent.add(pChildren);
    }
    pBottomBar = ripl.renderers.collectionRenderers.bottombar_helper(eventList,pLen,true);
    
    pContainer.add([pTitle, pContent, pBottomBar]);    
    eventList.displayOptions.renderTarget.update(pContainer);
});


$$ripl('usereventlist_cards',function (eventList) {
    if (!eventList.displayOptions.renderTarget) { return; }

    var pTitle, pContent, pBottomBar,pBottomRight,
        pLen = eventList._availableItems.length;
    var pChildren = [];
    var pContainer = $ripl.create('div', {className:'ripl_displayObject'});

    pTitle = ripl.renderers.collectionRenderers.title_helper(eventList);
    pContent = $ripl.create('div',{className:'ripl_contentcontainer'});

    if (pLen == 0) 
    {
        pContent.add(eventList.displayOptions.noitems);
    }
    else
    {
        var pageInfo = ripl.renderers.collectionRenderers.pagination_helper(eventList);

        for (var i = pageInfo.start; i < pageInfo.max; i++)
        {
            var eventItem = eventList._availableItems[i];
            var c = eventItem.contentObject;
            
            var pDiv = $ripl.create('div',{className:'ripl_contentitem_render_card ripl_colors_normal'});

            var pTextCell = $ripl.create('div',{className:'ripl_contentitem_render_card_info'});
           
            pTextCell.add('<a href="http://www.ripl.com/'+eventItem.actorObject.login+'">'+eventItem.actorObject.displayName+'</a> '+eventItem.actionType+'<br />');
            
            var pItemTitle = c.getAnchor({'className':'ripl_contentitem_render_card_title ripl_link ripl_colors_link'},c.title.ripl_truncate(40));
            
            var pTextCellData = $ripl.create('div');
            if (c.base_type == 'Music')
            {
                pTextCellData.update(c.artist.ripl_truncate(26) + '<br />'+ c.album.ripl_truncate(26) + '<br />');
            }
            var pInfoCell = $ripl.create('div',{className:'ripl_contentitem_render_card_updated ripl_colors_deemphasis'});
//            if (eventItem.actionTime) {pInfoCell.add('added ' + eventItem.actionTime.ripl_formatSince()); }
            // TODO: genericize user information (and profile link) to allow 3rd party hosting
            var time = new Date(eventItem.actionTime);
            pInfoCell.add(time.ripl_formatSince());
            
            pTextCell.add([pItemTitle,pTextCellData,pInfoCell]);
            
            c.addToContainer(pDiv);
//            eventItem.actorObject.addToContainer(pDiv);
            pDiv.add(pTextCell);
            pChildren.push(pDiv);
        }
        pContent.add(pChildren);
    }
    pBottomBar = ripl.renderers.collectionRenderers.bottombar_helper(eventList,pLen,true);
    
    pContainer.add([pTitle, pContent, pBottomBar]);    
    eventList.displayOptions.renderTarget.update(pContainer);
});


$$ripl('eventlist_cards',function (eventList) {
    if (!eventList.displayOptions.renderTarget) { return; }

    var pTitle, pContent, pBottomBar,pBottomRight,
        pLen = eventList._availableItems.length;
    var pChildren = [];
    var pContainer = $ripl.create('div', {className:'ripl_displayObject'});
    
    pTitle = ripl.renderers.collectionRenderers.title_helper(eventList);
   
    pContent = $ripl.create('div',{className:'ripl_contentcontainer'});

    if (pLen == 0) 
    {
        pContent.add(eventList.displayOptions.noitems);
    }
    else
    {
        var pageInfo = ripl.renderers.collectionRenderers.pagination_helper(eventList);

        for (var i = pageInfo.start; i < pageInfo.max; i++)
        {
            var eventItem = eventList._availableItems[i];
            var c = eventItem.contentObject;
            
            var pDiv = $ripl.create('div',{className:'ripl_contentitem_render_card ripl_colors_normal'});

            var pTextCell = $ripl.create('div',{className:'ripl_contentitem_render_card_info'});
            var pItemTitle = c.getAnchor({'className':'ripl_contentitem_render_card_title ripl_link ripl_colors_link'},c.title.ripl_truncate(40));
            
            var pTextCellData = $ripl.create('div');
            if (c.base_type == 'Music')
            {
                pTextCellData.update(c.artist.ripl_truncate(26) + '<br />'+ c.album.ripl_truncate(26) + '<br />');
            }
            var pInfoCell = $ripl.create('div',{className:'ripl_contentitem_render_card_updated ripl_colors_deemphasis'});
            
            if (c.last_update != null) {pInfoCell.add('added ' + c.getFriendlyUpdateTime()); }
            if(ripl.coreObjects.EventItem.riplEventTypes[eventItem.actionType]){
            	pInfoCell.add('<img src="'+ripl.coreObjects.EventItem.riplEventTypes[eventItem.actionType]+'" alt="'+eventItem.actionType+'" />');
            }
            // TODO: genericize user information (and profile link) to allow 3rd party hosting
            pInfoCell.add('<a href="http://www.ripl.com/'+eventItem.actorObject.login+'">'+eventItem.actorObject.displayName+'</a> '+eventItem.actionType+'<br />');
            var time = new Date(eventItem.actionTime*1000);
            pInfoCell.add(time.ripl_formatSince());
            
            pTextCell.add([pItemTitle,pTextCellData,pInfoCell]);
            
            c.addToContainer(pDiv);
            eventItem.actorObject.addToContainer(pDiv);
            pDiv.add(pTextCell);
            pChildren.push(pDiv);
        }
        pContent.add(pChildren);
    }
    pBottomBar = ripl.renderers.collectionRenderers.bottombar_helper(eventList,pLen,true);
    
    pContainer.add([pTitle, pContent, pBottomBar]);    
    eventList.displayOptions.renderTarget.update(pContainer);
});



$$ripl('commentlist_default',function (commentList) {
    if (!commentList.displayOptions.renderTarget) { return; }
    var i    = 0,
        pTitle, pContent, pBottomBar,
        pLen = commentList._availableItems.length,    
        pageInfo,  
        pDiv = $ripl.create('div',{
            className:'ripl_displayObject'
            });
    
    pTitle = ripl.renderers.collectionRenderers.title_helper(commentList);
    pContent = $ripl.create('div',{className:'ripl_contentcontainer'});
    
    if (pLen == 0) 
    {
        pContent.add(commentList.displayOptions.noitems);
    }
    else
    {
        pageInfo = ripl.renderers.collectionRenderers.pagination_helper(commentList);
        for (i = pageInfo.start; i < pageInfo.max; i++)
        {
            commentList._availableItems[i].addToContainer(pContent);
        }
    }
    pBottomBar = ripl.renderers.collectionRenderers.bottombar_helper(commentList,pLen);
    pDiv.add([pTitle,pContent, pBottomBar]);
    
    $ripl.update(commentList.displayOptions.renderTarget,pDiv);
});


$$ripl('contentlist_default',function (contentList) {
    if (!contentList.displayOptions.renderTarget) { return; }
    
    var pTitle, pContent, i,
        pLen = contentList._availableItems.length,    
        pageInfo, pBottomLeft, pBottomRight, pBottomBar,
        pDiv = $ripl.create('div',{
            className:'ripl_displayObject'
                });
    
    pTitle = ripl.renderers.collectionRenderers.title_helper(contentList);

    pContent = $ripl.create('div',{className:'ripl_contentcontainer'});    
    if (pLen == 0) 
    {
        pContent.add(contentList.displayOptions.noitems);
    }
    else
    {
        pageInfo = ripl.renderers.collectionRenderers.pagination_helper(contentList);
        for (i = pageInfo.start; i < pageInfo.max; i++)
        {
            contentList._availableItems[i].addToContainer(pContent);
        }
    }
    
    pBottomBar = ripl.renderers.collectionRenderers.bottombar_helper(contentList,pLen);
    pDiv.add([pTitle, pContent, pBottomBar]);

    $ripl.update(contentList.displayOptions.renderTarget,pDiv);
});

$$ripl('albumlist_default',function (albumList) {
    if (!albumList.displayOptions.renderTarget) { return; }
    
    var pTitle, pContent, i,
        pLen = albumList._availableItems.length,    
        pageInfo, pBottomLeft, pBottomRight, pBottomBar,
        pDiv = $ripl.create('div',{
            className:'ripl_displayObject'
                });
    
    pTitle = ripl.renderers.collectionRenderers.title_helper(albumList);

    pContent = $ripl.create('div',{className:'ripl_albumcontainer'});    
    if (pLen == 0) 
    {
        pContent.add(albumList.displayOptions.noitems);
    }
    else
    {
        pageInfo = ripl.renderers.collectionRenderers.pagination_helper(albumList);
        for (i = pageInfo.start; i < pageInfo.max; i++)
        {
        	albumList._availableItems[i].addToContainer(pContent);
        }
    }
    
    pBottomBar = ripl.renderers.collectionRenderers.bottombar_helper(albumList,pLen);
    pDiv.add([pTitle, pContent, pBottomBar]);

    $ripl.update(albumList.displayOptions.renderTarget,pDiv);
});

$$ripl('photoalbum_detail',function (albumList) {
    if (!albumList.displayOptions.renderTarget) { return; }
    
    var pBottomBar,
        pLen = albumList._availableItems.length,    
        pageInfo
        render = $ripl.getElementById(albumList.displayOptions.renderTarget);
    
    render.update(ripl.renderers.collectionRenderers.title_helper(albumList));                           
    if (pLen == 0) 
    {
    	render.add(albumList.displayOptions.noitems);
    }
    else
    {
        pageInfo = ripl.renderers.collectionRenderers.pagination_helper(albumList);
        window.location.hash = pageInfo.max;
        render.add('<img style="margin:auto;display:block;height:100%;margin-top:-204px;top:50%;position:relative" src="'+albumList._availableItems[pageInfo.start].preview_image_url+'" alt="'+albumList._availableItems[pageInfo.start].title+'" />');
        pBottomBar = ripl.renderers.collectionRenderers.collection_helper_pageChanger(albumList);
    }
    render.add(pBottomBar);
});

$$ripl('userlist_default',function(userList){
    var pBottomBar, pBottomRight, pageInfo, pContent, pTitle, pDiv, i 
        pLen = userList._availableItems.length;
    
    var options = userList.displayOptions;
    pDiv = $ripl.create('div', {
        className:'ripl_displayObject'
        });
    
    pTitle = ripl.renderers.collectionRenderers.title_helper(userList);

    pContent = $ripl.create('div',{className:'ripl_contentcontainer'});    
    
    if (pLen == 0) 
    {
        pContent.add(userList.displayOptions.noitems);        
    }
    else
    {
        pageInfo = ripl.renderers.collectionRenderers.pagination_helper(userList);

        for (i = pageInfo.start; i < pageInfo.max; i++)
        {
            userList._availableItems[i].addToContainer(pContent);         
        }
    }
    pBottomBar = ripl.renderers.collectionRenderers.bottombar_helper(userList,pLen);
    pDiv.add([pTitle, pContent, pBottomBar]);
    $ripl.update(userList.displayOptions.renderTarget,pDiv);
    
});

$$ripl('html_default',function (htmlObject) {
    var pTitle, pContent, 
        pDiv = $ripl.create('div', {
        className:'ripl_displayObject'
        });
    
    
    
    if (htmlObject.displayOptions.title)
    {
        pTitle = $ripl.create('div',{className:'ripl_displaytitle'},htmlObject.displayOptions.title);
        pDiv.add(pTitle);
    }    
    pContent = $ripl.create('div',{className:'ripl_contentcontainer'});
    pContent.add(htmlObject.html);
    pDiv.add([pTitle, pContent]);
    $ripl.update(htmlObject.displayOptions.renderTarget,pDiv);
    
});

$$ripl('contentlist_cards',function (contentList) {
    if (!contentList.displayOptions.renderTarget) { return; }

    var pTitle, pContent, pBottomBar,pBottomRight,
        pLen = contentList._availableItems.length;
    var pChildren = [];
    var pContainer = $ripl.create('div', {className:'ripl_displayObject'});
    
    pTitle = ripl.renderers.collectionRenderers.title_helper(contentList);
   
    pContent = $ripl.create('div',{className:'ripl_contentcontainer'});

    if (pLen == 0) 
    {
        pContent.add(contentList.displayOptions.noitems);
    }
    else
    {
        var pageInfo = ripl.renderers.collectionRenderers.pagination_helper(contentList);

        for (var i = pageInfo.start; i < pageInfo.max; i++)
        {
            var contentItem = contentList._availableItems[i];
            
            var pDiv = $ripl.create('div',{className:'ripl_contentitem_render_card ripl_colors_normal'});

            var pTextCell = $ripl.create('div',{className:'ripl_contentitem_render_card_info'});
            var pItemTitle = contentItem.getAnchor({'className':'ripl_contentitem_render_card_title ripl_link ripl_colors_link'},contentItem.title.ripl_truncate(40));
            
            var pTextCellData = $ripl.create('div');
            if (contentItem.base_type == 'Music')
            {
                pTextCellData.update(contentItem.artist.ripl_truncate(26) + '<br />'+ contentItem.album.ripl_truncate(26) + '<br />');
            }
            var pInfoCell = $ripl.create('div',{className:'ripl_contentitem_render_card_updated ripl_colors_deemphasis'});
            if (contentItem.last_update != null) {pInfoCell.add('added ' + contentItem.getFriendlyUpdateTime()); }
            if (contentItem.provider_id != null && contentItem.provider_id!='' && contentItem.provider_id != 'Ripl') { pInfoCell.add(' through '+ contentItem.provider_id); }
            pTextCell.add([pItemTitle,pTextCellData,pInfoCell]);
            contentItem.addToContainer(pDiv);
            pDiv.add(pTextCell);
            pChildren.push(pDiv);
        }
        pContent.add(pChildren);
    }
    pBottomBar = ripl.renderers.collectionRenderers.bottombar_helper(contentList,pLen,true);
    
    $ripl.add(pContainer,[pTitle, pContent, pBottomBar]);    
    $ripl.update(contentList.displayOptions.renderTarget,pContainer);
});




$$ripl('contentlist_text',function (contentList) {
    if (!contentList.displayOptions.renderTarget) { return; }
    var pTitle, pLen = contentList._availableItems.length;
    var pContainer = $ripl.create('div', {className:'ripl_displayObject'});
    
    pTitle = ripl.renderers.collectionRenderers.title_helper(contentList);

    var pContent = $ripl.create('div',{className:'ripl_contentcontainer'});

    if (pLen == 0) 
    {
        pContent.add(contentList.displayOptions.noitems);
    }
    else
    {
        var pageInfo = ripl.renderers.collectionRenderers.pagination_helper(contentList);
        
        for (var i = pageInfo.start; i < pageInfo.max; i++)
        {
            var pItem = contentList._availableItems[i];
            var pDiv = $ripl.create('div', {className:'ripl_textContainer'});
            
            var pItemTitle = pItem.getAnchor({},pItem.title);
            var pText = $ripl.create('span',
                    {className:'ripl_contentitem_render_text ripl_colors_normal'},
                    '<br />added ' + pItem.getFriendlyUpdateTime() + ((pItem.provider_id != 'Ripl') ? ' ( through '+ pItem.provider_id + ' )' : '')
            );
            pDiv.add([pItemTitle,pText]);
            pContent.add(pDiv);
        }
    }
    pBottomBar = ripl.renderers.collectionRenderers.bottombar_helper(contentList,pLen,true);    
    pContainer.add([pTitle, pContent, pBottomBar]);
    $ripl.update(contentList.displayOptions.renderTarget,pContainer);
});

ripl.coreObjects = {};
ripl.coreObjects.OptionBuilder = function(obj1, obj2)
{
    var retVal = {};
    var key;
    for (key in obj1)
    {
        retVal[key] = obj1[key];
    }
    for (key in obj2)
    {
        retVal[key] = obj2[key];
    }
    return retVal;
};
ripl.coreObjects.extend = function(base,derived)
{
    for (var i in base)
    {
        if (!derived[i]) { derived[i] = base[i]; }
    }
};


ripl.coreObjects.clone = function ripl_coreObjects_clone(o) 
{
    function ripl_cloner(o) 
    {
        for (var i in o) 
        {
            this[i] = o[i];
        }
    }
    return new ripl_cloner(o);
};

ripl.coreObjects._riplDisplayObject = function() {};
ripl.coreObjects._riplDisplayObject.prototype.addToContainer = function(container)
{
    var pDomObj = this.domObj;

    var pGetDomObj = !pDomObj;
    /*@cc_on
    @if (@_win32 || @_win64)
        pGetDomObj = true;
    @end
    @*/    
    if (pGetDomObj) 
    { 
        pDomObj = this.getStandardDomObj(); 
    }
    $ripl.add(container,pDomObj);
    this.domContainer = container;
    this.event.fire('added',container);
};
ripl.coreObjects._riplDisplayObject.prototype.removeFromContainer = function()
{
    $ripl.removeElement(this.domObj);
    this.event.fire('removed',pDomContainer);
};
ripl.coreObjects._riplDisplayObject.prototype.show = function()
{
    $ripl.show(this.domObj);    
    this.event.fire('visible',true);
};
ripl.coreObjects._riplDisplayObject.prototype.hide = function()
{
    $ripl.hide(this.domObj);    
    this.event.fire('visible',false);
};
ripl.coreObjects._riplDisplayObject.prototype._handleDomEvent=function(event)
{
    this.event.fire(event.type,this,event);    
};

ripl.coreObjects._riplDisplayObject.prototype.getAnchor = function(attributes,text)
{
    var pAtts = {
            href:(this.eventOptions.onclick) ? 'javascript:void(0)' : this.getLink(),
            title:this.toString(),
            className:'ripl_link ripl_colors_link'
    };
    if (attributes) { pAtts = ripl.coreObjects.OptionBuilder(pAtts,attributes); }
    
    var pAnchor = $ripl.create('a',pAtts, text);
    
//    this.hookDomListeners(pAnchor);

    if (this.eventOptions.onclick) { pAnchor.listen('click',this.eventOptions.onclick,this); }
    if (this.eventOptions.onmouseover) { pAnchor.listen('mouseover',this.eventOptions.onmouseover, this); }
    if (this.eventOptions.onmouseout) { pAnchor.listen('mouseout',this.eventOptions.onmouseout, this); }
    return pAnchor;
};

ripl.coreObjects._riplCollection = function() {
    this.friendlyType = 'collection';
    
};
ripl.coreObjects._riplCollection.prototype.getIdsAsArray = function()
{
    var pRetVal = [];
    for (var i = 0; i < this._rawItems.length;i++)
    {
        pRetVal.push(this._rawItems[i].pid);
    }
    return pRetVal;
};
ripl.coreObjects._riplCollection.prototype.getCount = function()
{
    return this._rawItems.length;
};
ripl.coreObjects._riplCollection.prototype.getAvailableCount = function()
{
    return this._availableItems.length;
};
ripl.coreObjects._riplCollection.prototype.empty = function(renderNow)
{
    this.dirty = true;
    this._rawItems = [];
    if (renderNow) { this.render(); }
};
ripl.coreObjects._riplCollection.prototype.getItemById = function(itemId)
{
    for (var i = 0; i < this._rawItems.length; i++)
    {
        if (this._rawItems[i].pid == itemId)
        {
            return this._rawItems[i]; 
        }
    }
    return false;
};

ripl.coreObjects._riplCollection.prototype.addObject = function(obj,typeOverride)
{
    var pType = (typeOverride) ? typeOverride : this.objectPrototype;

    this.addItem(new pType(obj));
    
};
ripl.coreObjects._riplCollection.prototype.addObjects = function(objArr,typeOverride)
{
    if (!objArr) {return;}
    for (var i = 0; i < objArr.length; i++)
    {
        this.addObject(objArr[i],typeOverride);
    }
};

ripl.coreObjects._riplCollection.prototype.addItem = function(obj)
{
    var key;
    if (!this._rawItems.ripl_InArrayKey(obj,'pid'))
    {
        this.dirty = true;
        for (key in this.childParameters)
        {
            obj.displayOptions[key] = this.childParameters[key];
        }
        
        this._rawItems.push(obj);
    }
};
ripl.coreObjects._riplCollection.prototype.addItems = function(objArr)
{
    for (var i = 0; i < objArr.length; i++)
    {
        this.addItem(objArr[i]);
    }
};

ripl.coreObjects._riplCollection.prototype.merge = function (objectList)
{
    for (var i = 0; i < objectList._rawItems.length; i++)
    {
        this.addItem(objectList._rawItems[i]);
    }
};
ripl.coreObjects._riplCollection.prototype.removeItemById = function(index)
{
    this.dirty = true;
    for (var i = this._rawItems.length - 1; i >=0; i--)
    {
        if (this._rawItems[i].pid == index)
        {
            return this._rawItems.splice(i,1)[0];
        }
    }
    return false;
};
ripl.coreObjects._riplCollection.prototype.nextPage = function(evt)
{
    this.displayOptions.currentpagenumber++;
    this.render();
};
ripl.coreObjects._riplCollection.prototype.prevPage = function(evt)
{
    this.displayOptions.currentpagenumber--;
    this.render();
};
ripl.coreObjects._riplCollection.prototype._invalidateEvents = function()
{
    for (var i=0; i < this._rawItems.length; i++)
    {
        this._rawItems[i].eventOptions = this.eventOptions;
    }
};

ripl.coreObjects._riplCollection.prototype.setChildParameter = function(key,value)
{
    this.childParameters[key] = value;
    
    for (var i=0; i < this._rawItems.length; i++)
    {
        this._rawItems[i][key] = value;
    }    
};

ripl.coreObjects._riplCollection.prototype.setOnClick = function(closure)
{
    this.eventOptions.onclick=closure;
    this.eventsDirty = true;
};
ripl.coreObjects._riplCollection.prototype.setOnMouseover = function(closure)
{
    this.eventOptions.onmouseover=closure;
    this.eventsDirty = true;
};
ripl.coreObjects._riplCollection.prototype.setOnMouseout = function(closure)
{
    this.eventOptions.onmouseout=closure;
    this.eventsDirty = true;
};
ripl.coreObjects._riplCollection.prototype._sortByKey = function(arr,key) 
{
    if (arr.length == 0) { return arr; }
    if (typeof arr[0] != 'object') { return; }
    
    function sortNumeric(a,b) 
    {
        return a[key]-b[key];
    }
    function sortAlphabetic(a,b)
    {
        return (a[key] < b[key]) ? -1 : (a[key] > b[key]) ? 1 : 0;
    }
    switch (typeof arr[0][key])
    {
        case 'string':
            return arr.sort(sortAlphabetic);
        case 'number':
            return arr.sort(sortNumeric);
        case 'object':
        default:
        	if (arr[0][key] instanceof Date) return arr.sort(sortNumeric);
            return arr;
    }
};
ripl.coreObjects._riplCollection.prototype.setsortkey = function(sortkey, renderNow)
{
    this.displayOptions.sortkey = sortkey;
    this.sortDirty = true;
    if (renderNow) { this.render(); }
};
ripl.coreObjects._riplCollection.prototype.setsortreverse = function(sortreverse, renderNow)
{
    this.displayOptions.sortreverse = sortreverse;
    this.sortDirty = true;
    if (renderNow) { this.render(); }
};
ripl.coreObjects._riplCollection.prototype.toggleSortOrder = function(renderNow)
{
    this.displayOptions.sortreverse = !this.options.sortreverse;
    this.sortDirty = true;
    if (renderNow) { this.render(); }
};

ripl.coreObjects._riplCollection.prototype._sort = function()
{
    this._sortByKey(this._availableItems,this.displayOptions.sortkey);
//    this._availableItems = this._availableItems.sort(pSortFunction);
    if (this.displayOptions.sortreverse) {this._availableItems.reverse(); }
    this.dirty = false;    
    this.event.fire('sort');    
};
ripl.coreObjects._riplCollection.prototype.settargetstyle = function(e,newStyle,renderNow)
{
    this.displayOptions.targetstyle = newStyle;
    if (renderNow) { this.render(); }
    this.event.fire('targetstyle_change',newStyle);
};
ripl.coreObjects._riplCollection.prototype.render = function()
{
    if (this.dirty)
    {
        if (this._filterList) { this._filterList(); }
    }
    else if (this.sortDirty)
    {
        this._sort();
    }
    if (this.eventsDirty)
    {
        this._invalidateEvents();
    }
    if (ripl.renderers.collectionRenderers[this.displayOptions.targetstyle])
    {
        ripl.renderers.collectionRenderers[this.displayOptions.targetstyle](this);
    }
    else
    {
        ripl.renderers.collectionRenderers[this.defaultRenderStyle](this);
    }
    this.event.fire('render');    
};
ripl.coreObjects._riplCollection.prototype.parseString = function(string)
{
    var outString = string;
    var pLen = this._availableItems.length;
    outString = outString.replace('{{count}}', pLen);
    outString = outString.replace('{{friendlycount}}', (pLen==1) ? pLen + ' ' + this.friendlyType : pLen + ' ' + this.friendlyType + 's');
    if (outString.indexOf('|') > -1)
    {
        var outVar = outString.split('|');
        for (var i = 0; i < outVar.length; i++)
        {
            outVar[i] = '<span class="substring'+i+'">' + outVar[i] + '</span>';
        }
        outString = outVar.join('');
    }
    return outString;
};

ripl.coreObjects.content = {
        types:{},
        _typesDirty:true,
        _typesCache:null,
        addType:function(typeName)
        {
            this._typesDirty = true;
            this.types[typeName] = true;
        },
        getTypes:function()
        {
            if (!this._typesDirty) { return this._typesCache; }
            var retVal = [];
            for (var i in this.types)
            {
                retVal.push(i);
            }
            return retVal;
        }
    };
ripl.coreObjects.content.addType('Video');
ripl.coreObjects.content.addType('Music');
ripl.coreObjects.content.addType('Blog');
ripl.coreObjects.content.addType('Photo');

ripl.coreObjects.MixedList = function(displayOptions,childParameters,eventOptions)
{
    this._rawContent = new ripl.coreObjects.ContentList(displayOptions,childParameters,eventOptions);
    this._rawUsers = new ripl.coreObjects.UserList(displayOptions,childParameters,eventOptions);

    this._rawItems = [];
    
    this.displayOptions = ripl.coreObjects.OptionBuilder(ripl.coreObjects.clone(ripl.globalDefaults.ContentListOptions),displayOptions);
    this.childParameters = ripl.coreObjects.OptionBuilder({
            chain:ripl.enums.contentChains.NOT_LOGGED,
            referer:-1
        },childParameters);
    this.eventOptions =  ripl.coreObjects.OptionBuilder({
            onclick:null,
            onmouseover:null,
            onmouseout:null
        },eventOptions);         
    this.event = new ripl.events.eventManagerBase(this);   
};
ripl.coreObjects.extend(ripl.coreObjects._riplCollection.prototype, ripl.coreObjects.MixedList.prototype);
ripl.coreObjects.MixedList.prototype._filterList= function()
{
    this._availableItems = this._rawItems;
    this._sort();
};

ripl.coreObjects.MixedList.prototype.addItem = function(item)
{
    this._rawItems.push(item);    
}

ripl.coreObjects.MixedList.prototype.addContentObjects = function(inObjects)
{
    this._rawContent.referer = this.options.referer;
    this._rawContent.addObjects(inObjects);
}
ripl.coreObjects.MixedList.prototype.addUserObjects = function(inObjects)
{
    this._rawUsers.addObjects(inObjects);
}



ripl.coreObjects.ContentList = function(displayOptions,childParameters,eventOptions)
{
    this._rawItems = [];
    this._availableItems = [];

    this.objectPrototype = ripl.coreObjects.ContentItem;
    this.defaultRenderStyle = 'contentlist_default';
    this.friendlyType = 'item';
    
    this.dirty = true;
    this.sortDirty = true;
    this.eventsDirty=true;
    
    this.displayOptions = ripl.coreObjects.OptionBuilder(ripl.coreObjects.clone(ripl.globalDefaults.ContentListOptions),displayOptions);
    this.childParameters = ripl.coreObjects.OptionBuilder({
            chain:ripl.enums.contentChains.NOT_LOGGED,
            referer:-1
        },childParameters);
    this.eventOptions =  ripl.coreObjects.OptionBuilder({
            onclick:null,
            onmouseover:null,
            onmouseout:null
        },eventOptions);     
    
    this.event = new ripl.events.eventManagerBase(this);   
};
ripl.coreObjects.extend(ripl.coreObjects._riplCollection.prototype, ripl.coreObjects.ContentList.prototype);

ripl.coreObjects.ContentList.prototype.setChildOptions = function()
{
    for (var i = this._rawItems.length - 1; i >=0; i--)
    {
        this._rawItems.splice(i,1);
    }
};

// Override
ripl.coreObjects.ContentList.prototype.addItem = function(obj)
{
    if (!this._rawItems.ripl_InArrayKey(obj,'pid'))
    {
        for (var i in this.childParameters)
        {
            obj.displayOptions[i] = this.childParameters[i];
        }        
        this.dirty = true;
        obj.chain = this.displayOptions.chain;
        if (this.displayOptions.referer > -1) { obj.referer = this.options.referer; }

        this._rawItems.push(obj);
    }
};
ripl.coreObjects.ContentList.prototype.removeItemsByOwner = function(ownerId)
{
    this.dirty = true;
    for (var i = this._rawItems.length - 1; i >=0; i--)
    {
        if (this._rawItems[i].owner_id == ownerId)
        {
            this._rawItems.splice(i,1);
        }
    }
};
ripl.coreObjects.ContentList.prototype.getItemsByOwner = function(ownerId)
{
    var pRetVal = [];
    for (var i = this._rawItems.length - 1; i >=0; i--)
    {
        if (this._rawItems[i].owner_id == ownerId)
        {
            pRetVal.push(this._rawItems[i]);
        }
    }
    return pRetVal;
};
ripl.coreObjects.ContentList.prototype._filterList = function()
{
    var retList = [];
    for (var i = 0; i < this._rawItems.length; i++)
    {
        var pItem = this._rawItems[i];
        if (this.displayOptions.typeFilters.ripl_InArraySubstring(pItem.base_type)) { retList.push(pItem); }
    }
    this._availableItems = retList;
    this.dirty = false;
    this._sort();
};

ripl.coreObjects.ContentList.prototype.setTypeFilters = function(typeFilters, renderNow)
{
    this.displayOptions.typeFilters = typeFilters;
    this.dirty = true;
    if (renderNow) { this.render(); }
    this.event.fire('typeFilters_change',typeFilters);    
};



ripl.coreObjects.EventList = function(displayOptions,childParameters,eventOptions)
{
    this._rawItems = [];
    this._availableItems = [];
    
    this._contentItems = new ripl.coreObjects.ContentList(displayOptions,childParameters,eventOptions);
    this._userItems = new ripl.coreObjects.UserList(displayOptions,childParameters,eventOptions);
    
    this.objectPrototype = ripl.coreObjects.EventItem;
    this.defaultRenderStyle = 'eventlist_default';

    this.dirty = true;
    this.sortDirty = true;
    this.eventsDirty=true;
    
    this.displayOptions = ripl.coreObjects.OptionBuilder(ripl.coreObjects.clone(ripl.globalDefaults.EventListOptions),displayOptions);
    this.childParameters = ripl.coreObjects.OptionBuilder({
    },childParameters);    
    this.eventOptions =  ripl.coreObjects.OptionBuilder({
            onclick:null,
            onmouseover:null,
            onmouseout:null
        },eventOptions);     
    
    this.event = new ripl.events.eventManagerBase(this);       
}
ripl.coreObjects.extend(ripl.coreObjects._riplCollection.prototype, ripl.coreObjects.EventList.prototype);
ripl.coreObjects.EventList.prototype._filterList= function()
{
    this._availableItems = this._rawItems;
    for (var i = 0; i < this._availableItems.length; i++)
    {
        this._availableItems[i].linkObjects(this._userItems,this._contentItems);
    }
    this._sort();
};

ripl.coreObjects.UserList = function(displayOptions,childParameters,eventOptions)
{
    this._rawItems = [];
    this._availableItems = [];

    this.objectPrototype = ripl.coreObjects.User;
    this.defaultRenderStyle = 'userlist_default';
    this.friendlyType = 'user';
    this.dirty = true;
    this.sortDirty = true;
    this.eventsDirty=true;
    
    this.displayOptions = ripl.coreObjects.OptionBuilder(ripl.coreObjects.clone(ripl.globalDefaults.UserListOptions),displayOptions);
    this.childParameters = ripl.coreObjects.OptionBuilder({
        showfollow:true,
        showname:false
    },childParameters);    
    this.eventOptions =  ripl.coreObjects.OptionBuilder({
            onclick:null,
            onmouseover:null,
            onmouseout:null
        },eventOptions);     
    
    this.event = new ripl.events.eventManagerBase(this);   
};
ripl.coreObjects.extend(ripl.coreObjects._riplCollection.prototype, ripl.coreObjects.UserList.prototype);

ripl.coreObjects.UserList.prototype._filterList= function()
{
    this._availableItems = this._rawItems;
    this._sort();
};


ripl.coreObjects.CommentList = function(displayOptions, childParameters, eventOptions)
{

    this._rawItems = [];
    this._availableItems = [];
    
    this._users = new ripl.coreObjects.UserList();
    
    this.objectPrototype = ripl.coreObjects.Comment;
    this.defaultRenderStyle = 'commentlist_default';
    this.friendlyType = 'comment';    
    this.dirty = true;
    this.sortDirty = true;
    this.eventsDirty=true;
    
    this.displayOptions = ripl.coreObjects.OptionBuilder(ripl.coreObjects.clone(ripl.globalDefaults.CommentListOptions),displayOptions);
    this.childParameters = ripl.coreObjects.OptionBuilder({
        showfollow:true,
        showname:false
    },childParameters);    
    this.eventOptions =  ripl.coreObjects.OptionBuilder({
            onclick:null,
            onmouseover:null,
            onmouseout:null
        },eventOptions);     
    
    this.event = new ripl.events.eventManagerBase(this);   
    
    
}
ripl.coreObjects.extend(ripl.coreObjects._riplCollection.prototype, ripl.coreObjects.CommentList.prototype);

ripl.coreObjects.CommentList.prototype._filterList= function()
{
    this._availableItems = this._rawItems;
    this._sort();
};
ripl.coreObjects.CommentList.prototype.addUsers = function(userObjects)
{
    this._users.addObjects(userObjects);
}
ripl.coreObjects.CommentList.prototype.link = function()
{
    for (var i = 0; i < this._rawItems.length; i++)
    {
        this._rawItems[i].linkObjects(this._users);
    }
}

ripl.coreObjects.Comment = function(objectData,displayOptions,eventOptions)
{
    this.pid = objectData.pid;
    this.related_item_id = objectData.related_item_id;
    this.related_item_type = objectData.related_item_type;
    this.senderId = objectData.senderId;
    this.message = objectData.message;
    this.post_date = new Date(objectData.post_date);

    this.displayOptions = ripl.coreObjects.OptionBuilder({},displayOptions);
    this.eventOptions =  ripl.coreObjects.OptionBuilder({onclick:null,onmouseover:null,onmouseout:null},eventOptions);     

    this.event = new ripl.events.eventManagerBase(this); 
}
ripl.coreObjects.extend(ripl.coreObjects._riplDisplayObject.prototype, ripl.coreObjects.Comment.prototype);

ripl.coreObjects.Comment.prototype.linkObjects = function(userList)
{
    this.senderObject = new ripl.coreObjects.User(userList.getItemById(this.senderId),this.displayOptions,this.eventOptions,this.eventOptions);
}

ripl.coreObjects.Comment.prototype.getStandardDomObj = function()
{
    if (!this.senderObject) return;
    var pContainer = $ripl.create('div',{className:'ripl_comment_container', style:'border-bottom:1px solid #555555'});

    var pLink = this.senderObject.getAnchor();
    var pThumb = $ripl.create('img',{src:this.senderObject.getAvatarUrl(),className:'ripl_user_renderer ripl_user_renderer_inline'});
    
    pLink.add(pThumb);
    pContainer.add(pLink);
     

     var pSpan = $ripl.create('span',{className:'ripl_comment_body ripl_colors_normal'},
            this.message + '<br /><span class="ripl_small_date ripl_colors_deemphasis">' + this.post_date.ripl_formatSince() + ' by <a href="'+this.senderObject.getLink()+'">' + this.senderObject.displayName + '</a></span>'
        );
    
    return pContainer.add(pSpan);
};

ripl.coreObjects.HtmlObject = function(inHtml,displayOptions)
{
    this.html = inHtml;
    this.defaultRenderStyle = 'html_default';
    this.displayOptions = ripl.coreObjects.OptionBuilder({
        showname:false,
        showfollow:true
    },displayOptions);
    this.event = new ripl.events.eventManagerBase(this); 
}
ripl.coreObjects.HtmlObject.prototype.render = function()
{
    ripl.renderers.collectionRenderers[this.defaultRenderStyle](this);
    this.event.fire('render'); 
}

ripl.coreObjects.User = function(objectData,displayOptions,eventOptions)
{
    this.pid = (objectData.pid) ? objectData.pid : parseInt(objectData.uid,10);
    this.login = objectData.login;
    this.displayName = (objectData.displayName) ? objectData.displayName : '';
    this.avatarurl = objectData.avatarurl;
    this.following = objectData.following;
    this.isCurrent = objectData.isCurrent;
    this.location = objectData.location;
    this.userType = (objectData.userType) ? objectData.userType : 'normal';
    this.fanindex = (objectData.fanindex != null) ? parseInt(objectData.fanindex,10) : -1;
    this.rank= (objectData.rank != null) ? parseInt(objectData.rank,10) : -1;
// begin: requires detail level of 3.
    if (objectData.joindate)  this.joindate = new Date(objectData.joindate*1000);
    this.friendscore = (objectData.friendscore != null) ? parseFloat(objectData.friendscore) : 0;
    this.age = objectData.age;
    this.gender = objectData.gender;
    this.followerCount = objectData.followerCount;
    this.itemCount = objectData.itemCount;
 // end: requires detail level of 3.
    
    this.referralCount = -1;
    this.objectType = 'User';
    this.domObj = null;
    this.domContainer = null;
    this.displayOptions = ripl.coreObjects.OptionBuilder({
            showname:false,
            showfollow:true,
            showvisit:true
        },displayOptions);
    this.eventOptions =  ripl.coreObjects.OptionBuilder({
        onclick:null,
        onmouseover:null,
        onmouseout:null
    },eventOptions);     
    
    this.event = new ripl.events.eventManagerBase(this);
};
ripl.coreObjects.extend(ripl.coreObjects._riplDisplayObject.prototype, ripl.coreObjects.User.prototype);


ripl.coreObjects.User.prototype.toggleFollow = function()
{
    if (ripl.auth.isAuthed())
    {
        if (this.following)
        {
            ripl.service.methods.ripl.relationships.removeFollow.call({target_user:this.pid, callback:'ripl.service.nullHandler' });
        }
        else
        {
            ripl.service.methods.ripl.relationships.addFollow.call({target_user:this.pid, callback:'ripl.service.nullHandler' });
        }
        
        this.following = !this.following;
        this.writeInnerDomObj(this.domObj);
                
    }else{
    	// set post auth
    	ripl.auth.postAuth = this.toggleFollow.createDelegate(this);
    	// show auth
    	ripl.showLogin();
    }   
};

ripl.coreObjects.User.prototype.getLink = function()
{
    //!
    return ripl.environment.site + this.login;
};
ripl.coreObjects.User.prototype.toString = function()
{
    return this.displayName;
};

ripl.coreObjects.User.prototype.getAvatarUrl = function()
{
//    var pImageRef = ripl.environment.ugcBase;
    return this.avatarurl;    
};

ripl.coreObjects.User.prototype.getFrameClassname = function()
{
    switch (this.userType)
    {
        case 'artist':
            return 'ripl_avatar_artistFrame';
        case 'system':
            return 'ripl_avatar_userFrame';
        default:
            return 'ripl_avatar_userFrame';    
    }
};

ripl.coreObjects.User.prototype.getGenericLinkText = function()
{
    var pValue;
    switch (this.userType)
    {
        case 'artist':
            pValue = 'visit artist profile';
            break;
        case 'system':
            pValue = 'visit content profile';
            break;
        default:
            pValue = 'visit user profile';
    }
    if (this.userType == 'artist') { pValue = 'visit artist profile'; }
    return pValue;
};
ripl.coreObjects.User.prototype.getTile = function(inClickHandler,inOverHandler,inOutHandler)
{
    var pCell = $ripl.create('td');// new Element('td');
    var pCell2 = $ripl.create('td',{'className':'th_userTileText'},this.displayName);// new Element('td',{className:'th_userTileText'});
    var pRow =  $ripl.create('tr');//new Element('tr');
    var pBody =  $ripl.create('tBody');//.insert(pRow);//new Element('tr');
    var pTable = $ripl.create('table');//.insert(pBody);

    pTable.add(pBody);
    pBody.add(pRow);

    pCell.add(this.getUserDomObj(inClickHandler,inOverHandler,inOutHandler));
    pRow.add([pCell, pCell2]);
    return pTable;
};

ripl.coreObjects.User.prototype.getFrameUrl = function()
{
    var pImageRef = ripl.environment.imageBase;
    if (this.fanindex > -1)
    {
        pImageRef += 'userFrames/superfan_' + (this.fanindex +1);
    }
    else
    {
        switch (this.userType)
        {
            case 'artist':
                pImageRef += 'userFrames/userFrame_artist.png';
                break;
            case 'system':
                pImageRef += 'userFrames/ripl_content.png';                
                break;
            default:
                pImageRef += 'userFrames/userFrame_ripl.png';                
        }
    }
    return pImageRef;    
};

ripl.coreObjects.User.prototype.writeInnerDomObj=function(container)
{
    var pHref1, pHref2;
    pHref1 = this.getAnchor();
    pHref2 = this.getAnchor();
    var pChildren = [];
    var pImage = $ripl.create('img',{
            className:'ripl_th_user_image',
            style:'background-image:url(' + this.getAvatarUrl() + ')',
            src:this.getFrameUrl()
        });
    pHref1.add(pImage);
    pChildren.push(pHref1);

    if (this.displayOptions.showfollow)
    {
        var followClass = 'ripl_btnFollow';
        if (this.following)
        {
            followClass = 'ripl_btnUnFollow';
        }
        if (this.isCurrent) { followClass = 'ripl_btnFollowSpacer'; }
        followClass += ' ripl_toggleFollow_'+this.pid;

        var pFollow = $ripl.create('div',{className:followClass});
        pFollow.listen('click', this.toggleFollow, this);
        pChildren.push(pFollow);
    }
    var dispName = $ripl.create('span',{
                    className:'displayName',
                    style:'display:'+((this.displayOptions.showname)?'auto':'none')},
                    this.displayName
        );
    pChildren.push(dispName);
    container.update(pChildren);
}

ripl.coreObjects.User.prototype.getStandardDomObj = function()
{
    var pDiv = $ripl.create('div',{className:'ripl_th_user_container'});
    this.writeInnerDomObj(pDiv);
    this.domObj = pDiv;
    return pDiv;
};

ripl.coreObjects.User.prototype.getWideDomObj = function()
{
    var pContainer, pAvatar, pFrame, pTextInfo, pTitle, pUserInfo, pJoinInfo, pPopularity, pInteractions, pProfileButton, pFollowButton, pAnchor, pClickOverlay;
    
    pContainer = $ripl.create('div',{className:'ripl_usercard'});
    pAvatar = $ripl.create('div',{className:'ripl_avatar', style:'background-image:url('+this.getAvatarUrl()+')'});
    pFrame = $ripl.create('div',{className:'ripl_framewide'});
    pTextInfo = $ripl.create('div',{className:'ripl_usercard_textinfo'});

    pTitle = $ripl.create('div',{className:'ripl_usertitle'}, this.displayName);
    
    if ((this.userType != 'artist') && (this.userType != 'system'))
    {
        pUserInfo = $ripl.create('div',{className:'ripl_userinfo'}, this.gender + ', ' + this.age + ' | ' + this.location);
    }
    if (this.userType != 'system')
    {
        pJoinInfo = $ripl.create('div',{className:'ripl_joininfo'}, 'joined ' + this.joindate.ripl_formatSimple(true));
    }
    pPopularity = $ripl.create('div',{className:'ripl_userpopularity'}, this.followerCount + ' followers | ' + this.itemCount + ' items added');
    
    pInteractions = $ripl.create('div',{className:'ripl_userinteractions'});
    
    if (this.displayOptions.showvisit)
    {
    	pProfileButton = $ripl.create('input',{className:'ripl_userbuttons', value:'visit profile', type:'button'});
    	pProfileButton.listen('click', function(){location.href=this.getLink();},this);        
    }
    if ((!this.isCurrent) && (this.displayOptions.showfollow))
    {
    	if (!this.following)
    	{
    		pFollowButton = $ripl.create('input',{className:'ripl_userbuttons', value:'follow', type:'button'});
    		pFollowButton.listen('click', this.toggleFollowEx, this);
    	}
    	else
    	{
    		pFollowButton = $ripl.create('input',{className:'ripl_userbuttons', value:'unfollow', type:'button'});
    		pFollowButton.listen('click', this.toggleFollowEx, this);
    	}
    }
    
    pAnchor = this.getAnchor();
    pClickOverlay = $ripl.create('img',{className:'ripl_frame_overlay', src:ripl.environment.imageBase + "blank.gif"});
    
    pAnchor.add(pClickOverlay);
    
    
    pTextInfo.add([pTitle, pUserInfo, pJoinInfo, pPopularity]);
    pInteractions.add([pProfileButton, pFollowButton]);
    pContainer.add([pAvatar, pFrame, pTextInfo, pInteractions, pAnchor]);
    
    return pContainer;
}
ripl.coreObjects.User.prototype.toggleFollowEx = function(e,item)
{
    if (ripl.auth.isAuthed())
    {
        if (this.following)
        {
            ripl.service.methods.ripl.relationships.removeFollow.call({target_user:this.pid, callback:'ripl.service.nullHandler' });
        }
        else
        {
            ripl.service.methods.ripl.relationships.addFollow.call({target_user:this.pid, callback:'ripl.service.nullHandler' });
        }
        
        this.following = !this.following;
        if (e.currentTarget)
        {
        	if (this.following) e.currentTarget.value='unfollow';
        	else e.currentTarget.value='follow';
        }
//        this.writeInnerDomObj(this.domObj);
                
    }else{
    	// set post auth
    	ripl.auth.postAuth = this.toggleFollow.createDelegate(this);
    	// show auth
    	ripl.showLogin();
    }   
};



ripl.coreObjects.EventItem = function(objectData,displayOptions,eventOptions)
{
    this.objectType = 'EventItem';
    
    this.eventType = objectData.item_type;
    this.contentObject = null;
    this.actorObject = null;
    this.ownerObject = null;
    this.relevantUser = null;
    
    this.pid = objectData.action_time+'_'+objectData.actor_id+'_'+objectData.content_id;
    this.actionTime = new Date(parseInt(objectData.action_time,10)*1000);
    this.actionType = objectData.action_type;
    this.contentId = parseInt(objectData.content_id);
//    this.ownerId = jsonObj['owner_id'];
    this.actorId = parseInt(objectData.actor_id);
    this.ownerId = parseInt(objectData.owner_id);
    
    this.count = objectData.item_count;
    this.rating = objectData.rating;
    this.domObj = null;
    
    this.domContainer = null;
    this.displayOptions = ripl.coreObjects.OptionBuilder({
            showname:false,
            showfollow:true
        },displayOptions);
    this.eventOptions =  ripl.coreObjects.OptionBuilder({
        onclick:null,
        onmouseover:null,
        onmouseout:null
    },eventOptions);
    
    this.intialized = false;
    
    this.event = new ripl.events.eventManagerBase(this);
    
//!    this.chain = ContentChains.NOT_LOGGED;    
};
ripl.coreObjects.extend(ripl.coreObjects._riplDisplayObject.prototype, ripl.coreObjects.EventItem.prototype);

ripl.coreObjects.EventItem.riplEventTypes = {
        'added':'/images/action_add.png', 
        'favorited':'/images/action_favorite.png', 
        'rated':'/images/action_rate.png',
        'commented':'/images/action_comment.png', 
        'shared':'/images/action_share.png', 
        'tagged':'/images/action_tag.png' 
    };
ripl.coreObjects.EventItem.prototype.linkObjects = function(userList,contentList)
{
    this.actorObject = new ripl.coreObjects.User(userList.getItemById(this.actorId),this.displayOptions,this.eventOptions);
    this.ownerObject = new ripl.coreObjects.User(userList.getItemById(this.ownerId),this.displayOptions,this.eventOptions);
    this.contentObject = new ripl.coreObjects.ContentItem(contentList.getItemById(this.contentId),this.displayOptions,this.eventOptions);
}


ripl.coreObjects.EventItem.prototype.toString = function()
{
    //!
    return '';
//    return this.title;
};

ripl.coreObjects.ContentItem = function(objectData,displayOptions,eventOptions)
{
    this.pid = parseInt(objectData.pid,10);
    this.base_type = objectData.base_type;
//!!
    //    this.chain = ContentChains.NOT_LOGGED;
    this.title = objectData.title ? objectData.title.replace(/\\/g,'') : 'Untitled';
    this.artist = (objectData.artist != undefined) ?  objectData.artist.replace(/\\/g,'') : '';
    this.album = (objectData.album != undefined) ?  objectData.album.replace(/\\/g,'') : '';
    this.description = (objectData.description != undefined) ?  objectData.description.replace(/\\/g,'') : '';
    this.thumbnail_image_url = (objectData.thumbnail_image_url != undefined) ? objectData.thumbnail_image_url : ripl.environment.imageBase + '/music/no_art.gif';
    
    this.preview_image_url = objectData.preview_image_url;
    this.provider_id = objectData.provider_id;
    this.updated = new Date(parseInt(objectData.updated)*1000);
    this.foreign_provider_guid = objectData.foreign_provider_guid;
    this.content_location_url = objectData.content_location_url;
    this.owner_id = parseInt(objectData.owner_id,10);
    this.rating = (objectData.rating!=null) ? parseFloat(objectData.rating) : -1; 
    this.rank = (objectData.rank != null) ? parseInt(objectData.rank,10) : -1;
    
    this.riplscore = (objectData.riplscore != null) ? parseFloat(objectData.riplscore) : 0;
    this.friendscore = (objectData.friendscore != null) ? parseFloat(objectData.friendscore) : 0;
    this.aggregatescore = this.riplscore + this.friendscore;
    
    this.play_count = parseInt(objectData.play_count,10);
    if (objectData.last_play)  this.last_play = new Date(objectData.last_play*1000);        
        
    if (objectData.count)
    {
        this.count = parseInt(objectData.count,10);
    }
    else
    {
        this.count = ripl.coreObjects.ContentItem.serial;
        ripl.coreObjects.ContentItem.serial++;
    }
    
    this.referer = this.owner_id;
//!
    //this.loc = 'content_detail';
    this.item_count = parseInt(objectData.item_count,10);
    this.last_update = objectData.updated;
    this.domObj = null;
    this.domContainer = null;
    this.objectType ='ContentItem';
    this.displayOptions = ripl.coreObjects.OptionBuilder({
        showname:false,
        showfollow:true
    },displayOptions);

    this.eventOptions =  ripl.coreObjects.OptionBuilder({
        onclick:null,
        onmouseover:null,
        onmouseout:null
    },eventOptions); 
    
    this.event = new ripl.events.eventManagerBase(this);   
};
ripl.coreObjects.extend(ripl.coreObjects._riplDisplayObject.prototype, ripl.coreObjects.ContentItem.prototype);

ripl.coreObjects.ContentItem.serial = 0;
ripl.coreObjects.ContentItem.prototype.getGenericLinkText = function()
{
    var pValue = 'view content item';
    switch (this.base_type)
    {
        case 'video':
            pValue = 'watch video';
            break;
    }
    return pValue;
};

ripl.coreObjects.ContentItem.prototype.getThumbnailImage = function()
{
    var pRenderInfo = ripl.renderers.getContentThumbnailRenderer(this);
    var pThumbUrl = (this.thumbnail_image_url) ? this.thumbnail_image_url : pRenderInfo.noThumbnail;
    var pImg = $ripl.create("img",{
            className:pRenderInfo.cssClass,
            src:ripl.environment.imageBase + pRenderInfo.foregroundImage,
            style:'background-image:url('+pThumbUrl+')'
        });
    return pImg;
};
ripl.coreObjects.ContentItem.prototype.getStandardDomObj = function()
{
	var pImg = this.getThumbnailImage();
    var pA = this.getAnchor().add(pImg);
    this.domObj = pA;
    return pA;
};
ripl.coreObjects.ContentItem.prototype.getLink= function()
{
    return ripl.environment.site + '/contentDetailView.php?contentid=' + this.pid;
};


ripl.coreObjects.ContentItem.prototype.toString = function()
{
    return this.title;
};
ripl.coreObjects.ContentItem.prototype.getFriendlyUpdateTime = function()
{
    return new Date(this.last_update * 1000).ripl_format(Date.ripl_TIME_SINCE);
};
ripl.coreObjects.ContentItem.prototype.getStandardUpdateTime = function()
{
    return new Date(this.last_update * 1000).ripl_format(Date.ripl_SIMPLETIME);
};

ripl.service = {
    apikey:'ripl',
    nullHandler:function(){},
    
    autoRender:true,
    _callSerial:0,
    getSerial:function()
    {
        ripl.service._callSerial++;
        return ripl.service._callSerial;
    },
    _craftUrl:function(methodName,params,ssl)
    {
        var pString = (ssl ? ripl.environment.endpoint.replace("http:","https:") : ripl.environment.endpoint) + '?method=' + methodName;
        for (var key in params)
        {
            if (key =='api_key' && methodName!="ripl.auth.login") { continue; }
            if (key =='token') { continue; }
            pString += '&' + key + '=' + params[key];
        }        
        
        if (ripl.service.apikey) { pString += '&api_key=' + ripl.service.apikey; }
        if (ripl.auth.token) { pString += '&token=' + ripl.auth.token; }

        return pString;
    },
    _methodBase:function(response,relevant,target,content,signed,additionalParameters,implemented,ssl)
    {
        this.responseType = response;
        this.requireRelevant = relevant;
        this.requireTarget = target;
        this.requireContent = content;
        this.requireSigned = signed;
        this.additionalParameters = (additionalParameters) ? additionalParameters : [];
        this.implemented = (!implemented) ? false : true;      
        this.name = '';
        this.call = function(params,displayOptions,childDisplayOptions,eventOptions)
        {
            var pSerial = ripl.service.getSerial();
            params.serial = pSerial;
//            if (ripl.auth.token) params.token = ripl.auth.token;
            if (!params.callback) { params.callback = ripl.service.getDefaultCallback(this); }
            var pUrl =  ripl.service._craftUrl(this.name,params,ssl);

            ripl.service.callCache[pSerial] = {'params':params,'displayOptions':displayOptions,'childDisplayOptions':childDisplayOptions,'eventOptions':eventOptions};

            ripl.dataservices.getJSONP(pUrl);
        };
    },
    callCache:[],
    methods:{},
    getDefaultCallback:function(methodInfo,returnClosure)
    {
        switch(methodInfo.responseType)
        {
            case ripl.enums.API_RESPONSE_CONTENTLIST:
                if (returnClosure) return ripl.apiHandler.renderContentList;
                else return 'ripl.apiHandler.renderContentList';
            case ripl.enums.API_RESPONSE_USERLIST:
                if (returnClosure) return ripl.apiHandler.renderUserList;
                else return 'ripl.apiHandler.renderUserList';
            case ripl.enums.API_RESPONSE_EVENTLIST:
                if (returnClosure) return ripl.apiHandler.renderEventList;
                else return 'ripl.apiHandler.renderEventList';
            case ripl.enums.API_RESPONSE_COMMENTSLIST:
                if (returnClosure) return ripl.apiHandler.renderCommentList;
                else return 'ripl.apiHandler.renderCommentList';
            case ripl.enums.API_RESPONSE_HTML:
                if (returnClosure) return ripl.apiHandler.renderHTML;
                else return 'ripl.apiHandler.renderHTML';                
        }
    },
    _methodHash:{},
    getMethodByKey:function(key)
    {
        return ripl.service._methodHash[key];
    },
    addMethod:function(root,group,name,methodinfo)
    {
        if (!ripl.service.methods[root]) { ripl.service.methods[root] = {}; }
        if (!ripl.service.methods[root][group]) { ripl.service.methods[root][group] = {}; }
        methodinfo.name = root + '.' + group + '.' + name;
        ripl.service.methods[root][group][name] = methodinfo;
        ripl.service._methodHash[root+'.'+group+'.'+name] = methodinfo;
    },
    getOwnedContent:function _ripl_service_getMyContent(userId,callback_name)
    {
//DEPRECATED
        if (!callback_name) { callback_name = 'ripl.apiHandler.renderContentList'; }
        var parameters = {target_user:userId,callback:callback_name};
        
        var pUrl = ripl.service._craftUrl('ripl.user.getOwnedContent',parameters);
        ripl.dataservices.getJSONP(pUrl);
    },
    getNapsterId:function(contentItem,callback_name)
    {
        var parameters = {service_key:'napster',content_id:contentItem.pid,callback:callback_name};
        var pUrl = ripl.service._craftUrl('ripl.content.getforeignid',parameters);
        ripl.dataservices.getJSONP(pUrl);
    },
    checkToken:function(token,callback)
    {
//DEPRECATED
        var parameters = {'callback':callback};
        var pUrl = ripl.service._craftUrl('ripl.auth.checkToken',parameters);
        ripl.dataservices.getJSONP(pUrl);
    }
};
$$ripl = ripl.service;
$$ripl.addMethod('ripl','auth','login',new $$ripl._methodBase(ripl.enums.API_RESPONSE_AUTHINFO,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_DISALLOWED,false,false,false,true));
$$ripl.addMethod('ripl','auth','fromForeignToken',new $$ripl._methodBase(ripl.enums.API_RESPONSE_AUTHINFO,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_DISALLOWED,false,false,false,true));
$$ripl.addMethod('ripl','user','forgotAuth',new $$ripl._methodBase(ripl.enums.API_RESPONSE_SUCCESS,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_DISALLOWED,false,false,false,true));
$$ripl.addMethod('ripl','user','getInfo',new $$ripl._methodBase(ripl.enums.API_RESPONSE_USERITEM,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','user','getFollowers',new $$ripl._methodBase(ripl.enums.API_RESPONSE_USERLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','user','getFollowings',new $$ripl._methodBase(ripl.enums.API_RESPONSE_USERLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','user','getSuperFans',new $$ripl._methodBase(ripl.enums.API_RESPONSE_USERLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','user','getOwnedContent',new $$ripl._methodBase(ripl.enums.API_RESPONSE_CONTENTLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','user','getPlayedContent',new $$ripl._methodBase(ripl.enums.API_RESPONSE_CONTENTLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','user','getFavoriteContent',new $$ripl._methodBase(ripl.enums.API_RESPONSE_CONTENTLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','user','getRecommendContent',new $$ripl._methodBase(ripl.enums.API_RESPONSE_CONTENTLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','user','getTags',new $$ripl._methodBase(ripl.enums.API_RESPONSE_ARRAY,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','user','getTagCloud',new $$ripl._methodBase(ripl.enums.API_RESPONSE_HTML,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','user','getTagMatchedUsers',new $$ripl._methodBase(ripl.enums.API_RESPONSE_USERLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','user','getTagMatchedContent',new $$ripl._methodBase(ripl.enums.API_RESPONSE_CONTENTLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','user','getHighestRatingsMatchedContent',new $$ripl._methodBase(ripl.enums.API_RESPONSE_CONTENTLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','user','getRecentActivities',new $$ripl._methodBase(ripl.enums.API_RESPONSE_EVENTLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','user','getRecentContentActivity',new $$ripl._methodBase(ripl.enums.API_RESPONSE_EVENTLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','user','getComments',new $$ripl._methodBase(ripl.enums.API_RESPONSE_COMMENTSLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','content','addTags',new $$ripl._methodBase(ripl.enums.API_RESPONSE_SUCCESS,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_REQUIRED,true));
$$ripl.addMethod('ripl','content','removeTags',new $$ripl._methodBase(ripl.enums.API_RESPONSE_SUCCESS,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_REQUIRED,true));
$$ripl.addMethod('ripl','content','addComment',new $$ripl._methodBase(ripl.enums.API_RESPONSE_SUCCESS,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_REQUIRED,true));
$$ripl.addMethod('ripl','content','removeComment',new $$ripl._methodBase(ripl.enums.API_RESPONSE_SUCCESS,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_DISALLOWED,true));
$$ripl.addMethod('ripl','content','setRating',new $$ripl._methodBase(ripl.enums.API_RESPONSE_SUCCESS,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_REQUIRED,true));
$$ripl.addMethod('ripl','content','addToFavorites',new $$ripl._methodBase(ripl.enums.API_RESPONSE_SUCCESS,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_REQUIRED,true));
$$ripl.addMethod('ripl','content','removeFromFavorites',new $$ripl._methodBase(ripl.enums.API_RESPONSE_SUCCESS,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_REQUIRED,true));
$$ripl.addMethod('ripl','content','watch',new $$ripl._methodBase(ripl.enums.API_RESPONSE_SUCCESS,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_REQUIRED,true));
$$ripl.addMethod('ripl','content','getInfo',new $$ripl._methodBase(ripl.enums.API_RESPONSE_CONTENTITEM,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_REQUIRED,false));
$$ripl.addMethod('ripl','content','getAlbum',new $$ripl._methodBase(ripl.enums.API_RESPONSE_CONTENTLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_REQUIRED,false));
$$ripl.addMethod('ripl','content','getSimilarContent',new $$ripl._methodBase(ripl.enums.API_RESPONSE_CONTENTLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_REQUIRED,false));
$$ripl.addMethod('ripl','content','getTagMatchedContent',new $$ripl._methodBase(ripl.enums.API_RESPONSE_CONTENTLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_REQUIRED,false));
$$ripl.addMethod('ripl','content','getTagMatchedUsers',new $$ripl._methodBase(ripl.enums.API_RESPONSE_USERLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_REQUIRED,false));
$$ripl.addMethod('ripl','content','getTags',new $$ripl._methodBase(ripl.enums.API_RESPONSE_RATINGSTREE,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_REQUIRED,false));
$$ripl.addMethod('ripl','content','getTagCloud',new $$ripl._methodBase(ripl.enums.API_RESPONSE_ARRAY,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_REQUIRED,false));
$$ripl.addMethod('ripl','content','getRatings',new $$ripl._methodBase(ripl.enums.API_RESPONSE_INDEXCONTENTLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_REQUIRED,false));
$$ripl.addMethod('ripl','content','getComments',new $$ripl._methodBase(ripl.enums.API_RESPONSE_COMMENTSLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_REQUIRED,false));
$$ripl.addMethod('ripl','content','getFavorited',new $$ripl._methodBase(ripl.enums.API_RESPONSE_USERLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_REQUIRED,false));
$$ripl.addMethod('ripl','content','getSimilarUsers',new $$ripl._methodBase(ripl.enums.API_RESPONSE_USERLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_REQUIRED,false));
$$ripl.addMethod('ripl','content','getRecentViewers',new $$ripl._methodBase(ripl.enums.API_RESPONSE_USERLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_REQUIRED,false));
$$ripl.addMethod('ripl','content','getRecentActivity',new $$ripl._methodBase(ripl.enums.API_RESPONSE_EVENTLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_REQUIRED,false));
$$ripl.addMethod('ripl','relationships','getBlocks',new $$ripl._methodBase(ripl.enums.API_RESPONSE_BOOLEAN,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','relationships','getFollows',new $$ripl._methodBase(ripl.enums.API_RESPONSE_BOOLEAN,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','relationships','getFollowedBy',new $$ripl._methodBase(ripl.enums.API_RESPONSE_BOOLEAN,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','relationships','setBlocks',new $$ripl._methodBase(ripl.enums.API_RESPONSE_SUCCESS,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,true));
$$ripl.addMethod('ripl','relationships','addFollow',new $$ripl._methodBase(ripl.enums.API_RESPONSE_SUCCESS,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,true));
$$ripl.addMethod('ripl','relationships','removeFollow',new $$ripl._methodBase(ripl.enums.API_RESPONSE_SUCCESS,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,true));
$$ripl.addMethod('ripl','relationships','addComment',new $$ripl._methodBase(ripl.enums.API_RESPONSE_SUCCESS,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_DISALLOWED,true));
$$ripl.addMethod('ripl','relationships','removeComment',new $$ripl._methodBase(ripl.enums.API_RESPONSE_SUCCESS,ripl.enums.API_USAGE_REQUIRED,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_OPTIONAL,true));
$$ripl.addMethod('ripl','charts','getTopTags',new $$ripl._methodBase(ripl.enums.API_RESPONSE_RATINGSTREE,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','charts','getTopTagsCloud',new $$ripl._methodBase(ripl.enums.API_RESPONSE_ARRAY,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','charts','getMostPlayed',new $$ripl._methodBase(ripl.enums.API_RESPONSE_CONTENTLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','charts','getMostShared',new $$ripl._methodBase(ripl.enums.API_RESPONSE_CONTENTLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','charts','getMostFavorited',new $$ripl._methodBase(ripl.enums.API_RESPONSE_CONTENTLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','charts','getMostCommented',new $$ripl._methodBase(ripl.enums.API_RESPONSE_CONTENTLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','charts','getHighestRated',new $$ripl._methodBase(ripl.enums.API_RESPONSE_CONTENTLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','people','findByLogin',new $$ripl._methodBase(ripl.enums.API_RESPONSE_USERLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','people','findByName',new $$ripl._methodBase(ripl.enums.API_RESPONSE_USERLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','people','findByEmail',new $$ripl._methodBase(ripl.enums.API_RESPONSE_USERLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','people','findByDisplayName',new $$ripl._methodBase(ripl.enums.API_RESPONSE_USERLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','people','findByDistance',new $$ripl._methodBase(ripl.enums.API_RESPONSE_USERLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_DISALLOWED,false));
$$ripl.addMethod('ripl','people','findByForeignId',new $$ripl._methodBase(ripl.enums.API_RESPONSE_USERLIST,ripl.enums.API_USAGE_OPTIONAL,ripl.enums.API_USAGE_DISALLOWED,ripl.enums.API_USAGE_DISALLOWED,false));



ripl.apiHandler = {
    next:null,
    standardListOptions:{itemsperpage:9},
    renderContentList:function _ripl_apiHandler_renderContentList(data)
    {
        if (data.error) return;
        var pCallDetails = ripl.service.callCache[parseInt(data.serial,10)];
        var pData = new ripl.coreObjects.ContentList(pCallDetails.displayOptions,pCallDetails.childDisplayOptions, pCallDetails.eventOptions);

        ripl.cache.content.addObjects(data.contentItems);
        pData.addObjects(data.contentItems);
        if (ripl.service.autoRender)
        {
            pData.render();
            if (pData.displayOptions.renderTarget)
            {
            	pData.displayOptions.renderTarget.list = pData;
            }
        }
        delete ripl.service.callCache[parseInt(data.serial,10)];
        return pData;
    },
    renderEventList:function _ripl_apiHandler_renderEventList(data)
    {
        if (data.error) return;
        var pCallDetails = ripl.service.callCache[parseInt(data.serial,10)];
        var pData = new ripl.coreObjects.EventList(pCallDetails.displayOptions,pCallDetails.childDisplayOptions, pCallDetails.eventOptions);
        ripl.cache.content.addObjects(data.content);
        ripl.cache.feedItems.addObjects(data.feedItems);
        ripl.cache.user.addObjects(data.users);
        pData.addObjects(data.feedItems);
        pData._contentItems.addObjects(data.content);
        pData._userItems.addObjects(data.users);
        if (ripl.service.autoRender)
        {
            pData.render();
            if (pData.displayOptions.renderTarget)
            {
            	pData.displayOptions.renderTarget.list = pData;
            }
        }
        delete ripl.service.callCache[parseInt(data.serial,10)];
        return pData;
    },
    renderPhotoAlbum:function _ripl_apiHandler_renderPhotoAlbum(data)
    {
        if (data.error) return;
        var pCallDetails = ripl.service.callCache[parseInt(data.serial,10)];
        var pData = new ripl.coreObjects.ContentList(pCallDetails.displayOptions || {itemsperpage:1,sortkey:'pid',currentpagenumber:(window.location.hash?Number(window.location.hash.substr(1,1)):1),sortreverse:false,targetstyle:'photoalbum_detail',renderTarget:"dynamicFrame",displaytypeselector:false},pCallDetails.childDisplayOptions, pCallDetails.eventOptions);
        ripl.cache.content.addObjects(data.contentItems.items);
        pData.addObjects(data.contentItems.items);
        pData._filterList();
        if (ripl.service.autoRender)
        {
            pData.render();
            if (pData.displayOptions.renderTarget)
            {
            	pData.displayOptions.renderTarget.list = pData;
            }
        }
        
        delete ripl.service.callCache[parseInt(data.serial,10)];
        return pData;
    },
    renderUserList:function _ripl_apiHandler_renderUserList(data)
    {
        if (data.error) return;
        var pCallDetails = ripl.service.callCache[parseInt(data.serial,10)];
        var pData = new ripl.coreObjects.UserList(pCallDetails.displayOptions,pCallDetails.childDisplayOptions,pCallDetails.eventOptions);
        ripl.cache.user.addObjects(data.users);
        pData.addObjects(data.users);
        if (ripl.service.autoRender)
        {
            pData.render();
            if (pData.displayOptions.renderTarget)
            {
            	pData.displayOptions.renderTarget.list = pData;
            }
            
        }
        delete ripl.service.callCache[parseInt(data.serial,10)];
        return pData;
    },
    renderCommentList:function _ripl_apiHandler_renderCommentList(data)
    {
        if (data.error) return;
        var pCallDetails = ripl.service.callCache[parseInt(data.serial,10)];
        var pData = new ripl.coreObjects.CommentList(pCallDetails.displayOptions,pCallDetails.childDisplayOptions,pCallDetails.eventOptions);
        pData.addObjects(data.comments);
        pData.addUsers(data.users);
        pData.link();
        if (ripl.service.autoRender)
        {
            pData.render();
            if (pData.displayOptions.renderTarget)
            {
            	pData.displayOptions.renderTarget.list = pData;
            }
        }
        delete ripl.service.callCache[parseInt(data.serial,10)];   
        return pData;
    },
    renderHTML:function (data)
    {
        if (data.error) return;
        var pCallDetails = ripl.service.callCache[parseInt(data.serial,10)];
        var pData = new ripl.coreObjects.HtmlObject(data.html, pCallDetails.displayOptions);
        if (ripl.service.autoRender)
        {
            pData.render();
            if (pData.displayOptions.renderTarget)
            {
            	pData.displayOptions.renderTarget.list = pData;
            }
        }
        delete ripl.service.callCache[parseInt(data.serial,10)];  
        return pData;
    }
        
};
ripl.auth = {
    currentUser:null,
    dialog:null,
    token:null,
    postAuth:null,
    link:function(serviceKey,foreignUserId,token)
    {
    },
    isAuthed:function()
    {
        return (ripl.auth.token != null);
    },
    login:function(login,pass,remember){
        ripl.service.methods.ripl.auth.login.call({api_key:'test_key',callback:'ripl.auth.checkCookieHandler',login:login,pwd:pass,remember:remember});
    },
    forgot:function(email){
        ripl.service.methods.ripl.user.forgotAuth.call({callback:'ripl.auth.forgotHandler',email:escape(email)});
    },
    forgotHandler:function(data){
    	if(data.error){
    		$ripl.getElementById('ripl_forgot_error').update(data.error.errmessage).show();
    	}else{
    		ripl.hideModal();
    	}
    },
    checkCookie:function(postAuth)
    {
        ripl.auth.postAuth = postAuth;
        ripl.dataservices.getJSONP(ripl.environment.endpointHelper + 'ripl_auth.php?callback=ripl.auth.checkCookieHandler');
    },
    checkCookieHandler:function(tokenInfo)
    {
    	if(ripl.auth.dialog && tokenInfo.error){
    		$ripl.getElementById('ripl_auth_error').update(tokenInfo.error.errmessage).show();
    		return;
    	}
        if (tokenInfo.user)
        {
            var pUser = new ripl.coreObjects.User(tokenInfo.user);
            if (pUser.pid > 0)
            {
            	if (tokenInfo.api_key)
            	{
            		ripl.service.apikey = tokenInfo.api_key;
            	}
                ripl.auth.token = tokenInfo.token;
//                ripl.service.apikey = 'ripl';
                ripl.auth.currentUser = pUser;
                if(ripl.auth.dialog){ 
            		ripl.hideModal();
                }
                ripl.events.libraryEvents.fire('authed'); 
            }
        }
        else
        {
            ripl.events.libraryEvents.fire('auth_failed'); 
        }
        if (ripl.auth.postAuth) { ripl.auth.postAuth(); };
        if(ripl.auth.dialog && !ripl.redirected){
        	//handle reloading
        	window.location=window.location; // until we have everything setup with reinit/reload on auth methods
        }
    }
};


ripl.sharing = {
        originalContent:null,
        currentUserId:0,
        currentActiveId:null,
        location:'not_logged',
        services:{},
        _serviceBase:function(serviceName, serviceIcon,shareFunction)
        {
            this.serviceName = serviceName;
            this.serviceIcon = serviceIcon;
            this.shareFunction = shareFunction;
            this.authed = false;
            this.authUser = "";
            this.authPassword ="";
        },
        addService:function(serviceName, serviceIcon,shareFunction)
        {
            var pService = new ripl.sharing._serviceBase(serviceName, serviceIcon,shareFunction);
            this.services[serviceName] = pService;
        },
        generateLinkBack:function(siteid)
        {
            var pUid = (ripl.auth.currentUser) ? ripl.auth.currentUser.pid : 0;
            var pLb = ripl.environment.site +'/?'+siteid+'=' + pUid.toString(36) + '-' + ripl.contentDisplay.current.contentItem.pid.toString(36);
            if (ripl.sharing.currentActiveId != null)
            {
                pLb += '#i_' + ripl.sharing.currentActiveId; 
            }
            return pLb;
        },

        log:function(inService)
        {
            //!
            return;
        },

        getShareBlock:function()
        {
            var pString ='';
            var pDiv = $ripl.create('div',{id:'tw_shareContainer', style:'float:left;padding-left:10px;padding-top:4px;'});
            for (var key in ripl.sharing.services)
            {
                pString += '<a href="javascript:void(0)" onclick="ripl.sharing.share(\''+key+'\');return false;" title="' + ripl.sharing.services[key].serviceName + '"><img border="0" src="'+ripl.sharing.services[key].serviceIcon+'" /></a>';
            }
            $ripl.update(pDiv, pString);
            return pDiv;
        },
        getShareBlockEx:function()
        {
            var pString ='';
            var pDiv = $ripl.create('div',{id:'tw_shareContainer', className:'ripl_sharecontainer'});
            pString = '<table><tr><td><a href="javascript:void(0)" onclick="ripl.sharing.share(\'RIPL\');return false;" title="' + ripl.sharing.services['RIPL'].serviceName + '"><img border="0" src="'+ripl.sharing.services['RIPL'].serviceIcon+'" /></a>';
            pString += '</td><td> <a href="javascript:void(0)" onclick="ripl.sharing.share(\'RIPL\');return false;" title="' + ripl.sharing.services['RIPL'].serviceName + '">Share On RIPL</a>';
            pString += ' | Other Services </td><td> ';
            for (var key in ripl.sharing.services)
            {
                if (key != 'RIPL') pString += '<a href="javascript:void(0)" onclick="ripl.sharing.share(\''+key+'\');return false;" title="' + ripl.sharing.services[key].serviceName + '"><img border="0" src="'+ripl.sharing.services[key].serviceIcon+'" /></a>';
            }
            pString += '</td></tr></table>';
            $ripl.update(pDiv, pString);
            return pDiv;
        },
        share:function(sharetype)
        {
        	ripl.contentDisplay.current.hideTemporal();
            if (ripl.sharing.services[sharetype])
            {
                ripl.sharing.services[sharetype].shareFunction();
            }
        }
        
};


ripl.sharing.addService('RIPL',ripl.environment.imageBase+'share_ripl.png',function()
        {
            ripl.redirect = ripl.environment.site+"messageWrite.php?contentid=" + ripl.contentDisplay.current.contentItem.pid + '&subid=' + ripl.contentDisplay.current.contentItem.pid;
            if (!ripl.auth.isAuthed()) { 
            	// set post auth
            	ripl.auth.postAuth = function(){
            		ripl.redirected = true;
            		window.location = ripl.redirect;
            	};
            	ripl.showLogin();
            	return; 
            } 
            window.location=ripl.redirect;
        });
ripl.sharing.addService('email',ripl.environment.imageBase+'share_email.png',function()
        {
            ripl.sharing.log('email');
            var pLink = ripl.sharing.generateLinkBack('e');
            var mailto = 'mailto:?subject=I found this on RIPL&body=Check out this ' + ripl.contentDisplay.current.contentItem.base_type + ' that I found on RIPL:  ';
            mailto += pLink;
            window.location=mailto;
        });
ripl.sharing.addService('twitter',ripl.environment.imageBase+'share_twitter.png',function()
        {
			ripl.contentDisplay.current.hideTemporal();
			$ripl.getElementsByClassName('.ripl_subCloseBtn',ripl.contentDisplay.current.containerElement).ripl_each($ripl.removeElement);
    		var l = window.location;
   			ripl.sharing.log('twitter');
            var pLink = ripl.sharing.generateLinkBack('t');
   			
            var pDiv = $ripl.create('div');
            var pURL = ripl.environment.endpointHelper+'twitter/shareform_twitter.php?embed=1&content_id='+ripl.contentDisplay.current.contentItem.pid;
            if(ripl.pageParams.oauth_token){
            	pURL = ripl.envBase+'twitter/?embed=1&oauth_token='+ripl.pageParams.oauth_token;
            }else{
	            if (ripl.service.apikey) { pURL += '&api_key=' + ripl.service.apikey; }
	            if (ripl.auth.token) { pURL += '&token=' + ripl.auth.token; }
	            pURL += '&urlTack=' + encodeURIComponent(pLink);
	            var delim = '&';
	            if(l.search=='') {delim = '?';}
	            pURL += '&returnURL='+ escape(l.protocol+'//'+l.host+l.pathname+l.search+delim+'ripl_shareMode=twitter&ripl_contentid='+ripl.contentDisplay.current.contentItem.pid+l.hash);
            }
            var pFrameSrc = '<iframe frameborder="0" allowtransparency="true" style="border:none;left:0px;width:100%;bottom:48px;position:absolute;z-index:10;height:400px" ';
            pFrameSrc += 'src="'+pURL+'"></iframe>';
            pDiv.update(pFrameSrc);
            ripl.contentDisplay.current.temporalItems.push(pDiv);
            var pInnerClose=$ripl.create('div',{className:'ripl_subCloseBtn'});
            pInnerClose.listen('click',function()
            		{
            			this.style.display='none';
            			ripl.contentDisplay.current.hideTemporal();
           		});            
            $ripl.add(ripl.contentDisplay.current.containerElement,[pDiv,pInnerClose]);
    
        });
            
ripl.sharing.addService('facebook',ripl.environment.imageBase+'share_facebook.png',function()
        {
			ripl.contentDisplay.current.hideTemporal();
			$ripl.getElementsByClassName('.ripl_subCloseBtn',ripl.contentDisplay.current.containerElement).ripl_each($ripl.removeElement);
    		var l = window.location;
            ripl.sharing.log('facebook');
            var pLink = escape(ripl.sharing.generateLinkBack('f'));
            //window.open('http://www.facebook.com/share.php?u=' + pLink,'facebook','toolbar=no,width=850,height=550');

            var pDiv = $ripl.create('div');
            var pURL = ripl.environment.endpointHelper+'facebook/?embed=1&content_id='+ripl.contentDisplay.current.contentItem.pid;
            
            if (ripl.service.apikey) { pURL += '&api_key=' + ripl.service.apikey; }
            if (ripl.auth.token) { pURL += '&token=' + ripl.auth.token; }
            pURL += '&urlTack=' + encodeURIComponent(pLink);
            var delim = '&';
            if(l.search=='') {delim = '?';}
            pURL += '&returnURL='+ escape(l.protocol+'//'+l.host+l.pathname+l.search+delim+'ripl_shareMode=facebook&ripl_contentid='+ripl.contentDisplay.current.contentItem.pid+l.hash);
            var pFrameSrc = '<iframe frameborder="0" allowtransparency="true" style="border:none;left:0px;width:100%;bottom:48px;position:absolute;z-index:10;height:400px" ';
            pFrameSrc += 'src="'+pURL+'"></iframe>';
            pDiv.update(pFrameSrc);
            ripl.contentDisplay.current.temporalItems.push(pDiv);
            var pInnerClose=$ripl.create('div',{href:'#',className:'ripl_subCloseBtn'});
//            var pInnerClose=$ripl.create('div',{href:'#',className:'ripl_subCloseBtn',onclick:'this.style.display="none";ripl.contentDisplay.current.hideTemporal()'});
            pInnerClose.listen('click',function()
            		{
            			this.style.display='none';
            			ripl.contentDisplay.current.hideTemporal();
           		});
            $ripl.add(ripl.contentDisplay.current.containerElement,[pDiv,pInnerClose]);
        });
ripl.sharing.addService('Digg',ripl.environment.imageBase+'share_digg.png',function()
        {
            ripl.sharing.log('digg');
            var baseHref = 'http://digg.com/submit?url=';
            var pOptions = escape(ripl.sharing.generateLinkBack('d'));
            if (ripl.contentDisplay.current.title != 'Untitled') { pOptions += '&title='+escape(ripl.contentDisplay.current.contentItem.title); }
            if (ripl.contentDisplay.current.contentItem.base_type == 'Photo') { pOptions += '&media=image'; }
            else if (ripl.contentDisplay.current.contentItem.base_type == 'Video') { pOptions += '&media=video'; }
            if (ripl.contentDisplay.current.contentItem.description != '') { pOptions += '&bodytext='+escape(ripl.contentDisplay.current.contentItem.description); }
            window.open(baseHref + pOptions,'digg','toolbar=yes,width=850,height=550');
        });
ripl.sharing.addService('delicious',ripl.environment.imageBase+'share_delicious.png',function()
        {
            ripl.sharing.log('delicious');
            var pLink = escape(ripl.sharing.generateLinkBack('l'));
            window.open('http://delicious.com/save?v5&noi&jump=close&url=' + pLink + '&title' +escape(ripl.contentDisplay.current.contentItem.title),'delicious','toolbar=no,width=850,height=550');
        });

ripl.contentDisplay = {
    current:null,
    types:{},
    setCurrentDisplay:function(displayType)
    {
        ripl.contentDisplay.current = displayType;
    },
    _displayTypeBase:function()
    {
        this.domElement = null;
        this.renderElement = null;
        this.containerElement = null;
        this.contentItem = null;
        this.temporalItems = [];
        this.created = false;
        this.create = function(){};
        this.hideTemporal = function()
        {
            for (var i=this.temporalItems.length-1; i >=0; i--)
            {
                var pItem = this.temporalItems.pop();
                $ripl.removeElement(pItem);
            }
        };
        this.hide = function()
        {
            this.hideTemporal();
            $ripl.update(this.renderElement);
            $ripl.hide(this.domElement);
        };
        this.show = function()
        {
            if (this.created)
            {
                this.domElement.show();
            }
            else
            {
                this.create();
            }
        };
        this.setContentItem = function(contentItem)
        {
            var i =0;
            this.contentItem = contentItem;
            var pItems = $ripl.getElementsByClassName('.ripl_loaderImage');
            pItems.ripl_each($ripl.show);

            var pTitles = $ripl.getElementsByClassName('.ripl_windowTitle');
            for (i =0; i < pTitles.length; i++)
            {
                $ripl.update(pTitles[i],contentItem.title);
            }
            
            var pType = contentItem.base_type.toLowerCase();
            var pProvider =  contentItem.provider_id.toLowerCase();
            if (pProvider == '') { pProvider = 'ripl'; }
            
            if (!ripl.renderers.types[pType]) {return false;}
            if (!ripl.renderers.types[pType].serviceRenderers[pProvider]) {return false;}

            ripl.renderers.types[pType].serviceRenderers[pProvider](contentItem); 
        };
    },
    addDisplayType:function(typeName,createFunction)
    {
        var pDisplayType = new ripl.contentDisplay._displayTypeBase();
        pDisplayType.create = createFunction;
        ripl.contentDisplay.types[typeName] = pDisplayType;
    }
};
ripl.contentDisplay.addDisplayType('content_detail',function(){
    var pContainer = $ripl.create('div');
    var pTarget = $ripl.create('div',{id:'dynamicFrame',style:'z-index:2;width:640px;height:408px;position:absolute;left:10px;top:34px'});

    pContainer.add(pTarget);
    
    this.domElement = $ripl(ripl.renderers.location);
    this.domElement.add(pContainer);

    this.containerElement = pContainer;
    this.renderElement = pTarget;
    this.created = true;   
});


ripl.contentDisplay.addDisplayType('popup',function()
{
    var pBody = $ripl.getElementsByTagName('body')[0];
    var pOverlay = $ripl.create('div',{className:'ripl_overlay'});
    var pElement = $ripl.create('div',{className:'ripl_popWindow'});
    var pClose = $ripl.create('div',{className:'ripl_closeBtn'});
    pClose.listen('click', ripl.contentDisplay.current.hide, ripl.contentDisplay.current)

    var pTitle = $ripl.create('div',{className:'ripl_windowTitle'});
    var pLoader = $ripl.create('img',{src:ripl.environment.jslib + 'images/ajax-loader.gif',className:'ripl_loaderImage'});
    var pTarget = $ripl.create('div',{id:'dynamicFrame',style:'z-index:2;width:640px;height:408px;position:absolute;left:10px;top:34px'});
    var pBottom = $ripl.create('div',{style:'position:absolute;top:442px;left:0px;width:100%;'});
    
    var pLinkBack = $ripl.create('div');
    pLinkBack.className= 'ripl_linkback';
    pLinkBack.listen('click', function(){location.href=ripl.contentDisplay.current.contentItem.getLink();},ripl.contentDisplay.current);

    pBottom.add([ripl.sharing.getShareBlock(), pLinkBack]);
    pElement.add([pClose,pTitle,pLoader,pTarget,pBottom]);
    pOverlay.add(pElement);
    pBody.add(pOverlay);


    ripl.renderers.location = 'dynamicFrame';
    this.domElement = pOverlay;
    this.containerElement = pElement;
    this.renderElement = pTarget;
    this.created = true;   
});
ripl.contentDisplay.setCurrentDisplay(ripl.contentDisplay.types.popup);

ripl.controls = {};
ripl.controls.types= {};
ripl.controls.addControl = function(key, closure)
{
    ripl.controls.types[key] = closure;
}

ripl.controls.addControl('ripl_textbox', function(el)
    {
		this.defaultText = el.value;
        el.listen('focus', 
            function(e)
            {
                if(!this.defaultText) 
                {
                    this.defaultText = this.value;
                }                        
                if(this.value==this.defaultText)
            	{
            		this.value = '';                        
            	}
            }
        );
        el.listen('blur', 
            function(e)
            {
                if(this.value=="")
                {
                	this.value = this.defaultText;
                	$ripl(this).addClass('ripl_input_default');
                }
                else if (this.value == this.defaultText)
                {
                	$ripl(this).addClass('ripl_input_default');
                }
                else
                {
                	this.removeClass('ripl_input_default');
                }
            }
        );
    });

ripl.controls.addControl('ripl_shareblock', function(el)
    {
        el.update(ripl.sharing.getShareBlockEx());    
    });


ripl.controls.addControl('ripl_accordion', function(el)
    {
        this.domElement = $ripl(el);
        this.options = 
        {
            toggleClass: 'ripl_accordion_toggle',
            toggleActive: 'ripl_accordion_toggle_active',
            contentClass: 'ripl_accordion_content'
        }
        this.queued = null;
        this.contents = $ripl.getElementsByClassName('.' + this.options.contentClass, this.domElement);
        this.isAnimating = false;
        this.current = this.contents[0];
        this.toExpand = null;
        this.domElement.listen('click', this.clickHandler, this);
    });

ripl.controls.types.ripl_accordion.prototype.clickHandler = function(e)
{
    var el = $ripl((e.target) ? e.target : e.srcElement);

    if (el.hasClass(this.options.toggleClass))
    {
        if (!this.isAnimating)
        {
            this.expand(el);
        }
        else
        {
            this.queued = el;
        }
    }
}

ripl.controls.types.ripl_accordion.prototype.expand = function(el)
{
    var pType = 0;
    var pTarget = el;
    while (pType != 1)
    {
        pTarget = pTarget.next();
        if (pTarget == null)
        {
            return;
        }
        pType = pTarget.nodeType;
    }
    
    if (pTarget)
    {
        this.toExpand = pTarget;
        if (this.current != this.toExpand)
        {
            this.toExpand.show();
            this.current.hide();
            this.animate();
        }
    }
}
ripl.controls.types.ripl_accordion.prototype.animate = function()
{
    var pType = 0;
    var pTarget = this.toExpand;
    while (pType != 1)
    {
        pTarget = pTarget.previous();
        if (pTarget == null)
        {
            return;
        }
        pType = pTarget.nodeType;
    }    
    
    var pOldTargets = $ripl.getElementsByClassName('.' + this.options.toggleActive, this.domObject);
    for (var i=0; i < pOldTargets.length; i++)
    {
        pOldTargets[i].removeClass(this.options.toggleActive);
    }
    pTarget.addClass(this.options.toggleActive);
    
    this.toExpand.show();
    this.current.hide();
    this.current = this.toExpand;
}





ripl.utilities = {
    isArray:function(obj) {
        for (var i in obj)
        {
            return Object.prototype.toString.call(obj) === '[object Array]'; 
        }
    },
    cleanObject:function(obj) {
        for (var i in obj)
        {
            if (obj[i] == null) delete obj[i];
            if (!isNaN(parseInt(obj[i],10))) obj[i] = parseInt(obj[i],10)
        }        
    },
    isDefined:function(variable) {
        return (typeof(window[variable]) == "undefined")?  false: true;        
    },
    autosubmitParent:function(e, obj)
    {
        $ripl(obj).up('form').submit();
    },
    autosubmit:function(e, action)
    {
        var keynum;
        if(window.event) // IE
        {
            keynum = e.keyCode;
        }
        else if(e.which) // Netscape/Firefox/Opera
        {
            keynum = e.which;
        }
        if (keynum == 13) 
        {
            if(typeof(action)=='function')
            {
                action();
            }
            else
            {
                var pForm = $ripl(action);
                if (!pForm)
                {
                    pForm = $ripl((e.target) ? e.target : e.srcElement);
                }
                if(typeof(action)=='string')
                {
                    pForm.submit();
                }else{
                	try
                	{
                		pForm.up('form').submit();
                	} catch (err) {}
                }
                
            }
            return false;
        }
        return true;
    }
}

ripl.cookie = {
    _events:new ripl.events.eventManagerBase(),
    build:function()
    {
        return makeArray(arguments).ripl_compact().join('; ');
    },
    secondsFromNow:function(seconds)
    {
        return (new Date()).ripl_addSeconds(seconds).toGMTString();
    },
    set: function(name, value, seconds, path)
    {
        var pExpire = seconds ? 'expires=' + ripl.cookie.secondsFromNow(seconds) :null;
        if (!path) path = 'path=/';
        var pCookie = ripl.cookie.build(name + '=' + value, pExpire, path);
        ripl.cookie._events.fire('cookie_set', pCookie);
        document.cookie = pCookie;
    },
    get:function(name)
    {
        ripl.cookie._events.fire('cookie_get', name);
        var valueMatch = new RegExp(name + "=([^;]+)").exec(document.cookie);
        return valueMatch ? valueMatch[1] : null;
    },
    unset:function(name)
    {
        ripl.cookie._events.fire('unset',name);
        ripl.cookie.set(name,'',-1);        
    }
}


ripl.globalDefaults = {};
ripl.globalDefaults = {
        listClickMode:ripl.enums.CLICK_TO_PLAY,
        linkBackOverride:false
    };

ripl.globalDefaults.ContentListOptions = {
		renderTarget:null,
        targetstyle:'contentlist_default',
        typeFilters:ripl.coreObjects.content.getTypes(),
        displaytypeselector:true,
        sortkey:'last_update',
        sortreverse:true,
        currentpagenumber:1,
        itemsperpage:12,
        noitems:'No items were found'
        };
ripl.globalDefaults.UserListOptions = {
        renderTarget:null,
        targetstyle:'userlist_default',
        displaytypeselector:false,
        sortkey:'last_update',
        sortreverse:false,
        currentpagenumber:1,
        itemsperpage:12,
        noitems:'No items were found',
        padding:'0px 15px'};
ripl.globalDefaults.EventListOptions = {
		renderTarget:null,
        targetstyle:'eventlist_default',
        typeFilters:ripl.coreObjects.content.getTypes(),
        displaytypeselector:true,
        sortkey:'actionTime',
        sortreverse:true,
        currentpagenumber:1,
        itemsperpage:12,
        noitems:'No items were found'
        };
ripl.globalDefaults.CommentListOptions = {
        renderTarget:null,
        targetstyle:'commentlist_default',
        displaytypeselector:false,
        sortkey:'last_update',
        sortreverse:true,
        currentpagenumber:1,
        itemsperpage:12,
        noitems:'No comments have been added',
        padding:'0px 15px'};

ripl.cache ={
	feedItems:new ripl.coreObjects.EventList(),
    content:new ripl.coreObjects.ContentList(),
    user:new ripl.coreObjects.UserList()
};
ripl.preinitialize();
ripl.events.domReady(ripl.initialize);




/**
 * 
 * Top level instance extensions & utility functions
 * 
 */

// convert array-like objects to actual arrays
function makeArray(array){ 
  return Array().slice.call( array ); 
} 

Array.prototype.ripl_Autofill = function Array_ripl_Autofill(autofillValue)
{
    for ( var i = 0; i < this.length; i++) {this[i] = autofillValue;}
};
Array.prototype.ripl_InArray = function Array_ripl_InArray( obj ) 
{
    var len = this.length, 
        x   = 0;
    for (x; x < len; ++x )
    {
        if ( this[x] == obj ) { return true; }
    }
    return false;
};
Array.prototype.ripl_each = function(closure)
{
    var len = this.length, 
    x   = 0;
    for (x; x < len; ++x )
    {
        closure(this[x]);
    }
}
Array.prototype.ripl_compact = function()
{
    var len = this.length, 
    x   = 0,
    pOut = [];
    for (x; x < len; ++x )
    {
        if (this[x] !=null)
        {
            pOut.push(this[x]);
        }
    }    
    return pOut;
}
Array.prototype.ripl_InArraySubstring = function Array_ripl_InArraySubstring( obj ) 
{
    if (!obj) {return false;}
    var len = this.length,
        x   = 0;
    for (x; x < len; ++x )
    {
        if ( obj.indexOf(this[x]) == 0 ) {return true;}
    }
    return false;
};
Array.prototype.ripl_InArrayKey = function Array_ripl_InArrayKey(obj, key)
{
    var len = this.length,
        x   = 0;
    for (x; x < len; ++x )
    {
        if ( this[x][key] == obj[key] ) {return true;}
    }
    return false;
};

String.prototype.ripl_Trim = function() 
{
    var str = this;
    this.replace(/^\s+/, '');
    for (var i = str.length - 1; i >= 0; i--) {
        if (/\S/.test(str.charAt(i))) {
            str = str.substring(0, i + 1);
            break;
        }
    }
    this.value=str;
    return str;    
};
String.prototype.ripl_truncate = function(length, truncateText)
{
    length = length || 30;
    truncateText = truncateText || '...';
    return (this.length > length) ? this.slice(0, length - truncateText.length) + truncateText : String(this);
}

Number.prototype.ripl_ZeroFormat = function Number_ripl_ZeroFormat(digits)
{
    var n = this.toString(), pLen = digits - n.length;
    for ( var i = 0; i < pLen; i++)
    {
        n = '0' + n;
    }
    return n;
};

// BEGIN ENGLISH DATE FORMATTERS
Date.prototype.ripl_format = function(formatType)
{
    if ((formatType === null) || (formatType === undefined)) {formatType = 0; } // Make format optional, default to SIMPLETIME.
    if (formatType == Date.ripl_SIMPLETIME)
    {
        return this.ripl_formatSimple();
    }
    else if (formatType == Date.ripl_TIME_SINCE)
    {
        return this.ripl_formatSince();
    }
};
Date.ripl_Month = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ];
Date.prototype.ripl_formatSimple = function _formatSimple(excludeTime)
{
    var h    = this.getHours(),
        pOut = [ Date.ripl_Month[this.getMonth()], '&nbsp;', this.getDate() + 1, ',&nbsp;', this.getFullYear(), '&nbsp;'];
    if (!excludeTime)
    {
        pOut.push(((h % 12) ? h : 12), // Hours
                ':', this.getMinutes().ripl_ZeroFormat(2), // Minutes
                this.getHours() < 12 ? ' am' : ' pm'); // AM/PM)
    }
    return pOut.join('');
};
Date.prototype.ripl_formatSince = function _formatSince()
{
    var diff     = (((new Date()).getTime() - this.getTime()) / 1000),
        day_diff = Math.floor(diff / 86400);
    if (isNaN(day_diff) || day_diff < 0) { return; }
    
    return (diff < 60) && 'just now' || (diff < 120) && '1 minute ago' || (diff < 3600) && Math.floor(diff / 60) + ' minutes ago' || (diff < 7200) && '1 hour ago' || (diff < 86400) && Math.floor(diff / 3600) + ' hours ago'
            || (day_diff == 1) && 'Yesterday' || (day_diff < 7) && day_diff + ' days ago' || (day_diff < 12) && '1 week ago' || (day_diff < 28) && Math.ceil(day_diff / 7) + " weeks ago" || (day_diff < 50) && '1 month ago'
            || (day_diff < 320) && Math.ceil(day_diff / 28) + ' months ago' || (diff < 400) && '1 year ago' || 'More than 1 year ago';
};

Date.ripl_SIMPLETIME = 0;
Date.ripl_TIME_SINCE = 1;

Date.prototype.ripl_addSeconds = function(seconds)
{
    this.setTime(this.getTime() + (seconds * 1000) );
    return this;
}

/**
 * Creates a delegate (callback) that sets the scope to obj.
 * Call directly on any function. Example: <code>this.myFunction.createDelegate(this)</code>
 * Will create a function that is automatically scoped to this.
 * @param {Object} obj (optional) The object for which the scope is set
 * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
 * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
 *                                             if a number the args are inserted at the specified position
 * @return {Function} The new function
 */
Function.prototype.createDelegate = function createDelegate(obj, args, appendArgs){
	var method = this;
	return function(){
		var callArgs = args || arguments;
		if(appendArgs === true){
			callArgs = Array.prototype.slice.call(arguments, 0);
			callArgs = callArgs.concat(args);
		}else if(typeof appendArgs == "number"){
			callArgs = Array.prototype.slice.call(arguments, 0); // copy arguments first
			var applyArgs = [appendArgs, 0].concat(args); // create method call params
			Array.prototype.splice.apply(callArgs, applyArgs); // splice them in
		}
		return method.apply(obj || window, callArgs);
	};
};

/**
 * End ripllib.js core
 * 
 * Begin Sizzle CSS selector
 * 
 */


ripl.SizzleData = {
        chunker:/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
        toString:Object.prototype.toString,
        done:0,
        hasDuplicate:false,
        baseHasDupliate:true
        
    };
[0, 0].sort(function(){
    ripl.SizzleData.baseHasDuplicate = false;
    return 0;
});
ripl.Sizzle =  function(selector, context, results, seed) {
    results = results || [];
    var origContext = context = context || document;

    if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
        return [];
    }
    
    if ( !selector || typeof selector !== "string" ) {
        return results;
    }

    var parts = [], m, set, checkSet, extra, prune = true, contextXML = ripl.SizzleData.isXML(context),
        soFar = selector;
    
    // Reset the position of the chunker regexp (start from head)
    while ( (ripl.SizzleData.chunker.exec(""), m = ripl.SizzleData.chunker.exec(soFar)) !== null ) {
        soFar = m[3];
        
        parts.push( m[1] );
        
        if ( m[2] ) {
            extra = m[3];
            break;
        }
    }

    if ( parts.length > 1 && ripl.SizzleData.origPOS.exec( selector ) ) {
        if ( parts.length === 2 && ripl.SizzleExpr.relative[ parts[0] ] ) {
            set = ripl.SizzleData.posProcess( parts[0] + parts[1], context );
        } else {
            set = ripl.SizzleExpr.relative[ parts[0] ] ?
                [ context ] :
                    ripl.Sizzle( parts.shift(), context );

            while ( parts.length ) {
                selector = parts.shift();

                if ( ripl.SizzleExpr.relative[ selector ] ) {
                    selector += parts.shift();
                }
                
                set = ripl.SizzleData.posProcess( selector, set );
            }
        }
    } else {
        // Take a shortcut and set the context if the root selector is an ID
        // (but not if it'll be faster if the inner selector is an ID)
        if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
                ripl.SizzleExpr.match.ID.test(parts[0]) && !ripl.SizzleExpr.match.ID.test(parts[parts.length - 1]) ) {
            var ret = ripl.Sizzle.find( parts.shift(), context, contextXML );
            context = ret.expr ? ripl.Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
        }

        if ( context ) {
            var ret = seed ?
                { expr: parts.pop(), set: ripl.SizzleData.makeArray(seed) } :
                    ripl.Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
            set = ret.expr ? ripl.Sizzle.filter( ret.expr, ret.set ) : ret.set;

            if ( parts.length > 0 ) {
                checkSet = ripl.SizzleData.makeArray(set);
            } else {
                prune = false;
            }

            while ( parts.length ) {
                var cur = parts.pop(), pop = cur;

                if ( !ripl.SizzleExpr.relative[ cur ] ) {
                    cur = "";
                } else {
                    pop = parts.pop();
                }

                if ( pop == null ) {
                    pop = context;
                }

                ripl.SizzleExpr.relative[ cur ]( checkSet, pop, contextXML );
            }
        } else {
            checkSet = parts = [];
        }
    }

    if ( !checkSet ) {
        checkSet = set;
    }

    if ( !checkSet ) {
        throw "Syntax error, unrecognized expression: " + (cur || selector);
    }

    if ( ripl.SizzleData.toString.call(checkSet) === "[object Array]" ) {
        if ( !prune ) {
            results.push.apply( results, checkSet );
        } else if ( context && context.nodeType === 1 ) {
            for ( var i = 0; checkSet[i] != null; i++ ) {
                if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && ripl.SizzleData.contains(context, checkSet[i])) ) {
                    results.push( set[i] );
                }
            }
        } else {
            for ( var i = 0; checkSet[i] != null; i++ ) {
                if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
                    results.push( set[i] );
                }
            }
        }
    } else {
        ripl.SizzleData.makeArray( checkSet, results );
    }

    if ( extra ) {
        ripl.Sizzle( extra, origContext, results, seed );
        ripl.Sizzle.uniqueSort( results );
    }

    return results;
};

ripl.Sizzle.uniqueSort = function(results){
    if ( ripl.SizzleData.sortOrder ) {
        ripl.SizzleData.hasDuplicate = ripl.SizzleData.baseHasDuplicate;
        results.sort(ripl.SizzleData.sortOrder);

        if ( ripl.SizzleData.hasDuplicate ) {
            for ( var i = 1; i < results.length; i++ ) {
                if ( results[i] === results[i-1] ) {
                    results.splice(i--, 1);
                }
            }
        }
    }

    return results;
};

ripl.Sizzle.matches = function(expr, set){
    return ripl.Sizzle(expr, null, null, set);
};

ripl.Sizzle.find = function(expr, context, isXML){
    var set, match;

    if ( !expr ) {
        return [];
    }

    for ( var i = 0, l = ripl.SizzleExpr.order.length; i < l; i++ ) {
        var type = ripl.SizzleExpr.order[i], match;
        
        if ( (match = ripl.SizzleExpr.leftMatch[ type ].exec( expr )) ) {
            var left = match[1];
            match.splice(1,1);

            if ( left.substr( left.length - 1 ) !== "\\" ) {
                match[1] = (match[1] || "").replace(/\\/g, "");
                set = ripl.SizzleExpr.find[ type ]( match, context, isXML );
                if ( set != null ) {
                    expr = expr.replace( ripl.SizzleExpr.match[ type ], "" );
                    break;
                }
            }
        }
    }

    if ( !set ) {
        set = context.getElementsByTagName("*");
    }

    return {set: set, expr: expr};
};

ripl.Sizzle.filter = function(expr, set, inplace, not){
    var old = expr, result = [], curLoop = set, match, anyFound,
        isXMLFilter = set && set[0] && ripl.SizzleData.isXML(set[0]);

    while ( expr && set.length ) {
        for ( var type in ripl.SizzleExpr.filter ) {
            if ( (match = ripl.SizzleExpr.match[ type ].exec( expr )) != null ) {
                var filter = ripl.SizzleExpr.filter[ type ], found, item;
                anyFound = false;

                if ( curLoop == result ) {
                    result = [];
                }

                if ( ripl.SizzleExpr.preFilter[ type ] ) {
                    match = ripl.SizzleExpr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );

                    if ( !match ) {
                        anyFound = found = true;
                    } else if ( match === true ) {
                        continue;
                    }
                }

                if ( match ) {
                    for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
                        if ( item ) {
                            found = filter( item, match, i, curLoop );
                            var pass = not ^ !!found;

                            if ( inplace && found != null ) {
                                if ( pass ) {
                                    anyFound = true;
                                } else {
                                    curLoop[i] = false;
                                }
                            } else if ( pass ) {
                                result.push( item );
                                anyFound = true;
                            }
                        }
                    }
                }

                if ( found !== undefined ) {
                    if ( !inplace ) {
                        curLoop = result;
                    }

                    expr = expr.replace( ripl.SizzleExpr.match[ type ], "" );

                    if ( !anyFound ) {
                        return [];
                    }

                    break;
                }
            }
        }

        // Improper expression
        if ( expr == old ) {
            if ( anyFound == null ) {
                throw "Syntax error, unrecognized expression: " + expr;
            } else {
                break;
            }
        }

        old = expr;
    }

    return curLoop;
};

ripl.SizzleExpr = ripl.Sizzle.selectors = {
    order: [ "ID", "NAME", "TAG" ],
    match: {
        ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
        CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
        NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
        ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
        TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
        CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
        POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
        PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
    },
    leftMatch: {},
    attrMap: {
        "class": "className",
        "for": "htmlFor"
    },
    attrHandle: {
        href: function(elem){
            return elem.getAttribute("href");
        }
    },
    relative: {
        "+": function(checkSet, part){
            var isPartStr = typeof part === "string",
                isTag = isPartStr && !/\W/.test(part),
                isPartStrNotTag = isPartStr && !isTag;

            if ( isTag ) {
                part = part.toLowerCase();
            }

            for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
                if ( (elem = checkSet[i]) ) {
                    while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}

                    checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
                        elem || false :
                        elem === part;
                }
            }

            if ( isPartStrNotTag ) {
                ripl.Sizzle.filter( part, checkSet, true );
            }
        },
        ">": function(checkSet, part){
            var isPartStr = typeof part === "string";

            if ( isPartStr && !/\W/.test(part) ) {
                part = part.toLowerCase();

                for ( var i = 0, l = checkSet.length; i < l; i++ ) {
                    var elem = checkSet[i];
                    if ( elem ) {
                        var parent = elem.parentNode;
                        checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
                    }
                }
            } else {
                for ( var i = 0, l = checkSet.length; i < l; i++ ) {
                    var elem = checkSet[i];
                    if ( elem ) {
                        checkSet[i] = isPartStr ?
                            elem.parentNode :
                            elem.parentNode === part;
                    }
                }

                if ( isPartStr ) {
                    ripl.Sizzle.filter( part, checkSet, true );
                }
            }
        },
        "": function(checkSet, part){
            var doneName = done++, checkFn = ripl.SizzleData.dirCheck;

            if ( !/\W/.test(part) ) {
                var nodeCheck = part = part.toLowerCase();
                checkFn = ripl.SizzleData.dirNodeCheck;
            }

            checkFn("parentNode", part, doneName, checkSet, nodeCheck, ripl.SizzleData.isXML);
        },
        "~": function(checkSet, part){
            var doneName = done++, checkFn = ripl.SizzleData.dirCheck;

            if ( typeof part === "string" && !/\W/.test(part) ) {
                var nodeCheck = part = part.toLowerCase();
                checkFn = ripl.SizzleData.dirNodeCheck;
            }

            checkFn("previousSibling", part, doneName, checkSet, nodeCheck, ripl.SizzleData.isXML);
        }
    },
    find: {
        ID: function(match, context, isXML){
            if ( typeof context.getElementById !== "undefined" && !isXML ) {
                var m = context.getElementById(match[1]);
                return m ? [m] : [];
            }
        },
        NAME: function(match, context){
            if ( typeof context.getElementsByName !== "undefined" ) {
                var ret = [], results = context.getElementsByName(match[1]);

                for ( var i = 0, l = results.length; i < l; i++ ) {
                    if ( results[i].getAttribute("name") === match[1] ) {
                        ret.push( results[i] );
                    }
                }

                return ret.length === 0 ? null : ret;
            }
        },
        TAG: function(match, context){
            return context.getElementsByTagName(match[1]);
        }
    },
    preFilter: {
        CLASS: function(match, curLoop, inplace, result, not, isXML){
            match = " " + match[1].replace(/\\/g, "") + " ";

            if ( isXML ) {
                return match;
            }

            for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
                if ( elem ) {
                    if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
                        if ( !inplace ) {
                            result.push( elem );
                        }
                    } else if ( inplace ) {
                        curLoop[i] = false;
                    }
                }
            }

            return false;
        },
        ID: function(match){
            return match[1].replace(/\\/g, "");
        },
        TAG: function(match, curLoop){
            return match[1].toLowerCase();
        },
        CHILD: function(match){
            if ( match[1] == "nth" ) {
                // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
                var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
                    match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
                    !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);

                // calculate the numbers (first)n+(last) including if they are negative
                match[2] = (test[1] + (test[2] || 1)) - 0;
                match[3] = test[3] - 0;
            }

            // TODO: Move to normal caching system
            match[0] = done++;

            return match;
        },
        ATTR: function(match, curLoop, inplace, result, not, isXML){
            var name = match[1].replace(/\\/g, "");
            
            if ( !isXML && ripl.SizzleExpr.attrMap[name] ) {
                match[1] = ripl.SizzleExpr.attrMap[name];
            }

            if ( match[2] === "~=" ) {
                match[4] = " " + match[4] + " ";
            }

            return match;
        },
        PSEUDO: function(match, curLoop, inplace, result, not){
            if ( match[1] === "not" ) {
                // If we're dealing with a complex expression, or a simple one
                if ( ( ripl.SizzleData.chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
                    match[3] = ripl.Sizzle(match[3], null, null, curLoop);
                } else {
                    var ret = ripl.Sizzle.filter(match[3], curLoop, inplace, true ^ not);
                    if ( !inplace ) {
                        result.push.apply( result, ret );
                    }
                    return false;
                }
            } else if ( ripl.SizzleExpr.match.POS.test( match[0] ) || ripl.SizzleExpr.match.CHILD.test( match[0] ) ) {
                return true;
            }
            
            return match;
        },
        POS: function(match){
            match.unshift( true );
            return match;
        }
    },
    filters: {
        enabled: function(elem){
            return elem.disabled === false && elem.type !== "hidden";
        },
        disabled: function(elem){
            return elem.disabled === true;
        },
        checked: function(elem){
            return elem.checked === true;
        },
        selected: function(elem){
            // Accessing this property makes selected-by-default
            // options in Safari work properly
            elem.parentNode.selectedIndex;
            return elem.selected === true;
        },
        parent: function(elem){
            return !!elem.firstChild;
        },
        empty: function(elem){
            return !elem.firstChild;
        },
        has: function(elem, i, match){
            return !!Sizzle( match[3], elem ).length;
        },
        header: function(elem){
            return /h\d/i.test( elem.nodeName );
        },
        text: function(elem){
            return "text" === elem.type;
        },
        radio: function(elem){
            return "radio" === elem.type;
        },
        checkbox: function(elem){
            return "checkbox" === elem.type;
        },
        file: function(elem){
            return "file" === elem.type;
        },
        password: function(elem){
            return "password" === elem.type;
        },
        submit: function(elem){
            return "submit" === elem.type;
        },
        image: function(elem){
            return "image" === elem.type;
        },
        reset: function(elem){
            return "reset" === elem.type;
        },
        button: function(elem){
            return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
        },
        input: function(elem){
            return /input|select|textarea|button/i.test(elem.nodeName);
        }
    },
    setFilters: {
        first: function(elem, i){
            return i === 0;
        },
        last: function(elem, i, match, array){
            return i === array.length - 1;
        },
        even: function(elem, i){
            return i % 2 === 0;
        },
        odd: function(elem, i){
            return i % 2 === 1;
        },
        lt: function(elem, i, match){
            return i < match[3] - 0;
        },
        gt: function(elem, i, match){
            return i > match[3] - 0;
        },
        nth: function(elem, i, match){
            return match[3] - 0 == i;
        },
        eq: function(elem, i, match){
            return match[3] - 0 == i;
        }
    },
    filter: {
        PSEUDO: function(elem, match, i, array){
            var name = match[1], filter = ripl.SizzleExpr.filters[ name ];

            if ( filter ) {
                return filter( elem, i, match, array );
            } else if ( name === "contains" ) {
                return (elem.textContent || elem.innerText || ripl.SizzleData.getText([ elem ]) || "").indexOf(match[3]) >= 0;
            } else if ( name === "not" ) {
                var not = match[3];

                for ( var i = 0, l = not.length; i < l; i++ ) {
                    if ( not[i] === elem ) {
                        return false;
                    }
                }

                return true;
            }
        },
        CHILD: function(elem, match){
            var type = match[1], node = elem;
            switch (type) {
                case 'only':
                case 'first':
                    while ( (node = node.previousSibling) )  {
                        if ( node.nodeType === 1 ) { 
                            return false; 
                        }
                    }
                    if ( type == 'first') { 
                        return true; 
                    }
                    node = elem;
                case 'last':
                    while ( (node = node.nextSibling) )  {
                        if ( node.nodeType === 1 ) { 
                            return false; 
                        }
                    }
                    return true;
                case 'nth':
                    var first = match[2], last = match[3];

                    if ( first == 1 && last == 0 ) {
                        return true;
                    }
                    
                    var doneName = match[0],
                        parent = elem.parentNode;
    
                    if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
                        var count = 0;
                        for ( node = parent.firstChild; node; node = node.nextSibling ) {
                            if ( node.nodeType === 1 ) {
                                node.nodeIndex = ++count;
                            }
                        } 
                        parent.sizcache = doneName;
                    }
                    
                    var diff = elem.nodeIndex - last;
                    if ( first == 0 ) {
                        return diff == 0;
                    } else {
                        return ( diff % first == 0 && diff / first >= 0 );
                    }
            }
        },
        ID: function(elem, match){
            return elem.nodeType === 1 && elem.getAttribute("id") === match;
        },
        TAG: function(elem, match){
            return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
        },
        CLASS: function(elem, match){
            return (" " + (elem.className || elem.getAttribute("class")) + " ")
                .indexOf( match ) > -1;
        },
        ATTR: function(elem, match){
            var name = match[1],
                result = ripl.SizzleExpr.attrHandle[ name ] ?
                        ripl.SizzleExpr.attrHandle[ name ]( elem ) :
                    elem[ name ] != null ?
                        elem[ name ] :
                        elem.getAttribute( name ),
                value = result + "",
                type = match[2],
                check = match[4];

            return result == null ?
                type === "!=" :
                type === "=" ?
                value === check :
                type === "*=" ?
                value.indexOf(check) >= 0 :
                type === "~=" ?
                (" " + value + " ").indexOf(check) >= 0 :
                !check ?
                value && result !== false :
                type === "!=" ?
                value != check :
                type === "^=" ?
                value.indexOf(check) === 0 :
                type === "$=" ?
                value.substr(value.length - check.length) === check :
                type === "|=" ?
                value === check || value.substr(0, check.length + 1) === check + "-" :
                false;
        },
        POS: function(elem, match, i, array){
            var name = match[2], filter = ripl.SizzleExpr.setFilters[ name ];

            if ( filter ) {
                return filter( elem, i, match, array );
            }
        }
    }
};

ripl.SizzleData.dirNodeCheck = function( dir, cur, doneName, checkSet, nodeCheck, isXML ) 
{
    var sibDir = dir == "previousSibling" && !isXML;
    for ( var i = 0, l = checkSet.length; i < l; i++ ) {
        var elem = checkSet[i];
        if ( elem ) {
            if ( sibDir && elem.nodeType === 1 ){
                elem.sizcache = doneName;
                elem.sizset = i;
            }
            elem = elem[dir];
            var match = false;

            while ( elem ) {
                if ( elem.sizcache === doneName ) {
                    match = checkSet[elem.sizset];
                    break;
                }

                if ( elem.nodeType === 1 && !isXML ){
                    elem.sizcache = doneName;
                    elem.sizset = i;
                }

                if ( elem.nodeName.toLowerCase() === cur ) {
                    match = elem;
                    break;
                }

                elem = elem[dir];
            }

            checkSet[i] = match;
        }
    }
};

ripl.SizzleData.dirCheck = function( dir, cur, doneName, checkSet, nodeCheck, isXML ) 
{
    var sibDir = dir == "previousSibling" && !isXML;
    for ( var i = 0, l = checkSet.length; i < l; i++ ) {
        var elem = checkSet[i];
        if ( elem ) {
            if ( sibDir && elem.nodeType === 1 ) {
                elem.sizcache = doneName;
                elem.sizset = i;
            }
            elem = elem[dir];
            var match = false;

            while ( elem ) {
                if ( elem.sizcache === doneName ) {
                    match = checkSet[elem.sizset];
                    break;
                }

                if ( elem.nodeType === 1 ) {
                    if ( !isXML ) {
                        elem.sizcache = doneName;
                        elem.sizset = i;
                    }
                    if ( typeof cur !== "string" ) {
                        if ( elem === cur ) {
                            match = true;
                            break;
                        }

                    } else if ( ripl.Sizzle.filter( cur, [elem] ).length > 0 ) {
                        match = elem;
                        break;
                    }
                }

                elem = elem[dir];
            }

            checkSet[i] = match;
        }
    }
};

ripl.SizzleData.contains = document.compareDocumentPosition ? function(a, b){
    return a.compareDocumentPosition(b) & 16;
} : function(a, b){
    return a !== b && (a.contains ? a.contains(b) : true);
};

ripl.SizzleData.isXML = function(elem){
    // documentElement is verified for cases where it doesn't yet exist
    // (such as loading iframes in IE - #4833) 
    var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
    return documentElement ? documentElement.nodeName !== "HTML" : false;
};

ripl.SizzleData.posProcess = function(selector, context)
{
    var tmpSet = [], later = "", match,
        root = context.nodeType ? [context] : context;

    // Position selectors must be done after the filter
    // And so must :not(positional) so we move all PSEUDOs to the end
    while ( (match = ripl.SizzleExpr.match.PSEUDO.exec( selector )) ) {
        later += match[0];
        selector = selector.replace( ripl.SizzleExpr.match.PSEUDO, "" );
    }

    selector = ripl.SizzleExpr.relative[selector] ? selector + "*" : selector;

    for ( var i = 0, l = root.length; i < l; i++ ) {
        ripl.Sizzle( selector, root[i], tmpSet );
    }

    return ripl.Sizzle.filter( later, tmpSet );
};
ripl.SizzleData.origPos =  ripl.SizzleExpr.match.POS;

for (var pType in ripl.SizzleExpr.match ) {
    ripl.SizzleExpr.match[ pType ] = new RegExp( ripl.SizzleExpr.match[ pType ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
    ripl.SizzleExpr.leftMatch[ pType ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + ripl.SizzleExpr.match[ pType ].source );
}
ripl.SizzleData.makeArray = function(array, results) {
    array = Array.prototype.slice.call( array, 0 );

    if ( results ) {
        results.push.apply( results, array );
        return results;
    }
    
    return array;
};

// Perform a simple check to determine if the browser is capable of
// converting a NodeList to an array using builtin methods.
try 
{
    Array.prototype.slice.call( document.documentElement.childNodes, 0 );

// Provide a fallback method if it does not work
} 
catch(e)
{
    ripl.SizzleData.makeArray = function(array, results) {
        var ret = results || [];

        if ( ripl.SizzleData.toString.call(array) === "[object Array]" ) {
            Array.prototype.push.apply( ret, array );
        } else {
            if ( typeof array.length === "number" ) {
                for ( var i = 0, l = array.length; i < l; i++ ) {
                    ret.push( array[i] );
                }
            } else {
                for ( var i = 0; array[i]; i++ ) {
                    ret.push( array[i] );
                }
            }
        }
        return ret;
    };
}

if ( document.documentElement.compareDocumentPosition ) {
    ripl.SizzleData.sortOrder = function( a, b ) {
        if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
            if ( a == b ) {
                ripl.SizzleData.hasDuplicate = true;
            }
            return a.compareDocumentPosition ? -1 : 1;
        }

        var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
        if ( ret === 0 ) {
            ripl.SizzleData.hasDuplicate = true;
        }
        return ret;
    };
} else if ( "sourceIndex" in document.documentElement ) {
    ripl.SizzleData.sortOrder = function( a, b ) {
        if ( !a.sourceIndex || !b.sourceIndex ) {
            if ( a == b ) {
                ripl.SizzleData.hasDuplicate = true;
            }
            return a.sourceIndex ? -1 : 1;
        }

        var ret = a.sourceIndex - b.sourceIndex;
        if ( ret === 0 ) {
            ripl.SizzleData.hasDuplicate = true;
        }
        return ret;
    };
} else if ( document.createRange ) {
    ripl.SizzleData.sortOrder = function( a, b ) {
        if ( !a.ownerDocument || !b.ownerDocument ) {
            if ( a == b ) {
                ripl.SizzleData.hasDuplicate = true;
            }
            return a.ownerDocument ? -1 : 1;
        }

        var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
        aRange.setStart(a, 0);
        aRange.setEnd(a, 0);
        bRange.setStart(b, 0);
        bRange.setEnd(b, 0);
        var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
        if ( ret === 0 ) {
            ripl.SizzleData.hasDuplicate = true;
        }
        return ret;
    };
}

//Utility function for retreiving the text value of an array of DOM nodes
ripl.SizzleData.getText = function(elems)
{
    var ret = "", elem;

    for ( var i = 0; elems[i]; i++ ) {
        elem = elems[i];

        // Get the text from text nodes and CDATA nodes
        if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
            ret += elem.nodeValue;

        // Traverse everything else, except comment nodes
        } else if ( elem.nodeType !== 8 ) {
            ret += ripl.SizzleData.getText( elem.childNodes );
        }
    }

    return ret;
}


ripl.SizzleData.form = document.createElement("div"),
id = "script" + (new Date()).getTime();
ripl.SizzleData.form.innerHTML = "<a name='" + id + "'/>";

// Inject it into the root element, check its status, and remove it quickly
var root = document.documentElement;
root.insertBefore( ripl.SizzleData.form, root.firstChild );

// The workaround has to do additional checks after a getElementById
// Which slows things down for other browsers (hence the branching)
if ( document.getElementById( id ) ) 
{
    ripl.SizzleExpr.find.ID = function(match, context, isXML)
    {
        if ( typeof context.getElementById !== "undefined" && !isXML ) {
            var m = context.getElementById(match[1]);
            return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
        }
    };

    ripl.SizzleExpr.filter.ID = function(elem, match){
        var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
        return elem.nodeType === 1 && node && node.nodeValue === match;
    };
}
root.removeChild( ripl.SizzleData.form );
root = ripl.SizzleData.form = null; // release memory in IE
delete ripl.SizzleData.form;


// Check to see if the browser returns only elements
// when doing getElementsByTagName("*")

// Create a fake element
ripl.SizzleData.div = document.createElement("div");
ripl.SizzleData.div.appendChild( document.createComment("") );

// Make sure no comments are found
if ( ripl.SizzleData.div.getElementsByTagName("*").length > 0 ) {
    ripl.SizzleExpr.find.TAG = function(match, context){
        var results = context.getElementsByTagName(match[1]);

        // Filter out possible comments
        if ( match[1] === "*" ) {
            var tmp = [];

            for ( var i = 0; results[i]; i++ ) {
                if ( results[i].nodeType === 1 ) {
                    tmp.push( results[i] );
                }
            }

            results = tmp;
        }

        return results;
    };
}

// Check to see if an attribute returns normalized href attributes
ripl.SizzleData.div.innerHTML = "<a href='#'></a>";
if ( ripl.SizzleData.div.firstChild && typeof ripl.SizzleData.div.firstChild.getAttribute !== "undefined" &&
        ripl.SizzleData.div.firstChild.getAttribute("href") !== "#" ) {
    ripl.SizzleExpr.attrHandle.href = function(elem){
        return elem.getAttribute("href", 2);
    };
}

ripl.SizzleData.div = null; // release memory in IE
delete ripl.SizzleData.div;



if ( document.querySelectorAll ) 
{
    var oldSizzle = ripl.Sizzle, div = document.createElement("div");
    div.innerHTML = "<p class='TEST'></p>";

    // Safari can't handle uppercase or unicode characters when
    // in quirks mode.
    if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) 
    {
    }
    else
    {
        ripl.Sizzle = function(query, context, extra, seed)
        {
            context = context || document;
    
            // Only use querySelectorAll on non-XML documents
            // (ID selectors don't work in non-HTML documents)
            if ( !seed && context.nodeType === 9 && !ripl.SizzleData.isXML(context) ) 
            {
                try {
                    return ripl.SizzleData.makeArray( context.querySelectorAll(query), extra );
                } catch(e){}
            }
        
            return oldSizzle(query, context, extra, seed);
        };
    
        for ( var prop in oldSizzle ) {
            ripl.Sizzle[ prop ] = oldSizzle[ prop ];
        }
    }
    div = null; // release memory in IE
}

ripl.SizzleData.div = document.createElement("div");

ripl.SizzleData.div.innerHTML = "<div class='test e'></div><div class='test'></div>";

// Opera can't find a second classname (in 9.6)
// Also, make sure that getElementsByClassName actually exists
if ( !ripl.SizzleData.div.getElementsByClassName || ripl.SizzleData.div.getElementsByClassName("e").length === 0 ) {}
else
{
    // Safari caches class attributes, doesn't catch changes (in 3.2)
    ripl.SizzleData.div.lastChild.className = "e";
    
    if ( ripl.SizzleData.div.getElementsByClassName("e").length === 1 ) {}
    else
    {
        
        ripl.SizzleExpr.order.splice(1, 0, "CLASS");
        ripl.SizzleExpr.find.CLASS = function(match, context, isXML) {
            if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
                return context.getElementsByClassName(match[1]);
            }
        };
    }
}
ripl.SizzleData.div = null; // release memory in IE
delete ripl.SizzleData.div;


        




