/* START MicrosoftAjax.js */
//----------------------------------------------------------
// Copyright (C) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------
// MicrosoftAjax.js
Function.__typeName="Function";Function.__class=true;Function.createCallback=function(b,a){return function(){var e=arguments.length;if(e>0){var d=[];for(var c=0;c<e;c++)d[c]=arguments[c];d[e]=a;return b.apply(this,d)}return b.call(this,a)}};Function.createDelegate=function(a,b){return function(){return b.apply(a,arguments)}};Function.emptyFunction=Function.emptyMethod=function(){};Function._validateParams=function(e,c){var a;a=Function._validateParameterCount(e,c);if(a){a.popStackFrame();return a}for(var b=0;b<e.length;b++){var d=c[Math.min(b,c.length-1)],f=d.name;if(d.parameterArray)f+="["+(b-c.length+1)+"]";a=Function._validateParameter(e[b],d,f);if(a){a.popStackFrame();return a}}return null};Function._validateParameterCount=function(e,a){var c=a.length,d=0;for(var b=0;b<a.length;b++)if(a[b].parameterArray)c=Number.MAX_VALUE;else if(!a[b].optional)d++;if(e.length<d||e.length>c){var f=Error.parameterCount();f.popStackFrame();return f}return null};Function._validateParameter=function(c,a,h){var b,g=a.type,l=!!a.integer,k=!!a.domElement,m=!!a.mayBeNull;b=Function._validateParameterType(c,g,l,k,m,h);if(b){b.popStackFrame();return b}var e=a.elementType,f=!!a.elementMayBeNull;if(g===Array&&typeof c!=="undefined"&&c!==null&&(e||!f)){var j=!!a.elementInteger,i=!!a.elementDomElement;for(var d=0;d<c.length;d++){var n=c[d];b=Function._validateParameterType(n,e,j,i,f,h+"["+d+"]");if(b){b.popStackFrame();return b}}}return null};Function._validateParameterType=function(a,c,n,m,k,d){var b;if(typeof a==="undefined")if(k)return null;else{b=Error.argumentUndefined(d);b.popStackFrame();return b}if(a===null)if(k)return null;else{b=Error.argumentNull(d);b.popStackFrame();return b}if(c&&c.__enum){if(typeof a!=="number"){b=Error.argumentType(d,Object.getType(a),c);b.popStackFrame();return b}if(a%1===0){var e=c.prototype;if(!c.__flags||a===0){for(var i in e)if(e[i]===a)return null}else{var l=a;for(var i in e){var f=e[i];if(f===0)continue;if((f&a)===f)l-=f;if(l===0)return null}}}b=Error.argumentOutOfRange(d,a,String.format(Sys.Res.enumInvalidValue,a,c.getName()));b.popStackFrame();return b}if(m){var h;if(typeof a.nodeType!=="number"){var g=a.ownerDocument||a.document||a;if(g!=a){var j=g.defaultView||g.parentWindow;h=j!=a&&!(j.document&&a.document&&j.document===a.document)}else h=typeof g.body==="undefined"}else h=a.nodeType===3;if(h){b=Error.argument(d,Sys.Res.argumentDomElement);b.popStackFrame();return b}}if(c&&!c.isInstanceOfType(a)){b=Error.argumentType(d,Object.getType(a),c);b.popStackFrame();return b}if(c===Number&&n)if(a%1!==0){b=Error.argumentOutOfRange(d,a,Sys.Res.argumentInteger);b.popStackFrame();return b}return null};Error.__typeName="Error";Error.__class=true;Error.create=function(d,b){var a=new Error(d);a.message=d;if(b)for(var c in b)a[c]=b[c];a.popStackFrame();return a};Error.argument=function(a,c){var b="Sys.ArgumentException: "+(c?c:Sys.Res.argument);if(a)b+="\n"+String.format(Sys.Res.paramName,a);var d=Error.create(b,{name:"Sys.ArgumentException",paramName:a});d.popStackFrame();return d};Error.argumentNull=function(a,c){var b="Sys.ArgumentNullException: "+(c?c:Sys.Res.argumentNull);if(a)b+="\n"+String.format(Sys.Res.paramName,a);var d=Error.create(b,{name:"Sys.ArgumentNullException",paramName:a});d.popStackFrame();return d};Error.argumentOutOfRange=function(c,a,d){var b="Sys.ArgumentOutOfRangeException: "+(d?d:Sys.Res.argumentOutOfRange);if(c)b+="\n"+String.format(Sys.Res.paramName,c);if(typeof a!=="undefined"&&a!==null)b+="\n"+String.format(Sys.Res.actualValue,a);var e=Error.create(b,{name:"Sys.ArgumentOutOfRangeException",paramName:c,actualValue:a});e.popStackFrame();return e};Error.argumentType=function(d,c,b,e){var a="Sys.ArgumentTypeException: ";if(e)a+=e;else if(c&&b)a+=String.format(Sys.Res.argumentTypeWithTypes,c.getName(),b.getName());else a+=Sys.Res.argumentType;if(d)a+="\n"+String.format(Sys.Res.paramName,d);var f=Error.create(a,{name:"Sys.ArgumentTypeException",paramName:d,actualType:c,expectedType:b});f.popStackFrame();return f};Error.argumentUndefined=function(a,c){var b="Sys.ArgumentUndefinedException: "+(c?c:Sys.Res.argumentUndefined);if(a)b+="\n"+String.format(Sys.Res.paramName,a);var d=Error.create(b,{name:"Sys.ArgumentUndefinedException",paramName:a});d.popStackFrame();return d};Error.format=function(a){var c="Sys.FormatException: "+(a?a:Sys.Res.format),b=Error.create(c,{name:"Sys.FormatException"});b.popStackFrame();return b};Error.invalidOperation=function(a){var c="Sys.InvalidOperationException: "+(a?a:Sys.Res.invalidOperation),b=Error.create(c,{name:"Sys.InvalidOperationException"});b.popStackFrame();return b};Error.notImplemented=function(a){var c="Sys.NotImplementedException: "+(a?a:Sys.Res.notImplemented),b=Error.create(c,{name:"Sys.NotImplementedException"});b.popStackFrame();return b};Error.parameterCount=function(a){var c="Sys.ParameterCountException: "+(a?a:Sys.Res.parameterCount),b=Error.create(c,{name:"Sys.ParameterCountException"});b.popStackFrame();return b};Error.prototype.popStackFrame=function(){if(typeof this.stack==="undefined"||this.stack===null||typeof this.fileName==="undefined"||this.fileName===null||typeof this.lineNumber==="undefined"||this.lineNumber===null)return;var a=this.stack.split("\n"),c=a[0],e=this.fileName+":"+this.lineNumber;while(typeof c!=="undefined"&&c!==null&&c.indexOf(e)===-1){a.shift();c=a[0]}var d=a[1];if(typeof d==="undefined"||d===null)return;var b=d.match(/@(.*):(\d+)$/);if(typeof b==="undefined"||b===null)return;this.fileName=b[1];this.lineNumber=parseInt(b[2]);a.shift();this.stack=a.join("\n")};Object.__typeName="Object";Object.__class=true;Object.getType=function(b){var a=b.constructor;if(!a||typeof a!=="function"||!a.__typeName||a.__typeName==="Object")return Object;return a};Object.getTypeName=function(a){return Object.getType(a).getName()};String.__typeName="String";String.__class=true;String.prototype.endsWith=function(a){return this.substr(this.length-a.length)===a};String.prototype.startsWith=function(a){return this.substr(0,a.length)===a};String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")};String.prototype.trimEnd=function(){return this.replace(/\s+$/,"")};String.prototype.trimStart=function(){return this.replace(/^\s+/,"")};String.format=function(){return String._toFormattedString(false,arguments)};String.localeFormat=function(){return String._toFormattedString(true,arguments)};String._toFormattedString=function(l,j){var c="",e=j[0];for(var a=0;true;){var f=e.indexOf("{",a),d=e.indexOf("}",a);if(f<0&&d<0){c+=e.slice(a);break}if(d>0&&(d<f||f<0)){c+=e.slice(a,d+1);a=d+2;continue}c+=e.slice(a,f);a=f+1;if(e.charAt(a)==="{"){c+="{";a++;continue}if(d<0)break;var h=e.substring(a,d),g=h.indexOf(":"),k=parseInt(g<0?h:h.substring(0,g),10)+1,i=g<0?"":h.substring(g+1),b=j[k];if(typeof b==="undefined"||b===null)b="";if(b.toFormattedString)c+=b.toFormattedString(i);else if(l&&b.localeFormat)c+=b.localeFormat(i);else if(b.format)c+=b.format(i);else c+=b.toString();a=d+1}return c};Boolean.__typeName="Boolean";Boolean.__class=true;Boolean.parse=function(b){var a=b.trim().toLowerCase();if(a==="false")return false;if(a==="true")return true};Date.__typeName="Date";Date.__class=true;Date._appendPreOrPostMatch=function(e,b){var d=0,a=false;for(var c=0,g=e.length;c<g;c++){var f=e.charAt(c);switch(f){case "'":if(a)b.append("'");else d++;a=false;break;case "\\":if(a)b.append("\\");a=!a;break;default:b.append(f);a=false}}return d};Date._expandFormat=function(a,b){if(!b)b="F";if(b.length===1)switch(b){case "d":return a.ShortDatePattern;case "D":return a.LongDatePattern;case "t":return a.ShortTimePattern;case "T":return a.LongTimePattern;case "F":return a.FullDateTimePattern;case "M":case "m":return a.MonthDayPattern;case "s":return a.SortableDateTimePattern;case "Y":case "y":return a.YearMonthPattern;default:throw Error.format(Sys.Res.formatInvalidString)}return b};Date._expandYear=function(c,a){if(a<100){var b=(new Date).getFullYear();a+=b-b%100;if(a>c.Calendar.TwoDigitYearMax)return a-100}return a};Date._getParseRegExp=function(b,e){if(!b._parseRegExp)b._parseRegExp={};else if(b._parseRegExp[e])return b._parseRegExp[e];var c=Date._expandFormat(b,e);c=c.replace(/([\^\$\.\*\+\?\|\[\]\(\)\{\}])/g,"\\\\$1");var a=new Sys.StringBuilder("^"),j=[],f=0,i=0,h=Date._getTokenRegExp(),d;while((d=h.exec(c))!==null){var l=c.slice(f,d.index);f=h.lastIndex;i+=Date._appendPreOrPostMatch(l,a);if(i%2===1){a.append(d[0]);continue}switch(d[0]){case "dddd":case "ddd":case "MMMM":case "MMM":a.append("(\\D+)");break;case "tt":case "t":a.append("(\\D*)");break;case "yyyy":a.append("(\\d{4})");break;case "fff":a.append("(\\d{3})");break;case "ff":a.append("(\\d{2})");break;case "f":a.append("(\\d)");break;case "dd":case "d":case "MM":case "M":case "yy":case "y":case "HH":case "H":case "hh":case "h":case "mm":case "m":case "ss":case "s":a.append("(\\d\\d?)");break;case "zzz":a.append("([+-]?\\d\\d?:\\d{2})");break;case "zz":case "z":a.append("([+-]?\\d\\d?)")}Array.add(j,d[0])}Date._appendPreOrPostMatch(c.slice(f),a);a.append("$");var k=a.toString().replace(/\s+/g,"\\s+"),g={"regExp":k,"groups":j};b._parseRegExp[e]=g;return g};Date._getTokenRegExp=function(){return /dddd|ddd|dd|d|MMMM|MMM|MM|M|yyyy|yy|y|hh|h|HH|H|mm|m|ss|s|tt|t|fff|ff|f|zzz|zz|z/g};Date.parseLocale=function(a){return Date._parse(a,Sys.CultureInfo.CurrentCulture,arguments)};Date.parseInvariant=function(a){return Date._parse(a,Sys.CultureInfo.InvariantCulture,arguments)};Date._parse=function(g,c,h){var e=false;for(var a=1,i=h.length;a<i;a++){var f=h[a];if(f){e=true;var b=Date._parseExact(g,f,c);if(b)return b}}if(!e){var d=c._getDateTimeFormats();for(var a=0,i=d.length;a<i;a++){var b=Date._parseExact(g,d[a],c);if(b)return b}}return null};Date._parseExact=function(s,y,j){s=s.trim();var m=j.dateTimeFormat,v=Date._getParseRegExp(m,y),x=(new RegExp(v.regExp)).exec(s);if(x===null)return null;var w=v.groups,f=null,c=null,h=null,g=null,d=0,n=0,o=0,e=0,k=null,r=false;for(var p=0,z=w.length;p<z;p++){var a=x[p+1];if(a)switch(w[p]){case "dd":case "d":h=parseInt(a,10);if(h<1||h>31)return null;break;case "MMMM":c=j._getMonthIndex(a);if(c<0||c>11)return null;break;case "MMM":c=j._getAbbrMonthIndex(a);if(c<0||c>11)return null;break;case "M":case "MM":var c=parseInt(a,10)-1;if(c<0||c>11)return null;break;case "y":case "yy":f=Date._expandYear(m,parseInt(a,10));if(f<0||f>9999)return null;break;case "yyyy":f=parseInt(a,10);if(f<0||f>9999)return null;break;case "h":case "hh":d=parseInt(a,10);if(d===12)d=0;if(d<0||d>11)return null;break;case "H":case "HH":d=parseInt(a,10);if(d<0||d>23)return null;break;case "m":case "mm":n=parseInt(a,10);if(n<0||n>59)return null;break;case "s":case "ss":o=parseInt(a,10);if(o<0||o>59)return null;break;case "tt":case "t":var u=a.toUpperCase();r=u===m.PMDesignator.toUpperCase();if(!r&&u!==m.AMDesignator.toUpperCase())return null;break;case "f":e=parseInt(a,10)*100;if(e<0||e>999)return null;break;case "ff":e=parseInt(a,10)*10;if(e<0||e>999)return null;break;case "fff":e=parseInt(a,10);if(e<0||e>999)return null;break;case "dddd":g=j._getDayIndex(a);if(g<0||g>6)return null;break;case "ddd":g=j._getAbbrDayIndex(a);if(g<0||g>6)return null;break;case "zzz":var q=a.split(/:/);if(q.length!==2)return null;var i=parseInt(q[0],10);if(i<-12||i>13)return null;var l=parseInt(q[1],10);if(l<0||l>59)return null;k=i*60+(a.startsWith("-")?-l:l);break;case "z":case "zz":var i=parseInt(a,10);if(i<-12||i>13)return null;k=i*60}}var b=new Date;if(f===null)f=b.getFullYear();if(c===null)c=b.getMonth();if(h===null)h=b.getDate();b.setFullYear(f,c,h);if(b.getDate()!==h)return null;if(g!==null&&b.getDay()!==g)return null;if(r&&d<12)d+=12;b.setHours(d,n,o,e);if(k!==null){var t=b.getMinutes()-(k+b.getTimezoneOffset());b.setHours(b.getHours()+parseInt(t/60,10),t%60)}return b};Date.prototype.format=function(a){return this._toFormattedString(a,Sys.CultureInfo.InvariantCulture)};Date.prototype.localeFormat=function(a){return this._toFormattedString(a,Sys.CultureInfo.CurrentCulture)};Date.prototype._toFormattedString=function(e,h){if(!e||e.length===0||e==="i")if(h&&h.name.length>0)return this.toLocaleString();else return this.toString();var d=h.dateTimeFormat;e=Date._expandFormat(d,e);var a=new Sys.StringBuilder,b;function c(a){if(a<10)return "0"+a;return a.toString()}function g(a){if(a<10)return "00"+a;if(a<100)return "0"+a;return a.toString()}var j=0,i=Date._getTokenRegExp();for(;true;){var l=i.lastIndex,f=i.exec(e),k=e.slice(l,f?f.index:e.length);j+=Date._appendPreOrPostMatch(k,a);if(!f)break;if(j%2===1){a.append(f[0]);continue}switch(f[0]){case "dddd":a.append(d.DayNames[this.getDay()]);break;case "ddd":a.append(d.AbbreviatedDayNames[this.getDay()]);break;case "dd":a.append(c(this.getDate()));break;case "d":a.append(this.getDate());break;case "MMMM":a.append(d.MonthNames[this.getMonth()]);break;case "MMM":a.append(d.AbbreviatedMonthNames[this.getMonth()]);break;case "MM":a.append(c(this.getMonth()+1));break;case "M":a.append(this.getMonth()+1);break;case "yyyy":a.append(this.getFullYear());break;case "yy":a.append(c(this.getFullYear()%100));break;case "y":a.append(this.getFullYear()%100);break;case "hh":b=this.getHours()%12;if(b===0)b=12;a.append(c(b));break;case "h":b=this.getHours()%12;if(b===0)b=12;a.append(b);break;case "HH":a.append(c(this.getHours()));break;case "H":a.append(this.getHours());break;case "mm":a.append(c(this.getMinutes()));break;case "m":a.append(this.getMinutes());break;case "ss":a.append(c(this.getSeconds()));break;case "s":a.append(this.getSeconds());break;case "tt":a.append(this.getHours()<12?d.AMDesignator:d.PMDesignator);break;case "t":a.append((this.getHours()<12?d.AMDesignator:d.PMDesignator).charAt(0));break;case "f":a.append(g(this.getMilliseconds()).charAt(0));break;case "ff":a.append(g(this.getMilliseconds()).substr(0,2));break;case "fff":a.append(g(this.getMilliseconds()));break;case "z":b=this.getTimezoneOffset()/60;a.append((b<=0?"+":"-")+Math.floor(Math.abs(b)));break;case "zz":b=this.getTimezoneOffset()/60;a.append((b<=0?"+":"-")+c(Math.floor(Math.abs(b))));break;case "zzz":b=this.getTimezoneOffset()/60;a.append((b<=0?"+":"-")+c(Math.floor(Math.abs(b)))+d.TimeSeparator+c(Math.abs(this.getTimezoneOffset()%60)))}}return a.toString()};Number.__typeName="Number";Number.__class=true;Number.parseLocale=function(a){return Number._parse(a,Sys.CultureInfo.CurrentCulture)};Number.parseInvariant=function(a){return Number._parse(a,Sys.CultureInfo.InvariantCulture)};Number._parse=function(b,o){b=b.trim();if(b.match(/^[+-]?infinity$/i))return parseFloat(b);if(b.match(/^0x[a-f0-9]+$/i))return parseInt(b);var a=o.numberFormat,g=Number._parseNumberNegativePattern(b,a,a.NumberNegativePattern),h=g[0],e=g[1];if(h===""&&a.NumberNegativePattern!==1){g=Number._parseNumberNegativePattern(b,a,1);h=g[0];e=g[1]}if(h==="")h="+";var j,d,f=e.indexOf("e");if(f<0)f=e.indexOf("E");if(f<0){d=e;j=null}else{d=e.substr(0,f);j=e.substr(f+1)}var c,k,m=d.indexOf(a.NumberDecimalSeparator);if(m<0){c=d;k=null}else{c=d.substr(0,m);k=d.substr(m+a.NumberDecimalSeparator.length)}c=c.split(a.NumberGroupSeparator).join("");var n=a.NumberGroupSeparator.replace(/\u00A0/g," ");if(a.NumberGroupSeparator!==n)c=c.split(n).join("");var l=h+c;if(k!==null)l+="."+k;if(j!==null){var i=Number._parseNumberNegativePattern(j,a,1);if(i[0]==="")i[0]="+";l+="e"+i[0]+i[1]}if(l.match(/^[+-]?\d*\.?\d*(e[+-]?\d+)?$/))return parseFloat(l);return Number.NaN};Number._parseNumberNegativePattern=function(a,d,e){var b=d.NegativeSign,c=d.PositiveSign;switch(e){case 4:b=" "+b;c=" "+c;case 3:if(a.endsWith(b))return ["-",a.substr(0,a.length-b.length)];else if(a.endsWith(c))return ["+",a.substr(0,a.length-c.length)];break;case 2:b+=" ";c+=" ";case 1:if(a.startsWith(b))return ["-",a.substr(b.length)];else if(a.startsWith(c))return ["+",a.substr(c.length)];break;case 0:if(a.startsWith("(")&&a.endsWith(")"))return ["-",a.substr(1,a.length-2)]}return ["",a]};Number.prototype.format=function(a){return this._toFormattedString(a,Sys.CultureInfo.InvariantCulture)};Number.prototype.localeFormat=function(a){return this._toFormattedString(a,Sys.CultureInfo.CurrentCulture)};Number.prototype._toFormattedString=function(d,j){if(!d||d.length===0||d==="i")if(j&&j.name.length>0)return this.toLocaleString();else return this.toString();var o=["n %","n%","%n"],n=["-n %","-n%","-%n"],p=["(n)","-n","- n","n-","n -"],m=["$n","n$","$ n","n $"],l=["($n)","-$n","$-n","$n-","(n$)","-n$","n-$","n$-","-n $","-$ n","n $-","$ n-","$ -n","n- $","($ n)","(n $)"];function g(a,c,d){for(var b=a.length;b<c;b++)a=d?"0"+a:a+"0";return a}function i(j,i,l,n,p){var h=l[0],k=1,o=Math.pow(10,i),m=Math.round(j*o)/o;if(!isFinite(m))m=j;j=m;var b=j.toString(),a="",c,e=b.split(/e/i);b=e[0];c=e.length>1?parseInt(e[1]):0;e=b.split(".");b=e[0];a=e.length>1?e[1]:"";var q;if(c>0){a=g(a,c,false);b+=a.slice(0,c);a=a.substr(c)}else if(c<0){c=-c;b=g(b,c+1,true);a=b.slice(-c,b.length)+a;b=b.slice(0,-c)}if(i>0){if(a.length>i)a=a.slice(0,i);else a=g(a,i,false);a=p+a}else a="";var d=b.length-1,f="";while(d>=0){if(h===0||h>d)if(f.length>0)return b.slice(0,d+1)+n+f+a;else return b.slice(0,d+1)+a;if(f.length>0)f=b.slice(d-h+1,d+1)+n+f;else f=b.slice(d-h+1,d+1);d-=h;if(k<l.length){h=l[k];k++}}return b.slice(0,d+1)+n+f+a}var a=j.numberFormat,e=Math.abs(this);if(!d)d="D";var b=-1;if(d.length>1)b=parseInt(d.slice(1),10);var c;switch(d.charAt(0)){case "d":case "D":c="n";if(b!==-1)e=g(""+e,b,true);if(this<0)e=-e;break;case "c":case "C":if(this<0)c=l[a.CurrencyNegativePattern];else c=m[a.CurrencyPositivePattern];if(b===-1)b=a.CurrencyDecimalDigits;e=i(Math.abs(this),b,a.CurrencyGroupSizes,a.CurrencyGroupSeparator,a.CurrencyDecimalSeparator);break;case "n":case "N":if(this<0)c=p[a.NumberNegativePattern];else c="n";if(b===-1)b=a.NumberDecimalDigits;e=i(Math.abs(this),b,a.NumberGroupSizes,a.NumberGroupSeparator,a.NumberDecimalSeparator);break;case "p":case "P":if(this<0)c=n[a.PercentNegativePattern];else c=o[a.PercentPositivePattern];if(b===-1)b=a.PercentDecimalDigits;e=i(Math.abs(this)*100,b,a.PercentGroupSizes,a.PercentGroupSeparator,a.PercentDecimalSeparator);break;default:throw Error.format(Sys.Res.formatBadFormatSpecifier)}var k=/n|\$|-|%/g,f="";for(;true;){var q=k.lastIndex,h=k.exec(c);f+=c.slice(q,h?h.index:c.length);if(!h)break;switch(h[0]){case "n":f+=e;break;case "$":f+=a.CurrencySymbol;break;case "-":f+=a.NegativeSign;break;case "%":f+=a.PercentSymbol}}return f};RegExp.__typeName="RegExp";RegExp.__class=true;Array.__typeName="Array";Array.__class=true;Array.add=Array.enqueue=function(a,b){a[a.length]=b};Array.addRange=function(a,b){a.push.apply(a,b)};Array.clear=function(a){a.length=0};Array.clone=function(a){if(a.length===1)return [a[0]];else return Array.apply(null,a)};Array.contains=function(a,b){return Array.indexOf(a,b)>=0};Array.dequeue=function(a){return a.shift()};Array.forEach=function(b,e,d){for(var a=0,f=b.length;a<f;a++){var c=b[a];if(typeof c!=="undefined")e.call(d,c,a,b)}};Array.indexOf=function(d,e,a){if(typeof e==="undefined")return -1;var c=d.length;if(c!==0){a=a-0;if(isNaN(a))a=0;else{if(isFinite(a))a=a-a%1;if(a<0)a=Math.max(0,c+a)}for(var b=a;b<c;b++)if(typeof d[b]!=="undefined"&&d[b]===e)return b}return -1};Array.insert=function(a,b,c){a.splice(b,0,c)};Array.parse=function(value){if(!value)return [];return eval(value)};Array.remove=function(b,c){var a=Array.indexOf(b,c);if(a>=0)b.splice(a,1);return a>=0};Array.removeAt=function(a,b){a.splice(b,1)};if(!window)this.window=this;window.Type=Function;Type.prototype.callBaseMethod=function(a,d,b){var c=this.getBaseMethod(a,d);if(!b)return c.apply(a);else return c.apply(a,b)};Type.prototype.getBaseMethod=function(d,c){var b=this.getBaseType();if(b){var a=b.prototype[c];return a instanceof Function?a:null}return null};Type.prototype.getBaseType=function(){return typeof this.__baseType==="undefined"?null:this.__baseType};Type.prototype.getInterfaces=function(){var a=[],b=this;while(b){var c=b.__interfaces;if(c)for(var d=0,f=c.length;d<f;d++){var e=c[d];if(!Array.contains(a,e))a[a.length]=e}b=b.__baseType}return a};Type.prototype.getName=function(){return typeof this.__typeName==="undefined"?"":this.__typeName};Type.prototype.implementsInterface=function(d){this.resolveInheritance();var c=d.getName(),a=this.__interfaceCache;if(a){var e=a[c];if(typeof e!=="undefined")return e}else a=this.__interfaceCache={};var b=this;while(b){var f=b.__interfaces;if(f)if(Array.indexOf(f,d)!==-1)return a[c]=true;b=b.__baseType}return a[c]=false};Type.prototype.inheritsFrom=function(b){this.resolveInheritance();var a=this.__baseType;while(a){if(a===b)return true;a=a.__baseType}return false};Type.prototype.initializeBase=function(a,b){this.resolveInheritance();if(this.__baseType)if(!b)this.__baseType.apply(a);else this.__baseType.apply(a,b);return a};Type.prototype.isImplementedBy=function(a){if(typeof a==="undefined"||a===null)return false;var b=Object.getType(a);return !!(b.implementsInterface&&b.implementsInterface(this))};Type.prototype.isInstanceOfType=function(b){if(typeof b==="undefined"||b===null)return false;if(b instanceof this)return true;var a=Object.getType(b);return !!(a===this)||a.inheritsFrom&&a.inheritsFrom(this)||a.implementsInterface&&a.implementsInterface(this)};Type.prototype.registerClass=function(c,b,d){this.prototype.constructor=this;this.__typeName=c;this.__class=true;if(b){this.__baseType=b;this.__basePrototypePending=true}Sys.__upperCaseTypes[c.toUpperCase()]=this;if(d){this.__interfaces=[];for(var a=2,f=arguments.length;a<f;a++){var e=arguments[a];this.__interfaces.push(e)}}return this};Type.prototype.registerInterface=function(a){Sys.__upperCaseTypes[a.toUpperCase()]=this;this.prototype.constructor=this;this.__typeName=a;this.__interface=true;return this};Type.prototype.resolveInheritance=function(){if(this.__basePrototypePending){var b=this.__baseType;b.resolveInheritance();for(var a in b.prototype){var c=b.prototype[a];if(!this.prototype[a])this.prototype[a]=c}delete this.__basePrototypePending}};Type.getRootNamespaces=function(){return Array.clone(Sys.__rootNamespaces)};Type.isClass=function(a){if(typeof a==="undefined"||a===null)return false;return !!a.__class};Type.isInterface=function(a){if(typeof a==="undefined"||a===null)return false;return !!a.__interface};Type.isNamespace=function(a){if(typeof a==="undefined"||a===null)return false;return !!a.__namespace};Type.parse=function(typeName,ns){var fn;if(ns){fn=Sys.__upperCaseTypes[ns.getName().toUpperCase()+"."+typeName.toUpperCase()];return fn||null}if(!typeName)return null;if(!Type.__htClasses)Type.__htClasses={};fn=Type.__htClasses[typeName];if(!fn){fn=eval(typeName);Type.__htClasses[typeName]=fn}return fn};Type.registerNamespace=function(f){var d=window,c=f.split(".");for(var b=0;b<c.length;b++){var e=c[b],a=d[e];if(!a){a=d[e]={__namespace:true,__typeName:c.slice(0,b+1).join(".")};if(b===0)Sys.__rootNamespaces[Sys.__rootNamespaces.length]=a;a.getName=function(){return this.__typeName}}d=a}};window.Sys={__namespace:true,__typeName:"Sys",getName:function(){return "Sys"},__upperCaseTypes:{}};Sys.__rootNamespaces=[Sys];Sys.IDisposable=function(){};Sys.IDisposable.prototype={};Sys.IDisposable.registerInterface("Sys.IDisposable");Sys.StringBuilder=function(a){this._parts=typeof a!=="undefined"&&a!==null&&a!==""?[a.toString()]:[];this._value={};this._len=0};Sys.StringBuilder.prototype={append:function(a){this._parts[this._parts.length]=a},appendLine:function(a){this._parts[this._parts.length]=typeof a==="undefined"||a===null||a===""?"\r\n":a+"\r\n"},clear:function(){this._parts=[];this._value={};this._len=0},isEmpty:function(){if(this._parts.length===0)return true;return this.toString()===""},toString:function(a){a=a||"";var b=this._parts;if(this._len!==b.length){this._value={};this._len=b.length}var d=this._value;if(typeof d[a]==="undefined"){if(a!=="")for(var c=0;c<b.length;)if(typeof b[c]==="undefined"||b[c]===""||b[c]===null)b.splice(c,1);else c++;d[a]=this._parts.join(a)}return d[a]}};Sys.StringBuilder.registerClass("Sys.StringBuilder");if(!window.XMLHttpRequest)window.XMLHttpRequest=function(){var b=["Msxml2.XMLHTTP.3.0","Msxml2.XMLHTTP"];for(var a=0,c=b.length;a<c;a++)try{return new ActiveXObject(b[a])}catch(d){}return null};Sys.Browser={};Sys.Browser.InternetExplorer={};Sys.Browser.Firefox={};Sys.Browser.Safari={};Sys.Browser.Opera={};Sys.Browser.agent=null;Sys.Browser.hasDebuggerStatement=false;Sys.Browser.name=navigator.appName;Sys.Browser.version=parseFloat(navigator.appVersion);Sys.Browser.documentMode=0;if(navigator.userAgent.indexOf(" MSIE ")>-1){Sys.Browser.agent=Sys.Browser.InternetExplorer;Sys.Browser.version=parseFloat(navigator.userAgent.match(/MSIE (\d+\.\d+)/)[1]);if(Sys.Browser.version>=8)if(document.documentMode>=7)Sys.Browser.documentMode=document.documentMode;Sys.Browser.hasDebuggerStatement=true}else if(navigator.userAgent.indexOf(" Firefox/")>-1){Sys.Browser.agent=Sys.Browser.Firefox;Sys.Browser.version=parseFloat(navigator.userAgent.match(/Firefox\/(\d+\.\d+)/)[1]);Sys.Browser.name="Firefox";Sys.Browser.hasDebuggerStatement=true}else if(navigator.userAgent.indexOf(" AppleWebKit/")>-1){Sys.Browser.agent=Sys.Browser.Safari;Sys.Browser.version=parseFloat(navigator.userAgent.match(/AppleWebKit\/(\d+(\.\d+)?)/)[1]);Sys.Browser.name="Safari"}else if(navigator.userAgent.indexOf("Opera/")>-1)Sys.Browser.agent=Sys.Browser.Opera;Type.registerNamespace("Sys.UI");Sys._Debug=function(){};Sys._Debug.prototype={_appendConsole:function(a){if(typeof Debug!=="undefined"&&Debug.writeln)Debug.writeln(a);if(window.console&&window.console.log)window.console.log(a);if(window.opera)window.opera.postError(a);if(window.debugService)window.debugService.trace(a)},_appendTrace:function(b){var a=document.getElementById("TraceConsole");if(a&&a.tagName.toUpperCase()==="TEXTAREA")a.value+=b+"\n"},assert:function(c,a,b){if(!c){a=b&&this.assert.caller?String.format(Sys.Res.assertFailedCaller,a,this.assert.caller):String.format(Sys.Res.assertFailed,a);if(confirm(String.format(Sys.Res.breakIntoDebugger,a)))this.fail(a)}},clearTrace:function(){var a=document.getElementById("TraceConsole");if(a&&a.tagName.toUpperCase()==="TEXTAREA")a.value=""},fail:function(message){this._appendConsole(message);if(Sys.Browser.hasDebuggerStatement)eval("debugger")},trace:function(a){this._appendConsole(a);this._appendTrace(a)},traceDump:function(a,b){var c=this._traceDump(a,b,true)},_traceDump:function(a,c,f,b,d){c=c?c:"traceDump";b=b?b:"";if(a===null){this.trace(b+c+": null");return}switch(typeof a){case "undefined":this.trace(b+c+": Undefined");break;case "number":case "string":case "boolean":this.trace(b+c+": "+a);break;default:if(Date.isInstanceOfType(a)||RegExp.isInstanceOfType(a)){this.trace(b+c+": "+a.toString());break}if(!d)d=[];else if(Array.contains(d,a)){this.trace(b+c+": ...");return}Array.add(d,a);if(a==window||a===document||window.HTMLElement&&a instanceof HTMLElement||typeof a.nodeName==="string"){var k=a.tagName?a.tagName:"DomElement";if(a.id)k+=" - "+a.id;this.trace(b+c+" {"+k+"}")}else{var i=Object.getTypeName(a);this.trace(b+c+(typeof i==="string"?" {"+i+"}":""));if(b===""||f){b+="    ";var e,j,l,g,h;if(Array.isInstanceOfType(a)){j=a.length;for(e=0;e<j;e++)this._traceDump(a[e],"["+e+"]",f,b,d)}else for(g in a){h=a[g];if(!Function.isInstanceOfType(h))this._traceDump(h,g,f,b,d)}}}Array.remove(d,a)}}};Sys._Debug.registerClass("Sys._Debug");Sys.Debug=new Sys._Debug;Sys.Debug.isDebug=false;function Sys$Enum$parse(c,e){var a,b,i;if(e){a=this.__lowerCaseValues;if(!a){this.__lowerCaseValues=a={};var g=this.prototype;for(var f in g)a[f.toLowerCase()]=g[f]}}else a=this.prototype;if(!this.__flags){i=e?c.toLowerCase():c;b=a[i.trim()];if(typeof b!=="number")throw Error.argument("value",String.format(Sys.Res.enumInvalidValue,c,this.__typeName));return b}else{var h=(e?c.toLowerCase():c).split(","),j=0;for(var d=h.length-1;d>=0;d--){var k=h[d].trim();b=a[k];if(typeof b!=="number")throw Error.argument("value",String.format(Sys.Res.enumInvalidValue,c.split(",")[d].trim(),this.__typeName));j|=b}return j}}function Sys$Enum$toString(c){if(typeof c==="undefined"||c===null)return this.__string;var d=this.prototype,a;if(!this.__flags||c===0){for(a in d)if(d[a]===c)return a}else{var b=this.__sortedValues;if(!b){b=[];for(a in d)b[b.length]={key:a,value:d[a]};b.sort(function(a,b){return a.value-b.value});this.__sortedValues=b}var e=[],g=c;for(a=b.length-1;a>=0;a--){var h=b[a],f=h.value;if(f===0)continue;if((f&c)===f){e[e.length]=h.key;g-=f;if(g===0)break}}if(e.length&&g===0)return e.reverse().join(", ")}return ""}Type.prototype.registerEnum=function(b,c){Sys.__upperCaseTypes[b.toUpperCase()]=this;for(var a in this.prototype)this[a]=this.prototype[a];this.__typeName=b;this.parse=Sys$Enum$parse;this.__string=this.toString();this.toString=Sys$Enum$toString;this.__flags=c;this.__enum=true};Type.isEnum=function(a){if(typeof a==="undefined"||a===null)return false;return !!a.__enum};Type.isFlags=function(a){if(typeof a==="undefined"||a===null)return false;return !!a.__flags};Sys.EventHandlerList=function(){this._list={}};Sys.EventHandlerList.prototype={addHandler:function(b,a){Array.add(this._getEvent(b,true),a)},removeHandler:function(c,b){var a=this._getEvent(c);if(!a)return;Array.remove(a,b)},getHandler:function(b){var a=this._getEvent(b);if(!a||a.length===0)return null;a=Array.clone(a);return function(c,d){for(var b=0,e=a.length;b<e;b++)a[b](c,d)}},_getEvent:function(a,b){if(!this._list[a]){if(!b)return null;this._list[a]=[]}return this._list[a]}};Sys.EventHandlerList.registerClass("Sys.EventHandlerList");Sys.EventArgs=function(){};Sys.EventArgs.registerClass("Sys.EventArgs");Sys.EventArgs.Empty=new Sys.EventArgs;Sys.CancelEventArgs=function(){Sys.CancelEventArgs.initializeBase(this);this._cancel=false};Sys.CancelEventArgs.prototype={get_cancel:function(){return this._cancel},set_cancel:function(a){this._cancel=a}};Sys.CancelEventArgs.registerClass("Sys.CancelEventArgs",Sys.EventArgs);Sys.INotifyPropertyChange=function(){};Sys.INotifyPropertyChange.prototype={};Sys.INotifyPropertyChange.registerInterface("Sys.INotifyPropertyChange");Sys.PropertyChangedEventArgs=function(a){Sys.PropertyChangedEventArgs.initializeBase(this);this._propertyName=a};Sys.PropertyChangedEventArgs.prototype={get_propertyName:function(){return this._propertyName}};Sys.PropertyChangedEventArgs.registerClass("Sys.PropertyChangedEventArgs",Sys.EventArgs);Sys.INotifyDisposing=function(){};Sys.INotifyDisposing.prototype={};Sys.INotifyDisposing.registerInterface("Sys.INotifyDisposing");Sys.Component=function(){if(Sys.Application)Sys.Application.registerDisposableObject(this)};Sys.Component.prototype={_id:null,_initialized:false,_updating:false,get_events:function(){if(!this._events)this._events=new Sys.EventHandlerList;return this._events},get_id:function(){return this._id},set_id:function(a){this._id=a},get_isInitialized:function(){return this._initialized},get_isUpdating:function(){return this._updating},add_disposing:function(a){this.get_events().addHandler("disposing",a)},remove_disposing:function(a){this.get_events().removeHandler("disposing",a)},add_propertyChanged:function(a){this.get_events().addHandler("propertyChanged",a)},remove_propertyChanged:function(a){this.get_events().removeHandler("propertyChanged",a)},beginUpdate:function(){this._updating=true},dispose:function(){if(this._events){var a=this._events.getHandler("disposing");if(a)a(this,Sys.EventArgs.Empty)}delete this._events;Sys.Application.unregisterDisposableObject(this);Sys.Application.removeComponent(this)},endUpdate:function(){this._updating=false;if(!this._initialized)this.initialize();this.updated()},initialize:function(){this._initialized=true},raisePropertyChanged:function(b){if(!this._events)return;var a=this._events.getHandler("propertyChanged");if(a)a(this,new Sys.PropertyChangedEventArgs(b))},updated:function(){}};Sys.Component.registerClass("Sys.Component",null,Sys.IDisposable,Sys.INotifyPropertyChange,Sys.INotifyDisposing);function Sys$Component$_setProperties(a,i){var d,j=Object.getType(a),e=j===Object||j===Sys.UI.DomElement,h=Sys.Component.isInstanceOfType(a)&&!a.get_isUpdating();if(h)a.beginUpdate();for(var c in i){var b=i[c],f=e?null:a["get_"+c];if(e||typeof f!=="function"){var k=a[c];if(!b||typeof b!=="object"||e&&!k)a[c]=b;else Sys$Component$_setProperties(k,b)}else{var l=a["set_"+c];if(typeof l==="function")l.apply(a,[b]);else if(b instanceof Array){d=f.apply(a);for(var g=0,m=d.length,n=b.length;g<n;g++,m++)d[m]=b[g]}else if(typeof b==="object"&&Object.getType(b)===Object){d=f.apply(a);Sys$Component$_setProperties(d,b)}}}if(h)a.endUpdate()}function Sys$Component$_setReferences(c,b){for(var a in b){var e=c["set_"+a],d=$find(b[a]);e.apply(c,[d])}}var $create=Sys.Component.create=function(h,f,d,c,g){var a=g?new h(g):new h,b=Sys.Application,i=b.get_isCreatingComponents();a.beginUpdate();if(f)Sys$Component$_setProperties(a,f);if(d)for(var e in d)a["add_"+e](d[e]);if(a.get_id())b.addComponent(a);if(i){b._createdComponents[b._createdComponents.length]=a;if(c)b._addComponentToSecondPass(a,c);else a.endUpdate()}else{if(c)Sys$Component$_setReferences(a,c);a.endUpdate()}return a};Sys.UI.MouseButton=function(){throw Error.notImplemented()};Sys.UI.MouseButton.prototype={leftButton:0,middleButton:1,rightButton:2};Sys.UI.MouseButton.registerEnum("Sys.UI.MouseButton");Sys.UI.Key=function(){throw Error.notImplemented()};Sys.UI.Key.prototype={backspace:8,tab:9,enter:13,esc:27,space:32,pageUp:33,pageDown:34,end:35,home:36,left:37,up:38,right:39,down:40,del:127};Sys.UI.Key.registerEnum("Sys.UI.Key");Sys.UI.Point=function(a,b){this.x=a;this.y=b};Sys.UI.Point.registerClass("Sys.UI.Point");Sys.UI.Bounds=function(c,d,b,a){this.x=c;this.y=d;this.height=a;this.width=b};Sys.UI.Bounds.registerClass("Sys.UI.Bounds");Sys.UI.DomEvent=function(e){var a=e,b=this.type=a.type.toLowerCase();this.rawEvent=a;this.altKey=a.altKey;if(typeof a.button!=="undefined")this.button=typeof a.which!=="undefined"?a.button:a.button===4?Sys.UI.MouseButton.middleButton:a.button===2?Sys.UI.MouseButton.rightButton:Sys.UI.MouseButton.leftButton;if(b==="keypress")this.charCode=a.charCode||a.keyCode;else if(a.keyCode&&a.keyCode===46)this.keyCode=127;else this.keyCode=a.keyCode;this.clientX=a.clientX;this.clientY=a.clientY;this.ctrlKey=a.ctrlKey;this.target=a.target?a.target:a.srcElement;if(!b.startsWith("key"))if(typeof a.offsetX!=="undefined"&&typeof a.offsetY!=="undefined"){this.offsetX=a.offsetX;this.offsetY=a.offsetY}else if(this.target&&this.target.nodeType!==3&&typeof a.clientX==="number"){var c=Sys.UI.DomElement.getLocation(this.target),d=Sys.UI.DomElement._getWindow(this.target);this.offsetX=(d.pageXOffset||0)+a.clientX-c.x;this.offsetY=(d.pageYOffset||0)+a.clientY-c.y}this.screenX=a.screenX;this.screenY=a.screenY;this.shiftKey=a.shiftKey};Sys.UI.DomEvent.prototype={preventDefault:function(){if(this.rawEvent.preventDefault)this.rawEvent.preventDefault();else if(window.event)this.rawEvent.returnValue=false},stopPropagation:function(){if(this.rawEvent.stopPropagation)this.rawEvent.stopPropagation();else if(window.event)this.rawEvent.cancelBubble=true}};Sys.UI.DomEvent.registerClass("Sys.UI.DomEvent");var $addHandler=Sys.UI.DomEvent.addHandler=function(a,d,e){if(!a._events)a._events={};var c=a._events[d];if(!c)a._events[d]=c=[];var b;if(a.addEventListener){b=function(b){return e.call(a,new Sys.UI.DomEvent(b))};a.addEventListener(d,b,false)}else if(a.attachEvent){b=function(){var b={};try{b=Sys.UI.DomElement._getWindow(a).event}catch(c){}return e.call(a,new Sys.UI.DomEvent(b))};a.attachEvent("on"+d,b)}c[c.length]={handler:e,browserHandler:b}},$addHandlers=Sys.UI.DomEvent.addHandlers=function(e,d,c){for(var b in d){var a=d[b];if(c)a=Function.createDelegate(c,a);$addHandler(e,b,a)}},$clearHandlers=Sys.UI.DomEvent.clearHandlers=function(a){if(a._events){var e=a._events;for(var b in e){var d=e[b];for(var c=d.length-1;c>=0;c--)$removeHandler(a,b,d[c].handler)}a._events=null}},$removeHandler=Sys.UI.DomEvent.removeHandler=function(a,e,f){var d=null,c=a._events[e];for(var b=0,g=c.length;b<g;b++)if(c[b].handler===f){d=c[b].browserHandler;break}if(a.removeEventListener)a.removeEventListener(e,d,false);else if(a.detachEvent)a.detachEvent("on"+e,d);c.splice(b,1)};Sys.UI.DomElement=function(){};Sys.UI.DomElement.registerClass("Sys.UI.DomElement");Sys.UI.DomElement.addCssClass=function(a,b){if(!Sys.UI.DomElement.containsCssClass(a,b))if(a.className==="")a.className=b;else a.className+=" "+b};Sys.UI.DomElement.containsCssClass=function(b,a){return Array.contains(b.className.split(" "),a)};Sys.UI.DomElement.getBounds=function(a){var b=Sys.UI.DomElement.getLocation(a);return new Sys.UI.Bounds(b.x,b.y,a.offsetWidth||0,a.offsetHeight||0)};var $get=Sys.UI.DomElement.getElementById=function(f,e){if(!e)return document.getElementById(f);if(e.getElementById)return e.getElementById(f);var c=[],d=e.childNodes;for(var b=0;b<d.length;b++){var a=d[b];if(a.nodeType==1)c[c.length]=a}while(c.length){a=c.shift();if(a.id==f)return a;d=a.childNodes;for(b=0;b<d.length;b++){a=d[b];if(a.nodeType==1)c[c.length]=a}}return null};switch(Sys.Browser.agent){case Sys.Browser.InternetExplorer:Sys.UI.DomElement.getLocation=function(a){if(a.self||a.nodeType===9)return new Sys.UI.Point(0,0);var b=a.getBoundingClientRect();if(!b)return new Sys.UI.Point(0,0);var d=a.ownerDocument.documentElement,e=b.left-2+d.scrollLeft,f=b.top-2+d.scrollTop;try{var c=a.ownerDocument.parentWindow.frameElement||null;if(c){var g=c.frameBorder==="0"||c.frameBorder==="no"?2:0;e+=g;f+=g}}catch(h){}return new Sys.UI.Point(e,f)};break;case Sys.Browser.Safari:Sys.UI.DomElement.getLocation=function(c){if(c.window&&c.window===c||c.nodeType===9)return new Sys.UI.Point(0,0);var f=0,g=0,j=null,e=null,b;for(var a=c;a;j=a,(e=b,a=a.offsetParent)){b=Sys.UI.DomElement._getCurrentStyle(a);var d=a.tagName?a.tagName.toUpperCase():null;if((a.offsetLeft||a.offsetTop)&&(d!=="BODY"||(!e||e.position!=="absolute"))){f+=a.offsetLeft;g+=a.offsetTop}}b=Sys.UI.DomElement._getCurrentStyle(c);var h=b?b.position:null;if(!h||h!=="absolute")for(var a=c.parentNode;a;a=a.parentNode){d=a.tagName?a.tagName.toUpperCase():null;if(d!=="BODY"&&d!=="HTML"&&(a.scrollLeft||a.scrollTop)){f-=a.scrollLeft||0;g-=a.scrollTop||0}b=Sys.UI.DomElement._getCurrentStyle(a);var i=b?b.position:null;if(i&&i==="absolute")break}return new Sys.UI.Point(f,g)};break;case Sys.Browser.Opera:Sys.UI.DomElement.getLocation=function(b){if(b.window&&b.window===b||b.nodeType===9)return new Sys.UI.Point(0,0);var d=0,e=0,i=null;for(var a=b;a;i=a,a=a.offsetParent){var f=a.tagName;d+=a.offsetLeft||0;e+=a.offsetTop||0}var g=b.style.position,c=g&&g!=="static";for(var a=b.parentNode;a;a=a.parentNode){f=a.tagName?a.tagName.toUpperCase():null;if(f!=="BODY"&&f!=="HTML"&&(a.scrollLeft||a.scrollTop)&&(c&&(a.style.overflow==="scroll"||a.style.overflow==="auto"))){d-=a.scrollLeft||0;e-=a.scrollTop||0}var h=a&&a.style?a.style.position:null;c=c||h&&h!=="static"}return new Sys.UI.Point(d,e)};break;default:Sys.UI.DomElement.getLocation=function(d){if(d.window&&d.window===d||d.nodeType===9)return new Sys.UI.Point(0,0);var e=0,f=0,i=null,g=null,b=null;for(var a=d;a;i=a,(g=b,a=a.offsetParent)){var c=a.tagName?a.tagName.toUpperCase():null;b=Sys.UI.DomElement._getCurrentStyle(a);if((a.offsetLeft||a.offsetTop)&&!(c==="BODY"&&(!g||g.position!=="absolute"))){e+=a.offsetLeft;f+=a.offsetTop}if(i!==null&&b){if(c!=="TABLE"&&c!=="TD"&&c!=="HTML"){e+=parseInt(b.borderLeftWidth)||0;f+=parseInt(b.borderTopWidth)||0}if(c==="TABLE"&&(b.position==="relative"||b.position==="absolute")){e+=parseInt(b.marginLeft)||0;f+=parseInt(b.marginTop)||0}}}b=Sys.UI.DomElement._getCurrentStyle(d);var h=b?b.position:null;if(!h||h!=="absolute")for(var a=d.parentNode;a;a=a.parentNode){c=a.tagName?a.tagName.toUpperCase():null;if(c!=="BODY"&&c!=="HTML"&&(a.scrollLeft||a.scrollTop)){e-=a.scrollLeft||0;f-=a.scrollTop||0;b=Sys.UI.DomElement._getCurrentStyle(a);if(b){e+=parseInt(b.borderLeftWidth)||0;f+=parseInt(b.borderTopWidth)||0}}}return new Sys.UI.Point(e,f)}}Sys.UI.DomElement.removeCssClass=function(d,c){var a=" "+d.className+" ",b=a.indexOf(" "+c+" ");if(b>=0)d.className=(a.substr(0,b)+" "+a.substring(b+c.length+1,a.length)).trim()};Sys.UI.DomElement.setLocation=function(b,c,d){var a=b.style;a.position="absolute";a.left=c+"px";a.top=d+"px"};Sys.UI.DomElement.toggleCssClass=function(b,a){if(Sys.UI.DomElement.containsCssClass(b,a))Sys.UI.DomElement.removeCssClass(b,a);else Sys.UI.DomElement.addCssClass(b,a)};Sys.UI.DomElement.getVisibilityMode=function(a){return a._visibilityMode===Sys.UI.VisibilityMode.hide?Sys.UI.VisibilityMode.hide:Sys.UI.VisibilityMode.collapse};Sys.UI.DomElement.setVisibilityMode=function(a,b){Sys.UI.DomElement._ensureOldDisplayMode(a);if(a._visibilityMode!==b){a._visibilityMode=b;if(Sys.UI.DomElement.getVisible(a)===false)if(a._visibilityMode===Sys.UI.VisibilityMode.hide)a.style.display=a._oldDisplayMode;else a.style.display="none";a._visibilityMode=b}};Sys.UI.DomElement.getVisible=function(b){var a=b.currentStyle||Sys.UI.DomElement._getCurrentStyle(b);if(!a)return true;return a.visibility!=="hidden"&&a.display!=="none"};Sys.UI.DomElement.setVisible=function(a,b){if(b!==Sys.UI.DomElement.getVisible(a)){Sys.UI.DomElement._ensureOldDisplayMode(a);a.style.visibility=b?"visible":"hidden";if(b||a._visibilityMode===Sys.UI.VisibilityMode.hide)a.style.display=a._oldDisplayMode;else a.style.display="none"}};Sys.UI.DomElement._ensureOldDisplayMode=function(a){if(!a._oldDisplayMode){var b=a.currentStyle||Sys.UI.DomElement._getCurrentStyle(a);a._oldDisplayMode=b?b.display:null;if(!a._oldDisplayMode||a._oldDisplayMode==="none")switch(a.tagName.toUpperCase()){case "DIV":case "P":case "ADDRESS":case "BLOCKQUOTE":case "BODY":case "COL":case "COLGROUP":case "DD":case "DL":case "DT":case "FIELDSET":case "FORM":case "H1":case "H2":case "H3":case "H4":case "H5":case "H6":case "HR":case "IFRAME":case "LEGEND":case "OL":case "PRE":case "TABLE":case "TD":case "TH":case "TR":case "UL":a._oldDisplayMode="block";break;case "LI":a._oldDisplayMode="list-item";break;default:a._oldDisplayMode="inline"}}};Sys.UI.DomElement._getWindow=function(a){var b=a.ownerDocument||a.document||a;return b.defaultView||b.parentWindow};Sys.UI.DomElement._getCurrentStyle=function(a){if(a.nodeType===3)return null;var c=Sys.UI.DomElement._getWindow(a);if(a.documentElement)a=a.documentElement;var b=c&&a!==c&&c.getComputedStyle?c.getComputedStyle(a,null):a.currentStyle||a.style;if(!b&&Sys.Browser.agent===Sys.Browser.Safari&&a.style){var g=a.style.display,f=a.style.position;a.style.position="absolute";a.style.display="block";var e=c.getComputedStyle(a,null);a.style.display=g;a.style.position=f;b={};for(var d in e)b[d]=e[d];b.display="none"}return b};Sys.IContainer=function(){};Sys.IContainer.prototype={};Sys.IContainer.registerInterface("Sys.IContainer");Sys._ScriptLoader=function(){this._scriptsToLoad=null;this._sessions=[];this._scriptLoadedDelegate=Function.createDelegate(this,this._scriptLoadedHandler)};Sys._ScriptLoader.prototype={dispose:function(){this._stopSession();this._loading=false;if(this._events)delete this._events;this._sessions=null;this._currentSession=null;this._scriptLoadedDelegate=null},loadScripts:function(d,b,c,a){var e={allScriptsLoadedCallback:b,scriptLoadFailedCallback:c,scriptLoadTimeoutCallback:a,scriptsToLoad:this._scriptsToLoad,scriptTimeout:d};this._scriptsToLoad=null;this._sessions[this._sessions.length]=e;if(!this._loading)this._nextSession()},notifyScriptLoaded:function(){if(!this._loading)return;this._currentTask._notified++;if(Sys.Browser.agent===Sys.Browser.Safari)if(this._currentTask._notified===1)window.setTimeout(Function.createDelegate(this,function(){this._scriptLoadedHandler(this._currentTask.get_scriptElement(),true)}),0)},queueCustomScriptTag:function(a){if(!this._scriptsToLoad)this._scriptsToLoad=[];Array.add(this._scriptsToLoad,a)},queueScriptBlock:function(a){if(!this._scriptsToLoad)this._scriptsToLoad=[];Array.add(this._scriptsToLoad,{text:a})},queueScriptReference:function(a){if(!this._scriptsToLoad)this._scriptsToLoad=[];Array.add(this._scriptsToLoad,{src:a})},_createScriptElement:function(c){var a=document.createElement("script");a.type="text/javascript";for(var b in c)a[b]=c[b];return a},_loadScriptsInternal:function(){var b=this._currentSession;if(b.scriptsToLoad&&b.scriptsToLoad.length>0){var c=Array.dequeue(b.scriptsToLoad),a=this._createScriptElement(c);if(a.text&&Sys.Browser.agent===Sys.Browser.Safari){a.innerHTML=a.text;delete a.text}if(typeof c.src==="string"){this._currentTask=new Sys._ScriptLoaderTask(a,this._scriptLoadedDelegate);this._currentTask.execute()}else{document.getElementsByTagName("head")[0].appendChild(a);Sys._ScriptLoader._clearScript(a);this._loadScriptsInternal()}}else{this._stopSession();var d=b.allScriptsLoadedCallback;if(d)d(this);this._nextSession()}},_nextSession:function(){if(this._sessions.length===0){this._loading=false;this._currentSession=null;return}this._loading=true;var a=Array.dequeue(this._sessions);this._currentSession=a;if(a.scriptTimeout>0)this._timeoutCookie=window.setTimeout(Function.createDelegate(this,this._scriptLoadTimeoutHandler),a.scriptTimeout*1000);this._loadScriptsInternal()},_raiseError:function(a){var c=this._currentSession.scriptLoadFailedCallback,b=this._currentTask.get_scriptElement();this._stopSession();if(c){c(this,b,a);this._nextSession()}else{this._loading=false;throw Sys._ScriptLoader._errorScriptLoadFailed(b.src,a)}},_scriptLoadedHandler:function(a,b){if(b&&this._currentTask._notified)if(this._currentTask._notified>1)this._raiseError(true);else{Array.add(Sys._ScriptLoader._getLoadedScripts(),a.src);this._currentTask.dispose();this._currentTask=null;this._loadScriptsInternal()}else this._raiseError(false)},_scriptLoadTimeoutHandler:function(){var a=this._currentSession.scriptLoadTimeoutCallback;this._stopSession();if(a)a(this);this._nextSession()},_stopSession:function(){if(this._timeoutCookie){window.clearTimeout(this._timeoutCookie);this._timeoutCookie=null}if(this._currentTask){this._currentTask.dispose();this._currentTask=null}}};Sys._ScriptLoader.registerClass("Sys._ScriptLoader",null,Sys.IDisposable);Sys._ScriptLoader.getInstance=function(){var a=Sys._ScriptLoader._activeInstance;if(!a)a=Sys._ScriptLoader._activeInstance=new Sys._ScriptLoader;return a};Sys._ScriptLoader.isScriptLoaded=function(b){var a=document.createElement("script");a.src=b;return Array.contains(Sys._ScriptLoader._getLoadedScripts(),a.src)};Sys._ScriptLoader.readLoadedScripts=function(){if(!Sys._ScriptLoader._referencedScripts){var b=Sys._ScriptLoader._referencedScripts=[],c=document.getElementsByTagName("script");for(i=c.length-1;i>=0;i--){var d=c[i],a=d.src;if(a.length)if(!Array.contains(b,a))Array.add(b,a)}}};Sys._ScriptLoader._clearScript=function(a){if(!Sys.Debug.isDebug)a.parentNode.removeChild(a)};Sys._ScriptLoader._errorScriptLoadFailed=function(b,d){var a;if(d)a=Sys.Res.scriptLoadMultipleCallbacks;else a=Sys.Res.scriptLoadFailed;var e="Sys.ScriptLoadFailedException: "+String.format(a,b),c=Error.create(e,{name:"Sys.ScriptLoadFailedException","scriptUrl":b});c.popStackFrame();return c};Sys._ScriptLoader._getLoadedScripts=function(){if(!Sys._ScriptLoader._referencedScripts){Sys._ScriptLoader._referencedScripts=[];Sys._ScriptLoader.readLoadedScripts()}return Sys._ScriptLoader._referencedScripts};Sys._ScriptLoaderTask=function(b,a){this._scriptElement=b;this._completedCallback=a;this._notified=0};Sys._ScriptLoaderTask.prototype={get_scriptElement:function(){return this._scriptElement},dispose:function(){if(this._disposed)return;this._disposed=true;this._removeScriptElementHandlers();Sys._ScriptLoader._clearScript(this._scriptElement);this._scriptElement=null},execute:function(){this._addScriptElementHandlers();document.getElementsByTagName("head")[0].appendChild(this._scriptElement)},_addScriptElementHandlers:function(){this._scriptLoadDelegate=Function.createDelegate(this,this._scriptLoadHandler);if(Sys.Browser.agent!==Sys.Browser.InternetExplorer){this._scriptElement.readyState="loaded";$addHandler(this._scriptElement,"load",this._scriptLoadDelegate)}else $addHandler(this._scriptElement,"readystatechange",this._scriptLoadDelegate);if(this._scriptElement.addEventListener){this._scriptErrorDelegate=Function.createDelegate(this,this._scriptErrorHandler);this._scriptElement.addEventListener("error",this._scriptErrorDelegate,false)}},_removeScriptElementHandlers:function(){if(this._scriptLoadDelegate){var a=this.get_scriptElement();if(Sys.Browser.agent!==Sys.Browser.InternetExplorer)$removeHandler(a,"load",this._scriptLoadDelegate);else $removeHandler(a,"readystatechange",this._scriptLoadDelegate);if(this._scriptErrorDelegate){this._scriptElement.removeEventListener("error",this._scriptErrorDelegate,false);this._scriptErrorDelegate=null}this._scriptLoadDelegate=null}},_scriptErrorHandler:function(){if(this._disposed)return;this._completedCallback(this.get_scriptElement(),false)},_scriptLoadHandler:function(){if(this._disposed)return;var a=this.get_scriptElement();if(a.readyState!=="loaded"&&a.readyState!=="complete")return;var b=this;window.setTimeout(function(){b._completedCallback(a,true)},0)}};Sys._ScriptLoaderTask.registerClass("Sys._ScriptLoaderTask",null,Sys.IDisposable);Sys.ApplicationLoadEventArgs=function(b,a){Sys.ApplicationLoadEventArgs.initializeBase(this);this._components=b;this._isPartialLoad=a};Sys.ApplicationLoadEventArgs.prototype={get_components:function(){return this._components},get_isPartialLoad:function(){return this._isPartialLoad}};Sys.ApplicationLoadEventArgs.registerClass("Sys.ApplicationLoadEventArgs",Sys.EventArgs);Sys.HistoryEventArgs=function(a){Sys.HistoryEventArgs.initializeBase(this);this._state=a};Sys.HistoryEventArgs.prototype={get_state:function(){return this._state}};Sys.HistoryEventArgs.registerClass("Sys.HistoryEventArgs",Sys.EventArgs);Sys._Application=function(){Sys._Application.initializeBase(this);this._disposableObjects=[];this._components={};this._createdComponents=[];this._secondPassComponents=[];this._appLoadHandler=null;this._beginRequestHandler=null;this._clientId=null;this._currentEntry="";this._endRequestHandler=null;this._history=null;this._enableHistory=false;this._historyFrame=null;this._historyInitialized=false;this._historyInitialLength=0;this._historyLength=0;this._historyPointIsNew=false;this._ignoreTimer=false;this._initialState=null;this._state={};this._timerCookie=0;this._timerHandler=null;this._uniqueId=null;this._unloadHandlerDelegate=Function.createDelegate(this,this._unloadHandler);this._loadHandlerDelegate=Function.createDelegate(this,this._loadHandler);Sys.UI.DomEvent.addHandler(window,"unload",this._unloadHandlerDelegate);Sys.UI.DomEvent.addHandler(window,"load",this._loadHandlerDelegate)};Sys._Application.prototype={_creatingComponents:false,_disposing:false,get_isCreatingComponents:function(){return this._creatingComponents},get_stateString:function(){var a=window.location.hash;if(this._isSafari2()){var b=this._getHistory();if(b)a=b[window.history.length-this._historyInitialLength]}if(a.length>0&&a.charAt(0)==="#")a=a.substring(1);if(Sys.Browser.agent===Sys.Browser.Firefox)a=this._serializeState(this._deserializeState(a,true));return a},get_enableHistory:function(){return this._enableHistory},set_enableHistory:function(a){this._enableHistory=a},add_init:function(a){if(this._initialized)a(this,Sys.EventArgs.Empty);else this.get_events().addHandler("init",a)},remove_init:function(a){this.get_events().removeHandler("init",a)},add_load:function(a){this.get_events().addHandler("load",a)},remove_load:function(a){this.get_events().removeHandler("load",a)},add_navigate:function(a){this.get_events().addHandler("navigate",a)},remove_navigate:function(a){this.get_events().removeHandler("navigate",a)},add_unload:function(a){this.get_events().addHandler("unload",a)},remove_unload:function(a){this.get_events().removeHandler("unload",a)},addComponent:function(a){this._components[a.get_id()]=a},addHistoryPoint:function(c,f){this._ensureHistory();var b=this._state;for(var a in c){var d=c[a];if(d===null){if(typeof b[a]!=="undefined")delete b[a]}else b[a]=d}var e=this._serializeState(b);this._historyPointIsNew=true;this._setState(e,f);this._raiseNavigate()},beginCreateComponents:function(){this._creatingComponents=true},dispose:function(){if(!this._disposing){this._disposing=true;if(this._timerCookie){window.clearTimeout(this._timerCookie);delete this._timerCookie}if(this._endRequestHandler){Sys.WebForms.PageRequestManager.getInstance().remove_endRequest(this._endRequestHandler);delete this._endRequestHandler}if(this._beginRequestHandler){Sys.WebForms.PageRequestManager.getInstance().remove_beginRequest(this._beginRequestHandler);delete this._beginRequestHandler}if(window.pageUnload)window.pageUnload(this,Sys.EventArgs.Empty);var c=this.get_events().getHandler("unload");if(c)c(this,Sys.EventArgs.Empty);var b=Array.clone(this._disposableObjects);for(var a=0,e=b.length;a<e;a++)b[a].dispose();Array.clear(this._disposableObjects);Sys.UI.DomEvent.removeHandler(window,"unload",this._unloadHandlerDelegate);if(this._loadHandlerDelegate){Sys.UI.DomEvent.removeHandler(window,"load",this._loadHandlerDelegate);this._loadHandlerDelegate=null}var d=Sys._ScriptLoader.getInstance();if(d)d.dispose();Sys._Application.callBaseMethod(this,"dispose")}},endCreateComponents:function(){var b=this._secondPassComponents;for(var a=0,d=b.length;a<d;a++){var c=b[a].component;Sys$Component$_setReferences(c,b[a].references);c.endUpdate()}this._secondPassComponents=[];this._creatingComponents=false},findComponent:function(b,a){return a?Sys.IContainer.isInstanceOfType(a)?a.findComponent(b):a[b]||null:Sys.Application._components[b]||null},getComponents:function(){var a=[],b=this._components;for(var c in b)a[a.length]=b[c];return a},initialize:function(){if(!this._initialized&&!this._initializing){this._initializing=true;window.setTimeout(Function.createDelegate(this,this._doInitialize),0)}},notifyScriptLoaded:function(){var a=Sys._ScriptLoader.getInstance();if(a)a.notifyScriptLoaded()},registerDisposableObject:function(a){if(!this._disposing)this._disposableObjects[this._disposableObjects.length]=a},raiseLoad:function(){var b=this.get_events().getHandler("load"),a=new Sys.ApplicationLoadEventArgs(Array.clone(this._createdComponents),!this._initializing);if(b)b(this,a);if(window.pageLoad)window.pageLoad(this,a);this._createdComponents=[]},removeComponent:function(b){var a=b.get_id();if(a)delete this._components[a]},setServerId:function(a,b){this._clientId=a;this._uniqueId=b},setServerState:function(a){this._ensureHistory();this._state.__s=a;this._updateHiddenField(a)},unregisterDisposableObject:function(a){if(!this._disposing)Array.remove(this._disposableObjects,a)},_addComponentToSecondPass:function(b,a){this._secondPassComponents[this._secondPassComponents.length]={component:b,references:a}},_deserializeState:function(a,i){var e={};a=a||"";var b=a.indexOf("&&");if(b!==-1&&b+2<a.length){e.__s=a.substr(b+2);a=a.substr(0,b)}var g=a.split("&");for(var f=0,k=g.length;f<k;f++){var d=g[f],c=d.indexOf("=");if(c!==-1&&c+1<d.length){var j=d.substr(0,c),h=d.substr(c+1);e[j]=i?h:decodeURIComponent(h)}}return e},_doInitialize:function(){Sys._Application.callBaseMethod(this,"initialize");var b=this.get_events().getHandler("init");if(b){this.beginCreateComponents();b(this,Sys.EventArgs.Empty);this.endCreateComponents()}if(Sys.WebForms){this._beginRequestHandler=Function.createDelegate(this,this._onPageRequestManagerBeginRequest);Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(this._beginRequestHandler);this._endRequestHandler=Function.createDelegate(this,this._onPageRequestManagerEndRequest);Sys.WebForms.PageRequestManager.getInstance().add_endRequest(this._endRequestHandler)}var a=this.get_stateString();if(a!==this._currentEntry)this._navigate(a);this.raiseLoad();this._initializing=false},_enableHistoryInScriptManager:function(){this._enableHistory=true},_ensureHistory:function(){if(!this._historyInitialized&&this._enableHistory){if(Sys.Browser.agent===Sys.Browser.InternetExplorer&&Sys.Browser.documentMode<8){this._historyFrame=document.getElementById("__historyFrame");this._ignoreIFrame=true}if(this._isSafari2()){var a=document.getElementById("__history");this._setHistory([window.location.hash]);this._historyInitialLength=window.history.length}this._timerHandler=Function.createDelegate(this,this._onIdle);this._timerCookie=window.setTimeout(this._timerHandler,100);try{this._initialState=this._deserializeState(this.get_stateString())}catch(b){}this._historyInitialized=true}},_getHistory:function(){var a=document.getElementById("__history");if(!a)return "";var b=a.value;return b?Sys.Serialization.JavaScriptSerializer.deserialize(b,true):""},_isSafari2:function(){return Sys.Browser.agent===Sys.Browser.Safari&&Sys.Browser.version<=419.3},_loadHandler:function(){if(this._loadHandlerDelegate){Sys.UI.DomEvent.removeHandler(window,"load",this._loadHandlerDelegate);this._loadHandlerDelegate=null}this.initialize()},_navigate:function(c){this._ensureHistory();var b=this._deserializeState(c);if(this._uniqueId){var d=this._state.__s||"",a=b.__s||"";if(a!==d){this._updateHiddenField(a);__doPostBack(this._uniqueId,a);this._state=b;return}}this._setState(c);this._state=b;this._raiseNavigate()},_onIdle:function(){delete this._timerCookie;var a=this.get_stateString();if(a!==this._currentEntry){if(!this._ignoreTimer){this._historyPointIsNew=false;this._navigate(a);this._historyLength=window.history.length}}else this._ignoreTimer=false;this._timerCookie=window.setTimeout(this._timerHandler,100)},_onIFrameLoad:function(a){this._ensureHistory();if(!this._ignoreIFrame){this._historyPointIsNew=false;this._navigate(a)}this._ignoreIFrame=false},_onPageRequestManagerBeginRequest:function(){this._ignoreTimer=true},_onPageRequestManagerEndRequest:function(e,d){var b=d.get_dataItems()[this._clientId],a=document.getElementById("__EVENTTARGET");if(a&&a.value===this._uniqueId)a.value="";if(typeof b!=="undefined"){this.setServerState(b);this._historyPointIsNew=true}else this._ignoreTimer=false;var c=this._serializeState(this._state);if(c!==this._currentEntry){this._ignoreTimer=true;this._setState(c);this._raiseNavigate()}},_raiseNavigate:function(){var c=this.get_events().getHandler("navigate"),b={};for(var a in this._state)if(a!=="__s")b[a]=this._state[a];var d=new Sys.HistoryEventArgs(b);if(c)c(this,d)},_serializeState:function(d){var b=[];for(var a in d){var e=d[a];if(a==="__s")var c=e;else b[b.length]=a+"="+encodeURIComponent(e)}return b.join("&")+(c?"&&"+c:"")},_setHistory:function(b){var a=document.getElementById("__history");if(a)a.value=Sys.Serialization.JavaScriptSerializer.serialize(b)},_setState:function(a,c){a=a||"";if(a!==this._currentEntry){if(window.theForm){var e=window.theForm.action,f=e.indexOf("#");window.theForm.action=(f!==-1?e.substring(0,f):e)+"#"+a}if(this._historyFrame&&this._historyPointIsNew){this._ignoreIFrame=true;this._historyPointIsNew=false;var d=this._historyFrame.contentWindow.document;d.open("javascript:'<html></html>'");d.write("<html><head><title>"+(c||document.title)+"</title><scri"+'pt type="text/javascript">parent.Sys.Application._onIFrameLoad(\''+a+"');</scri"+"pt></head><body></body></html>");d.close()}this._ignoreTimer=false;var h=this.get_stateString();this._currentEntry=a;if(a!==h){if(this._isSafari2()){var g=this._getHistory();g[window.history.length-this._historyInitialLength+1]=a;this._setHistory(g);this._historyLength=window.history.length+1;var b=document.createElement("form");b.method="get";b.action="#"+a;document.appendChild(b);b.submit();document.removeChild(b)}else window.location.hash=a;if(typeof c!=="undefined"&&c!==null)document.title=c}}},_unloadHandler:function(){this.dispose()},_updateHiddenField:function(b){if(this._clientId){var a=document.getElementById(this._clientId);if(a)a.value=b}}};Sys._Application.registerClass("Sys._Application",Sys.Component,Sys.IContainer);Sys.Application=new Sys._Application;var $find=Sys.Application.findComponent;Type.registerNamespace("Sys.Net");Sys.Net.WebRequestExecutor=function(){this._webRequest=null;this._resultObject=null};Sys.Net.WebRequestExecutor.prototype={get_webRequest:function(){return this._webRequest},_set_webRequest:function(a){this._webRequest=a},get_started:function(){throw Error.notImplemented()},get_responseAvailable:function(){throw Error.notImplemented()},get_timedOut:function(){throw Error.notImplemented()},get_aborted:function(){throw Error.notImplemented()},get_responseData:function(){throw Error.notImplemented()},get_statusCode:function(){throw Error.notImplemented()},get_statusText:function(){throw Error.notImplemented()},get_xml:function(){throw Error.notImplemented()},get_object:function(){if(!this._resultObject)this._resultObject=Sys.Serialization.JavaScriptSerializer.deserialize(this.get_responseData());return this._resultObject},executeRequest:function(){throw Error.notImplemented()},abort:function(){throw Error.notImplemented()},getResponseHeader:function(){throw Error.notImplemented()},getAllResponseHeaders:function(){throw Error.notImplemented()}};Sys.Net.WebRequestExecutor.registerClass("Sys.Net.WebRequestExecutor");Sys.Net.XMLDOM=function(d){if(!window.DOMParser){var c=["Msxml2.DOMDocument.3.0","Msxml2.DOMDocument"];for(var b=0,f=c.length;b<f;b++)try{var a=new ActiveXObject(c[b]);a.async=false;a.loadXML(d);a.setProperty("SelectionLanguage","XPath");return a}catch(g){}}else try{var e=new window.DOMParser;return e.parseFromString(d,"text/xml")}catch(g){}return null};Sys.Net.XMLHttpExecutor=function(){Sys.Net.XMLHttpExecutor.initializeBase(this);var a=this;this._xmlHttpRequest=null;this._webRequest=null;this._responseAvailable=false;this._timedOut=false;this._timer=null;this._aborted=false;this._started=false;this._onReadyStateChange=function(){if(a._xmlHttpRequest.readyState===4){try{if(typeof a._xmlHttpRequest.status==="undefined")return}catch(b){return}a._clearTimer();a._responseAvailable=true;try{a._webRequest.completed(Sys.EventArgs.Empty)}finally{if(a._xmlHttpRequest!=null){a._xmlHttpRequest.onreadystatechange=Function.emptyMethod;a._xmlHttpRequest=null}}}};this._clearTimer=function(){if(a._timer!=null){window.clearTimeout(a._timer);a._timer=null}};this._onTimeout=function(){if(!a._responseAvailable){a._clearTimer();a._timedOut=true;a._xmlHttpRequest.onreadystatechange=Function.emptyMethod;a._xmlHttpRequest.abort();a._webRequest.completed(Sys.EventArgs.Empty);a._xmlHttpRequest=null}}};Sys.Net.XMLHttpExecutor.prototype={get_timedOut:function(){return this._timedOut},get_started:function(){return this._started},get_responseAvailable:function(){return this._responseAvailable},get_aborted:function(){return this._aborted},executeRequest:function(){this._webRequest=this.get_webRequest();var c=this._webRequest.get_body(),a=this._webRequest.get_headers();this._xmlHttpRequest=new XMLHttpRequest;this._xmlHttpRequest.onreadystatechange=this._onReadyStateChange;var e=this._webRequest.get_httpVerb();this._xmlHttpRequest.open(e,this._webRequest.getResolvedUrl(),true);if(a)for(var b in a){var f=a[b];if(typeof f!=="function")this._xmlHttpRequest.setRequestHeader(b,f)}if(e.toLowerCase()==="post"){if(a===null||!a["Content-Type"])this._xmlHttpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=utf-8");if(!c)c=""}var d=this._webRequest.get_timeout();if(d>0)this._timer=window.setTimeout(Function.createDelegate(this,this._onTimeout),d);this._xmlHttpRequest.send(c);this._started=true},getResponseHeader:function(b){var a;try{a=this._xmlHttpRequest.getResponseHeader(b)}catch(c){}if(!a)a="";return a},getAllResponseHeaders:function(){return this._xmlHttpRequest.getAllResponseHeaders()},get_responseData:function(){return this._xmlHttpRequest.responseText},get_statusCode:function(){var a=0;try{a=this._xmlHttpRequest.status}catch(b){}return a},get_statusText:function(){return this._xmlHttpRequest.statusText},get_xml:function(){var a=this._xmlHttpRequest.responseXML;if(!a||!a.documentElement){a=Sys.Net.XMLDOM(this._xmlHttpRequest.responseText);if(!a||!a.documentElement)return null}else if(navigator.userAgent.indexOf("MSIE")!==-1)a.setProperty("SelectionLanguage","XPath");if(a.documentElement.namespaceURI==="http://www.mozilla.org/newlayout/xml/parsererror.xml"&&a.documentElement.tagName==="parsererror")return null;if(a.documentElement.firstChild&&a.documentElement.firstChild.tagName==="parsererror")return null;return a},abort:function(){if(this._aborted||this._responseAvailable||this._timedOut)return;this._aborted=true;this._clearTimer();if(this._xmlHttpRequest&&!this._responseAvailable){this._xmlHttpRequest.onreadystatechange=Function.emptyMethod;this._xmlHttpRequest.abort();this._xmlHttpRequest=null;this._webRequest.completed(Sys.EventArgs.Empty)}}};Sys.Net.XMLHttpExecutor.registerClass("Sys.Net.XMLHttpExecutor",Sys.Net.WebRequestExecutor);Sys.Net._WebRequestManager=function(){this._defaultTimeout=0;this._defaultExecutorType="Sys.Net.XMLHttpExecutor"};Sys.Net._WebRequestManager.prototype={add_invokingRequest:function(a){this._get_eventHandlerList().addHandler("invokingRequest",a)},remove_invokingRequest:function(a){this._get_eventHandlerList().removeHandler("invokingRequest",a)},add_completedRequest:function(a){this._get_eventHandlerList().addHandler("completedRequest",a)},remove_completedRequest:function(a){this._get_eventHandlerList().removeHandler("completedRequest",a)},_get_eventHandlerList:function(){if(!this._events)this._events=new Sys.EventHandlerList;return this._events},get_defaultTimeout:function(){return this._defaultTimeout},set_defaultTimeout:function(a){this._defaultTimeout=a},get_defaultExecutorType:function(){return this._defaultExecutorType},set_defaultExecutorType:function(a){this._defaultExecutorType=a},executeRequest:function(webRequest){var executor=webRequest.get_executor();if(!executor){var failed=false;try{var executorType=eval(this._defaultExecutorType);executor=new executorType}catch(a){failed=true}webRequest.set_executor(executor)}if(executor.get_aborted())return;var evArgs=new Sys.Net.NetworkRequestEventArgs(webRequest),handler=this._get_eventHandlerList().getHandler("invokingRequest");if(handler)handler(this,evArgs);if(!evArgs.get_cancel())executor.executeRequest()}};Sys.Net._WebRequestManager.registerClass("Sys.Net._WebRequestManager");Sys.Net.WebRequestManager=new Sys.Net._WebRequestManager;Sys.Net.NetworkRequestEventArgs=function(a){Sys.Net.NetworkRequestEventArgs.initializeBase(this);this._webRequest=a};Sys.Net.NetworkRequestEventArgs.prototype={get_webRequest:function(){return this._webRequest}};Sys.Net.NetworkRequestEventArgs.registerClass("Sys.Net.NetworkRequestEventArgs",Sys.CancelEventArgs);Sys.Net.WebRequest=function(){this._url="";this._headers={};this._body=null;this._userContext=null;this._httpVerb=null;this._executor=null;this._invokeCalled=false;this._timeout=0};Sys.Net.WebRequest.prototype={add_completed:function(a){this._get_eventHandlerList().addHandler("completed",a)},remove_completed:function(a){this._get_eventHandlerList().removeHandler("completed",a)},completed:function(b){var a=Sys.Net.WebRequestManager._get_eventHandlerList().getHandler("completedRequest");if(a)a(this._executor,b);a=this._get_eventHandlerList().getHandler("completed");if(a)a(this._executor,b)},_get_eventHandlerList:function(){if(!this._events)this._events=new Sys.EventHandlerList;return this._events},get_url:function(){return this._url},set_url:function(a){this._url=a},get_headers:function(){return this._headers},get_httpVerb:function(){if(this._httpVerb===null){if(this._body===null)return "GET";return "POST"}return this._httpVerb},set_httpVerb:function(a){this._httpVerb=a},get_body:function(){return this._body},set_body:function(a){this._body=a},get_userContext:function(){return this._userContext},set_userContext:function(a){this._userContext=a},get_executor:function(){return this._executor},set_executor:function(a){this._executor=a;this._executor._set_webRequest(this)},get_timeout:function(){if(this._timeout===0)return Sys.Net.WebRequestManager.get_defaultTimeout();return this._timeout},set_timeout:function(a){this._timeout=a},getResolvedUrl:function(){return Sys.Net.WebRequest._resolveUrl(this._url)},invoke:function(){Sys.Net.WebRequestManager.executeRequest(this);this._invokeCalled=true}};Sys.Net.WebRequest._resolveUrl=function(b,a){if(b&&b.indexOf("://")!==-1)return b;if(!a||a.length===0){var d=document.getElementsByTagName("base")[0];if(d&&d.href&&d.href.length>0)a=d.href;else a=document.URL}var c=a.indexOf("?");if(c!==-1)a=a.substr(0,c);c=a.indexOf("#");if(c!==-1)a=a.substr(0,c);a=a.substr(0,a.lastIndexOf("/")+1);if(!b||b.length===0)return a;if(b.charAt(0)==="/"){var e=a.indexOf("://"),g=a.indexOf("/",e+3);return a.substr(0,g)+b}else{var f=a.lastIndexOf("/");return a.substr(0,f+1)+b}};Sys.Net.WebRequest._createQueryString=function(d,b){if(!b)b=encodeURIComponent;var a=new Sys.StringBuilder,f=0;for(var c in d){var e=d[c];if(typeof e==="function")continue;var g=Sys.Serialization.JavaScriptSerializer.serialize(e);if(f!==0)a.append("&");a.append(c);a.append("=");a.append(b(g));f++}return a.toString()};Sys.Net.WebRequest._createUrl=function(a,b){if(!b)return a;var d=Sys.Net.WebRequest._createQueryString(b);if(d.length>0){var c="?";if(a&&a.indexOf("?")!==-1)c="&";return a+c+d}else return a};Sys.Net.WebRequest.registerClass("Sys.Net.WebRequest");Sys.Net.WebServiceProxy=function(){};Sys.Net.WebServiceProxy.prototype={get_timeout:function(){return this._timeout},set_timeout:function(a){if(a<0)throw Error.argumentOutOfRange("value",a,Sys.Res.invalidTimeout);this._timeout=a},get_defaultUserContext:function(){return this._userContext},set_defaultUserContext:function(a){this._userContext=a},get_defaultSucceededCallback:function(){return this._succeeded},set_defaultSucceededCallback:function(a){this._succeeded=a},get_defaultFailedCallback:function(){return this._failed},set_defaultFailedCallback:function(a){this._failed=a},get_path:function(){return this._path},set_path:function(a){this._path=a},_invoke:function(d,e,g,f,c,b,a){if(c===null||typeof c==="undefined")c=this.get_defaultSucceededCallback();if(b===null||typeof b==="undefined")b=this.get_defaultFailedCallback();if(a===null||typeof a==="undefined")a=this.get_defaultUserContext();return Sys.Net.WebServiceProxy.invoke(d,e,g,f,c,b,a,this.get_timeout())}};Sys.Net.WebServiceProxy.registerClass("Sys.Net.WebServiceProxy");Sys.Net.WebServiceProxy.invoke=function(k,a,j,d,i,c,f,h){var b=new Sys.Net.WebRequest;b.get_headers()["Content-Type"]="application/json; charset=utf-8";if(!d)d={};var g=d;if(!j||!g)g={};b.set_url(Sys.Net.WebRequest._createUrl(k+"/"+encodeURIComponent(a),g));var e=null;if(!j){e=Sys.Serialization.JavaScriptSerializer.serialize(d);if(e==="{}")e=""}b.set_body(e);b.add_completed(l);if(h&&h>0)b.set_timeout(h);b.invoke();function l(d){if(d.get_responseAvailable()){var g=d.get_statusCode(),b=null;try{var e=d.getResponseHeader("Content-Type");if(e.startsWith("application/json"))b=d.get_object();else if(e.startsWith("text/xml"))b=d.get_xml();else b=d.get_responseData()}catch(m){}var k=d.getResponseHeader("jsonerror"),h=k==="true";if(h){if(b)b=new Sys.Net.WebServiceError(false,b.Message,b.StackTrace,b.ExceptionType)}else if(e.startsWith("application/json"))b=b.d;if(g<200||g>=300||h){if(c){if(!b||!h)b=new Sys.Net.WebServiceError(false,String.format(Sys.Res.webServiceFailedNoMsg,a),"","");b._statusCode=g;c(b,f,a)}}else if(i)i(b,f,a)}else{var j;if(d.get_timedOut())j=String.format(Sys.Res.webServiceTimedOut,a);else j=String.format(Sys.Res.webServiceFailedNoMsg,a);if(c)c(new Sys.Net.WebServiceError(d.get_timedOut(),j,"",""),f,a)}}return b};Sys.Net.WebServiceProxy._generateTypedConstructor=function(a){return function(b){if(b)for(var c in b)this[c]=b[c];this.__type=a}};Sys.Net.WebServiceError=function(c,d,b,a){this._timedOut=c;this._message=d;this._stackTrace=b;this._exceptionType=a;this._statusCode=-1};Sys.Net.WebServiceError.prototype={get_timedOut:function(){return this._timedOut},get_statusCode:function(){return this._statusCode},get_message:function(){return this._message},get_stackTrace:function(){return this._stackTrace},get_exceptionType:function(){return this._exceptionType}};Sys.Net.WebServiceError.registerClass("Sys.Net.WebServiceError");Type.registerNamespace("Sys.Services");Sys.Services._ProfileService=function(){Sys.Services._ProfileService.initializeBase(this);this.properties={}};Sys.Services._ProfileService.DefaultWebServicePath="";Sys.Services._ProfileService.prototype={_defaultLoadCompletedCallback:null,_defaultSaveCompletedCallback:null,_path:"",_timeout:0,get_defaultLoadCompletedCallback:function(){return this._defaultLoadCompletedCallback},set_defaultLoadCompletedCallback:function(a){this._defaultLoadCompletedCallback=a},get_defaultSaveCompletedCallback:function(){return this._defaultSaveCompletedCallback},set_defaultSaveCompletedCallback:function(a){this._defaultSaveCompletedCallback=a},get_path:function(){return this._path||""},load:function(c,d,e,f){var b,a;if(!c){a="GetAllPropertiesForCurrentUser";b={authenticatedUserOnly:false}}else{a="GetPropertiesForCurrentUser";b={properties:this._clonePropertyNames(c),authenticatedUserOnly:false}}this._invoke(this._get_path(),a,false,b,Function.createDelegate(this,this._onLoadComplete),Function.createDelegate(this,this._onLoadFailed),[d,e,f])},save:function(d,b,c,e){var a=this._flattenProperties(d,this.properties);this._invoke(this._get_path(),"SetPropertiesForCurrentUser",false,{values:a.value,authenticatedUserOnly:false},Function.createDelegate(this,this._onSaveComplete),Function.createDelegate(this,this._onSaveFailed),[b,c,e,a.count])},_clonePropertyNames:function(e){var c=[],d={};for(var b=0;b<e.length;b++){var a=e[b];if(!d[a]){Array.add(c,a);d[a]=true}}return c},_flattenProperties:function(a,i,j){var b={},e,d,g=0;if(a&&a.length===0)return {value:b,count:0};for(var c in i){e=i[c];d=j?j+"."+c:c;if(Sys.Services.ProfileGroup.isInstanceOfType(e)){var k=this._flattenProperties(a,e,d),h=k.value;g+=k.count;for(var f in h){var l=h[f];b[f]=l}}else if(!a||Array.indexOf(a,d)!==-1){b[d]=e;g++}}return {value:b,count:g}},_get_path:function(){var a=this.get_path();if(!a.length)a=Sys.Services._ProfileService.DefaultWebServicePath;if(!a||!a.length)throw Error.invalidOperation(Sys.Res.servicePathNotSet);return a},_onLoadComplete:function(a,e,g){if(typeof a!=="object")throw Error.invalidOperation(String.format(Sys.Res.webServiceInvalidReturnType,g,"Object"));var c=this._unflattenProperties(a);for(var b in c)this.properties[b]=c[b];var d=e[0]||this.get_defaultLoadCompletedCallback()||this.get_defaultSucceededCallback();if(d){var f=e[2]||this.get_defaultUserContext();d(a.length,f,"Sys.Services.ProfileService.load")}},_onLoadFailed:function(d,b){var a=b[1]||this.get_defaultFailedCallback();if(a){var c=b[2]||this.get_defaultUserContext();a(d,c,"Sys.Services.ProfileService.load")}},_onSaveComplete:function(a,b,f){var c=b[3];if(a!==null)if(a instanceof Array)c-=a.length;else if(typeof a==="number")c=a;else throw Error.invalidOperation(String.format(Sys.Res.webServiceInvalidReturnType,f,"Array"));var d=b[0]||this.get_defaultSaveCompletedCallback()||this.get_defaultSucceededCallback();if(d){var e=b[2]||this.get_defaultUserContext();d(c,e,"Sys.Services.ProfileService.save")}},_onSaveFailed:function(d,b){var a=b[1]||this.get_defaultFailedCallback();if(a){var c=b[2]||this.get_defaultUserContext();a(d,c,"Sys.Services.ProfileService.save")}},_unflattenProperties:function(e){var c={},d,f,h=0;for(var a in e){h++;f=e[a];d=a.indexOf(".");if(d!==-1){var g=a.substr(0,d);a=a.substr(d+1);var b=c[g];if(!b||!Sys.Services.ProfileGroup.isInstanceOfType(b)){b=new Sys.Services.ProfileGroup;c[g]=b}b[a]=f}else c[a]=f}e.length=h;return c}};Sys.Services._ProfileService.registerClass("Sys.Services._ProfileService",Sys.Net.WebServiceProxy);Sys.Services.ProfileService=new Sys.Services._ProfileService;Sys.Services.ProfileGroup=function(a){if(a)for(var b in a)this[b]=a[b]};Sys.Services.ProfileGroup.registerClass("Sys.Services.ProfileGroup");Sys.Services._AuthenticationService=function(){Sys.Services._AuthenticationService.initializeBase(this)};Sys.Services._AuthenticationService.DefaultWebServicePath="";Sys.Services._AuthenticationService.prototype={_defaultLoginCompletedCallback:null,_defaultLogoutCompletedCallback:null,_path:"",_timeout:0,_authenticated:false,get_defaultLoginCompletedCallback:function(){return this._defaultLoginCompletedCallback},set_defaultLoginCompletedCallback:function(a){this._defaultLoginCompletedCallback=a},get_defaultLogoutCompletedCallback:function(){return this._defaultLogoutCompletedCallback},set_defaultLogoutCompletedCallback:function(a){this._defaultLogoutCompletedCallback=a},get_isLoggedIn:function(){return this._authenticated},get_path:function(){return this._path||""},login:function(c,b,a,h,f,d,e,g){this._invoke(this._get_path(),"Login",false,{userName:c,password:b,createPersistentCookie:a},Function.createDelegate(this,this._onLoginComplete),Function.createDelegate(this,this._onLoginFailed),[c,b,a,h,f,d,e,g])},logout:function(c,a,b,d){this._invoke(this._get_path(),"Logout",false,{},Function.createDelegate(this,this._onLogoutComplete),Function.createDelegate(this,this._onLogoutFailed),[c,a,b,d])},_get_path:function(){var a=this.get_path();if(!a.length)a=Sys.Services._AuthenticationService.DefaultWebServicePath;if(!a||!a.length)throw Error.invalidOperation(Sys.Res.servicePathNotSet);return a},_onLoginComplete:function(e,c,f){if(typeof e!=="boolean")throw Error.invalidOperation(String.format(Sys.Res.webServiceInvalidReturnType,f,"Boolean"));var b=c[4],d=c[7]||this.get_defaultUserContext(),a=c[5]||this.get_defaultLoginCompletedCallback()||this.get_defaultSucceededCallback();if(e){this._authenticated=true;if(a)a(true,d,"Sys.Services.AuthenticationService.login");if(typeof b!=="undefined"&&b!==null)window.location.href=b}else if(a)a(false,d,"Sys.Services.AuthenticationService.login")},_onLoginFailed:function(d,b){var a=b[6]||this.get_defaultFailedCallback();if(a){var c=b[7]||this.get_defaultUserContext();a(d,c,"Sys.Services.AuthenticationService.login")}},_onLogoutComplete:function(f,a,e){if(f!==null)throw Error.invalidOperation(String.format(Sys.Res.webServiceInvalidReturnType,e,"null"));var b=a[0],d=a[3]||this.get_defaultUserContext(),c=a[1]||this.get_defaultLogoutCompletedCallback()||this.get_defaultSucceededCallback();this._authenticated=false;if(c)c(null,d,"Sys.Services.AuthenticationService.logout");if(!b)window.location.reload();else window.location.href=b},_onLogoutFailed:function(c,b){var a=b[2]||this.get_defaultFailedCallback();if(a)a(c,b[3],"Sys.Services.AuthenticationService.logout")},_setAuthenticated:function(a){this._authenticated=a}};Sys.Services._AuthenticationService.registerClass("Sys.Services._AuthenticationService",Sys.Net.WebServiceProxy);Sys.Services.AuthenticationService=new Sys.Services._AuthenticationService;Sys.Services._RoleService=function(){Sys.Services._RoleService.initializeBase(this);this._roles=[]};Sys.Services._RoleService.DefaultWebServicePath="";Sys.Services._RoleService.prototype={_defaultLoadCompletedCallback:null,_rolesIndex:null,_timeout:0,_path:"",get_defaultLoadCompletedCallback:function(){return this._defaultLoadCompletedCallback},set_defaultLoadCompletedCallback:function(a){this._defaultLoadCompletedCallback=a},get_path:function(){return this._path||""},get_roles:function(){return Array.clone(this._roles)},isUserInRole:function(a){var b=this._get_rolesIndex()[a.trim().toLowerCase()];return !!b},load:function(a,b,c){Sys.Net.WebServiceProxy.invoke(this._get_path(),"GetRolesForCurrentUser",false,{},Function.createDelegate(this,this._onLoadComplete),Function.createDelegate(this,this._onLoadFailed),[a,b,c],this.get_timeout())},_get_path:function(){var a=this.get_path();if(!a||!a.length)a=Sys.Services._RoleService.DefaultWebServicePath;if(!a||!a.length)throw Error.invalidOperation(Sys.Res.servicePathNotSet);return a},_get_rolesIndex:function(){if(!this._rolesIndex){var b={};for(var a=0;a<this._roles.length;a++)b[this._roles[a].toLowerCase()]=true;this._rolesIndex=b}return this._rolesIndex},_onLoadComplete:function(a,c,f){if(a&&!(a instanceof Array))throw Error.invalidOperation(String.format(Sys.Res.webServiceInvalidReturnType,f,"Array"));this._roles=a;this._rolesIndex=null;var b=c[0]||this.get_defaultLoadCompletedCallback()||this.get_defaultSucceededCallback();if(b){var e=c[2]||this.get_defaultUserContext(),d=Array.clone(a);b(d,e,"Sys.Services.RoleService.load")}},_onLoadFailed:function(d,b){var a=b[1]||this.get_defaultFailedCallback();if(a){var c=b[2]||this.get_defaultUserContext();a(d,c,"Sys.Services.RoleService.load")}}};Sys.Services._RoleService.registerClass("Sys.Services._RoleService",Sys.Net.WebServiceProxy);Sys.Services.RoleService=new Sys.Services._RoleService;Type.registerNamespace("Sys.Serialization");Sys.Serialization.JavaScriptSerializer=function(){};Sys.Serialization.JavaScriptSerializer.registerClass("Sys.Serialization.JavaScriptSerializer");Sys.Serialization.JavaScriptSerializer._charsToEscapeRegExs=[];Sys.Serialization.JavaScriptSerializer._charsToEscape=[];Sys.Serialization.JavaScriptSerializer._dateRegEx=new RegExp('(^|[^\\\\])\\"\\\\/Date\\((-?[0-9]+)(?:[a-zA-Z]|(?:\\+|-)[0-9]{4})?\\)\\\\/\\"',"g");Sys.Serialization.JavaScriptSerializer._escapeChars={};Sys.Serialization.JavaScriptSerializer._escapeRegEx=new RegExp('["\\\\\\x00-\\x1F]',"i");Sys.Serialization.JavaScriptSerializer._escapeRegExGlobal=new RegExp('["\\\\\\x00-\\x1F]',"g");Sys.Serialization.JavaScriptSerializer._jsonRegEx=new RegExp("[^,:{}\\[\\]0-9.\\-+Eaeflnr-u \\n\\r\\t]","g");Sys.Serialization.JavaScriptSerializer._jsonStringRegEx=new RegExp('"(\\\\.|[^"\\\\])*"',"g");Sys.Serialization.JavaScriptSerializer._serverTypeFieldName="__type";Sys.Serialization.JavaScriptSerializer._init=function(){var c=["\\u0000","\\u0001","\\u0002","\\u0003","\\u0004","\\u0005","\\u0006","\\u0007","\\b","\\t","\\n","\\u000b","\\f","\\r","\\u000e","\\u000f","\\u0010","\\u0011","\\u0012","\\u0013","\\u0014","\\u0015","\\u0016","\\u0017","\\u0018","\\u0019","\\u001a","\\u001b","\\u001c","\\u001d","\\u001e","\\u001f"];Sys.Serialization.JavaScriptSerializer._charsToEscape[0]="\\";Sys.Serialization.JavaScriptSerializer._charsToEscapeRegExs["\\"]=new RegExp("\\\\","g");Sys.Serialization.JavaScriptSerializer._escapeChars["\\"]="\\\\";Sys.Serialization.JavaScriptSerializer._charsToEscape[1]='"';Sys.Serialization.JavaScriptSerializer._charsToEscapeRegExs['"']=new RegExp('"',"g");Sys.Serialization.JavaScriptSerializer._escapeChars['"']='\\"';for(var a=0;a<32;a++){var b=String.fromCharCode(a);Sys.Serialization.JavaScriptSerializer._charsToEscape[a+2]=b;Sys.Serialization.JavaScriptSerializer._charsToEscapeRegExs[b]=new RegExp(b,"g");Sys.Serialization.JavaScriptSerializer._escapeChars[b]=c[a]}};Sys.Serialization.JavaScriptSerializer._serializeBooleanWithBuilder=function(b,a){a.append(b.toString())};Sys.Serialization.JavaScriptSerializer._serializeNumberWithBuilder=function(a,b){if(isFinite(a))b.append(String(a));else throw Error.invalidOperation(Sys.Res.cannotSerializeNonFiniteNumbers)};Sys.Serialization.JavaScriptSerializer._serializeStringWithBuilder=function(a,c){c.append('"');if(Sys.Serialization.JavaScriptSerializer._escapeRegEx.test(a)){if(Sys.Serialization.JavaScriptSerializer._charsToEscape.length===0)Sys.Serialization.JavaScriptSerializer._init();if(a.length<128)a=a.replace(Sys.Serialization.JavaScriptSerializer._escapeRegExGlobal,function(a){return Sys.Serialization.JavaScriptSerializer._escapeChars[a]});else for(var d=0;d<34;d++){var b=Sys.Serialization.JavaScriptSerializer._charsToEscape[d];if(a.indexOf(b)!==-1)if(Sys.Browser.agent===Sys.Browser.Opera||Sys.Browser.agent===Sys.Browser.FireFox)a=a.split(b).join(Sys.Serialization.JavaScriptSerializer._escapeChars[b]);else a=a.replace(Sys.Serialization.JavaScriptSerializer._charsToEscapeRegExs[b],Sys.Serialization.JavaScriptSerializer._escapeChars[b])}}c.append(a);c.append('"')};Sys.Serialization.JavaScriptSerializer._serializeWithBuilder=function(b,a,i,g){var c;switch(typeof b){case "object":if(b)if(Number.isInstanceOfType(b))Sys.Serialization.JavaScriptSerializer._serializeNumberWithBuilder(b,a);else if(Boolean.isInstanceOfType(b))Sys.Serialization.JavaScriptSerializer._serializeBooleanWithBuilder(b,a);else if(String.isInstanceOfType(b))Sys.Serialization.JavaScriptSerializer._serializeStringWithBuilder(b,a);else if(Array.isInstanceOfType(b)){a.append("[");for(c=0;c<b.length;++c){if(c>0)a.append(",");Sys.Serialization.JavaScriptSerializer._serializeWithBuilder(b[c],a,false,g)}a.append("]")}else{if(Date.isInstanceOfType(b)){a.append('"\\/Date(');a.append(b.getTime());a.append(')\\/"');break}var d=[],f=0;for(var e in b){if(e.startsWith("$"))continue;if(e===Sys.Serialization.JavaScriptSerializer._serverTypeFieldName&&f!==0){d[f++]=d[0];d[0]=e}else d[f++]=e}if(i)d.sort();a.append("{");var j=false;for(c=0;c<f;c++){var h=b[d[c]];if(typeof h!=="undefined"&&typeof h!=="function"){if(j)a.append(",");else j=true;Sys.Serialization.JavaScriptSerializer._serializeWithBuilder(d[c],a,i,g);a.append(":");Sys.Serialization.JavaScriptSerializer._serializeWithBuilder(h,a,i,g)}}a.append("}")}else a.append("null");break;case "number":Sys.Serialization.JavaScriptSerializer._serializeNumberWithBuilder(b,a);break;case "string":Sys.Serialization.JavaScriptSerializer._serializeStringWithBuilder(b,a);break;case "boolean":Sys.Serialization.JavaScriptSerializer._serializeBooleanWithBuilder(b,a);break;default:a.append("null")}};Sys.Serialization.JavaScriptSerializer.serialize=function(b){var a=new Sys.StringBuilder;Sys.Serialization.JavaScriptSerializer._serializeWithBuilder(b,a,false);return a.toString()};Sys.Serialization.JavaScriptSerializer.deserialize=function(data,secure){if(data.length===0)throw Error.argument("data",Sys.Res.cannotDeserializeEmptyString);try{var exp=data.replace(Sys.Serialization.JavaScriptSerializer._dateRegEx,"$1new Date($2)");if(secure&&Sys.Serialization.JavaScriptSerializer._jsonRegEx.test(exp.replace(Sys.Serialization.JavaScriptSerializer._jsonStringRegEx,"")))throw null;return eval("("+exp+")")}catch(a){throw Error.argument("data",Sys.Res.cannotDeserializeInvalidJson)}};Sys.CultureInfo=function(c,b,a){this.name=c;this.numberFormat=b;this.dateTimeFormat=a};Sys.CultureInfo.prototype={_getDateTimeFormats:function(){if(!this._dateTimeFormats){var a=this.dateTimeFormat;this._dateTimeFormats=[a.MonthDayPattern,a.YearMonthPattern,a.ShortDatePattern,a.ShortTimePattern,a.LongDatePattern,a.LongTimePattern,a.FullDateTimePattern,a.RFC1123Pattern,a.SortableDateTimePattern,a.UniversalSortableDateTimePattern]}return this._dateTimeFormats},_getMonthIndex:function(a){if(!this._upperMonths)this._upperMonths=this._toUpperArray(this.dateTimeFormat.MonthNames);return Array.indexOf(this._upperMonths,this._toUpper(a))},_getAbbrMonthIndex:function(a){if(!this._upperAbbrMonths)this._upperAbbrMonths=this._toUpperArray(this.dateTimeFormat.AbbreviatedMonthNames);return Array.indexOf(this._upperAbbrMonths,this._toUpper(a))},_getDayIndex:function(a){if(!this._upperDays)this._upperDays=this._toUpperArray(this.dateTimeFormat.DayNames);return Array.indexOf(this._upperDays,this._toUpper(a))},_getAbbrDayIndex:function(a){if(!this._upperAbbrDays)this._upperAbbrDays=this._toUpperArray(this.dateTimeFormat.AbbreviatedDayNames);return Array.indexOf(this._upperAbbrDays,this._toUpper(a))},_toUpperArray:function(c){var b=[];for(var a=0,d=c.length;a<d;a++)b[a]=this._toUpper(c[a]);return b},_toUpper:function(a){return a.split("\u00a0").join(" ").toUpperCase()}};Sys.CultureInfo._parse=function(b){var a=Sys.Serialization.JavaScriptSerializer.deserialize(b);return new Sys.CultureInfo(a.name,a.numberFormat,a.dateTimeFormat)};Sys.CultureInfo.registerClass("Sys.CultureInfo");Sys.CultureInfo.InvariantCulture=Sys.CultureInfo._parse('{"name":"","numberFormat":{"CurrencyDecimalDigits":2,"CurrencyDecimalSeparator":".","IsReadOnly":true,"CurrencyGroupSizes":[3],"NumberGroupSizes":[3],"PercentGroupSizes":[3],"CurrencyGroupSeparator":",","CurrencySymbol":"\u00a4","NaNSymbol":"NaN","CurrencyNegativePattern":0,"NumberNegativePattern":1,"PercentPositivePattern":0,"PercentNegativePattern":0,"NegativeInfinitySymbol":"-Infinity","NegativeSign":"-","NumberDecimalDigits":2,"NumberDecimalSeparator":".","NumberGroupSeparator":",","CurrencyPositivePattern":0,"PositiveInfinitySymbol":"Infinity","PositiveSign":"+","PercentDecimalDigits":2,"PercentDecimalSeparator":".","PercentGroupSeparator":",","PercentSymbol":"%","PerMilleSymbol":"\u2030","NativeDigits":["0","1","2","3","4","5","6","7","8","9"],"DigitSubstitution":1},"dateTimeFormat":{"AMDesignator":"AM","Calendar":{"MinSupportedDateTime":"@-62135568000000@","MaxSupportedDateTime":"@253402300799999@","AlgorithmType":1,"CalendarType":1,"Eras":[1],"TwoDigitYearMax":2029,"IsReadOnly":true},"DateSeparator":"/","FirstDayOfWeek":0,"CalendarWeekRule":0,"FullDateTimePattern":"dddd, dd MMMM yyyy HH:mm:ss","LongDatePattern":"dddd, dd MMMM yyyy","LongTimePattern":"HH:mm:ss","MonthDayPattern":"MMMM dd","PMDesignator":"PM","RFC1123Pattern":"ddd, dd MMM yyyy HH\':\'mm\':\'ss \'GMT\'","ShortDatePattern":"MM/dd/yyyy","ShortTimePattern":"HH:mm","SortableDateTimePattern":"yyyy\'-\'MM\'-\'dd\'T\'HH\':\'mm\':\'ss","TimeSeparator":":","UniversalSortableDateTimePattern":"yyyy\'-\'MM\'-\'dd HH\':\'mm\':\'ss\'Z\'","YearMonthPattern":"yyyy MMMM","AbbreviatedDayNames":["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],"ShortestDayNames":["Su","Mo","Tu","We","Th","Fr","Sa"],"DayNames":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"AbbreviatedMonthNames":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""],"MonthNames":["January","February","March","April","May","June","July","August","September","October","November","December",""],"IsReadOnly":true,"NativeCalendarName":"Gregorian Calendar","AbbreviatedMonthGenitiveNames":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""],"MonthGenitiveNames":["January","February","March","April","May","June","July","August","September","October","November","December",""]}}');if(typeof __cultureInfo==="undefined")var __cultureInfo='{"name":"en-US","numberFormat":{"CurrencyDecimalDigits":2,"CurrencyDecimalSeparator":".","IsReadOnly":false,"CurrencyGroupSizes":[3],"NumberGroupSizes":[3],"PercentGroupSizes":[3],"CurrencyGroupSeparator":",","CurrencySymbol":"$","NaNSymbol":"NaN","CurrencyNegativePattern":0,"NumberNegativePattern":1,"PercentPositivePattern":0,"PercentNegativePattern":0,"NegativeInfinitySymbol":"-Infinity","NegativeSign":"-","NumberDecimalDigits":2,"NumberDecimalSeparator":".","NumberGroupSeparator":",","CurrencyPositivePattern":0,"PositiveInfinitySymbol":"Infinity","PositiveSign":"+","PercentDecimalDigits":2,"PercentDecimalSeparator":".","PercentGroupSeparator":",","PercentSymbol":"%","PerMilleSymbol":"\u2030","NativeDigits":["0","1","2","3","4","5","6","7","8","9"],"DigitSubstitution":1},"dateTimeFormat":{"AMDesignator":"AM","Calendar":{"MinSupportedDateTime":"@-62135568000000@","MaxSupportedDateTime":"@253402300799999@","AlgorithmType":1,"CalendarType":1,"Eras":[1],"TwoDigitYearMax":2029,"IsReadOnly":false},"DateSeparator":"/","FirstDayOfWeek":0,"CalendarWeekRule":0,"FullDateTimePattern":"dddd, MMMM dd, yyyy h:mm:ss tt","LongDatePattern":"dddd, MMMM dd, yyyy","LongTimePattern":"h:mm:ss tt","MonthDayPattern":"MMMM dd","PMDesignator":"PM","RFC1123Pattern":"ddd, dd MMM yyyy HH\':\'mm\':\'ss \'GMT\'","ShortDatePattern":"M/d/yyyy","ShortTimePattern":"h:mm tt","SortableDateTimePattern":"yyyy\'-\'MM\'-\'dd\'T\'HH\':\'mm\':\'ss","TimeSeparator":":","UniversalSortableDateTimePattern":"yyyy\'-\'MM\'-\'dd HH\':\'mm\':\'ss\'Z\'","YearMonthPattern":"MMMM, yyyy","AbbreviatedDayNames":["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],"ShortestDayNames":["Su","Mo","Tu","We","Th","Fr","Sa"],"DayNames":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"AbbreviatedMonthNames":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""],"MonthNames":["January","February","March","April","May","June","July","August","September","October","November","December",""],"IsReadOnly":false,"NativeCalendarName":"Gregorian Calendar","AbbreviatedMonthGenitiveNames":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""],"MonthGenitiveNames":["January","February","March","April","May","June","July","August","September","October","November","December",""]}}';Sys.CultureInfo.CurrentCulture=Sys.CultureInfo._parse(__cultureInfo);delete __cultureInfo;Sys.UI.Behavior=function(b){Sys.UI.Behavior.initializeBase(this);this._element=b;var a=b._behaviors;if(!a)b._behaviors=[this];else a[a.length]=this};Sys.UI.Behavior.prototype={_name:null,get_element:function(){return this._element},get_id:function(){var a=Sys.UI.Behavior.callBaseMethod(this,"get_id");if(a)return a;if(!this._element||!this._element.id)return "";return this._element.id+"$"+this.get_name()},get_name:function(){if(this._name)return this._name;var a=Object.getTypeName(this),b=a.lastIndexOf(".");if(b!=-1)a=a.substr(b+1);if(!this.get_isInitialized())this._name=a;return a},set_name:function(a){this._name=a},initialize:function(){Sys.UI.Behavior.callBaseMethod(this,"initialize");var a=this.get_name();if(a)this._element[a]=this},dispose:function(){Sys.UI.Behavior.callBaseMethod(this,"dispose");if(this._element){var a=this.get_name();if(a)this._element[a]=null;Array.remove(this._element._behaviors,this);delete this._element}}};Sys.UI.Behavior.registerClass("Sys.UI.Behavior",Sys.Component);Sys.UI.Behavior.getBehaviorByName=function(b,c){var a=b[c];return a&&Sys.UI.Behavior.isInstanceOfType(a)?a:null};Sys.UI.Behavior.getBehaviors=function(a){if(!a._behaviors)return [];return Array.clone(a._behaviors)};Sys.UI.Behavior.getBehaviorsByType=function(d,e){var a=d._behaviors,c=[];if(a)for(var b=0,f=a.length;b<f;b++)if(e.isInstanceOfType(a[b]))c[c.length]=a[b];return c};Sys.UI.VisibilityMode=function(){throw Error.notImplemented()};Sys.UI.VisibilityMode.prototype={hide:0,collapse:1};Sys.UI.VisibilityMode.registerEnum("Sys.UI.VisibilityMode");Sys.UI.Control=function(a){Sys.UI.Control.initializeBase(this);this._element=a;a.control=this};Sys.UI.Control.prototype={_parent:null,_visibilityMode:Sys.UI.VisibilityMode.hide,get_element:function(){return this._element},get_id:function(){if(!this._element)return "";return this._element.id},set_id:function(){throw Error.invalidOperation(Sys.Res.cantSetId)},get_parent:function(){if(this._parent)return this._parent;if(!this._element)return null;var a=this._element.parentNode;while(a){if(a.control)return a.control;a=a.parentNode}return null},set_parent:function(a){this._parent=a},get_visibilityMode:function(){return Sys.UI.DomElement.getVisibilityMode(this._element)},set_visibilityMode:function(a){Sys.UI.DomElement.setVisibilityMode(this._element,a)},get_visible:function(){return Sys.UI.DomElement.getVisible(this._element)},set_visible:function(a){Sys.UI.DomElement.setVisible(this._element,a)},addCssClass:function(a){Sys.UI.DomElement.addCssClass(this._element,a)},dispose:function(){Sys.UI.Control.callBaseMethod(this,"dispose");if(this._element){this._element.control=undefined;delete this._element}if(this._parent)delete this._parent},onBubbleEvent:function(){return false},raiseBubbleEvent:function(b,c){var a=this.get_parent();while(a){if(a.onBubbleEvent(b,c))return;a=a.get_parent()}},removeCssClass:function(a){Sys.UI.DomElement.removeCssClass(this._element,a)},toggleCssClass:function(a){Sys.UI.DomElement.toggleCssClass(this._element,a)}};Sys.UI.Control.registerClass("Sys.UI.Control",Sys.Component);
Sys.Res={
"argumentInteger":"Value must be an integer.","scriptLoadMultipleCallbacks":"The script \u0027{0}\u0027 contains multiple calls to Sys.Application.notifyScriptLoaded(). Only one is allowed.","invokeCalledTwice":"Cannot call invoke more than once.","webServiceFailed":"The server method \u0027{0}\u0027 failed with the following error: {1}","webServiceInvalidJsonWrapper":"The server method \u0027{0}\u0027 returned invalid data. The \u0027d\u0027 property is missing from the JSON wrapper.","argumentType":"Object cannot be converted to the required type.","argumentNull":"Value cannot be null.","controlCantSetId":"The id property can\u0027t be set on a control.","formatBadFormatSpecifier":"Format specifier was invalid.","webServiceFailedNoMsg":"The server method \u0027{0}\u0027 failed.","argumentDomElement":"Value must be a DOM element.","invalidExecutorType":"Could not create a valid Sys.Net.WebRequestExecutor from: {0}.","cannotCallBeforeResponse":"Cannot call {0} when responseAvailable is false.","actualValue":"Actual value was {0}.","enumInvalidValue":"\u0027{0}\u0027 is not a valid value for enum {1}.","scriptLoadFailed":"The script \u0027{0}\u0027 could not be loaded.","parameterCount":"Parameter count mismatch.","cannotDeserializeEmptyString":"Cannot deserialize empty string.","formatInvalidString":"Input string was not in a correct format.","invalidTimeout":"Value must be greater than or equal to zero.","cannotAbortBeforeStart":"Cannot abort when executor has not started.","argument":"Value does not fall within the expected range.","cannotDeserializeInvalidJson":"Cannot deserialize. The data does not correspond to valid JSON.","invalidHttpVerb":"httpVerb cannot be set to an empty or null string.","nullWebRequest":"Cannot call executeRequest with a null webRequest.","eventHandlerInvalid":"Handler was not added through the Sys.UI.DomEvent.addHandler method.","cannotSerializeNonFiniteNumbers":"Cannot serialize non finite numbers.","argumentUndefined":"Value cannot be undefined.","webServiceInvalidReturnType":"The server method \u0027{0}\u0027 returned an invalid type. Expected type: {1}","servicePathNotSet":"The path to the web service has not been set.","argumentTypeWithTypes":"Object of type \u0027{0}\u0027 cannot be converted to type \u0027{1}\u0027.","cannotCallOnceStarted":"Cannot call {0} once started.","badBaseUrl1":"Base URL does not contain ://.","badBaseUrl2":"Base URL does not contain another /.","badBaseUrl3":"Cannot find last / in base URL.","setExecutorAfterActive":"Cannot set executor after it has become active.","paramName":"Parameter name: {0}","cannotCallOutsideHandler":"Cannot call {0} outside of a completed event handler.","cannotSerializeObjectWithCycle":"Cannot serialize object with cyclic reference within child properties.","format":"One of the identified items was in an invalid format.","assertFailedCaller":"Assertion Failed: {0}\r\nat {1}","argumentOutOfRange":"Specified argument was out of the range of valid values.","webServiceTimedOut":"The server method \u0027{0}\u0027 timed out.","notImplemented":"The method or operation is not implemented.","assertFailed":"Assertion Failed: {0}","invalidOperation":"Operation is not valid due to the current state of the object.","breakIntoDebugger":"{0}\r\n\r\nBreak into debugger?"};
/* END MicrosoftAjax.js */
/* START Telerik.Web.UI.Common.Core.js */
// Avoids the background image flickering in IE 6 (http://www.mister-pixel.com/)
try
{
	document.execCommand("BackgroundImageCache", false, true);
}
catch(err) {}

Type.registerNamespace("Telerik.Web.UI");

window.$telerik = window.TelerikCommonScripts = Telerik.Web.CommonScripts = {

    //NEW
    getOuterSize : function(element) 
    {                       
        var size = $telerik.getSize(element);
        var marginBox = $telerik.getMarginBox(element);
        
        return {
            x :  size.x - marginBox.left,
            y : size.y -  marginBox.top, 
            width : size.width + marginBox.left + marginBox.right, 
            height: size.height + marginBox.top + marginBox.bottom
        }
    },
    

	_borderStyleNames : ['borderTopStyle','borderRightStyle','borderBottomStyle','borderLeftStyle'],
	_borderWidthNames : ['borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth'],
	_paddingWidthNames : ['paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft'],
	_marginWidthNames : ['marginTop', 'marginRight', 'marginBottom', 'marginLeft'],
	radControls : [],
	
	registerControl : function (control)
	{
		if (!Array.contains(this.radControls, control))
			Array.add(this.radControls, control);
	},
	
	unregisterControl : function (control)
	{
		Array.remove(this.radControls, control);
	},
	
	repaintChildren : function (parentControl)
	{
		var parentElement = parentControl.get_element();
		
		for (var i = 0, length = this.radControls.length; i < length; i ++)
		{
	        var control = this.radControls[i];
        
		    if (control.repaint && this.isDescendant(parentElement, control.get_element()))
				control.repaint();
		}
	},
	
	_borderThickness : function ()
	{
		$telerik._borderThicknesses = { };

		var div0 = document.createElement('div');
		var div1 = document.createElement('div');

		div0.style.visibility = 'hidden';
		div0.style.position = 'absolute';
		div0.style.fontSize = '1px';
	    
		div1.style.height = '0px';
		div1.style.overflow = 'hidden';
	    
		document.body.appendChild(div0).appendChild(div1);
	                    
		var base = div0.offsetHeight;
		div1.style.borderTop = 'solid black';        

		div1.style.borderTopWidth = 'thin';
		$telerik._borderThicknesses['thin'] = div0.offsetHeight - base;
	    
		div1.style.borderTopWidth = 'medium';
		$telerik._borderThicknesses['medium'] = div0.offsetHeight - base;
	    
		div1.style.borderTopWidth = 'thick';
		$telerik._borderThicknesses['thick'] = div0.offsetHeight - base;
	    
		if (typeof(div0.removeChild) !== "undefined")
			div0.removeChild(div1);
			
		document.body.removeChild(div0);
		//Apparently, Safari does not like setting outerHTML on elements not in the document
		//throws NO_MODIFICATION_ALLOWED_ERR: DOM Exception 7
		if (!$telerik.isSafari)
			div1.outerHTML = null;
		if (!$telerik.isSafari)
			div0.outerHTML = null;
		div0 = null;
		div1 = null;
	},
	
	getCurrentStyle : function(element, attribute, defaultValue) {
     
        var currentValue = null;
        if (element) {
            if (element.currentStyle) {
                currentValue = element.currentStyle[attribute];
            } else if (document.defaultView && document.defaultView.getComputedStyle) {
                var style = document.defaultView.getComputedStyle(element, null);
                if (style) {
                    currentValue = style[attribute];
                }
            }
            
            if (!currentValue && element.style.getPropertyValue) {
                currentValue = element.style.getPropertyValue(attribute);
            }
            else if (!currentValue && element.style.getAttribute) {
                currentValue = element.style.getAttribute(attribute);
            }       
        }
        
        if ((!currentValue || currentValue == "" || typeof(currentValue) === 'undefined')) {
            if (typeof(defaultValue) != 'undefined') {
                currentValue = defaultValue;
            }
            else {
                currentValue = null;
            }
        }   
        return currentValue;  
    },
    
    getInheritedBackgroundColor : function(element) {
        if (!element) return '#FFFFFF';
        var background = $telerik.getCurrentStyle(element, 'backgroundColor');
        try {
            while (!background || background == '' || background == 'transparent' || background == 'rgba(0, 0, 0, 0)') {
                element = element.parentNode;
                if (!element) {
                    background = '#FFFFFF';
                } else {
                    background = $telerik.getCurrentStyle(element, 'backgroundColor');
                }
            }
        } catch(ex) {
            background = '#FFFFFF';
        }
        return background;
    },
    
	getLocation : function(element) {

		// workaround for an issue in getLocation where it will compute the location of the document element.
		// this will return an offset if scrolled.
		//
		if (element === document.documentElement) {
			return new Sys.UI.Point(0,0);
		}

		// Workaround for IE6 bug in getLocation (also required patching getBounds - remove that fix when this is removed)
		
		//TEKI: When in IE7 in a scenario when item is in a FRAMESET, the location value is wrong. However, using the IE6 code below it works fine
		if (Sys.Browser.agent == Sys.Browser.InternetExplorer /*&& Sys.Browser.version < 7*/) {
			if (element.window === element || element.nodeType === 9 || !element.getClientRects || !element.getBoundingClientRect) return new Sys.UI.Point(0,0);

			// Get the first bounding rectangle in screen coordinates
			var screenRects = element.getClientRects();
			if (!screenRects || !screenRects.length) {
				return new Sys.UI.Point(0,0);
			}
			var first = screenRects[0];

			// Delta between client coords and screen coords
			var dLeft = 0;
			var dTop = 0;

			var inFrame = false;
			try {
				inFrame = element.ownerDocument.parentWindow.frameElement;
			} catch(ex) {
				// If accessing the frameElement fails, a frame is probably in a different
				// domain than its parent - and we still want to do the calculation below
				inFrame = true;
			}

			// If we're in a frame, get client coordinates too so we can compute the delta
			if (inFrame) {
				// Get the bounding rectangle in client coords
				var clientRect = element.getBoundingClientRect();
				if (!clientRect) {
					return new Sys.UI.Point(0,0);
				}

				// Find the minima in screen coords
				var minLeft = first.left;
				var minTop = first.top;
				for (var i = 1; i < screenRects.length; i++) {
					var r = screenRects[i];
					if (r.left < minLeft) {
						minLeft = r.left;
					}
					if (r.top < minTop) {
						minTop = r.top;
					}
				}

				// Compute the delta between screen and client coords
				dLeft = minLeft - clientRect.left;
				dTop = minTop - clientRect.top;
			}

			// Subtract 2px, the border of the viewport (It can be changed in IE6 by applying a border style to the HTML element,
			// but this is not supported by ASP.NET AJAX, and it cannot be changed in IE7.), and also subtract the delta between
			// screen coords and client coords
			var ownerDocument = element.document.documentElement;
			
			var position = new Sys.UI.Point(first.left - 2 - dLeft + ownerDocument.scrollLeft, first.top - 2 - dTop + ownerDocument.scrollTop);

			if ($telerik.quirksMode)
			{						
				position.x += document.body.scrollLeft;
				position.y += document.body.scrollTop;
			}
			
			return position;
		}

		var position = Sys.UI.DomElement.getLocation(element);
		
		if ($telerik.isOpera)
		{
			var parent = element.offsetParent;
			
			while (parent && parent.tagName.toUpperCase() != 'BODY' 
				&& parent.tagName.toUpperCase() != 'HTML') 
			{
				position.x -= parent.scrollLeft;
				position.y -= parent.scrollTop;
				parent = parent.offsetParent;
			}
		}
		
		if ($telerik.isSafari)
		{
			var parent = element.parentNode;
			
			var parentTD = null;
			var parentTABLE = null;
			
			while (parent && parent.tagName.toUpperCase() != 'BODY' 
				&& parent.tagName.toUpperCase() != 'HTML') 
			{
				
				// Workaround for a problem with parent TABLES - when you have a parent TABLE element with border,
				// Safari acts as if the TABLE/TD has no border and calculates X and Y incorrectly. 
				// That is why we need to add the borders manually. In case this is fixed in a future verion of the browser
				// we will need to remove this code.
				if($telerik.isSafari3 || $telerik.isSafari2)
				{
				    if(parent.tagName.toUpperCase() == "TD")
			        {
			            parentTD = parent;
			        }
                    else if(parent.tagName.toUpperCase() == "TABLE")
                    {
                        parentTABLE = parent;
                    }
                    
                    if(parentTD && parentTABLE)
                    {                
                        position.x += parseInt($telerik.getCurrentStyle(parentTABLE, 'borderTopWidth'));
                        position.y += parseInt($telerik.getCurrentStyle(parentTABLE, 'borderLeftWidth'));
                            
                        // In case the TABLE has borderCollapse:collapse, we need to take the borderWidth of either
                        // the TABLE or the TD.
                        if($telerik.getCurrentStyle(parentTABLE, 'borderCollapse') != 'collapse')
                        {
                            position.x += parseInt($telerik.getCurrentStyle(parentTD, 'borderTopWidth'));
                            position.y += parseInt($telerik.getCurrentStyle(parentTD, 'borderLeftWidth'));
                        }
                        
                        parentTD = null;
                        parentTABLE = null;
                    }
                    // In case we use getLocation for a TD element, we need to calculate the borderWidth of its TABLE
                    // only in case that TABLE has no borderCollapse:collapse.
                    else if(parentTABLE)
                    {
                        if($telerik.getCurrentStyle(parentTABLE, 'borderCollapse') != 'collapse')
                        {
                            position.x += parseInt($telerik.getCurrentStyle(parentTABLE, 'borderTopWidth'));
                            position.y += parseInt($telerik.getCurrentStyle(parentTABLE, 'borderLeftWidth'));
                        }
                        parentTABLE = null;
                    }
                }
                
                // END of Workaround for a problem with parent TABLES
				
				parent = parent.parentNode;
			}			
		}

		if ($telerik.isIE && $telerik.quirksMode)
		{
			position.x += document.body.scrollLeft;
			position.y += document.body.scrollTop;
		}

		return position;
	},

    setLocation : function(element, point) {
        Sys.UI.DomElement.setLocation(element, point.x, point.y);
    },
    
    findControl : function(parent, id)
    {
        var children = parent.getElementsByTagName("*");
        for(var i = 0, l = children.length; i < l; i++)
        {
            var childID = children[i].id;
            if (childID && childID.endsWith(id))
                return $find(childID);
        }
        
        return null;
    },
    
    findElement : function(parent, id)
    {
        var children = parent.getElementsByTagName("*");
        for(var i = 0, l = children.length; i < l; i++)
        {
            var childID = children[i].id;
            if (childID && childID.endsWith(id))
                return $get(childID);
        }
        
        return null;
    },

    getContentSize : function(element) {
        /// <summary>
        /// Gets the "content-box" size of an element.
        /// </summary>
        /// <param name="element" type="Sys.UI.DomElement" domElement="true">
        /// DOM element
        /// </param>
        /// <returns type="Object">
        /// Size of the element (in the form {width,height})
        /// </returns>
        /// <remarks>
        /// The "content-box" is the size of the content area *inside* of the borders and
        /// padding of an element. The "content-box" size does not include the margins around
        /// the element.
        /// </remarks>
        
        if (!element) {
            throw Error.argumentNull('element');
        }
        var size = $telerik.getSize(element);
        var borderBox = $telerik.getBorderBox(element);
        var paddingBox = $telerik.getPaddingBox(element);
        return {
            width :  size.width - borderBox.horizontal - paddingBox.horizontal,
            height : size.height - borderBox.vertical - paddingBox.vertical
        }
    },
    
    getSize : function(element) {
        /// <summary>
        /// Gets the "border-box" size of an element.
        /// </summary>
        /// <param name="element" type="Sys.UI.DomElement" domElement="true">
        /// DOM element
        /// </param>
        /// <returns type="Object">
        /// Size of the element (in the form {width,height})
        /// </returns>
        /// <remarks>
        /// The "border-box" is the size of the content area *outside* of the borders and
        /// padding of an element.  The "border-box" size does not include the margins around
        /// the element.
        /// </remarks>
        
        if (!element) {
            throw Error.argumentNull('element');
        }
        return {
            width:  element.offsetWidth,
            height: element.offsetHeight
        };
    },
    
    setContentSize : function(element, size) {
        /// <summary>
        /// Sets the "content-box" size of an element.
        /// </summary>
        /// <param name="element" type="Sys.UI.DomElement" domElement="true">
        /// DOM element
        /// </param>
        /// <param name="size" type="Object">
        /// Size of the element (in the form {width,height})
        /// </param>
        /// <remarks>
        /// The "content-box" is the size of the content area *inside* of the borders and
        /// padding of an element. The "content-box" size does not include the margins around
        /// the element.
        /// </remarks>
        
        if (!element) {
            throw Error.argumentNull('element');
        }
        if (!size) {
            throw Error.argumentNull('size');
        }
        // FF respects -moz-box-sizing css extension, so adjust the box size for the border-box
        if($telerik.getCurrentStyle(element, 'MozBoxSizing') == 'border-box' || $telerik.getCurrentStyle(element, 'BoxSizing') == 'border-box') {
            var borderBox = $telerik.getBorderBox(element);
            var paddingBox = $telerik.getPaddingBox(element);
            size = {
                width: size.width + borderBox.horizontal + paddingBox.horizontal,
                height: size.height + borderBox.vertical + paddingBox.vertical
            };
        }
        element.style.width = size.width.toString() + 'px';
        element.style.height = size.height.toString() + 'px';
    },
    
    setSize : function(element, size) {
        /// <summary>
        /// Sets the "border-box" size of an element.
        /// </summary>
        /// <remarks>
        /// The "border-box" is the size of the content area *outside* of the borders and 
        /// padding of an element.  The "border-box" size does not include the margins around
        /// the element.
        /// </remarks>
        /// <param name="element" type="Sys.UI.DomElement">DOM element</param>
        /// <param name="size" type="Object">Size of the element (in the form {width,height})</param>
        /// <returns />
        
        if (!element) {
            throw Error.argumentNull('element');
        }
        if (!size) {
            throw Error.argumentNull('size');
        }
        var borderBox = $telerik.getBorderBox(element);
        var paddingBox = $telerik.getPaddingBox(element);
        var contentSize = {
            width:  size.width - borderBox.horizontal - paddingBox.horizontal,
            height: size.height - borderBox.vertical - paddingBox.vertical
        };
        $telerik.setContentSize(element, contentSize);
    },
	
	getBounds : function(element) {
        /// <summary>Gets the coordinates, width and height of an element.</summary>
        /// <param name="element" domElement="true"/>
        /// <returns type="Sys.UI.Bounds">
        ///   A Bounds object with four fields, x, y, width and height, which contain the pixel coordinates,
        ///   width and height of the element.
        /// </returns>

        var offset = $telerik.getLocation(element);
        return new Sys.UI.Bounds(offset.x, offset.y, element.offsetWidth || 0, element.offsetHeight || 0);
    },
	
	setBounds : function(element, bounds) {
        /// <summary>
        /// Sets the "border-box" bounds of an element
        /// </summary>
        /// <param name="element" type="Sys.UI.DomElement" domElement="true">
        /// DOM element
        /// </param>
        /// <param name="bounds" type="Object">
        /// Bounds of the element (of the form {x,y,width,height})
        /// </param>
        /// <remarks>
        /// The "border-box" is the size of the content area *outside* of the borders and
        /// padding of an element.  The "border-box" size does not include the margins around
        /// the element.
        /// </remarks>
        
        if (!element) {
            throw Error.argumentNull('element');
        }
        if (!bounds) {
            throw Error.argumentNull('bounds');
        }
        $telerik.setSize(element, bounds);
        $telerik.setLocation(element, bounds);
    },
    
    getClientBounds : function() {
        /// <summary>
        /// Gets the width and height of the browser client window (excluding scrollbars)
        /// </summary>
        /// <returns type="Sys.UI.Bounds">
        /// Browser's client width and height
        /// </returns>

        var clientWidth;
        var clientHeight;
        switch(Sys.Browser.agent) {
            case Sys.Browser.InternetExplorer:
                clientWidth = document.documentElement.clientWidth;
                clientHeight = document.documentElement.clientHeight;
                if (clientWidth == 0 && clientHeight == 0)
                {
                    //no doctype. use the body settings
                    clientWidth = document.body.clientWidth;
                    clientHeight = document.body.clientHeight;
                }
                break;
            case Sys.Browser.Safari:
                clientWidth = window.innerWidth;
                clientHeight = window.innerHeight;
                break;
            case Sys.Browser.Opera:
                clientWidth = Math.min(window.innerWidth, document.body.clientWidth);
                clientHeight = Math.min(window.innerHeight, document.body.clientHeight);
                break;
            default:  // Sys.Browser.Firefox, etc.
                clientWidth = Math.min(window.innerWidth, document.documentElement.clientWidth);
                clientHeight = Math.min(window.innerHeight, document.documentElement.clientHeight);
                break;
        }
        return new Sys.UI.Bounds(0, 0, clientWidth, clientHeight);
    },
    
    getMarginBox : function(element) {
        /// <summary>
        /// Gets the entire margin box sizes.
        /// </summary>
        /// <param name="element" type="Sys.UI.DomElement" domElement="true">
        /// DOM element
        /// </param>
        /// <returns type="Object">
        /// Element's margin box sizes (of the form {top,left,bottom,right,horizontal,vertical})
        /// </returns>
        if (!element) {
            throw Error.argumentNull('element');
        }
        var box = {
            top: $telerik.getMargin(element, Telerik.Web.BoxSide.Top),
            right: $telerik.getMargin(element, Telerik.Web.BoxSide.Right),
            bottom: $telerik.getMargin(element, Telerik.Web.BoxSide.Bottom),
            left: $telerik.getMargin(element, Telerik.Web.BoxSide.Left)
        }
        
        box.horizontal = box.left + box.right;
        box.vertical = box.top + box.bottom;
        return box;
    },
    
    getPaddingBox : function(element) {
        /// <summary>
        /// Gets the entire padding box sizes.
        /// </summary>
        /// <param name="element" type="Sys.UI.DomElement" domElement="true">
        /// DOM element
        /// </param>
        /// <returns type="Object">
        /// Element's padding box sizes (of the form {top,left,bottom,right,horizontal,vertical})
        /// </returns>
        
        if (!element) {
            throw Error.argumentNull('element');
        }
        var box = {
            top: $telerik.getPadding(element, Telerik.Web.BoxSide.Top),
            right: $telerik.getPadding(element, Telerik.Web.BoxSide.Right),
            bottom: $telerik.getPadding(element, Telerik.Web.BoxSide.Bottom),
            left: $telerik.getPadding(element, Telerik.Web.BoxSide.Left)
        }
        box.horizontal = box.left + box.right;
        box.vertical = box.top + box.bottom;
        return box;
    },
    
    getBorderBox : function(element) {
        /// <summary>
        /// Gets the entire border box sizes.
        /// </summary>
        /// <param name="element" type="Sys.UI.DomElement" domElement="true">
        /// DOM element
        /// </param>
        /// <returns type="Object">
        /// Element's border box sizes (of the form {top,left,bottom,right,horizontal,vertical})
        /// </returns>
        
        if (!element) {
            throw Error.argumentNull('element');
        }
        var box = {
            top: $telerik.getBorderWidth(element, Telerik.Web.BoxSide.Top),
            right: $telerik.getBorderWidth(element, Telerik.Web.BoxSide.Right),
            bottom: $telerik.getBorderWidth(element, Telerik.Web.BoxSide.Bottom),
            left: $telerik.getBorderWidth(element, Telerik.Web.BoxSide.Left)
        }
        box.horizontal = box.left + box.right;
        box.vertical = box.top + box.bottom;
        return box;
    },

	isBorderVisible : function(element, boxSide) {
        /// <summary>
        /// Gets whether the current border style for an element on a specific boxSide is not 'none'.
        /// </summary>
        /// <param name="element" type="Sys.UI.DomElement" domElement="true">
        /// DOM element
        /// </param>
        /// <param name="boxSide" type="Telerik.Web.BoxSide">
        /// Side of the element
        /// </param>
        /// <returns type="Boolean">
        /// Whether the current border style for an element on a specific boxSide is not 'none'.
        /// </returns>
        
        if (!element) {
            throw Error.argumentNull('element');
        }
        if(boxSide < Telerik.Web.BoxSide.Top || boxSide > Telerik.Web.BoxSide.Left) {
            throw Error.argumentOutOfRange(String.format(Sys.Res.enumInvalidValue, boxSide, 'Telerik.Web.BoxSide'));
        }
        var styleName = $telerik._borderStyleNames[boxSide];
        var styleValue = $telerik.getCurrentStyle(element, styleName);
        return styleValue != "none";
    },
    getMargin : function(element, boxSide) {
        /// <summary>
        /// Gets the margin thickness of an element on a specific boxSide.
        /// </summary>
        /// <param name="element" type="Sys.UI.DomElement" domElement="true">
        /// DOM element
        /// </param>
        /// <param name="boxSide" type="Telerik.Web.BoxSide">
        /// Side of the element
        /// </param>
        /// <returns type="Number" integer="true">
        /// Margin thickness on the element's specified side
        /// </returns>
        
        if (!element) {
            throw Error.argumentNull('element');
        }
        if(boxSide < Telerik.Web.BoxSide.Top || boxSide > Telerik.Web.BoxSide.Left) {
            throw Error.argumentOutOfRange(String.format(Sys.Res.enumInvalidValue, boxSide, 'Telerik.Web.BoxSide'));
        }
        var styleName = $telerik._marginWidthNames[boxSide];
        var styleValue = $telerik.getCurrentStyle(element, styleName);

        try { return $telerik.parsePadding(styleValue); } catch(ex) { return 0; }
    },

    getBorderWidth : function(element, boxSide) {
        /// <summary>
        /// Gets the border thickness of an element on a specific boxSide.
        /// </summary>
        /// <param name="element" type="Sys.UI.DomElement" domElement="true">
        /// DOM element
        /// </param>
        /// <param name="boxSide" type="Telerik.Web.BoxSide">
        /// Side of the element
        /// </param>
        /// <returns type="Number" integer="true">
        /// Border thickness on the element's specified side
        /// </returns>
        
        if (!element) {
            throw Error.argumentNull('element');
        }
        if(boxSide < Telerik.Web.BoxSide.Top || boxSide > Telerik.Web.BoxSide.Left) {
            throw Error.argumentOutOfRange(String.format(Sys.Res.enumInvalidValue, boxSide, 'Telerik.Web.BoxSide'));
        }
        if(!$telerik.isBorderVisible(element, boxSide)) {
            return 0;
        }        
        var styleName = $telerik._borderWidthNames[boxSide];    
        var styleValue = $telerik.getCurrentStyle(element, styleName);
        return $telerik.parseBorderWidth(styleValue);
    },
    
    getPadding : function(element, boxSide) {
        /// <summary>
        /// Gets the padding thickness of an element on a specific boxSide.
        /// </summary>
        /// <param name="element" type="Sys.UI.DomElement" domElement="true">
        /// DOM element
        /// </param>
        /// <param name="boxSide" type="Telerik.Web.BoxSide">
        /// Side of the element
        /// </param>
        /// <returns type="Number" integer="true">
        /// Padding on the element's specified side
        /// </returns>
        
        if (!element) {
            throw Error.argumentNull('element');
        }
        if(boxSide < Telerik.Web.BoxSide.Top || boxSide > Telerik.Web.BoxSide.Left) {
            throw Error.argumentOutOfRange(String.format(Sys.Res.enumInvalidValue, boxSide, 'Telerik.Web.BoxSide'));
        }
        var styleName = $telerik._paddingWidthNames[boxSide];
        var styleValue = $telerik.getCurrentStyle(element, styleName);
        return $telerik.parsePadding(styleValue);
    },
    
    parseBorderWidth : function(borderWidth) {
        /// <summary>
        /// Parses a border-width string into a pixel size
        /// </summary>
        /// <param name="borderWidth" type="String" mayBeNull="true">
        /// Type of border ('thin','medium','thick','inherit',px unit,null,'')
        /// </param>
        /// <returns type="Number" integer="true">
        /// Number of pixels in the border-width
        /// </returns>
        
        if(borderWidth) {
            switch(borderWidth) {
                case 'thin':
                case 'medium':
                case 'thick':
                    return $telerik._borderThicknesses[borderWidth];
                case 'inherit':
                    return 0;
            }
            var unit = $telerik.parseUnit(borderWidth);
            return unit.size;
        }
        return 0;
    },
    
    parsePadding : function(padding) {
        /// <summary>
        /// Parses a padding string into a pixel size
        /// </summary>
        /// <param name="padding" type="String" mayBeNull="true">
        /// Padding to parse ('inherit',px unit,null,'')
        /// </param>
        /// <returns type="Number" integer="true">
        /// Number of pixels in the padding
        /// </returns>
        
        if(padding) {
            if(padding == 'inherit') {
                return 0;
            }
            var unit = $telerik.parseUnit(padding);
            return unit.size;
        }
        return 0;
    },
    
    parseUnit : function(value) {
        /// <summary>
        /// Parses a unit string into a unit object
        /// </summary>
        /// <param name="value" type="String" mayBeNull="true">
        /// Value to parse (of the form px unit,% unit,em unit,...)
        /// </param>
        /// <returns type="Object">
        /// Parsed unit (of the form {size,type})
        /// </returns>
        
        if (!value) {
            throw Error.argumentNull('value');
        }
        
        value = value.trim().toLowerCase();
        var l = value.length;
        var s = -1;
        for(var i = 0; i < l; i++) {
            var ch = value.substr(i, 1);
            if((ch < '0' || ch > '9') && ch != '-' && ch != '.' && ch != ',') {
                break;
            }
            s = i;
        }
        if(s == -1) {
            throw Error.create('No digits');
        }
        var type;
        var size;
        if(s < (l - 1)) {
            type = value.substring(s + 1).trim();
        } else {
            type = 'px';
        }
        size = parseFloat(value.substr(0, s + 1));
        if(type == 'px') {
            size = Math.floor(size);
        }
        return { 
            size: size,
            type: type
        };
    },
    
    containsPoint : function(rect, x, y) {
        /// <summary>
        /// Tests whether a point (x,y) is contained within a rectangle
        /// </summary>
        /// <param name="rect" type="Object">The rectangle</param>
        /// <param name="x" type="Number">The x coordinate of the point</param>
        /// <param name="y" type="Number">The y coordinate of the point</param>
        
        //ORIGINAL TOOLKIT SCRIPT CHANGE: instead of rect.height it was written rect.width (!!!) Clearly a major bug!!!!
        return x >= rect.x && x <= (rect.x + rect.width) && y >= rect.y && y <= (rect.y + rect.height);
    },

    isDescendant : function(ancestor, descendant) {
        /// <summary>
        /// Whether the specified element is a descendant of the ancestor
        /// </summary>
        /// <param name="ancestor" type="Sys.UI.DomElement">Ancestor node</param>
        /// <param name="descendant" type="Sys.UI.DomElement">Possible descendant node</param>
        /// <returns type="Boolean" />
        
        for (var n = descendant.parentNode; n != null; n = n.parentNode) {
            if (n == ancestor) return true;
        }
        return false;
    },
	
	isDescendantOrSelf : function(ancestor, descendant) {
        /// <summary>
        /// Whether the specified element is a descendant of the ancestor or the same as the ancestor
        /// </summary>
        /// <param name="ancestor" type="Sys.UI.DomElement">Ancestor node</param>
        /// <param name="descendant" type="Sys.UI.DomElement">Possible descendant node</param>
        /// <returns type="Boolean" />

        if (ancestor === descendant) 
            return true;
        return $telerik.isDescendant(ancestor, descendant);
    },
    
	setOuterHeight : function (element, height)
	{
		if (height <= 0 || height == "") 
		{
			element.style.height = "";
		} 
		else
		{
			element.style.height = height + "px";
			var diff = element.offsetHeight - height;
			var newHeight = height - diff;
			if (newHeight > 0) {
				element.style.height = newHeight + "px";
			} else {
				element.style.height = "";
			}
		}
	},
	
    setOpacity : function(element, value) {
        /// <summary>
        /// Set the element's opacity
        /// </summary>
        /// <param name="element" type="Sys.UI.DomElement" domElement="true">
        /// Element
        /// </param>
        /// <param name="value" type="Number">
        /// Opacity of the element
        /// </param>
        
        if (!element) {
            throw Error.argumentNull('element');
        }
        try
        {
            if (element.filters) {
                var filters = element.filters;
                var createFilter = true;
                if (filters.length !== 0) {
                    var alphaFilter = filters['DXImageTransform.Microsoft.Alpha'];
                    if (alphaFilter) {
                        createFilter = false;
                        alphaFilter.opacity = value * 100;
                    }
                }
                if (createFilter) {
                    element.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + (value * 100) + ')';
                }
            }
            else {
                element.style.opacity = value;
            }
        }
        catch (ex) {}
    },
    	
    getOpacity : function(element) {
        /// <summary>
        /// Get the element's opacity
        /// </summary>
        /// <param name="element" type="Sys.UI.DomElement" domElement="true">
        /// Element
        /// </param>
        /// <returns type="Number">
        /// Opacity of the element
        /// </returns>
        
        if (!element) {
            throw Error.argumentNull('element');
        }
        
        var hasOpacity = false;
        var opacity;
        
        try
        {
            if (element.filters) {
                var filters = element.filters;
                if (filters.length !== 0) {
                    var alphaFilter = filters['DXImageTransform.Microsoft.Alpha'];
                    if (alphaFilter) {
                        opacity = alphaFilter.opacity / 100.0;
                        hasOpacity = true;
                    }
                }
            }
            else {
                opacity = $telerik.getCurrentStyle(element, 'opacity', 1);
                hasOpacity = true;
            }
        }
        catch (ex) {}
        
        if (hasOpacity === false) {
            return 1.0;
        }
        return parseFloat(opacity);
    },

    addCssClasses : function(element, classNames) {
        /// <summary>
        /// Adds multiple css classes to a DomElement
        /// </summary>
        /// <param name="element" type="Sys.UI.DomElement">The element to modify</param>
        /// <param name="classNames" type="Array">The class names to add</param>
        
        for(var i = 0; i < classNames.length; i++) {
            Sys.UI.DomElement.addCssClass(element, classNames[i]);
        }
    },
    
    removeCssClasses : function(element, classNames) {
        /// <summary>
        /// Removes multiple css classes to a DomElement
        /// </summary>
        /// <param name="element" type="Sys.UI.DomElement">The element to modify</param>
        /// <param name="classNames" type="Array">The class names to remove</param>
        
        for(var i = 0; i < classNames.length; i++) {
            Sys.UI.DomElement.removeCssClass(element, classNames[i]);
        }
    },    	
	setOuterWidth : function (element, width)
	{
		if (width <= 0 || width == "") 
		{
			element.style.width = "";
		}
		else
		{
			element.style.width = width + "px";
			var diff = element.offsetWidth - width;
			var newWidth = width - diff;
			if (newWidth > 0) {
				element.style.width = newWidth + "px";
			} else {
				element.style.width = "";
			}
		}
	},
	
	getScrollOffset : function(element, recursive)
	{
		var left = 0;
		var top = 0;
		var parent = element;

		while (parent != null && parent.scrollLeft != null) {
			left += parent.scrollLeft;
			top += parent.scrollTop;
			// Don't include anything below the body. 
			if (!recursive || (parent == document.body && (parent.scrollLeft != 0 || parent.scrollTop != 0)))
				break;

			parent = parent.parentNode;
		}

		return { x: left, y: top };
	},
	
	getElementByClassName : function(element, className, tagName)
	{
		var children = null;
		if (tagName)
		{
			children = element.getElementsByTagName(tagName);
		}
		else
		{
			children = element.getElementsByTagName("*");
		}
	    
		for (var i = 0, length = children.length; i < length; i++)
		{
			var child = children[i];
	        
			if (Sys.UI.DomElement.containsCssClass(child, className))
			{
				return child;
			}
		}
	    
		return null;
	},
	
	//The $addHandler and $removeHandler only work with DOM HTML elements.
	//In products that use iframes (RadWindow, RadEditor, EditorPopup) events need to be attached to the iframes' document and/or contentWindow.
	//In addition to this to construct an event object, the MS AJAX framework attempts to use the window.event - which is null in the main page, when the event originates from a child frame
	//Thus, the need to provide an alternative to the MS AJAX framework arises
	addExternalHandler : function(element, eventName, handler)
	{        	
		if (element.addEventListener)
		{
			element.addEventListener(eventName, handler, false);
		}
		else if (element.attachEvent)
		{	
			element.attachEvent("on" + eventName, handler);
		}
	},
	removeExternalHandler : function(element, eventName, handler)
	{    	
		if (element.addEventListener)
		{
			element.removeEventListener(eventName, handler, false);
		}
		else if (element.detachEvent)
		{
			element.detachEvent("on" + eventName, handler);
		}
	},
	
	cancelRawEvent : function(e)
	{    	
		if (!e) return false;
		if (e.preventDefault) e.preventDefault();
		if (e.stopPropagation) e.stopPropagation();
		e.cancelBubble = true;
		e.returnValue = false;	
		return false;
	},
	
	getOuterHtml : function(element)
	{
		if (element.outerHTML)
		{
			return element.outerHTML;
		}
		else
		{
			var elementCopy = element.cloneNode(true);
			var tmpDiv = element.ownerDocument.createElement("DIV");
			tmpDiv.appendChild(elementCopy);
			return tmpDiv.innerHTML;		
		}
	},
	
	setVisible : function(e, value) 
	{
		if (!e) return;

		if (value != $telerik.getVisible(e)) {
	        
			if (value) {
				if (e.style.removeAttribute) {
					e.style.removeAttribute("display");
				} else {
				   e.style.removeProperty("display");
				}
			}
			else {
				e.style.display = 'none';
			}
	        
			e.style.visibility = value ? 'visible' : 'hidden';
		}
	},
	
	getVisible : function(e) 
	{
		if (!e) return false;

		return (("none" != $telerik.getCurrentStyle(e, "display")) &&
        ("hidden" != $telerik.getCurrentStyle(e, "visibility")));
	},
	
	getViewPortSize : function()
	{
		var width = 0;
		var height = 0;

		var canvas = document.body;

		if (!$telerik.quirksMode && !$telerik.isSafari)
		{
			canvas = document.documentElement;
		}

		if (window.innerWidth)
		{
			width = window.innerWidth;
			height = window.innerHeight;
		}
		else
		{
			width = canvas.clientWidth;
			height = canvas.clientHeight;
		}

		width += canvas.scrollLeft;
		height += canvas.scrollTop;

		return { width : width - 6, height : height - 6 };
	},
	
	elementOverflowsTop : function (element)
	{
		return $telerik.getLocation(element).y < 0;
	}, 

	elementOverflowsLeft : function (element)
	{
		return $telerik.getLocation(element).x < 0;
	},

	elementOverflowsBottom : function (screenSize, element)
	{
		var bottomEdge = $telerik.getLocation(element).y + element.offsetHeight;
		return bottomEdge > screenSize.height;
	},

	elementOverflowsRight : function (screenSize, element)
	{
		var rightEdge = $telerik.getLocation(element).x + element.offsetWidth;
		return rightEdge > screenSize.width;
	},

	getDocumentRelativeCursorPosition : function(e)
	{
		var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
		var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
		var left = e.clientX + scrollLeft;
		var top = e.clientY + scrollTop;
		return {left:left, top:top};
	},
	
//	//Lini: this code is not needed anymore. It will be removed for the Q1 2008 release.
//	makeCompatible : function(type)
//	{
//		/// <exclude />
//		/// <summary>
//		///		Doubles the get_propertyName, set_propertyName, add_event, remove_event
//		///		methods with get_PropertyName, set_PropertyName, etc. ones, to save troubles for
//		///		users already having client-side code with the mistaken client-side convention.
//		///
//		///     Doubles the methodName(...) with MethodName(...) member to save troubles for
//	    ///		users already having client-side code with the mistaken client-side convention.
//		/// </summary>

//		var proto = type.prototype;
//		for (var memberName in proto)
//		{
//			if (/([gs]et|add|remove|raise)_[a-z].*/.test(memberName))
//			{
//				var propNameStart = RegExp.$1.length + 1;
//				var oldPropName = memberName.substr(0, propNameStart) + memberName.charAt(propNameStart).toUpperCase() + memberName.substr(propNameStart + 1);
//				proto[oldPropName] = proto[memberName];
//			}
//			else if (/^[a-z][a-zA-Z]+$/.test(memberName) && 
//		             proto.hasOwnProperty(memberName) &&
//		             typeof(proto[memberName]) == "function" && 
//		             memberName != "initialize" &&
//		             memberName != "dispose")
//		    {
//		        var oldMethodName = memberName.charAt(0).toUpperCase() + memberName.substr(1);
//		        proto[oldMethodName] = proto[memberName];		    
//		    }
//		}
//	},
	
	getFirstChildByTagName : function (element, tagName, index)
	{
		if (!element || !element.childNodes)
		{
			return null;
		}
		
		var currentNode = element.childNodes[index] || element.firstChild;
		
		while (currentNode)
		{
			if (currentNode.nodeType == 1 && currentNode.tagName.toLowerCase() == tagName)
				return currentNode;
			
			currentNode = currentNode.nextSibling;
		}
	
		return null;
	},

	getChildByClassName : function(element, className, index)
	{
		var currentNode = element.childNodes[index] || element.firstChild;
		while (currentNode)
		{
			if (currentNode.nodeType == 1 && currentNode.className.indexOf(className) > -1)
				return currentNode;
			currentNode = currentNode.nextSibling;
		}
		return null;
	},

	getChildrenByTagName : function (element, tagName)
	{
		var children = new Array();
		var childNodes = element.children || element.childNodes;
		
		for (var i = 0, length = childNodes.length; i < length; i++)
		{
			var child = childNodes[i];
			if (child.nodeType == 1 && child.tagName.toLowerCase() == tagName)
				Array.add(children, child);
		}
		return children;
	},
	
	getChildrenByClassName : function (element, className)
	{
		var children = new Array();
		var childNodes = element.children || element.childNodes;
		
		for (var i = 0, length = childNodes.length; i < length; i++)
		{
			var child = childNodes[i];
			if (child.nodeType == 1 && child.className.indexOf(className) > -1)
				Array.add(children, child);
		}
		return children;
	},
	
	isMouseOverElement : function(element, e)
	{
		var elementBounds = $telerik.getBounds(element);
		var cursor = $telerik.getDocumentRelativeCursorPosition(e);

		return $telerik.containsPoint(elementBounds, cursor.left, cursor.top);
	}
}

if (typeof(Sys.Browser.WebKit) == "undefined")
{
	Sys.Browser.WebKit = {}; //Safari 3 is considered WebKit
}
if (typeof(Sys.Browser.Chrome) == "undefined")
{
	Sys.Browser.Chrome = {};
}

if(navigator.userAgent.indexOf("Chrome") > -1)
{
	//Sys.Browser.version = navigator.userAgent.match(/Chrome\/(\d+(\.\d+(\.\d+))?)/)[1];
	Sys.Browser.version = parseFloat(navigator.userAgent.match(/WebKit\/(\d+(\.\d+)?)/)[1]);
	Sys.Browser.agent = Sys.Browser.Chrome;
	Sys.Browser.name = "Chrome";
}
else if(navigator.userAgent.indexOf("WebKit/") > -1)
{
	Sys.Browser.version = parseFloat(navigator.userAgent.match(/WebKit\/(\d+(\.\d+)?)/)[1]);
	if (Sys.Browser.version < 500)
	{
		Sys.Browser.agent = Sys.Browser.Safari;
		Sys.Browser.name = "Safari";
	}
	else
	{
		Sys.Browser.agent = Sys.Browser.WebKit;
		Sys.Browser.name = "WebKit";
	}
}

$telerik.isChrome = Sys.Browser.agent == Sys.Browser.Chrome;
$telerik.isSafari3 = Sys.Browser.agent == Sys.Browser.WebKit || Sys.Browser.agent == Sys.Browser.Chrome;
$telerik.isSafari2 = Sys.Browser.agent == Sys.Browser.Safari;
$telerik.isSafari = $telerik.isSafari2 || $telerik.isSafari3;
$telerik.isIE = Sys.Browser.agent == Sys.Browser.InternetExplorer;
$telerik.isIE7 = $telerik.isIE && Sys.Browser.version == 7;
$telerik.isIE6 = $telerik.isIE && Sys.Browser.version < 7;
$telerik.isOpera = Sys.Browser.agent == Sys.Browser.Opera;
$telerik.isFirefox = Sys.Browser.agent == Sys.Browser.Firefox;
$telerik.quirksMode = $telerik.isIE && document.compatMode != "CSS1Compat";
$telerik.standardsMode = !$telerik.quirksMode;

//Initialize the thickness of borders based on their style
$telerik._borderThickness();

Telerik.Web.UI.Orientation = function() {
    /// <summary>
    /// The Telerik.Web.UI.Orientation enumeration is used to specify 
    /// the orientation of a given asset
    /// </summary>
    /// <field name="Horizontal" type="Number" integer="true"/>
    /// <field name="Vertical" type="Number" integer="true"/>
    throw Error.invalidOperation();
}
Telerik.Web.UI.Orientation.prototype = {
    Horizontal : 0,
    Vertical : 1
} 
Telerik.Web.UI.Orientation.registerEnum('Telerik.Web.UI.Orientation', false);

Telerik.Web.UI.RadWebControl = function(element) 
{
    Telerik.Web.UI.RadWebControl.initializeBase(this, [element]);
    
    this._clientStateFieldID = null;
}

Telerik.Web.UI.RadWebControl.prototype = 
{
    initialize: function() 
    {
        Telerik.Web.UI.RadWebControl.callBaseMethod(this, 'initialize');
        
        $telerik.registerControl(this);
        
        if(!this.get_clientStateFieldID()) return;
        
        var input = $get(this.get_clientStateFieldID());    
        
        if(!input) return;
        
        input.setAttribute('autocomplete', 'off');
    },
    
    dispose: function() 
    {
        $telerik.unregisterControl(this);
        
        var element = this.get_element();
        
        Telerik.Web.UI.RadWebControl.callBaseMethod(this, 'dispose');
        
        if (element)
        {
			element.control = null;
			element._events = null;
		}
    },
    
    raiseEvent : function(eventName, eventArgs) {
        /// <summary>
        /// Raise the event
        /// </summary>
        /// <param name="eventName" type="String" mayBeNull="false">
        /// Name of the event to be raised
        /// </param>
        /// <param name="eventArgs" type="Sys.EventArgs" mayBeNull="true">
        /// Event arguments for the given event
        /// </param>
        /// <returns />

		var handler = this.get_events().getHandler(eventName);
		if (handler) {
			if (!eventArgs) {
				eventArgs = Sys.EventArgs.Empty;
			}
			handler(this, eventArgs);
        }
    },
    
    updateClientState: function()
    {
        /// <summary>
        /// Call this function to update the client state hidden field.
        /// Use this function with caution, because it is resource hungry.
        /// </summary>
		this.set_clientState(this.saveClientState());
    },
    
    saveClientState: function()
    {
        /// <summary>
        /// This function should return the serialized client state of the control.
        /// </summary>
        /// <example>
		/// saveClientState: function()
		/// {
		///		var state = 
		///		{
		///			Collapsed	: this.get_collapsed(),
		///			Width		: this.get_width(),
		///			Height		: this.get_height()
		///		};
		///		return Sys.Serialization.JavaScriptSerializer.serialize(state);
		/// }
        /// </example>
         return null;
    },
    
    get_clientStateFieldID : function() 
    {
        /// <value type="String">
        /// ID of the hidden field used to store the client state
        /// </value>
        return this._clientStateFieldID;
    },
    set_clientStateFieldID : function(value) 
    {
        if (this._clientStateFieldID != value) 
        {
            this._clientStateFieldID = value;
            this.raisePropertyChanged('ClientStateFieldID');
        }
    },

    get_clientState : function() {
        /// <value type="String">
        /// Client state
        /// </value>
        if (this._clientStateFieldID) 
        {
            var input = document.getElementById(this._clientStateFieldID);
            if (input) 
            {
                return input.value;
            }
        }
        return null;
    },
    set_clientState : function(value) 
    {
        if (this._clientStateFieldID) 
        {
            var input = document.getElementById(this._clientStateFieldID);
            if (input) 
            {
                input.value = value;
            }
        }
    },
    
    _getChildElement : function(id)
	{
		return $get(this.get_id() + "_" + id);
	},
	
	_findChildControl : function(id)
	{
		return $find(this.get_id() + "_" + id);
	}
}

Telerik.Web.UI.RadWebControl.registerClass('Telerik.Web.UI.RadWebControl', Sys.UI.Control);

Telerik.Web.Timer = function() {
    Telerik.Web.Timer.initializeBase(this);
    
    this._interval = 1000;
    this._enabled = false;
    this._timer = null;
    
    this._timerCallbackDelegate = Function.createDelegate(this, this._timerCallback);
}

Telerik.Web.Timer.prototype = {
    get_interval: function() {
        
        return this._interval;
    },
    set_interval: function(value) {
        
        if (this._interval !== value) {
            this._interval = value;
            this.raisePropertyChanged('interval');
            
            if (!this.get_isUpdating() && (this._timer !== null)) {
                this._stopTimer();
                this._startTimer();
            }
        }
    },
    
    get_enabled: function() {
        
        return this._enabled;
    },
    set_enabled: function(value) {
        
        if (value !== this.get_enabled()) {
            this._enabled = value;
            this.raisePropertyChanged('enabled');
            if (!this.get_isUpdating()) {
                if (value) {
                    this._startTimer();
                }
                else {
                    this._stopTimer();
                }
            }
        }
    },

    
    add_tick: function(handler) {
        this.get_events().addHandler("tick", handler);
    },

    remove_tick: function(handler) {
        this.get_events().removeHandler("tick", handler);
    },

    dispose: function() {
        this.set_enabled(false);
        this._stopTimer();
        
        Telerik.Web.Timer.callBaseMethod(this, 'dispose');
    },
    
    updated: function() {
        Telerik.Web.Timer.callBaseMethod(this, 'updated');

        if (this._enabled) {
            this._stopTimer();
            this._startTimer();
        }
    },

    _timerCallback: function() {
        var handler = this.get_events().getHandler("tick");
        if (handler) {
            handler(this, Sys.EventArgs.Empty);
        }
    },

    _startTimer: function() {
        this._timer = window.setInterval(this._timerCallbackDelegate, this._interval);
    },

    _stopTimer: function() {
        window.clearInterval(this._timer);
        this._timer = null;
    }
}

Telerik.Web.Timer.registerClass('Telerik.Web.Timer', Sys.Component);

Telerik.Web.BoxSide = function() {
}
Telerik.Web.BoxSide.prototype = {
    Top : 0,
    Right : 1,
    Bottom : 2,
    Left : 3
}
Telerik.Web.BoxSide.registerEnum("Telerik.Web.BoxSide", false);

if (Sys.CultureInfo.prototype._getAbbrMonthIndex) {
    try {
        Sys.CultureInfo.prototype._getAbbrMonthIndex('');
    } catch(ex) {
        Sys.CultureInfo.prototype._getAbbrMonthIndex = function(value) {
            if (!this._upperAbbrMonths) {
                this._upperAbbrMonths = this._toUpperArray(this.dateTimeFormat.AbbreviatedMonthNames);
            }
            return Array.indexOf(this._upperAbbrMonths, this._toUpper(value));
        }
        Sys.CultureInfo.CurrentCulture._getAbbrMonthIndex = Sys.CultureInfo.prototype._getAbbrMonthIndex;
        Sys.CultureInfo.InvariantCulture._getAbbrMonthIndex = Sys.CultureInfo.prototype._getAbbrMonthIndex;
    }
}

Type.registerNamespace("Telerik.Web.UI.Dialogs");

Telerik.Web.IParameterConsumer = function() {
}
Telerik.Web.IParameterConsumer.prototype = {
    clientInit: function(parameters) { throw Error.notImplemented(); }
}
Telerik.Web.IParameterConsumer.registerInterface('Telerik.Web.IParameterConsumer');

Telerik.Web.UI.Dialogs.CommonDialogScript = function()
{
}
Telerik.Web.UI.Dialogs.CommonDialogScript.get_windowReference = function()
{
	if (window.radWindow)
	{
		return window.radWindow;
	}
	if (window.frameElement && window.frameElement.radWindow)
	{
		return window.frameElement.radWindow;
	}
	return null;
};

Telerik.Web.UI.Dialogs.CommonDialogScript.registerClass('Telerik.Web.UI.Dialogs.CommonDialogScript', null);

Telerik.Web.UI.WebServiceLoaderEventArgs = function(context)
{
	Telerik.Web.UI.WebServiceLoaderEventArgs.initializeBase(this);
	this._context = context;
}

Telerik.Web.UI.WebServiceLoaderEventArgs.prototype =
{
	get_context : function ()
	{
		return this._context;
	}
}

Telerik.Web.UI.WebServiceLoaderEventArgs.registerClass('Telerik.Web.UI.WebServiceLoaderEventArgs', Sys.EventArgs);


// ---------- WebServiceLoaderSuccessEventArgs Class ----------
Telerik.Web.UI.WebServiceLoaderSuccessEventArgs = function(data, context)
{
	Telerik.Web.UI.WebServiceLoaderSuccessEventArgs.initializeBase(this, [context]);
	this._data = data;
}

Telerik.Web.UI.WebServiceLoaderSuccessEventArgs.prototype =
{
	get_data : function ()
	{
		return this._data;
	}	
}

Telerik.Web.UI.WebServiceLoaderSuccessEventArgs.registerClass('Telerik.Web.UI.WebServiceLoaderSuccessEventArgs', Telerik.Web.UI.WebServiceLoaderEventArgs);


// ---------- WebServiceLoaderErrorEventArgs Class ----------
Telerik.Web.UI.WebServiceLoaderErrorEventArgs = function(message, context)
{
	Telerik.Web.UI.WebServiceLoaderErrorEventArgs.initializeBase(this, [context]);
	this._message = message;
}

Telerik.Web.UI.WebServiceLoaderErrorEventArgs.prototype =
{
	get_message : function ()
	{
		return this._message;
	}
}

Telerik.Web.UI.WebServiceLoaderErrorEventArgs.registerClass('Telerik.Web.UI.WebServiceLoaderErrorEventArgs', Telerik.Web.UI.WebServiceLoaderEventArgs);


// ---------- WebServiceLoader Class ----------
Telerik.Web.UI.WebServiceLoader = function(webServiceSettings)
{
	this._webServiceSettings = webServiceSettings;
	this._events = null;
	this._currentWebRequest = null;
	this._onWebServiceSuccessDelegate = Function.createDelegate(this, this._onWebServiceSuccess);
	this._onWebServiceErrorDelegate = Function.createDelegate(this, this._onWebServiceError);
}

Telerik.Web.UI.WebServiceLoader.prototype =
{
	// Public properties
	get_webServiceSettings : function ()
	{
		return this._webServiceSettings;
	},
	
	get_events: function ()
	{
		if (!this._events)
		{
			this._events = new Sys.EventHandlerList();
		}
		
		return this._events;
	},
	
	
	// Public methods
	loadData : function (params, context)
	{
		var webServiceSettings = this.get_webServiceSettings();
		
		if (webServiceSettings.get_isEmpty())
		{
			Error.invalidOperation("Please, specify valid web service and method.");
			return;
		}

		var webServicePath = webServiceSettings.get_path();
		var webMethod = webServiceSettings.get_method();
		
		this._raiseEvent("loadingStarted", new Telerik.Web.UI.WebServiceLoaderEventArgs(context));

		this._currentWebRequest =	Sys.Net.WebServiceProxy.invoke(webServicePath, webMethod, false, params,
										this._onWebServiceSuccessDelegate, this._onWebServiceErrorDelegate, context);
	},
	
	
	// Events
	add_loadingStarted : function(handler)
	{
		this.get_events().addHandler("loadingStarted", handler);
	},

	add_loadingError : function(handler)
	{
		this.get_events().addHandler("loadingError", handler);
	},

	add_loadingSuccess : function(handler)
	{
		this.get_events().addHandler("loadingSuccess", handler);
	},
	
	
	// Private methods	
	_onWebServiceSuccess : function (data, context)
	{
		var successEventArgs = new Telerik.Web.UI.WebServiceLoaderSuccessEventArgs(data, context);
		this._raiseEvent("loadingSuccess", successEventArgs);
	},
	
	_onWebServiceError : function (error, context)
	{	
		var errorEventArgs = new Telerik.Web.UI.WebServiceLoaderErrorEventArgs(error.get_message(), context);
		this._raiseEvent("loadingError", errorEventArgs);
	},

	_raiseEvent : function (eventName, eventArgs)
	{
		var handler = this.get_events().getHandler(eventName);        

		if (handler)
		{
			if (!eventArgs)
			{
				eventArgs = Sys.EventArgs.Empty;
			}

			handler(this, eventArgs);
		}
	}
}

Telerik.Web.UI.WebServiceLoader.registerClass('Telerik.Web.UI.WebServiceLoader');

Telerik.Web.UI.WebServiceSettings = function(serializedWebServiceSettings)
{
	this._path = null;
	this._method = null;
	
	//Add a check for the parameter existance
	if (!serializedWebServiceSettings) serializedWebServiceSettings = {};
	
	if (typeof(serializedWebServiceSettings.path) != "undefined")
	{
		this._path = serializedWebServiceSettings.path;
	}
	
	if (typeof(serializedWebServiceSettings.method) != "undefined")
	{
		this._method = serializedWebServiceSettings.method;
	}
}

Telerik.Web.UI.WebServiceSettings.prototype =
{
	get_path : function ()
	{
		return this._path;
	},
	
	set_path : function(value)
	{
		this._path = value;
	},

	get_method : function ()
	{
		return this._method;
	},
	
	set_method : function(value)
	{
		this._method = value;
	},
	
	get_isEmpty : function ()
	{
		/// <value type="Boolean">
		///		A value indicating wether the web service settings contain
		///		a non-null and non-empty service path and method.
		/// </value>
		var path = this.get_path();
		var method = this.get_method();
		
		return (!(path && method))
	}
}

Telerik.Web.UI.WebServiceSettings.registerClass('Telerik.Web.UI.WebServiceSettings');
/* END Telerik.Web.UI.Common.Core.js */
/* START Telerik.Web.UI.Common.Animation.Animations.js */
// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Permissive License.
// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
// All other rights reserved.

Type.registerNamespace('Telerik.Web.Animation');

// Create an alias for the namespace to save 25 chars each time it's used since
// this is a very long script and will take awhile to download
var $TWA = Telerik.Web.Animation;

$TWA.registerAnimation = function(name, type) {
    /// <summary>
    /// Register an animation with the AJAX Control Toolkit animation framework. This serves a dual purpose:
    /// 1) to add standard utility methods to the animation type (such as a <code>play</code> method that creates
    /// an animation, plays it, and disposes it when the animation is over), and 2) to associate a name with the
    /// type that will be used when creating animations from a JSON description.  This method can also be called
    /// by other animation libraries to seamlessly interoperate with the AJAX Control Toolkit's animation
    /// framework.
    /// </summary>
    /// <param name="name" type="String">
    /// Name of the animation that will be used as the XML tag name in the XML animation description.  It
    /// should be a valid XML tag (i.e. an alpha-numeric sequence with no spaces, special characters, etc.).
    /// </param>
    /// <param name="type" type="Type">
    /// The type of the new animation must inherit from <see cref="Telerik.Web.Animation.Animation" />.
    /// </param>
    /// <returns />

    // Make sure the type inherits from Telerik.Web.Animation.Animation
    if (type && ((type === $TWA.Animation) || (type.inheritsFrom && type.inheritsFrom($TWA.Animation)))) {
        // We'll store the animation name/type mapping in a "static" object off of
        // Telerik.Web.Animation.  If this __animations object hasn't been
        // created yet, demand create it on the first registration.
        if (!$TWA.__animations) {
            $TWA.__animations = { };
        }
        
        // Add the current type to the collection of animations
        $TWA.__animations[name.toLowerCase()] = type;
        
        // Add a play function that will make it very easy to create, play, and
        // dispose of an animation.  This is effectively a "static" function on
        // each animation and will take the same parameters as that animation's
        // constructor.
        type.play = function() {
            /// <summary>
            /// Create an animation, play it immediately, and dispose it when finished.
            /// </summary>
            /// <param parameterArray="true" elementType="Object">
            /// The play function takes the same parameters as the type's constructor
            /// </param>
            /// <returns />
        
            // Create and initialize a new animation of the right type and pass in
            // any arguments given to the play function
            var animation = new type();
            type.apply(animation, arguments);
            animation.initialize();
            
            // Add an event handler to dispose the animation when it's finished
            var handler = Function.createDelegate(animation,
                function() {
                    /// <summary>
                    /// Dispose the animation after playing
                    /// </summary>
                    /// <returns />
                    animation.remove_ended(handler);
                    handler = null;
                    animation.dispose();
                });
            animation.add_ended(handler);
            
            // Once the animation has been created and initialized, play it and
            // dispose it as soon as it's finished
            animation.play();            
        }
    } else {
        // Raise an error if someone registers an animation that doesn't inherit
        // from our base Animation class
        throw Error.argumentType('type', type, $TWA.Animation, "Telerik.Web.Animation.registerAnimation can only register types that inherit from Telerik.Web.Animation.Animation");
    }
}

// In the Xml comments for each of the animations below, there is a special <animation /> tag
// that describes how the animation is referenced from a generic XML animation description


$TWA.Animation = function(target, duration, fps) {
    /// <summary>
    /// <code>Animation</code> is an abstract base class used as a starting point for all the other animations.
    /// It provides the basic mechanics for the animation (playing, pausing, stopping, timing, etc.)
    /// and leaves the actual animation to be done in the abstract methods <code>getAnimatedValue</code>
    /// and <code>setValue</code>.
    /// </summary>
    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
    /// Target of the animation
    /// </param>
    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
    /// Length of the animation in seconds.  The default is 1.
    /// </param>
    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
    /// Number of steps per second.  The default is 25.
    /// </param>
    /// <field name="DynamicProperties" type="Object">
    /// The DynamicProperties collection is used to associate JavaScript expressions with
    /// properties.  The expressions are evaluated just before the animation is played
    /// everytime (in the base onStart method).  The object itself maps strings with the
    /// names of property setters (like "set_verticalOffset") to JavaScript expressions
    /// (like "$find('MyBehavior').get_element().offsetHeight").  Note specifically that
    /// the dynamic properties are JavaScript expressions and not abitrary statements (i.e.
    /// you can't include things like "return foo;"), although you can include anything
    /// inside an anonymous function definition that you immediately invoke (i.e.,
    /// "(function() { return foo; })()").  A dynamic property can be set in the generic
    /// XML animation description by appending Script onto any legitimate property name
    /// (for example, instead of Height="70" we could use
    /// HeightScript="$find('MyBehavior').get_element().offsetHeight").  Any exceptions
    /// raised when setting dynamic properties (including both JavaScript evaluation errors
    /// and other exceptions raised by property setters) will only be propogated when
    /// debugging.
    /// </field>
    /// <remarks>
    /// Animations need to be as fast as possible - even in debug mode.  Don't add validation code to
    /// methods involved in every step of the animation.
    /// </remarks>
    /// <animation>Animation</animation>
    $TWA.Animation.initializeBase(this);
    
    // Length of the animation in seconds
    this._duration = 1;
    
    // Number of steps per second
    this._fps = 25;
    
    // Target Sys.UI.DomElement of the animation
    this._target = null;
    
    // Tick event handler
    this._tickHandler = null;
    
    // Animation timer
    this._timer = null;
    
    // Percentage of the animation already played
    this._percentComplete = 0;
    
    // Percentage of the animation to play on each step
    this._percentDelta = null;
    
    // Reference to the animation that owns this animation (currently only set in 
    // ParallelAnimation.add).  This concept of ownership allows an entire animation
    // subtree to be driven off a single timer so all the operations are properly
    // synchronized.
    this._owner = null;
    
    // Reference to the animation that contains this as a child (this is set
    // in ParentAnimation.add).  The primary use of the parent animation is in
    // resolving the animation target when one isn't specified.
    this._parentAnimation = null;
    
    // The DynamicProperties collection is used to associate JavaScript expressions with
    // properties.  The expressions are evaluated just before the animation is played
    // everytime (in the base onStart method).  See the additional information in the
    // XML <field> comment above.
    this.DynamicProperties = { };
    
    // Set the target, duration, and fps if they were provided in the constructor
    if (target) {
        this.set_target(target);
    }
    if (duration) {
        this.set_duration(duration);
    }
    if (fps) { 
        this.set_fps(fps);
    }
}
$TWA.Animation.prototype = {
    dispose : function() {
        /// <summary>
        /// Dispose the animation
        /// </summary>
        /// <returns />
        
        if (this._timer) {
            this._timer.dispose();
            this._timer = null;
        }
        
        this._tickHandler = null;
        this._target = null;
        
        $TWA.Animation.callBaseMethod(this, 'dispose');
    },
    
    play : function() {
        /// <summary>
        /// Play the animation from the beginning or where it was left off when paused.
        /// </summary>
        /// <returns />
        /// <remarks>
        /// If this animation is the child of another, you must call <code>play</code> on its parent instead.
        /// </remarks>
        
        // If ownership of this animation has been claimed, then we'll require the parent to
        // handle playing the animation (this is very important because then the entire animation
        // tree runs on the same timer and updates consistently)
        if (!this._owner) {
            var resume = true;
            if (!this._timer) {
                resume = false;
                
                if (!this._tickHandler) {
                    this._tickHandler = Function.createDelegate(this, this._onTimerTick);
                }

                this._timer = new Telerik.Web.Timer();
                this._timer.add_tick(this._tickHandler);
               
                this.onStart();
                
                this._timer.set_interval(1000 / this._fps);
                this._percentDelta = 100 / (this._duration * this._fps);
                this._updatePercentComplete(0, true);
            }

            this._timer.set_enabled(true);
            
            this.raisePropertyChanged('isPlaying');
            if (!resume) {
                this.raisePropertyChanged('isActive');
            }
        }
    },
    
    pause : function() {
        /// <summary>
        /// Pause the animation if it is playing.  Calling <code>play</code> will resume where
        /// the animation left off.
        /// </summary>
        /// <returns />
        /// <remarks>
        /// If this animation is the child of another, you must call <code>pause</code> on its parent instead.
        /// </remarks>
        
        if (!this._owner) {
            if (this._timer) {
                this._timer.set_enabled(false);
                
                this.raisePropertyChanged('isPlaying');
            }
        }
    },
    
    stop : function(finish) {
        /// <summary>
        /// Stop playing the animation.
        /// </summary>
        /// <param name="finish" type="Boolean" mayBeNull="true" optional="true">
        /// Whether or not stopping the animation should leave the target element in a state
        /// consistent with the animation playing completely by performing the last step.
        /// The default value is true.
        /// </param>
        /// <returns />
        /// <remarks>
        /// If this animation is the child of another, you must call <code>stop</code> on
        /// its parent instead.
        /// </remarks>
        
        if (!this._owner) {
            var t = this._timer;
            this._timer = null;
            if (t) {
                t.dispose();
                
                if (this._percentComplete !== 100) {
                    this._percentComplete = 100;
                    this.raisePropertyChanged('percentComplete');
                    if (finish || finish === undefined) {
                        this.onStep(100);
                    }
                }
                this.onEnd();
                
                this.raisePropertyChanged('isPlaying');
                this.raisePropertyChanged('isActive');
            }
        }
    },
    
    onStart : function() {
        /// <summary>
        /// The <code>onStart</code> method is called just before the animation is played each time.
        /// </summary>
        /// <returns />
        
        this.raiseStarted();
        
        // Initialize any dynamic properties
        for (var property in this.DynamicProperties) {
            try {
                // Invoke the property's setter on the evaluated expression
                this[property](eval(this.DynamicProperties[property]));
            } catch(ex) {
                // Propogate any exceptions if we're debugging, otherwise eat them
                if ( Sys.Debug.isDebug) {
                    throw ex;
                }
            }
        }
    },
    
    onStep : function(percentage) {
        /// <summary>
        /// The <code>onStep</code> method is called repeatedly to progress the animation through each frame
        /// </summary>
        /// <param name="percentage" type="Number">Percentage of the animation already complete</param>
        /// <returns />
        
        this.setValue(this.getAnimatedValue(percentage));
    },
    
    onEnd : function() {
        /// <summary>
        /// The <code>onEnd</code> method is called just after the animation is played each time.
        /// </summary>
        /// <returns />
        
        this.raiseEnded();
    },
    
    getAnimatedValue : function(percentage) {
        /// <summary>
        /// Determine the state of the animation after the given percentage of its duration has elapsed
        /// </summary>
        /// <param name="percentage" type="Number">Percentage of the animation already complete</param>
        /// <returns type="Object">
        /// State of the animation after the given percentage of its duration has elapsed that will
        /// be passed to <code>setValue</code>
        /// </returns>
        throw Error.notImplemented();
    },
    
    setValue : function(value) {
        /// <summary>
        /// Set the current state of the animation
        /// </summary>
        /// <param name="value" type="Object">Current state of the animation (as retreived from <code>getAnimatedValue</code>)</param>
        /// <returns />
        throw Error.notImplemented();
    },
    
    interpolate : function(start, end, percentage) {
        /// <summary>
        /// The <code>interpolate</code> function is used to find the appropriate value between starting and
        /// ending values given the current percentage.
        /// </summary>
        /// <param name="start" type="Number">
        /// Start of the range to interpolate
        /// </param>
        /// <param name="end" type="Number">
        /// End of the range to interpolate
        /// </param>
        /// <param name="percentage" type="Number">
        /// Percentage completed in the range to interpolate
        /// </param>
        /// <returns type="Number">
        /// Value the desired percentage between the start and end values
        /// </returns>
        /// <remarks>
        /// In the future, we hope to make several implementations of this available so we can dynamically
        /// change the apparent speed of the animations, although it may make more sense to modify the
        /// <code>_updatePercentComplete</code> function instead.
        /// </remarks>
        return start + (end - start) * (percentage / 100);
    },
    
    _onTimerTick : function() {
        /// <summary>
        /// Handler for the tick event to move the animation along through its duration
        /// </summary>
        /// <returns />
        this._updatePercentComplete(this._percentComplete + this._percentDelta, true);
		this.raise_onTick();
    },
    
    _updatePercentComplete : function(percentComplete, animate) {
        /// <summary>
        /// Update the animation and its target given the current percentage of its duration that
        /// has already elapsed
        /// </summary>
        /// <param name="percentComplete" type="Number">
        /// Percentage of the animation duration that has already elapsed
        /// </param>
        /// <param name="animate" type="Boolean" mayBeNull="true" optional="true">
        /// Whether or not updating the animation should visually modify the animation's target
        /// </param>
        /// <returns />
        
        if (percentComplete > 100) {
            percentComplete = 100;
        }
        
        this._percentComplete = percentComplete;
        this.raisePropertyChanged('percentComplete');
        
        if (animate) {
            this.onStep(percentComplete);
        }
        
        if (percentComplete === 100) {
            this.stop(false);
        }
    },
    
    setOwner : function(owner) {
        /// <summary>
        /// Make this animation the child of another animation
        /// </summary>
        /// <param name="owner" type="Telerik.Web.Animation.Animation">
        /// Parent animation
        /// </param>
        /// <returns />
        this._owner = owner;
    },
    
    raiseStarted : function() {
        /// <summary>
        /// Raise the <code>started</code> event
        /// </summary>
        /// <returns />
        var handlers = this.get_events().getHandler('started');
        if (handlers) {
            handlers(this, Sys.EventArgs.Empty);
        }
    },
    
    add_started : function(handler) {
        /// <summary>
        /// Adds an event handler for the <code>started</code> event.
        /// </summary>
        /// <param name="handler" type="Function">
        /// The handler to add to the event.
        /// </param>
        /// <returns />
        this.get_events().addHandler("started", handler);
    },
    
    remove_started : function(handler) {
        /// <summary>
        /// Removes an event handler for the <code>started</code> event.
        /// </summary>
        /// <param name="handler" type="Function">
        /// The handler to remove from the event.
        /// </param>
        /// <returns />
        this.get_events().removeHandler("started", handler);
    },
    
    raiseEnded : function() {
        /// <summary>
        /// Raise the <code>ended</code> event
        /// </summary>
        /// <returns />
        var handlers = this.get_events().getHandler('ended');
        if (handlers) {
            handlers(this, Sys.EventArgs.Empty);
        }
    },
    
    add_ended : function(handler) {
        /// <summary>
        /// Adds an event handler for the <code>ended</code> event.
        /// </summary>
        /// <param name="handler" type="Function">
        /// The handler to add to the event.
        /// </param>
        /// <returns />
        this.get_events().addHandler("ended", handler);
    },
    
    remove_ended : function(handler) {
        /// <summary>
        /// Removes an event handler for the <code>ended</code> event.
        /// </summary>
        /// <param name="handler" type="Function">
        /// The handler to remove from the event.
        /// </param>
        /// <returns />
        this.get_events().removeHandler("ended", handler);
    },

	raise_onTick : function ()
	{
        var handlers = this.get_events().getHandler('onTick');
        if (handlers)
		{
            handlers(this, Sys.EventArgs.Empty);
        }
	},
	
	add_onTick : function (handler)
	{
		this.get_events().addHandler("onTick", handler);
	},
	
	remove_onTick : function (handler)
	{
		this.get_events().removeHandler("onTick", handler);
	},

    get_target : function() {
        /// <value type="Sys.UI.DomElement" domElement="true" mayBeNull="true">
        /// Target of the animation.  If the target of this animation is null and
        /// the animation has a parent, then it will recursively use the target of
        /// the parent animation instead.
        /// </value>
        /// <remarks>
        /// Do not set this property in a generic Xml animation description. It should be set
        /// using either the extender's TargetControlID or the AnimationTarget property (the latter
        /// maps to Telerik.Web.Animation.set_animationTarget).  The only valid way to
        /// set this property in the generic Xml animation description is to use the dynamic
        /// property TargetScript="$get('myElement')".
        /// <remarks>
        if (!this._target && this._parentAnimation) {
            return this._parentAnimation.get_target();
        }
        return this._target;
    },
    set_target : function(value) {
        if (this._target != value) {
            this._target = value;
            this.raisePropertyChanged('target');
        }
    },
    
    set_animationTarget : function(id) {
        /// <value type="string" mayBeNull="false">
        /// ID of a Sys.UI.DomElement or Sys.UI.Control to use as the target of the animation
        /// </value>
        /// <remarks>
        /// If no Sys.UI.DomElement or Sys.UI.Control can be found for the given ID, an
        /// argument exception will be thrown.
        /// <remarks>
        
        // Try to find a Sys.UI.DomElement
        var target = null;
        var element = $get(id);
        if (element) {
            target = element;
        } else {
            // Try to find the control in the AJAX controls collection
            var ctrl = $find(id);
            if (ctrl) {
                element = ctrl.get_element();
                if (element) {
                    target = element;
                }
            }
        }
        
        // Use the new target if we have one, or raise an error if not
        if (target) { 
            this.set_target(target);
        } else {
            throw Error.argument('id', String.format('Telerik.Web.Animation.Animation.set_animationTarget requires the ID of a Sys.UI.DomElement or Sys.UI.Control.  No element or control could be found corresponding to "{0}"', id));
        }
    },
    
    get_duration : function() {
        /// <value type="Number">
        /// Length of the animation in seconds.  The default is 1.
        /// </value>
        return this._duration;
    },
    set_duration : function(value) {
        value = this._getFloat(value);
        if (this._duration != value) {
            this._duration = value;
            this.raisePropertyChanged('duration');
        }
    },
    
    get_fps : function() {
        /// <value type="Number" integer="true">
        /// Number of steps per second.  The default is 25.
        /// </value>
        return this._fps;
    },
    set_fps : function(value) {
        value = this._getInteger(value);
        if (this.fps != value) {
            this._fps = value;
            this.raisePropertyChanged('fps');
        }
    },
    
    get_isActive : function() {
        /// <value type="Boolean">
        /// <code>true</code> if animation is active, <code>false</code> if not.
        /// </value>
        return (this._timer !== null);
    },
    
    get_isPlaying : function() {
        /// <value type="Boolean">
        /// <code>true</code> if animation is playing, <code>false</code> if not.
        /// </value>
        return (this._timer !== null) && this._timer.get_enabled();
    },
    
    get_percentComplete : function() {
        /// <value type="Number">
        /// Percentage of the animation already played.
        /// </value>
        return this._percentComplete;
    },
    
    _getBoolean : function(value) {
        /// <summary>
        /// Helper to convert strings to booleans for property setters
        /// </summary>
        /// <param name="value" type="Object">
        /// Value to convert if it's a string
        /// </param>
        /// <returns type="Object">
        /// Value that has been converted if it was a string
        /// </returns>
        if (String.isInstanceOfType(value)) {
            return Boolean.parse(value);
        }
        return value;
    },
    
    _getInteger : function(value) {
        /// <summary>
        /// Helper to convert strings to integers for property setters
        /// </summary>
        /// <param name="value" type="Object">Value to convert if it's a string</param>
        /// <returns type="Object">Value that has been converted if it was a string</returns>
        if (String.isInstanceOfType(value)) {
            return parseInt(value);
        }
        return value;
    },
    
    _getFloat : function(value) {
        /// <summary>
        /// Helper to convert strings to floats for property setters
        /// </summary>
        /// <param name="value" type="Object">Value to convert if it's a string</param>
        /// <returns type="Object">Value that has been converted if it was a string</returns>
        if (String.isInstanceOfType(value)) {
            return parseFloat(value);
        }
        return value;
    },
    
    _getEnum : function(value, type) {
        /// <summary>
        /// Helper to convert strings to enum values for property setters
        /// </summary>
        /// <param name="value" type="Object">Value to convert if it's a string</param>
        /// <param name="type" type="Type">Type of the enum to convert to</param>
        /// <returns type="Object">Value that has been converted if it was a string</returns>
        if (String.isInstanceOfType(value) && type && type.parse) {
            return type.parse(value);
        }
        return value;
    }
}
$TWA.Animation.registerClass('Telerik.Web.Animation.Animation', Sys.Component);
$TWA.registerAnimation('animation', $TWA.Animation);


$TWA.ParentAnimation = function(target, duration, fps, animations) {
    /// <summary>
    /// The <code>ParentAnimation</code> serves as a base class for all animations that contain children (such as
    /// <see cref="Telerik.Web.Animation.ParallelAnimation" />, <see cref="Telerik.Web.SequenceAnimation" />,
    /// etc.).  It does not actually play the animations, so any classes that inherit from it must do so.  Any animation
    /// that requires nested child animations must inherit from this class, although it will likely want to inherit off of
    /// <see cref="Telerik.Web.Animation.ParallelAnimation" /> or <see cref="Telerik.Web.SequenceAnimation" />
    /// which will actually play their child animations.
    /// </summary>
    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
    /// Target of the animation
    /// </param>
    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
    /// Length of the animation in seconds.  The default is 1.
    /// </param>
    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
    /// Number of steps per second.  The default is 25.
    /// </param>
    /// <param name="animations" mayBeNull="true" optional="true" parameterArray="true" elementType="Telerik.Web.Animation.Animation">
    /// Array of child animations to be played
    /// </param>
    /// <animation>Parent</animation>
    $TWA.ParentAnimation.initializeBase(this, [target, duration, fps]);
    
    // Array of child animations (there are no assumptions placed on order because
    // it will matter for some derived animations like SequenceAnimation, but not
    // for others like ParallelAnimation) that is demand created in add
    this._animations = [];
    
    // Add any child animations passed into the constructor
    if (animations && animations.length) {
        for (var i = 0; i < animations.length; i++) {
            this.add(animations[i]);
        }
    }
}
$TWA.ParentAnimation.prototype = {
    initialize : function() {
    	/// <summary>
        /// Initialize the parent along with any child animations that have not yet been initialized themselves
    	/// </summary>
    	/// <returns />
        $TWA.ParentAnimation.callBaseMethod(this, 'initialize');
        
        // Initialize all the uninitialized child animations
        if (this._animations) {
            for (var i = 0; i < this._animations.length; i++) {
                var animation = this._animations[i];
                if (animation && !animation.get_isInitialized) {
                    animation.initialize();
                }
            }
        }
    },
    
    dispose : function() {
    	/// <summary>
        /// Dispose of the child animations
    	/// </summary>
    	/// <returns />

        this.clear();
        this._animations = null;
        $TWA.ParentAnimation.callBaseMethod(this, 'dispose');
    },
    
    get_animations : function() {
    	/// <value elementType="Telerik.Web.Animation.Animation">
        /// Array of child animations to be played (there are no assumptions placed on order because it will matter for some
        /// derived animations like <see cref="Telerik.Web.Animation.SequenceAnimation" />, but not for
        /// others like <see cref="Telerik.Web.Animation.ParallelAnimation" />).  To manipulate the child
        /// animations, use the functions <code>add</code>, <code>clear</code>, <code>remove</code>, and <code>removeAt</code>.
    	/// </value>
        return this._animations;
    },
    
    add : function(animation) {
    	/// <summary>
        /// Add an animation as a child of this animation.
    	/// </summary>
    	/// <param name="animation" type="Telerik.Web.Animation.Animation">Child animation to add</param>
    	/// <returns />

        if (this._animations) {
            if (animation) {
                animation._parentAnimation = this;
            }
            Array.add(this._animations, animation);
            this.raisePropertyChanged('animations');
        }
    },
    
    remove : function(animation) {
        /// <summary>
        /// Remove the animation from the array of child animations.
        /// </summary>
        /// <param name="animation" type="Telerik.Web.Animation.Animation">
        /// Child animation to remove
        /// </param>
        /// <returns />
        /// <remarks>
        /// This will dispose the removed animation.
        /// </remarks>

        if (this._animations) {
            if (animation) {
                animation.dispose();
            }
            Array.remove(this._animations, animation);
            this.raisePropertyChanged('animations');
        }
    },
    
    removeAt : function(index) {
        /// <summary>
        /// Remove the animation at a given index from the array of child animations.
        /// </summary>
        /// <param name="index" type="Number" integer="true">
        /// Index of the child animation to remove
        /// </param>
        /// <returns />
        
        if (this._animations) {
            var animation = this._animations[index];
            if (animation) {
                animation.dispose();
            }
            Array.removeAt(this._animations, index);
            this.raisePropertyChanged('animations');
        }
    },
    
    clear : function() {
    	/// <summary>
        /// Clear the array of child animations.
    	/// </summary>
    	/// <remarks>
    	/// This will dispose the cleared child animations.
    	/// </remarks>
    	/// <returns />

        if (this._animations) {
            for (var i = this._animations.length - 1; i >= 0; i--) {
                this._animations[i].dispose();
                this._animations[i] = null;
            }
            Array.clear(this._animations);
            this._animations = [];
            this.raisePropertyChanged('animations');
        }
    }
}
$TWA.ParentAnimation.registerClass('Telerik.Web.Animation.ParentAnimation', $TWA.Animation);
$TWA.registerAnimation('parent', $TWA.ParentAnimation);


$TWA.ParallelAnimation = function(target, duration, fps, animations) {
    /// <summary>
    /// The <code>ParallelAnimation</code> plays several animations simultaneously.  It inherits from
    /// <see cref="Telerik.Web.Animation.ParentAnimation" />, but makes itself the owner of all
    /// its child animations to allow the use a single timer and syncrhonization mechanisms shared with
    /// all the children (in other words, the <code>duration</code> properties of any child animations
    /// are ignored in favor of the parent's <code>duration</code>).  It is very useful in creating
    /// sophisticated effects through combination of simpler animations.
    /// </summary>
    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
    /// Target of the animation
    /// </param>
    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
    /// Length of the animation in seconds.  The default is 1.
    /// </param>
    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
    /// Number of steps per second.  The default is 25.
    /// </param>
    /// <param name="animations" mayBeNull="true" optional="true" parameterArray="true" elementType="Telerik.Web.Animation.Animation">
    /// Array of child animations
    /// </param>
    /// <animation>Parallel</animation>
    $TWA.ParallelAnimation.initializeBase(this, [target, duration, fps, animations]);
}
$TWA.ParallelAnimation.prototype = {
    add : function(animation) {
    	/// <summary>
        /// Add an animation as a child of this animation and make ourselves its owner.
    	/// </summary>
    	/// <param name="animation" type="Telerik.Web.Animation.Animation">Child animation to add</param>
    	/// <returns />
        $TWA.ParallelAnimation.callBaseMethod(this, 'add', [animation]);
        animation.setOwner(this);
    },
    
    onStart : function() {
        /// <summary>
        /// Get the child animations ready to play
        /// </summary>
        /// <returns />

        $TWA.ParallelAnimation.callBaseMethod(this, 'onStart');
        var animations = this.get_animations();
        for (var i = 0; i < animations.length; i++) {
            animations[i].onStart();
        }
    },
    
    onStep : function(percentage) {
        /// <summary>
        /// Progress the child animations through each frame
        /// </summary>
        /// <param name="percentage" type="Number">
        /// Percentage of the animation already complete
        /// </param>
        /// <returns />

        var animations = this.get_animations();
        for (var i = 0; i < animations.length; i++) {
            animations[i].onStep(percentage);
        }
    },
    
    onEnd : function() {
        /// <summary>
        /// Finish playing all of the child animations
        /// </summary>
        /// <returns />

        var animations = this.get_animations();
        for (var i = 0; i < animations.length; i++) {
            animations[i].onEnd();
        }
        $TWA.ParallelAnimation.callBaseMethod(this, 'onEnd');
    }
}
$TWA.ParallelAnimation.registerClass('Telerik.Web.Animation.ParallelAnimation', $TWA.ParentAnimation);
$TWA.registerAnimation('parallel', $TWA.ParallelAnimation);

$TWA.FadeEffect = function() {
    /// <summary>
    /// The FadeEffect enumeration determines whether a fade animation is used to fade in or fade out.
    /// </summary>
    /// <field name="FadeIn" type="Number" integer="true" />
    /// <field name="FadeOut" type="Number" integer="true" />
    throw Error.invalidOperation();
}
$TWA.FadeEffect.prototype = {
    FadeIn : 0,
    FadeOut : 1
}
$TWA.FadeEffect.registerEnum("Telerik.Web.Animation.FadeEffect", false);

$TWA.FadeAnimation = function(target, duration, fps, effect, minimumOpacity, maximumOpacity, forceLayoutInIE) {
    /// <summary>
    /// The <code>FadeAnimation</code> is used to fade an element in or out of view, depending on the
    /// provided <see cref="Telerik.Web.Animation.FadeEffect" />, by settings its opacity.
    /// The minimum and maximum opacity values can be specified to precisely control the fade.
    /// You may also consider using <see cref="Telerik.Web.Animation.FadeInAnimation" /> or
    /// <see cref="Telerik.Web.Animation.FadeOutAnimation" /> if you know the only direction you
    /// are fading.
    /// </summary>
    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
    /// Target of the animation
    /// </param>
    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
    /// Length of the animation in seconds.  The default is 1.
    /// </param>
    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
    /// Number of steps per second.  The default is 25.
    /// </param>
    /// <param name="effect" type="Telerik.Web.Animation.FadeEffect" mayBeNull="true" optional="true">
    /// Determine whether to fade the element in or fade the element out.  The possible values are <code>FadeIn</code>
    /// and <code>FadeOut</code>.  The default value is <code>FadeOut</code>.
    /// </param>
    /// <param name="minimumOpacity" type="Number" mayBeNull="true" optional="true">
    /// Minimum opacity to use when fading in or out. Its value can range from between 0 to 1. The default value is 0.
    /// </param>
    /// <param name="maximumOpacity" type="Number" mayBeNull="true" optional="true">
    /// Maximum opacity to use when fading in or out. Its value can range from between 0 to 1. The default value is 1.
    /// </param>
    /// <param name="forceLayoutInIE" type="Boolean" mayBeNull="true" optional="true">
    /// Whether or not we should force a layout to be created for Internet Explorer by giving it a width and setting its
    /// background color (the latter is required in case the user has ClearType enabled). The default value is <code>true</code>.
    /// This is obviously ignored when working in other browsers.
    /// </param>
    /// <animation>Fade</animation>
    $TWA.FadeAnimation.initializeBase(this, [target, duration, fps]);

    // The effect determines whether or not we fade in or out
    this._effect = (effect !== undefined) ? effect : $TWA.FadeEffect.FadeIn;
    
    // Maximum and minimum opacities default to 100% and 0%
    this._max = (maximumOpacity !== undefined) ? maximumOpacity : 1;
    this._min = (minimumOpacity !== undefined) ? minimumOpacity : 0;
    
    // Starting and ending opacities
    this._start = this._min;
    this._end = this._max;
    
    // Whether the a layout has already been created (to work around IE problems)
    this._layoutCreated = false;

    // Whether or not we should force a layout to be created for IE by giving it a width
    // and setting its background color (the latter is required in case the user has ClearType enabled).
    // http://msdn.microsoft.com/library/default.asp?url=/workshop/author/filter/reference/filters/alpha.asp
    this._forceLayoutInIE = (forceLayoutInIE === undefined || forceLayoutInIE === null) ? true : forceLayoutInIE;
    
    // Current target of the animation that is cached before the animation plays (since looking up
    // the target could mean walking all the way up to the root of the animation's tree, which we don't
    // want to do for every step of the animation)
    this._currentTarget = null;
    
    // Properly set up the min/max values provided by the constructor
    this._resetOpacities();
}
$TWA.FadeAnimation.prototype = {
    _resetOpacities : function() {
    	/// <summary>
        /// Set the starting and ending opacity values based on the effect (i.e. when we're fading
        /// in we go from <code>_min</code> to <code>_max</code>, but we go <code>_max</code> to
        /// <code>_min</code> when fading out)
    	/// </summary>
    	/// <returns />

        if (this._effect == $TWA.FadeEffect.FadeIn) {
            this._start = this._min;
            this._end = this._max;
        } else {
            this._start = this._max;
            this._end = this._min;
        }
    },
    
    _createLayout : function() {
    	/// <summary>
        /// Create a layout when using Internet Explorer (which entails setting a width and also
        /// a background color if it currently has neither)
    	/// </summary>
    	/// <returns />

        var element = this._currentTarget;
        if (element) {
            // Get the original width/height/back color
            var originalWidth = $telerik.getCurrentStyle(element, 'width');
            var originalHeight = $telerik.getCurrentStyle(element, 'height');
            var originalBackColor = $telerik.getCurrentStyle(element, 'backgroundColor');

            // Set the width which will force the creation of a layout
            if ((!originalWidth || originalWidth == '' || originalWidth == 'auto') &&
                (!originalHeight || originalHeight == '' || originalHeight == 'auto')) {
                element.style.width = element.offsetWidth + 'px';
            }
            
            // Set the back color to avoid ClearType problems
            if (!originalBackColor || originalBackColor == '' || originalBackColor == 'transparent' || originalBackColor == 'rgba(0, 0, 0, 0)') {
                element.style.backgroundColor = $telerik.getInheritedBackgroundColor(element);
            }
            
            // Mark that we've created the layout so we only do it once
            this._layoutCreated = true;
        }
    },
    
    onStart : function() {
    	/// <summary>
        /// The <code>onStart</code> method is called just before the animation is played each time.
        /// </summary>
        /// <returns />       
        $TWA.FadeAnimation.callBaseMethod(this, 'onStart');
        
        this._currentTarget = this.get_target();
        this.setValue(this._start);
        
        // Force the creation of a layout in IE if we're supposed to and the current browser is Internet Explorer
        if (this._forceLayoutInIE && !this._layoutCreated && Sys.Browser.agent == Sys.Browser.InternetExplorer) {
            this._createLayout();
        }
    },
    
    getAnimatedValue : function(percentage) {
    	/// <summary>
        /// Determine the current opacity after the given percentage of its duration has elapsed
        /// </summary>
        /// <param name="percentage" type="Number">Percentage of the animation already complete</param>
        /// <returns type="Number">
        /// Current opacity after the given percentage of its duration has elapsed that will
        /// be passed to <code>setValue</code>
        /// </returns>
        return this.interpolate(this._start, this._end, percentage);
    },
    
    setValue : function(value) {
        /// <summary>
        /// Set the current opacity of the element.
        /// </summary>
        /// <param name="value" type="Number">
        /// Current opacity (as retreived from <code>getAnimatedValue</code>)
        /// </param>
        /// <returns />
        /// <remarks>
        /// This method will be replaced by a dynamically generated function that requires no logic
        /// to determine whether it should use filters or the style's opacity.
        /// </remarks>
        if (this._currentTarget) {
            $telerik.setOpacity(this._currentTarget, value);
        }
    },
    
//    set_target : function(value) {
//        /// <value type="Sys.UI.DomElement">
//        /// Override the <code>target</code> property to dynamically create the setValue function.
//        /// </value>
//        /// <remarks>
//        /// Do not set this property in a generic Xml animation description. It will be set automatically
//        /// using either the extender's TargetControlID or the AnimationTarget property.
//        /// <remarks>
//        $TWA.FadeAnimation.callBaseMethod(this, 'set_target', [value]);
//        
//        var element = value;
//        if (element) {
//            var filters = element.filters;
//            if (filters) {
//                var alphaFilter = null;
//                if (filters.length !== 0) {
//                    alphaFilter = filters['DXImageTransform.Microsoft.Alpha'];
//                }
//                if (!alphaFilter) {
//                    element.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + (this._start * 100) + ')';
//                    alphaFilter = filters['DXImageTransform.Microsoft.Alpha'];
//                }
//                if (alphaFilter) {
//                    this.setValue = function(val) { alphaFilter.opacity = val * 100; }
//                } else {
//                    this.setValue = function(val) {
//                        element.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + (val * 100) + ')';
//                    };
//                }
//            }
//            else {
//                this.setValue = function(val) { element.style.opacity = val; };
//            }
//        }
//    },
    
    get_effect : function() {
    	/// <value type="Telerik.Web.Animation.FadeEffect">
        /// Determine whether to fade the element in or fade the element out.  The possible values are
        /// <code>FadeIn</code> and <code>FadeOut</code>.  The default value is <code>FadeOut</code>.
    	/// </value>
        return this._effect;
    },
    set_effect : function(value) {
        value = this._getEnum(value, $TWA.FadeEffect);
        if (this._effect != value) {
            this._effect = value;
            this._resetOpacities();
            this.raisePropertyChanged('effect');
        }
    },
    
    get_minimumOpacity : function() {
        /// <value type="Number">
        /// Minimum opacity to use when fading in or out. Its value can range from between 0 to 1.
        /// The default value is 0.
        /// </value>
	    return this._min;
    },
    set_minimumOpacity : function(value) {
        value = this._getFloat(value);
        if (this._min != value) {
            this._min = value;
            this._resetOpacities();
            this.raisePropertyChanged('minimumOpacity');
        }
    },
    
    get_maximumOpacity : function() {
        /// <value type="Number">
        /// Maximum opacity to use when fading in or out. Its value can range from between 0 to 1.
        /// The default value is 1.
        /// </value>
        return this._max;
    },
    set_maximumOpacity : function(value) {
        value = this._getFloat(value);
        if (this._max != value) {
            this._max = value;
            this._resetOpacities();
            this.raisePropertyChanged('maximumOpacity');
        }
    },
    
    get_forceLayoutInIE : function() {
        /// <value type="Boolean">
        /// Whether or not we should force a layout to be created for Internet Explorer by giving it a width and setting its
        /// background color (the latter is required in case the user has ClearType enabled). The default value is <code>true</code>.
        /// This is obviously ignored when working in other browsers.
        /// </value>
        return this._forceLayoutInIE;
    },
    set_forceLayoutInIE : function(value) {
        value = this._getBoolean(value);
        if (this._forceLayoutInIE != value) {
            this._forceLayoutInIE = value;
            this.raisePropertyChanged('forceLayoutInIE');
        }
    },
    
    set_startValue : function(value) {
        /// <value type="Number">
        /// Set the start value (so that child animations can set the current opacity as the start value when fading in or out)
        /// </value>
        value = this._getFloat(value);
        this._start = value;
    }
}
$TWA.FadeAnimation.registerClass('Telerik.Web.Animation.FadeAnimation', $TWA.Animation);
$TWA.registerAnimation('fade', $TWA.FadeAnimation);


$TWA.FadeInAnimation = function(target, duration, fps, minimumOpacity, maximumOpacity, forceLayoutInIE) {
    /// <summary>
    /// The <code>FadeInAnimation</code> will fade the target in by moving from hidden to visible.
    /// It starts the animation the target's current opacity.
    /// </summary>
    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
    /// Target of the animation
    /// </param>
    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
    /// Length of the animation in seconds.  The default is 1.
    /// </param>
    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
    /// Number of steps per second.  The default is 25.
    /// </param>
    /// <param name="minimumOpacity" type="Number" mayBeNull="true" optional="true">
    /// Minimum opacity to use when fading in or out. Its value can range from between 0 to 1. The default value is 0.
    /// </param>
    /// <param name="maximumOpacity" type="Number" mayBeNull="true" optional="true">
    /// Maximum opacity to use when fading in or out. Its value can range from between 0 to 1. The default value is 1.
    /// </param>
    /// <param name="forceLayoutInIE" type="Boolean" mayBeNull="true" optional="true">
    /// Whether or not we should force a layout to be created for Internet Explorer by giving it a width and setting its
    /// background color (the latter is required in case the user has ClearType enabled). The default value is <code>true</code>.
    /// This is obviously ignored when working in other browsers.
    /// </param>
    /// <animation>FadeIn</animation>
    $TWA.FadeInAnimation.initializeBase(this, [target, duration, fps, $TWA.FadeEffect.FadeIn, minimumOpacity, maximumOpacity, forceLayoutInIE]);
}
$TWA.FadeInAnimation.prototype = {
    onStart : function() {
    	/// <summary>
        /// The <code>onStart</code> method is called just before the animation is played each time.
        /// </summary>
        /// <returns />
        $TWA.FadeInAnimation.callBaseMethod(this, 'onStart');
        
        if (this._currentTarget) {
            this.set_startValue($telerik.getOpacity(this._currentTarget));
        }
    }
}
$TWA.FadeInAnimation.registerClass('Telerik.Web.Animation.FadeInAnimation', $TWA.FadeAnimation);
$TWA.registerAnimation('fadeIn', $TWA.FadeInAnimation);


$TWA.FadeOutAnimation = function(target, duration, fps, minimumOpacity, maximumOpacity, forceLayoutInIE) {
    /// <summary>
    /// The FadeInAnimation will fade the element out by moving from visible to hidden. It starts the animation
    /// at the element's current opacity.
    /// </summary>
    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
    /// Target of the animation
    /// </param>
    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
    /// Length of the animation in seconds.  The default is 1.
    /// </param>
    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
    /// Number of steps per second.  The default is 25.
    /// </param>
    /// <param name="minimumOpacity" type="Number" mayBeNull="true" optional="true">
    /// Minimum opacity to use when fading in or out. Its value can range from between 0 to 1. The default value is 0.
    /// </param>
    /// <param name="maximumOpacity" type="Number" mayBeNull="true" optional="true">
    /// Maximum opacity to use when fading in or out. Its value can range from between 0 to 1. The default value is 1.
    /// </param>
    /// <param name="forceLayoutInIE" type="Boolean" mayBeNull="true" optional="true">
    /// Whether or not we should force a layout to be created for Internet Explorer by giving it a width and setting its
    /// background color (the latter is required in case the user has ClearType enabled). The default value is <code>true</code>.
    /// This is obviously ignored when working in other browsers.
    /// </param>
    /// <animation>FadeOut</animation>
    $TWA.FadeOutAnimation.initializeBase(this, [target, duration, fps, $TWA.FadeEffect.FadeOut, minimumOpacity, maximumOpacity, forceLayoutInIE]);
}
$TWA.FadeOutAnimation.prototype = {
    onStart : function() {
    	/// <summary>
        /// The <code>onStart</code> method is called just before the animation is played each time.
        /// </summary>
        /// <returns />
        $TWA.FadeOutAnimation.callBaseMethod(this, 'onStart');

        if (this._currentTarget) {
            this.set_startValue($telerik.getOpacity(this._currentTarget));
        }
    }
}
$TWA.FadeOutAnimation.registerClass('Telerik.Web.Animation.FadeOutAnimation', $TWA.FadeAnimation);
$TWA.registerAnimation('fadeOut', $TWA.FadeOutAnimation);


$TWA.PropertyAnimation = function(target, duration, fps, property, propertyKey) {
    /// <summary>
    /// The <code>PropertyAnimation</code> is a useful base animation that will assign the value from
    /// <code>getAnimatedValue</code> to a specified <code>property</code>. You can provide the name of
    /// a <code>property</code> alongside an optional <code>propertyKey</code> (which indicates the value
    /// <code>property[propertyKey]</code>, like <code>style['backgroundColor']</code>).
    /// </summary>
    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
    /// Target of the animation
    /// </param>
    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
    /// Length of the animation in seconds.  The default is 1.
    /// </param>
    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
    /// Number of steps per second.  The default is 25.
    /// </param>
    /// <param name="property" type="String" mayBeNull="true" optional="true">
    /// Property of the <code>target</code> element to set when animating
    /// </param>
    /// <param name="propertyKey" type="String" mayBeNull="true" optional="true">
    /// Optional key of the property to be set (which indicates the value property[propertyKey], like style['backgroundColor']). Note that for the style property, the key must be in a JavaScript friendly format (i.e. backgroundColor instead of background-color).
    /// </param>
    /// <animation>Property</animation>
    $TWA.PropertyAnimation.initializeBase(this, [target, duration, fps]);

    // Name of the property to set
    this._property = property;
    
    // Optional Key of the property to set (i.e., if the property were "style" then
    // this might be "backgroundColor")
    this._propertyKey = propertyKey;
    
    // Current target of the animation that is cached before the animation plays (since looking up
    // the target could mean walking all the way up to the root of the animation's tree, which we don't
    // want to do for every step of the animation)
    this._currentTarget = null;
}
$TWA.PropertyAnimation.prototype = {
    onStart : function() {
    	/// <summary>
        /// The <code>onStart</code> method is called just before the animation is played each time.
        /// </summary>
        /// <returns />
        $TWA.PropertyAnimation.callBaseMethod(this, 'onStart');

        this._currentTarget = this.get_target();
    },

    setValue : function(value) {
        /// <summary>
        /// Set the current value of the property
        /// </summary>
        /// <param name="value" type="Object" mayBeNull="true">
        /// Value to assign
        /// </param>
        /// <returns />

        var element = this._currentTarget;
        if (element && this._property && this._property.length > 0) { 
            if (this._propertyKey && this._propertyKey.length > 0 && element[this._property]) {
                element[this._property][this._propertyKey] = value;
            } else {
                element[this._property] = value;
            }
        }
        // Sys.TypeDescriptor.setProperty(this.get_target(), this._property, value, this._propertyKey);
    },
    
    getValue : function() {
        /// <summary>
        /// Get the current value from the property
        /// </summary>
        /// <returns type="Object" mayBeNull="true">
        /// Current value of the property
        /// </returns>

        var element = this.get_target();
        if (element && this._property && this._property.length > 0) { 
            var property = element[this._property];
            if (property) {
                if (this._propertyKey && this._propertyKey.length > 0) {
                    return property[this._propertyKey];
                }
                return property;
            }
        }
        return null;
        // return Sys.TypeDescriptor.getProperty(this.get_target(), this._property, this._propertyKey);
    },
    
    get_property : function() {
        /// <value type="String">
        /// Property of the <code>target</code> element to set when animating
        /// </value>
        return this._property;
    },
    set_property : function(value) {
        if (this._property != value) {
            this._property = value;
            this.raisePropertyChanged('property');
        }
    },
    
    get_propertyKey : function() {
        /// <value type="String" mayBeNull="true" optional="true">
        /// Optional key of the property to be set (which indicates the value property[propertyKey], like style['backgroundColor']). Note that for the style property, the key must be in a JavaScript friendly format (i.e. backgroundColor instead of background-color).
        /// </value>
        return this._propertyKey;
    },
    set_propertyKey : function(value) {
        if (this._propertyKey != value) {
            this._propertyKey = value;
            this.raisePropertyChanged('propertyKey');
        }
    }
}
$TWA.PropertyAnimation.registerClass('Telerik.Web.Animation.PropertyAnimation', $TWA.Animation);
$TWA.registerAnimation('property', $TWA.PropertyAnimation);


$TWA.DiscreteAnimation = function(target, duration, fps, property, propertyKey, values) {
    /// <summary>
    /// The <code>DiscreteAnimation</code> inherits from <see cref="Telerik.Web.Animation.PropertyAnimation" />
    /// and sets the value of the <code>property</code> to the elements in a provided array of <code>values</code>.
    /// </summary>
    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true">
    /// Target of the animation
    /// </param>
    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
    /// Length of the animation in seconds.  The default is 1.
    /// </param>
    /// <param name="fps" type="Number" mayBeNull="true" optional="true">
    /// Number of steps per second.  The default is 25.
    /// </param>
    /// <param name="property" type="String" mayBeNull="true" optional="true">
    /// Property of the <code>target</code> element to set when animating
    /// </param>
    /// <param name="propertyKey" type="String" mayBeNull="true" optional="true">
    /// Optional key of the property to be set (which indicates the value property[propertyKey], like style['backgroundColor']). Note that for the style property, the key must be in a JavaScript friendly format (i.e. backgroundColor instead of background-color).
    /// </param>
    /// <param name="values" mayBeNull="true" optional="true" parameterArray="true" elementType="Object">
    /// Array of possible values of the property that will be iterated over as the animation is played
    /// </param>
    /// <animation>Discrete</animation>
    $TWA.DiscreteAnimation.initializeBase(this, [target, duration, fps, property, propertyKey]);

    // Values to assign to the property
    this._values = (values && values.length) ? values : [];
}
$TWA.DiscreteAnimation.prototype = {
    getAnimatedValue : function(percentage) {
        /// <summary>
        /// Assign the value whose index corresponds to the current percentage
        /// </summary>
        /// <param name="percentage" type="Number">
        /// Percentage of the animation already complete
        /// </param>
        /// <returns type="Object">
        /// State of the animation after the given percentage of its duration has elapsed that will
        /// be passed to <code>setValue</code>
        /// </returns>
        var index = Math.floor(this.interpolate(0, this._values.length - 1, percentage));
        return this._values[index];
    },
    
    get_values : function() {
        /// <value parameterArray="true" elementType="Object">
        /// Array of possible values of the property that will be iterated over as the animation is played
        /// </value>
        return this._values;
    },
    set_values : function(value) {
        if (this._values != value) {
            this._values = value;
            this.raisePropertyChanged('values');
        }
    }
}
$TWA.DiscreteAnimation.registerClass('Telerik.Web.Animation.DiscreteAnimation', $TWA.PropertyAnimation);
$TWA.registerAnimation('discrete', $TWA.DiscreteAnimation);


$TWA.InterpolatedAnimation = function(target, duration, fps, property, propertyKey, startValue, endValue) {
    /// <summary>
    /// The <code>InterpolatedAnimation</code> assigns a range of values between <code>startValue</code>
    /// and <code>endValue</code> to the designated property.
    /// </summary>
    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
    /// Target of the animation
    /// </param>
    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
    /// Length of the animation in seconds.  The default is 1.
    /// </param>
    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
    /// Number of steps per second.  The default is 25.
    /// </param>
    /// <param name="property" type="String" mayBeNull="true" optional="true">
    /// Property of the <code>target</code> element to set when animating.  The default value is 'style'.
    /// </param>
    /// <param name="propertyKey" type="String" mayBeNull="true" optional="true">
    /// Optional key of the property to be set (which indicates the value property[propertyKey], like style['backgroundColor']). Note that for the style property, the key must be in a JavaScript friendly format (i.e. backgroundColor instead of background-color).
    /// </param>
    /// <param name="startValue" type="Number" mayBeNull="true" optional="true">
    /// Start of the range of values
    /// </param>
    /// <param name="endValue" type="Number" mayBeNull="true" optional="true">
    /// End of the range of values
    /// </param>
    /// <animation>Interpolated</animation>
    $TWA.InterpolatedAnimation.initializeBase(this, [target, duration, fps, ((property !== undefined) ? property : 'style'), propertyKey]);

    // Start and end values
    this._startValue = startValue;
    this._endValue = endValue;
}
$TWA.InterpolatedAnimation.prototype = {
    get_startValue : function() {
        /// <value type="Number">
        /// Start of the range of values
        /// </value>
        return this._startValue;
    },
    set_startValue : function(value) {
        value = this._getFloat(value);
        if (this._startValue != value) {
            this._startValue = value;
            this.raisePropertyChanged('startValue');
        }
    },
    
    get_endValue : function() {
        /// <value type="Number">
        /// End of the range of values
        /// </value>
        return this._endValue;
    },
    set_endValue : function(value) {
        value = this._getFloat(value);
        if (this._endValue != value) {
            this._endValue = value;
            this.raisePropertyChanged('endValue');
        }
    }   
}
$TWA.InterpolatedAnimation.registerClass('Telerik.Web.Animation.InterpolatedAnimation', $TWA.PropertyAnimation);
$TWA.registerAnimation('interpolated', $TWA.InterpolatedAnimation);


$TWA.ColorAnimation = function(target, duration, fps, property, propertyKey, startValue, endValue) {
    /// <summary>
    /// The <code>ColorAnimation</code> transitions the value of the <code>property</code> between
    /// two colors (although it does ignore the alpha channel). The colors must be 7-character hex strings
    /// (like <code>#246ACF</code>).
    /// </summary>
    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true">
    /// Target of the animation
    /// </param>
    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
    /// Length of the animation in seconds.  The default is 1.
    /// </param>
    /// <param name="fps" type="Number" mayBeNull="true" optional="true">
    /// Number of steps per second.  The default is 25.
    /// </param>
    /// <param name="property" type="String" mayBeNull="true" optional="true">
    /// Property of the <code>target</code> element to set when animating.  The default value is 'style'.
    /// </param>
    /// <param name="propertyKey" type="String" mayBeNull="true" optional="true">
    /// Optional key of the property to be set (which indicates the value property[propertyKey], like style['backgroundColor']). Note that for the style property, the key must be in a JavaScript friendly format (i.e. backgroundColor instead of background-color).
    /// </param>
    /// <param name="startValue" type="String" mayBeNull="true" optional="true">
    /// Start of the range of colors
    /// </param>
    /// <param name="endValue" type="String" mayBeNull="true" optional="true">
    /// End of the range of colors
    /// </param>
    /// <animation>Color</animation>
    $TWA.ColorAnimation.initializeBase(this, [target, duration, fps, property, propertyKey, startValue, endValue]);
    
    // Cached start/end RBG triplets
    this._start = null;
    this._end = null;
    
    // Flags indicating whether each dimension of color will be interpolated
    this._interpolateRed = false;
    this._interpolateGreen = false;
    this._interpolateBlue = false;
}
$TWA.ColorAnimation.prototype = {
    onStart : function() {
        /// <summary>
        /// Determine which dimensions of color will be animated
        /// </summary>
        /// <returns />
        $TWA.ColorAnimation.callBaseMethod(this, 'onStart');
       
        this._start = $TWA.ColorAnimation.getRGB(this.get_startValue());
        this._end = $TWA.ColorAnimation.getRGB(this.get_endValue());
        
        this._interpolateRed = (this._start.Red != this._end.Red);
        this._interpolateGreen = (this._start.Green != this._end.Green);
        this._interpolateBlue = (this._start.Blue != this._end.Blue);
    },
    
    getAnimatedValue : function(percentage) {
        /// <summary>
        /// Get the interpolated color values
        /// </summary>
        /// <param name="percentage" type="Number">
        /// Percentage of the animation already complete
        /// </param>
        /// <returns type="String">
        /// Current color formatted as a 7-character hex string (like <code>#246ACF</code>).
        /// </returns>

        var r = this._start.Red;
        var g = this._start.Green;
        var b = this._start.Blue;
        
        if (this._interpolateRed)
            r = Math.round(this.interpolate(r, this._end.Red, percentage));
        
        if (this._interpolateGreen)
            g = Math.round(this.interpolate(g, this._end.Green, percentage));
        
        if (this._interpolateBlue)
            b = Math.round(this.interpolate(b, this._end.Blue, percentage));
        
        return $TWA.ColorAnimation.toColor(r, g, b);
    },
    
    set_startValue : function(value) {
        /// <value type="String">
        /// Starting color of the transition formatted as a 7-character hex string (like <code>#246ACF</code>).
        /// </value>

        if (this._startValue != value) {
            this._startValue = value;
            this.raisePropertyChanged('startValue');
        }
    },
    
    set_endValue : function(value) {
        /// <value type="String">
        /// Ending color of the transition formatted as a 7-character hex string (like <code>#246ACF</code>).
        /// </value>

        if (this._endValue != value) {
            this._endValue = value;
            this.raisePropertyChanged('endValue');
        }
    }   
}
$TWA.ColorAnimation.getRGB = function(color) {
    /// <summary>
    /// Convert the color to an RGB triplet
    /// </summary>
    /// <param name="color" type="String">
    /// Color formatted as a 7-character hex string (like <code>#246ACF</code>)
    /// </param>
    /// <returns type="Object">
    /// Object representing the color with <code>Red</code>, <code>Green</code>, and <code>Blue</code> properties.
    /// </returns>

    if (!color || color.length != 7) {
        throw String.format('Color must be a 7-character hex representation (e.g. #246ACF), not "{0}"', color);
    }
    return { 'Red': parseInt(color.substr(1,2), 16),
             'Green': parseInt(color.substr(3,2), 16),
             'Blue': parseInt(color.substr(5,2), 16) };
}
$TWA.ColorAnimation.toColor = function(red, green, blue) {
    /// <summary>
    /// Convert an RBG triplet into a 7-character hex string (like <code>#246ACF</code>)
    /// </summary>
    /// <param name="red" type="Number" integer="true">
    /// Value of the color's red dimension
    /// </param>
    /// <param name="green" type="Number" integer="true">
    /// Value of the color's green dimension
    /// </param>
    /// <param name="blue" type="Number" integer="true">
    /// Value of the color's blue dimension
    /// </param>
    /// <returns type="String">
    /// Color as a 7-character hex string (like <code>#246ACF</code>)
    /// </returns>

    var r = red.toString(16);
    var g = green.toString(16);
    var b = blue.toString(16);
    if (r.length == 1) r = '0' + r;
    if (g.length == 1) g = '0' + g;
    if (b.length == 1) b = '0' + b;
    return '#' + r + g + b;
}
$TWA.ColorAnimation.registerClass('Telerik.Web.Animation.ColorAnimation', $TWA.InterpolatedAnimation);
$TWA.registerAnimation('color', $TWA.ColorAnimation);


$TWA.LengthAnimation = function(target, duration, fps, property, propertyKey, startValue, endValue, unit) {
    /// <summary>
    /// The <code>LengthAnimation</code> is identical to <see cref="Telerik.Web.Animation.InterpolatedAnimation" />
    /// except it adds a <code>unit</code> to the value before assigning it to the <code>property</code>.
    /// </summary>
    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true">
    /// Target of the animation
    /// </param>
    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
    /// Length of the animation in seconds.  The default is 1.
    /// </param>
    /// <param name="fps" type="Number" mayBeNull="true" optional="true">
    /// Number of steps per second.  The default is 25.
    /// </param>
    /// <param name="property" type="String" mayBeNull="true" optional="true">
    /// Property of the <code>target</code> element to set when animating.  The default value is 'style'.
    /// </param>
    /// <param name="propertyKey" type="String" mayBeNull="true" optional="true">
    /// Optional key of the property to be set (which indicates the value property[propertyKey], like style['backgroundColor']). Note that for the style property, the key must be in a JavaScript friendly format (i.e. backgroundColor instead of background-color).
    /// </param>
    /// <param name="startValue" type="Number" mayBeNull="true" optional="true">
    /// Start of the range of values
    /// </param>
    /// <param name="endValue" type="Number" mayBeNull="true" optional="true">
    /// End of the range of values
    /// </param>
    /// <param name="unit" type="String" mayBeNull="true" optional="true">
    /// Unit of the interpolated values.  The default value is <code>'px'</code>.
    /// </param>
    /// <animation>Length</animation>
    $TWA.LengthAnimation.initializeBase(this, [target, duration, fps, property, propertyKey, startValue, endValue]);
    
    // Unit of length (which defaults to px)
    this._unit = (unit != null) ? unit : 'px';
}
$TWA.LengthAnimation.prototype = {

    getAnimatedValue : function(percentage) {
        /// <summary>
        /// Get the interpolated length value
        /// </summary>
        /// <param name="percentage" type="Number">
        /// Percentage of the animation already complete
        /// </param>
        /// <returns type="String">
        /// Interpolated length
        /// </returns>

        var value = this.interpolate(this.get_startValue(), this.get_endValue(), percentage);
        return Math.round(value) + this._unit;
    },
    
    get_unit : function() {
        /// <value type="String">
        /// Unit of the interpolated values.  The default value is <code>'px'</code>.
        /// </value>
        return this._unit;
    },
    set_unit : function(value) {
        if (this._unit != value) {
            this._unit = value;
            this.raisePropertyChanged('unit');
        }
    }
}
$TWA.LengthAnimation.registerClass('Telerik.Web.Animation.LengthAnimation', $TWA.InterpolatedAnimation);
$TWA.registerAnimation('length', $TWA.LengthAnimation);


$TWA.MoveAnimation = function(target, duration, fps, horizontal, vertical, relative, unit) {
    /// <summary>
    /// The <code>MoveAnimation</code> is used to move the <code>target</code> element. If the
    /// <code>relative</code> flag is set to <code>true</code>, then it treats the <code>horizontal</code>
    /// and <code>vertical</code> properties as offsets to move the element. If the <code>relative</code>
    /// flag is <code>false</code>, then it will treat the <code>horizontal</code> and <code>vertical</code>
    /// properties as coordinates on the page where the <code>target</code> element should be moved. It is
    /// important to note that the <code>target</code> must be positioned (i.e. <code>absolutely</code>) so
    /// that settings its <code>top</code>/<code>left<code> style attributes will change its location.
    /// </summary>
    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
    /// Target of the animation
    /// </param>
    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
    /// Length of the animation in seconds.  The default is 1.
    /// </param>
    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
    /// Number of steps per second.  The default is 25.
    /// </param>
    /// <param name="horizontal" type="Number" mayBeNull="true" optional="true">
    /// If <code>relative</code>  is <code>true</code>, this is the offset to move horizontally. Otherwise this is the x
    /// coordinate on the page where the <code>target</code> should be moved.
    /// </param>
    /// <param name="vertical" type="Number" mayBeNull="true" optional="true">
    /// If <code>relative</code> is <code>true</code>, this is the offset to move vertically. Otherwise this is the y
    /// coordinate on the page where the <code>target</code> should be moved.
    /// </param>
    /// <param name="relative" type="Boolean" mayBeNull="true" optional="true">
    /// <code>true</code> if we are moving relative to the current position, <code>false</code> if we are moving absolutely
    /// </param>
    /// <param name="unit" type="String" mayBeNull="true" optional="true">
    /// Length unit for the size of the <code>target</code>. The default value is <code>'px'</code>.
    /// </param>
    /// <animation>Move</animation>
    $TWA.MoveAnimation.initializeBase(this, [target, duration, fps, null]);

    // Distance to move horizontally and vertically
    this._horizontal = horizontal ? horizontal : 0;
    this._vertical = vertical ? vertical : 0;
    this._relative = (relative === undefined) ? true : relative;
    
    // Length animations representing the movememnts
    this._horizontalAnimation = new $TWA.LengthAnimation(target, duration, fps, 'style', 'left', null, null, unit);
    this._verticalAnimation = new $TWA.LengthAnimation(target, duration, fps, 'style', 'top', null, null, unit);
    this.add(this._verticalAnimation);
    this.add(this._horizontalAnimation);
}
$TWA.MoveAnimation.prototype = {
    
    onStart : function() {
        /// <summary>
        /// Use the <code>target</code>'s current position as the starting point for the animation
        /// </summary>
        /// <returns />
        $TWA.MoveAnimation.callBaseMethod(this, 'onStart');
        
        // Set the start and end values of the animations by getting
        // the element's current position and applying the offsets
        var element = this.get_target();
        this._horizontalAnimation.set_startValue(element.offsetLeft);
        this._horizontalAnimation.set_endValue(this._relative ? element.offsetLeft + this._horizontal : this._horizontal);
        this._verticalAnimation.set_startValue(element.offsetTop); 
        this._verticalAnimation.set_endValue(this._relative ? element.offsetTop + this._vertical : this._vertical);
    },
    
    get_horizontal : function() {
        /// <value type="Number">
        /// If <code>relative</code>  is <code>true</code>, this is the offset to move horizontally. Otherwise this is the x
        /// coordinate on the page where the <code>target</code> should be moved.
        /// </value>
        return this._horizontal;
    },
    set_horizontal : function(value) {
        value = this._getFloat(value);
        if (this._horizontal != value) {
            this._horizontal = value;
            this.raisePropertyChanged('horizontal');
        }
    },
    
    get_vertical : function() {
        /// <value type="Number">
        /// If <code>relative</code> is <code>true</code>, this is the offset to move vertically. Otherwise this is the y
        /// coordinate on the page where the <code>target</code> should be moved.
        /// </value>
        return this._vertical;
    },
    set_vertical : function(value) {
        value = this._getFloat(value);
        if (this._vertical != value) {
            this._vertical = value;
            this.raisePropertyChanged('vertical');
        }
    },
    
    get_relative : function() {
        /// <value type="Boolean">
        /// <code>true</code> if we are moving relative to the current position, <code>false</code> if we are moving absolutely
        /// </value>
        return this._relative;
    },
    set_relative : function(value) {
        value = this._getBoolean(value);
        if (this._relative != value) {
            this._relative = value;
            this.raisePropertyChanged('relative');
        }
    },
    
    get_unit : function() {
        /// <value type="String" mayBeNull="true">
        /// Length unit for the size of the <code>target</code>. The default value is <code>'px'</code>.
        /// </value>
        this._horizontalAnimation.get_unit();
    },
    set_unit : function(value) {
        var unit = this._horizontalAnimation.get_unit();
        if (unit != value) {
            this._horizontalAnimation.set_unit(value);
            this._verticalAnimation.set_unit(value);
            this.raisePropertyChanged('unit');
        }
    }
}
$TWA.MoveAnimation.registerClass('Telerik.Web.Animation.MoveAnimation', $TWA.ParallelAnimation);
$TWA.registerAnimation('move', $TWA.MoveAnimation);


$TWA.ResizeAnimation = function(target, duration, fps, width, height, unit) {
    /// <summary>
    /// The <code>ResizeAnimation</code> changes the size of the <code>target</code> from its
    /// current value to the specified <code>width</code> and <code>height</code>.
    /// </summary>
    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
    /// Target of the animation
    /// </param>
    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
    /// Length of the animation in seconds.  The default is 1.
    /// </param>
    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
    /// Number of steps per second.  The default is 25.
    /// </param>
    /// <param name="width" type="Number" mayBeNull="true" optional="true">
    /// New width of the <code>target</code>
    /// </param>
    /// <param name="height" type="Number" mayBeNull="true" optional="true">
    /// New height of the <code>target</code>
    /// </param>
    /// <param name="unit" type="String" mayBeNull="true" optional="true">
    /// Length unit for the size of the <code>target</code>. The default value is <code>'px'</code>.
    /// </param>
    /// <animation>Resize</animation>
    $TWA.ResizeAnimation.initializeBase(this, [target, duration, fps, null]);

    // New size of the element
    this._width = width;
    this._height = height;
    
    // Animations to set the size across both dimensions
    this._horizontalAnimation = new $TWA.LengthAnimation(target, duration, fps, 'style', 'width', null, null, unit);
    this._verticalAnimation = new $TWA.LengthAnimation(target, duration, fps, 'style', 'height', null, null, unit);
    this.add(this._horizontalAnimation);
    this.add(this._verticalAnimation);
}
$TWA.ResizeAnimation.prototype = {
    
    onStart : function() {
        /// <summary>
        /// Use the <code>target</code>'s current size as the starting point for the animation
        /// </summary>
        /// <returns />

        $TWA.ResizeAnimation.callBaseMethod(this, 'onStart');
        
        // Set the start and end values of the animations by getting
        // the element's current width and height
        var element = this.get_target();
        this._horizontalAnimation.set_startValue(element.offsetWidth);
        this._verticalAnimation.set_startValue(element.offsetHeight);
        this._horizontalAnimation.set_endValue((this._width !== null && this._width !== undefined) ?
            this._width : element.offsetWidth);
        this._verticalAnimation.set_endValue((this._height !== null && this._height !== undefined) ?
            this._height : element.offsetHeight);
    },
    
    get_width : function() {
        /// <value type="Number">
        /// New width of the <code>target</code>
        /// </value>

        return this._width;
    },
    set_width : function(value) {
        value = this._getFloat(value);
        if (this._width != value) {
            this._width = value;
            this.raisePropertyChanged('width');
        }
    },
    
    get_height : function() {
        /// <value type="Number">
        /// New height of the <code>target</code>
        /// </value>

        return this._height;
    },
    set_height : function(value) {
        value = this._getFloat(value);
        if (this._height != value) {
            this._height = value;   
            this.raisePropertyChanged('height');
        }
    },
    
    get_unit : function() {
        /// <value type="String">
        /// Length unit for the size of the <code>target</code>. The default value is <code>'px'</code>.
        /// </value>

        this._horizontalAnimation.get_unit();
    },
    set_unit : function(value) {
        var unit = this._horizontalAnimation.get_unit();
        if (unit != value) {
            this._horizontalAnimation.set_unit(value);
            this._verticalAnimation.set_unit(value);
            this.raisePropertyChanged('unit');
        }
    }
}
$TWA.ResizeAnimation.registerClass('Telerik.Web.Animation.ResizeAnimation', $TWA.ParallelAnimation);
$TWA.registerAnimation('resize', $TWA.ResizeAnimation);

$TWA.SequenceAnimation = function(target, duration, fps, animations, iterations) {
    /// <summary>
    /// The <code>SequenceAnimation</code> runs several animations one after the other.  It can also
    /// repeat the sequence of animations for a specified number of iterations (which defaults to a
    /// single iteration, but will repeat forever if you specify zero or less iterations).  Also, the
    /// <code>SequenceAnimation</code> cannot be a child of a <see cref="Telerik.Web.Animation.ParallelAnimation" />
    /// (or any animation inheriting from it).
    /// </summary>
    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
    /// Target of the animation
    /// </param>
    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
    /// Length of the animation in seconds.  The default is 1.
    /// </param>
    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
    /// Number of steps per second.  The default is 25.
    /// </param>
    /// <param name="animations" mayBeNull="true" optional="true" parameterArray="true" elementType="Telerik.Web.Animation.Animation">
    /// Array of child animations
    /// </param>
    /// <param name="iterations" type="Number" mayBeNull="true" optional="true" integer="true">
    /// Number of times to repeatedly play the sequence.  If zero or less iterations are specified, the sequence
    /// will repeat forever.  The default value is 1 iteration.
    /// </param>
    /// <remarks>
    /// The <code>SequenceAnimation</code> ignores the <code>duration</code> and <code>fps</code>
    /// properties, and will let each of its child animations use any settings they please.
    /// </remarks>
    /// <animation>Sequence</animation>
    $TWA.SequenceAnimation.initializeBase(this, [target, duration, fps, animations]);

    // Handler used to determine when an animation has finished
    this._handler = null;
    
    // Flags to note whether we're playing, paused, or stopped
    this._paused = false;
    this._playing = false;
    
    // Index of the currently executing animation in the sequence
    this._index = 0;
    
    // Counter used when playing the animation to determine the remaining number of times to play the entire sequence
    this._remainingIterations = 0;
    
    // Number of iterations
    this._iterations = (iterations !== undefined) ? iterations : 1;
}
$TWA.SequenceAnimation.prototype = {
    dispose : function() {
    	/// <summary>
        /// Dispose the animation
        /// </summary>
        /// <returns />
        this._handler = null;
        $TWA.SequenceAnimation.callBaseMethod(this, 'dispose');
    },
    
    stop : function() {
        /// <summary>
        /// Stop playing the entire sequence of animations
        /// </summary>
        /// <returns />
        /// <remarks>
        /// Stopping this animation will perform the last step of each child animation, thereby leaving their
        /// target elements in a state consistent with the animation playing completely. If this animation is
        /// the child of another, you must call <code>stop</code> on its parent instead.
        /// </remarks>

        if (this._playing) {
            var animations = this.get_animations();
            if (this._index < animations.length) {
                // Remove the handler from the currently running animation
                animations[this._index].remove_ended(this._handler);
                // Call stop on all remaining animations to ensure their
                // effects will be seen
                for (var i = this._index; i < animations.length; i++) {
                    animations[i].stop();
                }
            }
            this._playing = false;
            this._paused = false;
            this.raisePropertyChanged('isPlaying');
            this.onEnd();
        }
    },
    
    pause : function() {
        /// <summary>
        /// Pause the animation if it is playing.  Calling <code>play</code> will resume where
        /// the animation left off.
        /// </summary>
        /// <returns />
        /// <remarks>
        /// If this animation is the child of another, you must call <code>pause</code> on its parent instead.
        /// </remarks>

        if (this.get_isPlaying()) {
            var current = this.get_animations()[this._index];
            if (current != null) {
                current.pause();
            }
            this._paused = true;
            this.raisePropertyChanged('isPlaying');
        }
    },
    
    play : function() {
        /// <summary>
        /// Play the sequence of animations from the beginning or where it was left off when paused
        /// </summary>
        /// <returns />
        /// <remarks>
        /// If this animation is the child of another, you must call <code>play</code> on its parent instead
        /// </remarks>

        var animations = this.get_animations();
        if (!this._playing) {
            this._playing = true;
            if (this._paused) {
                this._paused = false;
                var current = animations[this._index];
                if (current != null) {
                    current.play();
                    this.raisePropertyChanged('isPlaying');
                }
            } else {
                this.onStart();
                // Reset the index and attach the handler to the first
                this._index = 0;
                var first = animations[this._index];
                if (first) {
                    first.add_ended(this._handler);
                    first.play();
                    this.raisePropertyChanged('isPlaying');
                } else {
                    this.stop();
                }
            }
        }
    },
    
    onStart : function() {
        /// <summary>
        /// The <code>onStart</code> method is called just before the animation is played each time
        /// </summary>
        /// <returns />
        $TWA.SequenceAnimation.callBaseMethod(this, 'onStart');
        this._remainingIterations = this._iterations - 1;
        
        // Create the handler we attach to each animation as it plays to determine when we've finished with it
        if (!this._handler) {
            this._handler = Function.createDelegate(this, this._onEndAnimation);
        }
    },
    
    _onEndAnimation : function() {
    	/// <summary>
        /// Wait for the end of each animation, and then continue by playing the other animations remaining
        /// in the sequence.  Stop when it reaches the last animation and there are no remaining iterations.
    	/// </summary>
    	/// <returns />

        // Remove the handler from the current animation
        var animations = this.get_animations();
        var current = animations[this._index++];
        if (current) {
            current.remove_ended(this._handler);
        }
        
        // Keep running animations and stop when we're out
        if (this._index < animations.length) {
            var next = animations[this._index];
            next.add_ended(this._handler);
            next.play();
        } else if (this._remainingIterations >= 1 || this._iterations <= 0) {
            this._remainingIterations--;
            this._index = 0;
            var first = animations[0];
            first.add_ended(this._handler);
            first.play();
        } else {
            this.stop();
        }
    },
    
    onStep : function(percentage) {
        /// <summary>
        /// Raises an invalid operation exception because this will only be called if a <code>SequenceAnimation</code>
        /// has been nested inside an <see cref="Telerik.Web.Animation.ParallelAnimation" /> (or a derived type).
        /// </summary>
        /// <param name="percentage" type="Number">Percentage of the animation already complete</param>
        /// <returns />
        throw Error.invalidOperation("CANNOT NEST");
    },
    
    onEnd : function() {
        /// <summary>
        /// The <code>onEnd</code> method is called just after the animation is played each time.
        /// </summary>
        /// <returns />
        this._remainingIterations = 0;
        $TWA.SequenceAnimation.callBaseMethod(this, 'onEnd');
    },
    
    get_isActive : function() {
    	/// <value type="Boolean">
        /// <code>true</code> if animation is active, <code>false</code> if not.
        /// </value>
        return true;
    },
    
    get_isPlaying : function() {
    	/// <value type="Boolean">
        /// <code>true</code> if animation is playing, <code>false</code> if not.
        /// </value>
        return this._playing && !this._paused;
    },
    
    get_iterations : function() {
        /// <value type="Number" integer="true">
        /// Number of times to repeatedly play the sequence.  If zero or less iterations are specified, the sequence
        /// will repeat forever.  The default value is 1 iteration.
        /// </value>
        return this._iterations;
    },
    set_iterations : function(value) {
        value = this._getInteger(value);
        if (this._iterations != value) {
            this._iterations = value;
            this.raisePropertyChanged('iterations');
        }
    },
    
    get_isInfinite : function() {
    	/// <value type="Boolean">
        /// <code>true</code> if this animation will repeat forever, <code>false</code> otherwise.
    	/// </value>
        return this._iterations <= 0;
    }
}
$TWA.SequenceAnimation.registerClass('Telerik.Web.Animation.SequenceAnimation', $TWA.ParentAnimation);
$TWA.registerAnimation('sequence', $TWA.SequenceAnimation);

$TWA.PulseAnimation = function(target, duration, fps, iterations, minimumOpacity, maximumOpacity, forceLayoutInIE) {
    /// <summary>
    /// The PulseAnimation fades an element in and our repeatedly to create a pulsating
    /// effect.  The iterations determines how many pulses there will be (which defaults
    /// to three, but it will repeat infinitely if given zero or less).  The duration
    /// property defines the duration of each fade in or fade out, not the duration of
    /// the animation as a whole.
    /// </summary>
    /// <param name="target" type="Sys.UI.DomElement" mayBeNull="true" optional="true" domElement="true">
    /// Target of the animation
    /// </param>
    /// <param name="duration" type="Number" mayBeNull="true" optional="true">
    /// Length of the animation in seconds.  The default is 1.
    /// </param>
    /// <param name="fps" type="Number" mayBeNull="true" optional="true" integer="true">
    /// Number of steps per second.  The default is 25.
    /// </param>
    /// <param name="iterations" type="Number" mayBeNull="true" optional="true" integer="true">
    /// Number of times to repeatedly play the sequence.  If zero or less iterations are specified, the sequence
    /// will repeat forever.  The default value is 1 iteration.
    /// </param>
    /// <param name="minimumOpacity" type="Number" mayBeNull="true" optional="true">
    /// Minimum opacity to use when fading in or out. Its value can range from between 0 to 1. The default value is 0.
    /// </param>
    /// <param name="maximumOpacity" type="Number" mayBeNull="true" optional="true">
    /// Maximum opacity to use when fading in or out. Its value can range from between 0 to 1. The default value is 1.
    /// </param>
    /// <param name="forceLayoutInIE" type="Boolean" mayBeNull="true" optional="true">
    /// Whether or not we should force a layout to be created for Internet Explorer by giving it a width and setting its
    /// background color (the latter is required in case the user has ClearType enabled). The default value is <code>true</code>.
    /// This is obviously ignored when working in other browsers.
    /// </param>
    /// <animation>Pulse</animation>
    $TWA.PulseAnimation.initializeBase(this, [target, duration, fps, null, ((iterations !== undefined) ? iterations : 3)]);

    // Create the FadeOutAnimation
    this._out = new $TWA.FadeOutAnimation(target, duration, fps, minimumOpacity, maximumOpacity, forceLayoutInIE);
    this.add(this._out);
    
    // Create the FadeInAnimation
    this._in = new $TWA.FadeInAnimation(target, duration, fps, minimumOpacity, maximumOpacity, forceLayoutInIE);
    this.add(this._in);
}
$TWA.PulseAnimation.prototype = {
   
    get_minimumOpacity : function() {
        /// <value type="Number">
        /// Minimum opacity to use when fading in or out. Its value can range from between 0 to 1. The default value is 0.
        /// </value>
        return this._out.get_minimumOpacity();
    },
    set_minimumOpacity : function(value) {
        value = this._getFloat(value);
        this._out.set_minimumOpacity(value);
        this._in.set_minimumOpacity(value);
        this.raisePropertyChanged('minimumOpacity');
    },
    
    get_maximumOpacity : function() {
        /// <value type="Number">
        /// Maximum opacity to use when fading in or out. Its value can range from between 0 to 1. The default value is 1.
        /// </value>
        return this._out.get_maximumOpacity();
    },
    set_maximumOpacity : function(value) {
        value = this._getFloat(value);
        this._out.set_maximumOpacity(value);
        this._in.set_maximumOpacity(value);
        this.raisePropertyChanged('maximumOpacity');
    },
    
    get_forceLayoutInIE : function() {
        /// <value type="Boolean">
        /// Whether or not we should force a layout to be created for Internet Explorer by giving it a width and setting its
        /// background color (the latter is required in case the user has ClearType enabled). The default value is <code>true</code>.
        /// This is obviously ignored when working in other browsers.
        /// </value>
        return this._out.get_forceLayoutInIE();
    },
    set_forceLayoutInIE : function(value) {
        value = this._getBoolean(value);
        this._out.set_forceLayoutInIE(value);
        this._in.set_forceLayoutInIE(value);
        this.raisePropertyChanged('forceLayoutInIE');
    },
    
    set_duration : function(value) {
        /// <value type="Number">
        /// Override the <code>duration</code> property
        /// </value>
        value = this._getFloat(value);
        $TWA.PulseAnimation.callBaseMethod(this, 'set_duration', [value]);
        this._in.set_duration(value);
        this._out.set_duration(value);
    },
    
    set_fps : function(value) {
        /// <value type="Number" integer="true">
        /// Override the <code>fps</code> property
        /// </value>
        value = this._getInteger(value);
        $TWA.PulseAnimation.callBaseMethod(this, 'set_fps', [value]);
        this._in.set_fps(value);
        this._out.set_fps(value);
    }
    
}
$TWA.PulseAnimation.registerClass('Telerik.Web.Animation.PulseAnimation', $TWA.SequenceAnimation);
$TWA.registerAnimation('pulse', $TWA.PulseAnimation);

/* END Telerik.Web.UI.Common.Animation.Animations.js */
/* START Telerik.Web.UI.Common.Animation.TelerikAnimations.js */
//---------------------------------------- ANIMATIONS --------------------------------------------------//
//Controls to benefit are - tooltip, window, dock, colorpicker
//Animations combine two animations [open/close] using the same set of data.
//Properties that are needed to provide information show and hide animations
//startBounds, endBounds, Telerik.Web.UI.ToolTipPosition position!-> will probably need to be made common for all controls.

//Window can be moved from original location, their opener can be moved, so calculating exact values to use can requier more actions to get the correct values
//Close animations assume the animated element's size and position
Type.registerNamespace('Telerik.Web.UI.Animations');

Telerik.Web.UI.Animations.ShowHideAnimation = function(controller, duration, fps, animatedElement, position, sourceElement) 
{                 
    ///<exclude/>    
    this.controller = controller;
        
    this._duration = (duration !=  null) ? duration : .3;
    this._fps = (fps !=  null) ? fps : 50;
    this._frames = duration * fps;		    
    this._position = null != position ? position : 32;//Telerik.Web.UI.ToolTipPosition.BottomCenter;
        
    this._animatedElement = animatedElement;//The element to be animated    
    this._sourceElement = sourceElement;    //The source element that initiates the animation can be used to obtain start/end bounds
    
    //Start bounds are optional and not set on some animations.If a sourceElement exists, it has higher priority than the startBounds
    this._startBounds = null;
    //End bounds are mandatory for animations that perform resizing, and must be set in onStart handler
    this._endBounds = null;
    
    //Created by classes that inherit the base class
    this._showAnimation = null;
    this._hideAnimation = null;
}


Telerik.Web.UI.Animations.ShowHideAnimation.prototype = 
{   
    //## region protected methods##
    
    //Returns the horizontal position of animated element relative to the sourceElement
    _getHorizontalPosition : function()
    {
      return parseInt((this._position + "").charAt(1));      
    },
    
    //Returns the vertical position of animated element relative to the sourceElement
    _getVerticalPosition : function()
    {
      return parseInt((this._position + "").charAt(0));      
    },
    
    //Use it to set proper values to the animation. 
    //if startBounds are set, use them as initial size/position values. Else - if _sourceElement is set - use its bounds for initial values
    _onBeforeShow : function()
    {    
        /* Override in subclass */
    },
            
    _onBeforeHide : function()
    {    
        /* Override in subclass */
    },
        
    _onAfterShow : function()
    {   
        /* Override in subclass */ 
    },
    
    _onAfterHide : function()
    {   
        /* Override in subclass */ 
    },
                                      
    //## region Public API ##//
    onShowStart : function()
    {
        /* Override when initializing */
    },
            
    onHideStart : function()
    {
        /* Override when initializing */
    },
    
    onShowEnd : function()
    {
       /* Override when initializing */
    },
    onHideEnd : function()
    {
       /* Override when initializing */
    },
    
    play : function(isHideSequence)
    {
        var animation = (true == isHideSequence) ? this._hideAnimation : this._showAnimation;
        
        if (animation)
        {
            //Stop running animation [if any]
            this.stop();
            
            if (!animation.__isTelerikModified)
            {
                var _this = this;
                animation.__isTelerikModified = true;
                
                //Attach to onStart and prevent onStart from being replaced multiple times on each animation play
                var oldStart = animation.onStart;
                animation.onStart = function()
                {                            
                    //Call current onStart to allow for setting configuration values
                    if (isHideSequence) _this.onHideStart();
                    else _this.onShowStart();
              
                    //Use the values set in the onStart event handler to finish the initialization process
                    if (true == isHideSequence)
                    {
                        _this._onBeforeHide();
                    }
                    else
                    {                                  
                        _this._onBeforeShow();          
                    }
                    
                    //Important: Call original onStart to perform initialiation, or else it would not work
                    //! The invocation must be here - as the last action!
                    if (oldStart) oldStart.call(this);
                };
                
                //Attach to onEnd and prevent onEnd from being replaced multiple times on each animation play
                var oldEnd = animation.onEnd;
                animation.onEnd = function()
                {                        
                    if (oldEnd) oldEnd.call(this);
                    if (_this.onEnd) _this.onEnd(isHideSequence);
                    
                    //Cleanup
                    if (true == isHideSequence)
                    {
                        _this._onAfterHide();
                    }
                    else
                    {                                  
                        _this._onAfterShow();          
                    }
                    
                    //Run finalizing code
                    if (isHideSequence) _this.onHideEnd();
                    else _this.onShowEnd();           
                }            
            }
            
            //NEW: Reset the duration
            animation.set_duration(this._duration);
          
            //Play animation            
            animation.play();    
        }
                
        this._runningAnimation = animation;                
    },
    
    set_startBounds : function(bounds)
    {
        this._startBounds = bounds;
    },

    set_endBounds : function(bounds)
    {
        this._endBounds = bounds;
    },
        
    dispose : function()
    {
        this.stop();
        if (this._showAnimation) this._showAnimation.dispose();
        if (this._hideAnimation) this._hideAnimation.dispose();
    },
    
    stop : function()
    {
        if (this._runningAnimation)
        {
            this._runningAnimation.stop();
            this._runningAnimation = null;
        }
    },
    
    //NEW: Pause functionality
    pause : function()
    {
        if (this._runningAnimation)
        {
            this._runningAnimation.pause();
            
        }
    },
    
    resume : function()
    {
        if (this._runningAnimation)
        {
            this._runningAnimation.play();
            
        }
    },
    
    //NEW: API methods    
    set_position : function(value)
    {
        this._position = value;
    },
    
    set_duration : function(value)
    {
        this._duration = value;        
        if (this._showAnimation) this._showAnimation.set_duration(this._duration);
        if (this._hideAnimation) this._hideAnimation.set_duration(this._duration);
    
    },
    
    get_startBounds : function()
    {
        return this._startBounds;
    },
    
    get_endBounds : function()
    {
        return this._endBounds;
    }
        
}
Telerik.Web.UI.Animations.ShowHideAnimation.registerClass('Telerik.Web.UI.Animations.ShowHideAnimation', null);


/****************************************************************************************************************
 *                                                  Resize animation 
 ****************************************************************************************************************/
Telerik.Web.UI.Animations.ResizeAnimation = function(controller, duration, fps, animatedElement, position, sourceElement) 
{                 
    Telerik.Web.UI.Animations.ResizeAnimation.initializeBase(this, [controller, duration, fps, animatedElement, position, sourceElement]);    
    
    var duration = this._duration;
    var fps = this._fps;
    var target =  this._animatedElement; 
    
    //Fake values for easier initialiation    
    //var width = 100, height = 100, startY = 0, endY = 100, startX = 0, endX = 100;
    var width, height, startY, endY, startX, endX;
    
	//_showAnimation			
    var resizeAnimation = new Telerik.Web.Animation.ResizeAnimation(target, duration, fps, width, height, 'px');    
    var leftAnimation = new Telerik.Web.Animation.LengthAnimation(target, duration, fps, "style", "left", startX, endX, "px");
    var topAnimation = new Telerik.Web.Animation.LengthAnimation(target, duration, fps, "style", "top", startY, endY, "px");							        
    var fadeAnimation = new Telerik.Web.Animation.FadeInAnimation(target, duration, fps, .3, 1, false);	    						

    this._showAnimation = new Telerik.Web.Animation.ParallelAnimation(target, duration, fps, 		    
                          [resizeAnimation, leftAnimation, topAnimation, fadeAnimation]
                        );                                   
    
    //_hideAnimation
    this._hideAnimation = new Telerik.Web.Animation.FadeInAnimation(this._animatedElement, this._duration, this._fps, 1, 0, false);	               	    
};

Telerik.Web.UI.Animations.ResizeAnimation.prototype = 
{    
    //Break into pieces, some of which will be overridden in ineriting animations
    _configureAnimatedElement : function()
    {
        var target = this._animatedElement;        
        target.style.overflow = "hidden";
        target.style.display = "";
        target.style.visibility = "visible";     
        target.style.width = "1px";
        target.style.height = "1px";        
    },
              
    _configureAnimation : function(animValues)
    {        
        //Configure the animations before you run the parent animation
		var anims = this._showAnimation.get_animations();
		var resizeAnim = anims[0];
		resizeAnim.set_width(animValues.width);
		resizeAnim.set_height(animValues.height);

        var leftAnim = anims[1];     
        leftAnim.set_startValue(animValues.startX);
        leftAnim.set_endValue(animValues.endX);
   
        var topAnim = anims[2];
        topAnim.set_startValue(animValues.startY);
        topAnim.set_endValue(animValues.endY);
    },
        
        
    _getStartBounds : function()
    {
        var startBounds = null;
        if (this._startBounds) startBounds = this._startBounds;
		else if (this._sourceElement) startBounds = $telerik.getBounds(this._sourceElement);
		else startBounds = new Sys.UI.Bounds(1,1,1,1); 	
		return startBounds;
    },
    
    _getEndBounds : function()
    {
        return this._endBounds;
    },
    
    //Can be overridden in subclasses
	_modifyAnimationValues : function(animValues)
    {      			
		//Additional smooth out - if the source element is smaller than tooltip, use the source element as starting size
		var target = this._animatedElement;
		var startBounds = this._getStartBounds();
			                   		
		if(startBounds.width < animValues.width) 
		{
		    animValues.startX = startBounds.x;
		    target.style.width = startBounds.width;
		}
		
		if(startBounds.height < animValues.height) 
		{
		    //Only if position is in center! Other than that -> if position top - start from top, position bottom start from bottom
		    animValues.startY = startBounds.y;				    
            target.style.height = startBounds.height;
		}
	},
		
    _setHorizontalValues : function(animValues)
    {
        var horSide = this._getHorizontalPosition();
        var popupBounds = this._getEndBounds();
        switch(horSide)
        {
            //Center
            case 2:                            
                animValues.startX = popupBounds.x + Math.floor(popupBounds.width/2);  
                animValues.endX = popupBounds.x;
                break;
            //Right
            case 3:              
                animValues.startX = popupBounds.x;
                animValues.endX = popupBounds.x;
                break;                
            //Left            
            case 1:
                animValues.startX = popupBounds.x + popupBounds.width;  
                animValues.endX = popupBounds.x;          
        }
    },
    
    _setVerticalValues : function(animValues)
    {
        var verSide = this._getVerticalPosition();                
        var popupBounds = this._getEndBounds();
         //Compute the vertical coordinate
        switch(verSide)
        {
            //Middle
            case 2:                                               
               animValues.startY = popupBounds.y + Math.floor(popupBounds.height/2);
               animValues.endY = popupBounds.y;
               break;
            //Top    
            case 1:               
               animValues.startY = popupBounds.y + popupBounds.height;
               animValues.endY = popupBounds.y;                
                break;
            //Bottom
            case 3:
               animValues.startY = popupBounds.y;
               animValues.endY = popupBounds.y;             
        }
    },
    
    _setSizeValues : function(animValues)
    {
        var popupBounds = this._endBounds;
        animValues["width"] = popupBounds.width;
		animValues["height"] = popupBounds.height;
    },
    
    //Inherit from parent class
    _onBeforeShow : function()
    {    
		//Create animation object
		var animValues = {};				
		this._setHorizontalValues(animValues);
		this._setVerticalValues(animValues);
		this._setSizeValues(animValues);
	
	    //Configure the element to be animated
		this._configureAnimatedElement();
						                
		//Overridden method - allow for value and target element modification
		this._modifyAnimationValues(animValues);
        //alert("Start x=" + animValues.startX + " , y = " + animValues.startY);
		//Configure the child animation objects using the supplied values
		this._configureAnimation(animValues);
    },
    
    _onAfterShow : function()
    {           
       this._animatedElement.style.overflow = "";        
       //Remove trasnparency filter(s) to make callout visible! Bug in IE         
       this._animatedElement.style.filter = "";               
    }            
}

Telerik.Web.UI.Animations.ResizeAnimation.registerClass('Telerik.Web.UI.Animations.ResizeAnimation', Telerik.Web.UI.Animations.ShowHideAnimation);


/****************************************************************************************************************
 *                                                  Slide animation 
 ****************************************************************************************************************/
 Telerik.Web.UI.Animations.SlideAnimation = function(controller, duration, fps, animatedElement, position, sourceElement) 
{                 
    Telerik.Web.UI.Animations.SlideAnimation.initializeBase(this, [controller, duration, fps, animatedElement, position, sourceElement]);            
};

Telerik.Web.UI.Animations.SlideAnimation.prototype = 
{         
    _modifyAnimationValues : function(animValues)
    {      					
	},
	
	 _configureAnimatedElement : function()
    {
        var target = this._animatedElement;        
        target.style.overflow = "hidden";
        target.style.display = "";
        target.style.visibility = "visible";     
        
        var verSide = this._getVerticalPosition();        
        if (verSide == 2)
        {
           target.style.width = "1px";
        }
        else target.style.height = "1px"; 
    },
		
   _setHorizontalValues : function(animValues)
    {
        var horSide = this._getHorizontalPosition();
        var popupBounds = this._getEndBounds();
        switch(horSide)
        {
            //Center
            case 2:                            
                animValues.startX = popupBounds.x;// + Math.floor(popupBounds.width/2);  
                animValues.endX = popupBounds.x;
                break;
            //Right
            case 3:              
                animValues.startX = popupBounds.x;
                animValues.endX = popupBounds.x;
                break;                
            //Left            
            case 1:
                var startX = popupBounds.x;
                
                if (2 == this._getVerticalPosition())  //Only if vertical pos is middle!
                        startX += popupBounds.width;
                
                animValues.startX = startX;
                                    
                animValues.endX = popupBounds.x;          
        }
    },
    
    _setVerticalValues : function(animValues)
    {
        var verSide = this._getVerticalPosition();                
        var popupBounds = this._getEndBounds();
         //Compute the vertical coordinate
        switch(verSide)
        {
            //Middle
            case 2:                                               
               animValues.startY = popupBounds.y;// + Math.floor(popupBounds.height/2);
               animValues.endY = popupBounds.y;
               break;
            //Top    
            case 1:               
               animValues.startY = popupBounds.y + popupBounds.height;
               animValues.endY = popupBounds.y;                
                break;
            //Bottom
            case 3:
               animValues.startY = popupBounds.y;
               animValues.endY = popupBounds.y;             
        }
    }
}

Telerik.Web.UI.Animations.SlideAnimation.registerClass('Telerik.Web.UI.Animations.SlideAnimation', Telerik.Web.UI.Animations.ResizeAnimation);
 
/****************************************************************************************************************
*                                                  FlyIn animation 
****************************************************************************************************************/
Telerik.Web.UI.Animations.FlyInAnimation = function(controller, duration, fps, animatedElement, position, sourceElement) 
{                 
    Telerik.Web.UI.Animations.FlyInAnimation.initializeBase(this, [controller, duration, fps, animatedElement, position, sourceElement]);    
};

Telerik.Web.UI.Animations.FlyInAnimation.prototype = 
{         
	_modifyAnimationValues : function(animValues)
    {      					
	},
		
    _setHorizontalValues : function(animValues)
    {    
        var horSide = this._getHorizontalPosition();
        var popupBounds = this._getEndBounds();
        
        var browserBounds = $telerik.getClientBounds();
        
        switch(horSide)
        {
            //Center
            case 2:                            
                animValues.startX = popupBounds.x;
                animValues.endX = popupBounds.x;
                break;
            //Right
            case 3:              
                animValues.startX = browserBounds.width;
                animValues.endX =  popupBounds.x;
                break;                
            //Left            
            case 1:
                animValues.startX = browserBounds.x;  
                animValues.endX = popupBounds.x;          
        }
                
    },
    
    _setVerticalValues : function(animValues)
    {
        var verSide = this._getVerticalPosition();                
        var popupBounds = this._getEndBounds();
        var browserBounds = $telerik.getClientBounds();
        
         //Compute the vertical coordinate
        switch(verSide)
        {
            //Middle
            case 2:                                               
               animValues.startY = popupBounds.y;
               animValues.endY = popupBounds.y;
               break;
            //Top    
            case 1:               
               animValues.startY = browserBounds.y - popupBounds.height;
               animValues.endY = popupBounds.y;                
                break;
            //Bottom
            case 3:
               animValues.startY = browserBounds.height;
               animValues.endY = popupBounds.y;             
        }                
    }
}

Telerik.Web.UI.Animations.FlyInAnimation.registerClass('Telerik.Web.UI.Animations.FlyInAnimation', Telerik.Web.UI.Animations.ResizeAnimation);
 
  
/****************************************************************************************************************
*                                                  Fade animation 
****************************************************************************************************************/
Telerik.Web.UI.Animations.FadeAnimation = function(controller, duration, fps, animatedElement) 
{                 
    Telerik.Web.UI.Animations.FadeAnimation.initializeBase(this, [controller, duration, fps, animatedElement]);    
    
    this._showAnimation = new Telerik.Web.Animation.FadeInAnimation(this._animatedElement, this._duration, this._fps, .5, 1, false);	      
    this._hideAnimation = new Telerik.Web.Animation.FadeInAnimation(this._animatedElement, this._duration, this._fps, .9, 0, false);	               
};

Telerik.Web.UI.Animations.FadeAnimation.prototype = 
{      
    _onAfterShow : function()
    {                            
        //Remove trasnparency filter(s) to make callout visible! Bug in IE         
        this._animatedElement.style.filter = "";       
    }       
}

Telerik.Web.UI.Animations.FadeAnimation.registerClass('Telerik.Web.UI.Animations.FadeAnimation', Telerik.Web.UI.Animations.ShowHideAnimation);

/****************************************************************************************************************
 *                                                  SimpleResize animation 
 ****************************************************************************************************************/
 Telerik.Web.UI.Animations.SimpleResizeAnimation = function(controller, duration, fps, animatedElement, position, sourceElement) 
{                 
    Telerik.Web.UI.Animations.SimpleResizeAnimation.initializeBase(this, [controller, duration, fps, animatedElement, position, sourceElement]);            
};

Telerik.Web.UI.Animations.SimpleResizeAnimation.prototype = 
{         
    _modifyAnimationValues : function(animValues)
    {      					
	},
	
	_configureAnimation : function(animValues)
    {        
        Telerik.Web.UI.Animations.SimpleResizeAnimation.callBaseMethod(this, '_configureAnimation', [animValues]);

		var anims = this._showAnimation.get_animations();
		var resizeAnim = anims[0];
		
		var startBounds = this._getStartBounds();
		// Modify the onStart of the resize animation as it sets as start(end)Width(Height) the offsetWidth(Height).
		// This is not correct in case the animated element has borders.
		resizeAnim.onStart = function()
		{
		     $TWA.ResizeAnimation.callBaseMethod(this, 'onStart');
        
            // Set the start and end values of the animations by getting
            // the element's current width and height
            var element = this.get_target();
            this._horizontalAnimation.set_startValue(startBounds.width);
            this._verticalAnimation.set_startValue(startBounds.height);
            this._horizontalAnimation.set_endValue((this._width !== null && this._width !== undefined) ?
                this._width : element.offsetWidth);
            this._verticalAnimation.set_endValue((this._height !== null && this._height !== undefined) ?
                this._height : element.offsetHeight);
		};
    },
	
	_configureAnimatedElement : function()
    {
        var target = this._animatedElement;        
        target.style.overflow = "hidden";
        target.style.display = "";
        target.style.visibility = "visible";  
    },
		
   _setHorizontalValues : function(animValues)
    {
        var horSide = this._getHorizontalPosition();
        var startBounds = this._getStartBounds();
        var endBound = this._getEndBounds();
                          
        animValues.startX = startBounds.x;
        animValues.endX = endBound.x;
    },
    
    _setVerticalValues : function(animValues)
    {
        var verSide = this._getVerticalPosition();                
        var startBounds = this._getStartBounds();
        var endBound = this._getEndBounds();
                                            
       animValues.startY = startBounds.y;
       animValues.endY = endBound.y;
    }
}

Telerik.Web.UI.Animations.SimpleResizeAnimation.registerClass('Telerik.Web.UI.Animations.SimpleResizeAnimation', Telerik.Web.UI.Animations.ResizeAnimation);
 
 

 
Telerik.Web.UI.Animations.ScrollAnimation = function(controller, duration, fps, animatedElement, position, sourceElement) 
{                 
    Telerik.Web.UI.Animations.ScrollAnimation.initializeBase(this, [controller, duration, fps, animatedElement, position, sourceElement]);            
    
    //HACK: Remove the fade animation - after the FUTURES we will rework the TelerikAnimations!
    var anims = this._showAnimation.get_animations();    
    if (anims[3])
    {        
        this._showAnimation.remove(anims[3]);
    }
    
};

Telerik.Web.UI.Animations.ScrollAnimation.prototype = 
{         
    //Override to empty
    _modifyAnimationValues : function(animValues)
    {      					
	},
	
	//Override to empty
	 _configureAnimatedElement : function()
    {
         //Called too late, so do not set anything to the element here         
    },
		
   _setHorizontalValues : function(animValues)
    {                  
        var startBounds = this._getStartBounds();                
        var popupBounds = this._getEndBounds();

        var horSide = this._getHorizontalPosition();                               
        switch(horSide)
        {
            //Center - currently not used, but with two dimensions it will!
            case 2:                            
                animValues.startX = startBounds.x;
                animValues.endX = startBounds.x;
                break;
            
            //Right
            case 3:              
                animValues.startX = startBounds.x;
                animValues.endX = startBounds.x + popupBounds.x;
                break;                
            //Left            
            case 1:                                                 
                animValues.startX = startBounds.x;                                    
                animValues.endX = startBounds.x - popupBounds.x;          
        }
        //alert(horSide +  " Start x=" + animValues.startX + " " +   animValues.endX);      
    },
    
    _setVerticalValues : function(animValues)
    {
        var verSide = this._getVerticalPosition();                
        
        var startBounds = this._getStartBounds();   
        var popupBounds = this._getEndBounds();
         //Compute the vertical coordinate
        switch(verSide)
        {
            //Middle
            case 2:                                               
               animValues.startY = popupBounds.y;
               animValues.endY = popupBounds.y;
               break;
            //Top    
            case 1:               
               animValues.startY = startBounds.y;
               animValues.endY = startBounds.y - popupBounds.y;
               break;
            //Bottom
            case 3:
               animValues.startY = startBounds.y;
               animValues.endY = startBounds.y + popupBounds.y;             
        }
        
        //alert(verSide + " Vertical values =" + animValues.startY + " " +   animValues.endY);              
    }
};

Telerik.Web.UI.Animations.ScrollAnimation.registerClass('Telerik.Web.UI.Animations.ScrollAnimation', Telerik.Web.UI.Animations.ResizeAnimation);	

/* END Telerik.Web.UI.Common.Animation.TelerikAnimations.js */
/* START Telerik.Web.UI.Rotator.RadRotator.js */
Type.registerNamespace("Telerik.Web.UI");

Telerik.Web.UI.RadRotator = function(element) {
	Telerik.Web.UI.RadRotator.initializeBase(this, [element]);
	this._skin = "Default";
	this._postBackReference = null;
	this._items = null;
	this._webServiceSettings = new Telerik.Web.UI.WebServiceSettings({});
	this._webServiceLoader = null;
	this._containerElement = null;
	this._clickDelegate = null;
	this._mouseOutDelegate = null;
	this._mouseOverDelegate = null;

	//TEKI: Props
	//Properties from old RadRotator that will be implemented
	this._useRandomSlide = false;

	//Properties of the new Rotator
	this._pauseOnMouseOver = true;

	var directionEnum = Telerik.Web.UI.RotatorScrollDirection;
	this._scrollDirection = directionEnum.Left + directionEnum.Right;
	this._slideShowAnimationSettings = {};

	this._rotatorType = Telerik.Web.UI.RotatorType.AutomaticAdvance;
	this._scrollDuration = 500;
	this._frameDuration = 2000;
	this._initialItemIndex = 0;
	this._canPause = true;

	this._wrapFrames = true;
	this._controlButtons = {};

	//HTML Elements
	this._relativeWrapper = null;
	this._clipElement = null;
	this._itemsElement = null;

	//Utility refs
	this._animationDirection = directionEnum.Left;

	//buttons
	this._rightButton = null;
	this._leftButton = null;
	this._downButton = null;
	this._upButton = null;

}

Telerik.Web.UI.RadRotator.prototype =
{
	initialize : function()
	{
		Telerik.Web.UI.RadRotator.callBaseMethod(this, "initialize");
		//Create UI
		this._setChildElements();
		this._createUI();
		this._createChildItems();
		this._attachEvents(true);

		//If the initialFrame # is specified - move it to proper position
		this._initialItemSet = false;
		this._loadInitialFrame();

		//Configure rotator buttons(if any)
		this._enableDisableButtons();

		//handle case when the parent is invisible and becomes visible
		this._fixVisibilityProblems(true);

		//raise the client load event
		this.raiseEvent("load", Sys.EventArgs.Empty);

		//If automatic - start animation
		if (this.isAutomaticAdvance())
		{
			var frameDuration = this.get_frameDuration();
			if (frameDuration > 0)
			{
				window.setTimeout(Function.createDelegate(this, this.startAutoPlay), frameDuration);
			}
			else
			{
				this.startAutoPlay();
			}
		}
	},


	dispose : function()
	{
		this._fixVisibilityProblems(false);

		this._attachEvents(false);
		this._containerElement = null;
		//TEKI - Dispose animation
		if (this._animation)
		{
			this._animation.dispose();
			this._animation = null;
		}
		if (this._slideShowAnimation)
		{
			this._slideShowAnimation.dispose();
			this._slideShowAnimation = null;
		}

		//use attachevents to attach/detach events?
		if (this._rightButton) $clearHandlers(this._rightButton);
		if (this._leftButton) $clearHandlers(this._leftButton);
		if (this._downButton) $clearHandlers(this._downButton);
		if (this._upButton) $clearHandlers(this._upButton);

		//UL items element
		if (this._itemsElement)
		{
			$clearHandlers(this._itemsElement);
		}

		Telerik.Web.UI.RadRotator.callBaseMethod(this, "dispose");
	},

	_createChildItems : function()
	{
		var childElements = $telerik.getChildrenByTagName(this.get_containerElement(), "li");

		for (var i = 0; i < childElements.length; i++)
		{
			var rotatorItem = $create(Telerik.Web.UI.RadRotatorItem, this.get_items()[i], null, null, childElements[i]);
			//calculate the item index
			var rotatorItemIndex = rotatorItem.get_index();
			childElements[i]._item = rotatorItem;
			this.get_items()[i] = rotatorItem;
		}
	},


	//================================ Changes added to support ButtonOver as well as changed logic for initial positioning of item when ScrollType is of type Automatic
	_getNextItemToShow : function()
	{
		var lis = this.getItemHtmlElements();

		var isForward = this.isScrollingForward();

		//Set the first or last item to be used as starting index (depending on direction)
		if (this._nextItemIndex == null)
		{
			var index = isForward ? 0 : lis.length - 1;
			this._nextItemIndex = index;
		}

		//Mozilla throws exception here if we use negative index. All other browsers are OK
		if (this._nextItemIndex < 0) return null;
		var li = lis[this._nextItemIndex];

		//Increase or decrease the index, depending on the direction
		if (isForward) this._nextItemIndex++;
		else this._nextItemIndex--;

		//NEW: Needed by the ButtonsOver way!
		if (this._nextItemIndex > lis.length - 1 || this._nextItemIndex < 0)
		{
			this._nextItemIndex = null;
		}

		return li;
	},

	//Return the item whose width/height will be used to judge whether there is enough length for the rotator to scroll an item
	get_currentItem : function()
	{
		var item = this._currentItem;
		if (!item)
		{
			var list = this._itemsElement;
			var lis = this.getItemHtmlElements();
			item = this.isScrollingForward() ? lis[0] : lis[lis.length - 1];
		}
		return item;
	},


	_needsShift : function(direction)
	{
		//If no direction is set, use the currently set
		if (null == direction) direction = this.get_animationDirection();
		var listElement = this._itemsElement;
		var viewPort = this._clipElement;
		var listLeft = parseInt(listElement.style.left);
		var listTop = parseInt(listElement.style.top);
		var listBounds = $telerik.getOuterSize(listElement);
		var viewPortBounds = $telerik.getContentSize(viewPort);

		var curItem = this.get_currentItem();
		if (!curItem)
		{
			return false;
		}

		var curItemSize = $telerik.getOuterSize(curItem);

		var canSlide = false;
		var directionEnum = Telerik.Web.UI.RotatorScrollDirection;
		switch (direction)
		{
			case directionEnum.Left:
				canSlide = listLeft + listBounds.width < viewPortBounds.width + curItemSize.width;
				break;

			case directionEnum.Up:
				canSlide = listTop + listBounds.height < viewPortBounds.height + curItemSize.height;
				break;
			case directionEnum.Right:
				canSlide = listLeft * -1 < curItemSize.width;
				break;
			case directionEnum.Down:
				canSlide = listTop * -1 < viewPortBounds.height;
				break;
		}
		return canSlide;
	},

	_getMoveAnimation : function()
	{
		if (this._animation) return this._animation;

		var list = this._itemsElement;
		var duration = this._getCalculatedAnimationDuration();
		var fps = 25;
		this._animation = new Telerik.Web.Animation.MoveAnimation(list, duration, fps, true, false, false, "px"); //horizontal = true, vertical = false

		//Due to problem with Mozilla and other browsers in the way that the Lenght animation is implemented, it rounds values to 0 or 1, but it always needs to be 0!
		//Otherwise there is a kind of shaking during the animation
		function returnZeroPixels(start, end, percentage) { return 0; }

		if (this.get_vertical())
		{
			this._animation._horizontalAnimation.interpolate = returnZeroPixels;
		}
		else
		{
			this._animation._verticalAnimation.interpolate = returnZeroPixels;
		}

		return this._animation;

	},


	scrollViewport : function()
	{
		var list = this._itemsElement;

		//Create animation
		if (!this._animation)
		{
			var move = this._getMoveAnimation();
			var initItemAnimation = Function.createDelegate(this, function()
			{
				//See if rotator can slide a full length
				var canSlide = this._hasViewportWidth();
				//If false && wrapFrames = true -> move the required number of items in a while - 1)move 2)canScroll cycle
				if (!canSlide && this.get_wrapFrames())
				{
					//Move frames from list
					var listLength = this.getItemHtmlElements().length;
					for (var i = 0; i < listLength; i++)
					{
						//First time we arleady know that we need to do shift
						this._shiftItemInList();
						canSlide = this._hasViewportWidth();
						if (canSlide) break;
					}
				}

				//Set next x or y - to be the size of the viewPort
				var itemSize = this._getViewPortPixelsToScroll();

				var isForward = this.isScrollingForward();
				//Scrolling is vertical or horizontal?
				if (this.get_vertical())
				{
					var endPosition = parseInt(list.style.top) + (isForward ? -itemSize : itemSize);
					move.set_vertical(endPosition);
				}
				else
				{
					var endPosition = parseInt(list.style.left) + (isForward ? -itemSize : itemSize);
					move.set_horizontal(endPosition);
				}
			});

			move.add_started(Function.createDelegate(this, function()
			{
				//NEW: If animation is currently playing get its values and set those
				this.stopViewportAnimation();

				var realTarget = null;
				var showingArgs = new Telerik.Web.UI.RadRotatorCancelEventArgs(realTarget);
				this.raiseEvent("itemShowing", showingArgs);
				if (showingArgs.get_cancel && showingArgs.get_cancel())
				{
					return false;
				}

				//NEW: Smooth out the list movement
				if (this.isSlideShow())
				{
					list.style.visibility = "hidden";
				}

				//Initialize animation
				initItemAnimation();
			}));

			move.add_ended(Function.createDelegate(this, function()
			{
				//Enable disable buttons if needed
				this._enableDisableButtons();

				if (this.isSlideShow())
				{
					//NEW: Smooth out the list movement
					list.style.visibility = "visible";
					this.runSlideShowAnimation();
				}
				else
				{
					//raise item shown event
					var realTarget = null;
					this.raiseEvent("itemShown", new Telerik.Web.UI.RadRotatorEventArgs(realTarget));
				}
			}));
		}
		this._animation.play();
	},


	scrollItem : function()
	{
		var clipElement = this._clipElement;
		var list = this._itemsElement;

		//Create animation
		if (!this._animation)
		{
			this._animation = this._getMoveAnimation();

			var move = this._animation;
			var initItemAnimation = Function.createDelegate(this, function()
			{
				//Get next list item
				var nextItem = this._getNextItemToShow();
				if (!nextItem)
				{
					return;
				}
				//NEW: Set it to be used by get_currentItem - this method is called to perform some size calculations
				this._currentItem = nextItem;

				//Set next x/y
				var itemSize = $telerik.getOuterSize(nextItem);

				//Multiply by -1 if the rotator is moving "forward"
				if (this.isScrollingForward())
				{
					itemSize.width *= -1;
					itemSize.height *= -1;
				}

				//Scrolling is vertical or horizontal?
				if (this.get_vertical())
				{
					var endPosition = parseInt(list.style.top) + itemSize.height;
					move.set_vertical(endPosition);
				}
				else
				{
					var endPosition = parseInt(list.style.left) + itemSize.width;
					move.set_horizontal(endPosition);
				}
			});


			move.add_started(Function.createDelegate(this, function()
			{
				var realTarget = null;
				var showingArgs = new Telerik.Web.UI.RadRotatorCancelEventArgs(realTarget);
				this.raiseEvent("itemShowing", showingArgs);
				if (showingArgs.get_cancel && showingArgs.get_cancel())
				{
					return false;
				}
				//Flip frames first if needed
				var needsShift = this._needsShift();
				if (needsShift)
				{
					this._shiftItemInList();
				}

				//Ignore if ButtonsOver mode is on, and mouse is out of rotator
				if (this._stopAnimationButtonOver) return;

				//Initialize animation
				initItemAnimation();
			}));

			move.add_ended(Function.createDelegate(this, function()
			{
				//raise item shown event
				var realTarget = null;
				this.raiseEvent("itemShown", new Telerik.Web.UI.RadRotatorEventArgs(realTarget));

				//Ignore if ButtonsOver mode is on, and mouse is out of rotator
				if (this._stopAnimationButtonOver) return;

				if (this.get_frameDuration() > 0) this._setAnimationTimeout(this.get_frameDuration());
				else this._animation.play(); //Restart animation
			}));
		}
		this._animation.stop();
		this._animation.play();
	},

	_checkItemsSize : function()
	{
		//checks if the list width is smaller than the rotator width
		//if it is - no need to scroll.
		var size = $telerik.getOuterSize(this._itemsElement);
		var isVertical = this.get_vertical();
		var itemsLength = (isVertical) ? size.height : size.width;
		var rotatorLength = (isVertical) ? this.get_height() : this.get_width();
		return parseInt(itemsLength) > parseInt(rotatorLength);
	},

	_shiftItemInList : function()
	{
		var list = this._itemsElement;
		var lis = this.getItemHtmlElements();
		var isVertical = this.get_vertical();
		var isForward = this.isScrollingForward();
		var curX = parseInt(list.style.left);
		var curY = parseInt(list.style.top);

		var nextItem = isForward ? lis[0] : lis[lis.length - 1];
		var itemSize = $telerik.getOuterSize(nextItem);

		nextItem.parentNode.removeChild(nextItem);

		if (!isForward)//Add item to the start of list
		{
			list.insertBefore(nextItem, list.firstChild);
		}

		//Set new left/top offset for the list
		if (isVertical)
		{
			list.style.top = (curY + (isForward ? itemSize.height : -itemSize.height)) + "px";
		}
		else
		{
			list.style.left = (curX + (isForward ? itemSize.width : -itemSize.width)) + "px";
		}

		if (isForward)
		{
			//Add item to end of list
			list.appendChild(nextItem);
		}

		//Set item index so that it "points" to proper LI
		this._nextItemIndex = isForward ? lis.length - 1 : 0;

		return nextItem;
	},


	_loadInitialFrame : function()
	{
		//Set the top/left for the first selected frame
		var firstVisible = this.get_initialItemIndex();
		var direction = this.get_defaultAnimationDirection();
		var directionEnum = Telerik.Web.UI.RotatorScrollDirection;
		var isVertical = this.isVertical();

		var listElement = this._itemsElement;
		var listSize = $telerik.getOuterSize(listElement);
		//NEW - Take care of the viewport size
		var viewPortSize = $telerik.getContentSize(this._clipElement);

		var x = 0;
		var y = 0;
		if (firstVisible >= 0)
		{
			if (isVertical)
			{
				y = (direction == directionEnum.Up) ? 0 : -listSize.height + viewPortSize.height;
			}
			else
			{
				x = (direction == directionEnum.Left) ? 0 : -listSize.width + viewPortSize.width;
			}
		}
		else if (firstVisible == -1)
		{
			//It should not be visible in the rotator, but depending on the scroll direction (say - Right, or Down) should be positioned
			//in such a way that when animation starts, the frame will start appearing right away.
			//NEW: -1 has a special meaning - it needs to set the rotator JUST OUTSIDE of the viewport and prepare it for sliding
			//However, depending on the direction where to slide, we need extra calcuations
			//			|  |-1 |  |
			//			-----------
			//			|-1| 0 |-1|
			//			-----------
			//			|  |-1 |  |
			if (isVertical)
			{
				//Set to the end of the viewport
				y = (direction == directionEnum.Down) ? -listSize.height : viewPortSize.height;
			}
			else
			{
				//Set to the end of the viewport
				x = (direction == directionEnum.Right) ? -listSize.width : viewPortSize.width;
			}
		}
		listElement.style.left = x + "px";
		listElement.style.top = y + "px";
		if (firstVisible > 0 && !this._initialItemSet)
		{
			//shift items to position the one with initialItemIndex at the beginning
			for (var i = 0; i < firstVisible; i++)
			{
				this._shiftItemInList();
			}
			//vertical rotator needs an additional shift if we want to see the same item 
			//as in horizontal scrolling
			//if (isVertical) this._shiftItemInList();
			listElement.style.left = x + "px";
			listElement.style.top = y + "px";
			this._initialItemSet = true;
		}
	},

	pause : function()
	{
		this._isPaused = true;
		//If animation actually exists
		if (this._animation && this._animation.get_isActive()) this._animation.pause();
	},

	resume : function()
	{
		if (this._timeoutPassed || !this._isPaused)
		{
			if (this._animation) this._animation.play();
		}
		if (this._isPaused)
		{
			this._isPaused = false;
			//If animation actually is in progress, resume it as well
			if (this._animation && this._animation.get_isActive()) this._animation.play();
		}
	},


	isViewportScrollMode : function()
	{
		//returns true if mode is of type that one scroll will scroll the whole viewport
		var typeEnum = Telerik.Web.UI.RotatorType;
		//AutomaticAdvance, iPod, 2DSurface, Carousel
		if (this._isRotatorTypeEnabled(typeEnum.AutomaticAdvance) ||
			this._isRotatorTypeEnabled(typeEnum.ButtonsOver) ||
			this._isRotatorTypeEnabled(typeEnum.FromCode)
			)
		{
			return false;
		}
		//Buttons, Slideshow, FromCode
		return true;
	},

	_getButtonScrollDirection : function(button)
	{
		var scrollEnum = Telerik.Web.UI.RotatorScrollDirection;
		var scrollValue = scrollEnum.Left;
		switch (button)
		{
			case this._rightButton: scrollValue = scrollEnum.Left; break;
			case this._leftButton: scrollValue = scrollEnum.Right; break;
			case this._downButton: scrollValue = scrollEnum.Up; break;
			case this._upButton: scrollValue = scrollEnum.Down; break;
		}
		return scrollValue;
	},

	//Refactor - itroduce a new method to be used in button over and buttonout
	_buttonClicked : function(e)
	{
		var button = e.target;
		if (this._isButtonDisabled(button)) return;

		var args = new Telerik.Web.UI.RadRotatorButtonEventArgs(button);
		this.raiseEvent("buttonClick", args);
		if (args.get_cancel())
		{
			return;
		}

		var scrollValue = this._getButtonScrollDirection(button);

		this.set_animationDirection(scrollValue);
		this.scrollViewport();

		return $telerik.cancelRawEvent(e);
	},


	_buttonOver : function(e)
	{
		var button = e.target;
		if (this._isButtonDisabled(button)) return;

		var args = new Telerik.Web.UI.RadRotatorButtonEventArgs(button);
		this.raiseEvent("buttonOver", args);
		if (args.get_cancel())
		{
			return;
		}

		var scrollValue = this._getButtonScrollDirection(button);

		this.set_animationDirection(scrollValue);
		//NEW: FLAG Scroll item
		this._stopAnimationButtonOver = false;
		this.scrollItem();
		return $telerik.cancelRawEvent(e);
	},

	_buttonOut : function(e)
	{
		var button = e.target;
		if (this._isButtonDisabled(button)) return;

		var args = new Telerik.Web.UI.RadRotatorButtonEventArgs(button);
		this.raiseEvent("buttonOut", args);
		if (args.get_cancel())
		{
			return;
		}

		var scrollValue = this._getButtonScrollDirection(button);
		this.set_animationDirection(scrollValue);

		//NEW: FLAG Pause animation - actually this has side effects - let if finish instead!
		this._stopAnimationButtonOver = true;
		return $telerik.cancelRawEvent(e);
	},


	_initializeButtonsRotatorType : function()
	{
		//Initialize & configure all buttons - show and hide those depending on the scrollDirection

		//Create references to these buttons
		var controlButtons = this.get_controlButtons();
		this._rightButton = $telerik.getElementByClassName(this._rootElement, this._rotatorRightClass);
		this._leftButton = $telerik.getElementByClassName(this._rootElement, this._rotatorLeftClass);
		this._downButton = $telerik.getElementByClassName(this._rootElement, this._rotatorDownClass);
		this._upButton = $telerik.getElementByClassName(this._rootElement, this._rotatorUpClass);

		//Create some initializations array to go through
		var directionEnum = Telerik.Web.UI.RotatorScrollDirection;
		var directionArray = [directionEnum.Right, directionEnum.Left, directionEnum.Down, directionEnum.Up];
		var buttonsArray = [this._leftButton, this._rightButton, this._upButton, this._downButton];
		var customButtonsArray = [controlButtons.LeftButtonID ? $get(controlButtons.LeftButtonID) : null,
								  controlButtons.RightButtonID ? $get(controlButtons.RightButtonID) : null,
								  controlButtons.UpButtonID ? $get(controlButtons.UpButtonID) : null,
								  controlButtons.DownButtonID ? $get(controlButtons.DownButtonID) : null];
		var cssArray = [this._rotatorLeftClass, this._rotatorRightClass, this._rotatorUpClass, this._rotatorDownClass];
		var marginsArray = ["marginLeft", "marginRight", "marginTop", "marginBottom"];
		var paddingsArray = ["paddingLeft", "paddingRight", "paddingTop", "paddingBottom"];
		var sizeArray = ["width", "width", "height", "height"];

		var relativeWrapper = this._relativeWrapper;
		var rootElement = this.get_element();

		for (var i = 0; i < buttonsArray.length; i++)
		{
			var button = buttonsArray[i];
			var buttonWithHandlers = (null != customButtonsArray[i]) ? customButtonsArray[i] : button;

			this._createButton(button, cssArray[i]);

			//See if button should be visible or hidden
			if (this._isScrollDirectionEnabled(directionArray[i]) && null == customButtonsArray[i])
			{
				//alert("buttonSize " + marginsArray[i]);
				button.style.display = "block";
				//Add margin and change width
				var sizeValue = sizeArray[i];
				var buttonSize = parseInt($telerik.getCurrentStyle(button, sizeValue));

				//Reduce size of the relative wrapper
				relativeWrapper.style[sizeValue] = (parseInt(relativeWrapper.style[sizeValue]) - buttonSize) + "px";

				//Add padding to root parent, and change its size
				rootElement.style[sizeValue] = (parseInt(rootElement.style[sizeValue]) - buttonSize) + "px";
				rootElement.style[paddingsArray[i]] = buttonSize + "px";
			}

			if (this._isRotatorTypeEnabled(Telerik.Web.UI.RotatorType.Buttons) ||
				this._isRotatorTypeEnabled(Telerik.Web.UI.RotatorType.SlideShowButtons)
			)
			{
				$addHandlers(buttonWithHandlers, { "click": this._buttonClicked }, this);
			}
			else
			{
				//Add the hover and out
				$addHandlers(buttonWithHandlers, { "mouseover": this._buttonOver, "mouseout": this._buttonOut }, this);
			}
		}

		//set properties
		this._rightButton = customButtonsArray[1] || this._rightButton;
		this._leftButton = customButtonsArray[0] || this._leftButton;
		this._downButton = customButtonsArray[3] || this._downButton;
		this._upButton = customButtonsArray[2] || this._upButton;

		//NEW - if custom buttons are used, hide the border, let the developer style the rotator
		var hideBorder = false;
		for (var i = 0; i < customButtonsArray.length; i++) { if (customButtonsArray[i]) hideBorder = true; break; }
		return hideBorder;
	},


	//=========SlideShow modes=========//
	runSlideShowAnimation : function()
	{
		if (!this._slideShowAnimation)
		{
			var list = this._itemsElement;
			var duration = this.get_slideShowAnimationSettings().duration || 500;
			duration = duration / 1000;
			var animationType = this.get_slideShowAnimationSettings().type || Telerik.Web.UI.RotatorAnimationType.None;
			var startDelegate = Function.createDelegate(this, function()
			{
				//disable pause/resume during this animation
				//otherwise mouseover/mouseout events will cause premature item shifts
				this._canPause = false;
			});
			var endDelegate = Function.createDelegate(this, function()
			{
				this._canPause = true;
				//raise item shown event
				var realTarget = null;
				this.raiseEvent("itemShown", new Telerik.Web.UI.RadRotatorEventArgs(realTarget));
				if (this.get_frameDuration() > 0 && this.isAutomaticAdvance()) this._setAnimationTimeout(this.get_frameDuration());
			});

			switch (animationType)
			{
				case Telerik.Web.UI.RotatorAnimationType.Fade:
					this._slideShowAnimation = new Telerik.Web.Animation.FadeInAnimation(list, duration);
					this._slideShowAnimation.add_started(startDelegate);
					this._slideShowAnimation.add_ended(endDelegate);
					break;
				case Telerik.Web.UI.RotatorAnimationType.Pulse:
					this._slideShowAnimation = new Telerik.Web.Animation.PulseAnimation(list, null);
					//Setting duration in the constructor results in exception, so it is set afterwards
					this._slideShowAnimation.set_iterations(1);
					this._slideShowAnimation.set_duration(duration);
					this._slideShowAnimation.add_ended(endDelegate);
					break;
				default:
					//no animation, just pause
					this._slideShowAnimation = {};
					this._slideShowAnimation.play = endDelegate;
					this._slideShowAnimation.dispose = function() { };
					break;
			}
		}
		this._slideShowAnimation.play();
	},

	//================================== TEKI ==========================================================//
	_hasViewportWidth : function(direction)
	{
		//If no direction is set, use the currently set
		if (null == direction) direction = this.get_animationDirection();
		var listElement = this._itemsElement;
		var viewPort = this._clipElement;
		var listLeft = parseInt(listElement.style.left);
		var listTop = parseInt(listElement.style.top);
		var listBounds = $telerik.getOuterSize(listElement);
		var viewPortBounds = $telerik.getContentSize(viewPort);

		var canSlide = false;
		var directionEnum = Telerik.Web.UI.RotatorScrollDirection;
		switch (direction)
		{
			case directionEnum.Left:
				canSlide = listBounds.width + listLeft > viewPortBounds.width * 2;
				break;
			case directionEnum.Up:
				canSlide = listBounds.height + listTop > viewPortBounds.height * 2;
				break;
			case directionEnum.Right:
				canSlide = (listLeft * -1 > viewPortBounds.width);
				break;
			case directionEnum.Down:
				canSlide = (listTop * -1 > viewPortBounds.height);
				break;
		}

		return canSlide;
	},


	stopViewportAnimation : function()
	{
		var move = this._animation;
		if (!move) return;
		if (move.get_isPlaying())
		{
			move.stop();
			var isVertical = this.get_vertical();
			var value = isVertical ? move.get_vertical() : move.get_horizontal();
			if (null != value)
			{
				this._itemsElement.style[isVertical ? "top" : "left"] = value + "px";
			}
		}
	},




	_getViewPortPixelsToScroll : function()
	{
		var vertical = this.get_vertical();
		var viewPortSize = $telerik.getContentSize(this._clipElement);
		var result = vertical ? viewPortSize.height : viewPortSize.width;
		return result;
	},


	showNext : function(animationDir)
	{
		//Set animation direction
		this.set_animationDirection(animationDir);

		if (!this._checkItemsSize())
		{
			//if the rotator width is bigger than the list of items - no need to scroll
			return;
		}

		if (this.isViewportScrollMode())
		{
			this.scrollViewport();
		}
		else
		{
			this.scrollItem();
		}
	},


	getItemHtmlElements : function()
	{
		//var lis = list.getElementsByTagName("LI");
		//return lis;
		//A better approach is needed to avoid returning items from nested lists. For now use implementation below. Will improve it in future.
		var list = this._itemsElement;
		if (!this._hasCleanedList)
		{
			var nodes = list.childNodes;
			for (var i = 0; i < nodes.length; i++)
			{
				var node = nodes[i];
				if (node && node.tagName != "LI")
				{
					list.removeChild(node);
					i--;
				}
			}
			this._hasCleanedList = true;
		}
		return list.childNodes;
	},


	_getCalculatedAnimationDuration : function(animationDir)
	{
		var result = this.get_scrollDuration() / 1000;
		return result;
	},


	//=============================== Animations pasue and start ================================================================//

	_setAnimationTimeout : function(milliseconds)
	{
		this._clearAnimationTimeout();
		this._timeoutPassed = false;
		this._currentAnimationTimeout = window.setTimeout(Function.createDelegate(this, function() { if (!this._isPaused) this.resume(); this._timeoutPassed = true; }), milliseconds);
	},

	_clearAnimationTimeout : function()
	{
		if (this._currentAnimationTimeout)
		{
			window.clearTimeout(this._currentAnimationTimeout);
		}
		this._currentAnimationTimeout = 0;
	},

	//=======================================================================================================================//

	//Determine whether the method advances scrolls automatically, or requires manual interaction
	isAutomaticAdvance : function()
	{
		var typeEnum = Telerik.Web.UI.RotatorType;
		if (this._isRotatorTypeEnabled(typeEnum.AutomaticAdvance) || this._isRotatorTypeEnabled(typeEnum.SlideShow))//+ CarouselAutomatic
		{
			return true;
		}
		//All other modes
		return false;
	},

	isSlideShow : function()
	{
		var typeEnum = Telerik.Web.UI.RotatorType;
		if (this._isRotatorTypeEnabled(typeEnum.SlideShow) || this._isRotatorTypeEnabled(typeEnum.SlideShowButtons))
		{
			return true;
		}
		//All other modes
		return false;
	},


	//===================================================================================================================//
	isScrollingForward : function()
	{
		return this.isScrollingLeft() || this.isScrollingUp();
	},

	isScrollingLeft : function()
	{
		return this._isAnimationDirectionOn(Telerik.Web.UI.RotatorScrollDirection.Left);
	},

	isScrollingUp : function()
	{
		return this._isAnimationDirectionOn(Telerik.Web.UI.RotatorScrollDirection.Up);
	},


	_isAnimationDirectionOn : function(animDir)
	{
		return animDir == this.get_animationDirection() ? true : false;
	},

	//===================================================================================================================//


	_enableDisableButtons : function()
	{
		//If no buttons, return
		if (this._rotatorType == Telerik.Web.UI.RotatorType.AutomaticAdvance) return;

		//If wrapFrames - enable buttons
		var wrapFrames = this.get_wrapFrames();

		var directionEnum = Telerik.Web.UI.RotatorScrollDirection;

		//Check if there is at least one more 'go' into a direction and enable a button, disable it if it is not possible to scroll more.
		this._enableButton(this._rightButton, wrapFrames || this._canSlideMore(directionEnum.Left));
		this._enableButton(this._leftButton, wrapFrames || this._canSlideMore(directionEnum.Right));
		this._enableButton(this._downButton, wrapFrames || this._canSlideMore(directionEnum.Up));
		this._enableButton(this._upButton, wrapFrames || this._canSlideMore(directionEnum.Down));
	},


	_enableButton : function(button, toEnable)
	{
		if (!button) return;

		if (toEnable)
		{
			//Removed disabled class
			Sys.UI.DomElement.removeCssClass(button, this._rotatorButtonDisabledClass);
			button.removeAttribute("disabled");
		}
		else
		{
			//Add disabled class
			Sys.UI.DomElement.addCssClass(button, this._rotatorButtonDisabledClass);
			button.setAttribute("disabled", "disabled");
		}
	},


	_canSlideMore : function(direction)
	{
		//If no direction is set, use the currently set
		if (null == direction) direction = this.get_animationDirection();

		//Right - if list.left < 0
		//Left - if list.width + list.left > port.width
		//Down - if list.top < 0
		//Up - if list.height + list.top > port.height
		var canSlide = false;
		var listElement = this._itemsElement;
		var viewPort = this._clipElement;
		var directionEnum = Telerik.Web.UI.RotatorScrollDirection;

		var listLeft = parseInt(listElement.style.left);
		var listTop = parseInt(listElement.style.top);
		var listBounds = $telerik.getBounds(listElement);

		var viewPortBounds = $telerik.getBounds(viewPort);

		if (direction == directionEnum.Left)
		{
			canSlide = (listBounds.width + listLeft) > viewPortBounds.width;
		}
		else if (direction == directionEnum.Up)
		{
			canSlide = (listBounds.height + listTop) > viewPortBounds.height;
		}
		else if (direction == directionEnum.Right)
		{
			canSlide = (listLeft < 0);
		}
		else if (direction == directionEnum.Down)
		{
			canSlide = (listTop < 0);
		}

		return canSlide;
	},

	_getCalculatedAnimationDirection : function()
	{
		var animationDir = this.get_animationDirection();
		//These animations are declared in RadToolTip and are used in all TelerikAnimations
		//TopCenter : 12,
		//MiddleRight : 21,
		//MiddleLeft : 23,
		//BottomCenter : 32,
		var directionEnum = Telerik.Web.UI.RotatorScrollDirection;
		var direction = 23;

		switch (animationDir)
		{
			case directionEnum.Left: direction = 21; break;
			case directionEnum.Down: direction = 32; break;
			case directionEnum.Up: direction = 12; break;
			default: direction = 23;
		}
		return direction;
	},


	startAutoPlay : function()
	{
		//Set the default frame before you start animation for the first time
		this._loadInitialFrame();

		//Start animation!
		this.showNext(this.get_defaultAnimationDirection());
	},

	get_defaultAnimationDirection : function()
	{
		//Get the first possible enabled direction

		var directionEnum = Telerik.Web.UI.RotatorScrollDirection;
		var dir = 0;

		if (this._isScrollDirectionEnabled(directionEnum.Left))
		{
			dir = directionEnum.Left;
		}
		else if (this._isScrollDirectionEnabled(directionEnum.Up))
		{
			dir = directionEnum.Up;
		}
		else if (this._isScrollDirectionEnabled(directionEnum.Right))
		{
			dir = directionEnum.Right;
		}
		else if (this._isScrollDirectionEnabled(directionEnum.Down))
		{
			dir = directionEnum.Down;
		}
		if (!dir) dir = directionEnum.Left;

		return dir;
	},

	get_containerElement : function()
	{
		return this._itemsElement;
	},


	_setChildElements : function()
	{
		//================== Class names - define for easy change ===========================//
		this._rotatorListClass = "radr_itemsList";
		this._rotatorVerticalClass = "radr_verticalList";
		this._rotatorRelativeWrapperClass = "radr_relativeWrapper";
		this._rotatorClipRegionClass = "radr_clipRegion";
		this._rotatorRightClass = "radr_buttonRight";
		this._rotatorLeftClass = "radr_buttonLeft";
		this._rotatorDownClass = "radr_buttonDown";
		this._rotatorUpClass = "radr_buttonUp";
		this._rotatorButtonDisabledClass = "radr_buttonDisabled";

		//======================Get HTML elements that were rendered from the server==================================//
		this._rootElement = this.get_element();

		//Get relativeWrapper that holds the clip list
		this._relativeWrapper = $telerik.getElementByClassName(this._rootElement, this._rotatorRelativeWrapperClass);

		//Get the clip region element
		this._clipElement = $telerik.getElementByClassName(this._rootElement, this._rotatorClipRegionClass);

		//Get the list of items element
		this._itemsElement = $telerik.getElementByClassName(this._rootElement, this._rotatorListClass);

	},

	_createUI : function()
	{
		if (!this.isVisible())
		{
			//do not calculate the rotator size if it is not visible yet
			return;
		}

		//Set explicit size for the viewport!
		var rootElement = this.get_element();
		var relativeWrapper = this._relativeWrapper;
		var clipRegion = this._clipElement;

		relativeWrapper.style.height = rootElement.offsetHeight + "px";
		relativeWrapper.style.width = rootElement.offsetWidth + "px";

		//Create buttons
		//See if type is buttons, and we need buttons or it sAutomaticAdvance
		var hideBorder = true;
		if (this._isRotatorTypeEnabled(Telerik.Web.UI.RotatorType.Buttons) ||
			this._isRotatorTypeEnabled(Telerik.Web.UI.RotatorType.ButtonsOver) ||
			this._isRotatorTypeEnabled(Telerik.Web.UI.RotatorType.SlideShowButtons)
		)
		{
			//Here we need to know whether to hide the border
			hideBorder = this._initializeButtonsRotatorType();
		}

		if (hideBorder) Sys.UI.DomElement.addCssClass(rootElement, "radr_noBorder");

		//Set the proper list orientation for the scrolling
		if (this.get_vertical())
		{
			this.set_vertical(true);
		}

		//Set relativeWrapper overlow to auto for a while to calculate list size
		relativeWrapper.style.overflow = "auto";

		//The list size calculation happens here
		//Set overflow to auto
		clipRegion.style.overflow = "auto";
		//Set huge width (and height if the list is vertical) so that its size can be calculated OK
		clipRegion.style.width = "10000px";
		clipRegion.style.height = "10000px";

		//Set the width and height of the list element
		//NEW: Because of bug in rendering in IE6 and IE7 we need to set the width of the vertical list to be as wide as the VIEWPORT!
		this._itemsElement.style.width = this.get_vertical() ? relativeWrapper.style.width : this._itemsElement.offsetWidth + "px";
		//this._itemsElement.style.width = this.get_vertical() ? "1px": this._itemsElement.offsetWidth + "px";
		this._itemsElement.style.height = this._itemsElement.offsetHeight + "px";

		//Restore things
		//Fix element sized and overflows, calculations are complete!
		relativeWrapper.style.overflow = "";
		clipRegion.style.width = relativeWrapper.style.width;
		clipRegion.style.height = relativeWrapper.style.height;

		//Finish the element setup!
		//Hide the overflow of the clip region
		clipRegion.style.overflow = "hidden";
		//IE6 seems to have a problem with parent not being relative
		clipRegion.style.position = "relative";

		//Set position to relative/absolute to the list as well!
		this._itemsElement.style.position = "relative";

		//Make visible - last thing you do after all initialization is complete
		rootElement.style.visibility = "visible";
	},

	_createButton : function(baseElement, className)
	{
		var elem = baseElement;
		if (!elem)
		{
			elem = document.createElement("div");
		}

		if (!elem.className) elem.className = this._rotatorDownClass;
		return elem;
	},


	//A method that says if a button is enabled by using its containsCssClass method da checkva za disabled. I ako e disabled, clicka mu nishto ne pravi
	_isButtonDisabled : function(button)
	{
		if (!button) return true; //we consider a non-existent button to be disabled
		return Sys.UI.DomElement.containsCssClass(button, this._rotatorButtonDisabledClass);
	},

	_isScrollDirectionEnabled : function(scrollDir)
	{
		//return true;
		return scrollDir & this._scrollDirection ? true : false;
	},

	_isRotatorTypeEnabled : function(type)
	{
		return type == this._rotatorType ? true : false;
	},

	//================================= TEKI: New props (or modified existing props ==================================//
	//Sets a property how the rotator will render and what options the user will have for interacting with it on the client.
	get_rotatorType : function()
	{
		return this._rotatorType;
	},
	set_rotatorType : function(value)
	{
		this._rotatorType = value;
	},


	//Sets a property whether frames should wrap after the rotator scrolls to the end
	get_wrapFrames : function()
	{
		return this._wrapFrames;
	},
	set_wrapFrames : function(value)
	{
		this._wrapFrames = value;
	},


	//Duration is the time it takes for one length of the rotator to be scrolled! Thus we can calculate time it takes for any lenght of items
	//When in slideshow mode, scroll duration is set to 1 - instant item move without animation
	get_scrollDuration : function()
	{
		if (this.isSlideShow())
		{
			return 1;
		}
		else
		{
			return this._scrollDuration;
		}
	},

	set_scrollDuration : function(value)
	{
		this._scrollDuration = value;
	},

	set_vertical : function(value)
	{
		//If UI is created set it
		if (this._itemsElement)
		{
			Sys.UI.DomElement.addCssClass(this._itemsElement, this._rotatorVerticalClass);
		}
	},

	get_vertical : function()
	{
		//Vertical is always when developer specified Down or Up or both scrollDirections
		var directionEnum = Telerik.Web.UI.RotatorScrollDirection;
		return (this._isScrollDirectionEnabled(directionEnum.Down) || this._isScrollDirectionEnabled(directionEnum.Up));
	},

	isVertical : function()
	{
		if (this._itemsElement) return Sys.UI.DomElement.containsCssClass(this._itemsElement, this._rotatorVerticalClass);
		return false;
	},

	get_height : function()
	{
		return this.get_element().style.height;
	},

	set_height : function(value)
	{
		this.get_element().style.height = value;
		if (this.isVisible())
		{
			this.repaint();
		}
	},

	get_width : function()
	{
		return this.get_element().style.width;
	},
	set_width : function(value)
	{
		this.get_element().style.width = value;
		if (this.isVisible())
		{
			this.repaint();
		}
	},

	get_scrollDirection : function()
	{
		return this._scrollDirection;
	},

	set_scrollDirection : function(value)
	{
		this._scrollDirection = value;
	},

	get_frameDuration : function()
	{
		return this._frameDuration;
	},

	set_frameDuration : function(value)
	{
		this._frameDuration = value;
	},

	get_controlButtons : function()
	{
		return this._controlButtons;
	},

	set_controlButtons : function(value)
	{
		this._controlButtons = value;
	},

	get_initialItemIndex : function()
	{
		return this._initialItemIndex;
	},

	set_initialItemIndex : function(value)
	{
		this._initialItemIndex = value;
	},

	get_slideShowAnimationSettings : function()
	{
		return this._slideShowAnimationSettings;
	},

	set_slideShowAnimationSettings : function(value)
	{
		this._slideShowAnimationSettings = value;
	},


	//Client-side property only - set by buttons or code
	set_animationDirection : function(animationDir)
	{
		this._animationDirection = animationDir ? animationDir : Telerik.Web.UI.RotatorScrollDirection.Left;
	},

	get_animationDirection : function()
	{
		return this._animationDirection;
	},
	//================================== /TEKI ==========================================================//

	_attachEvents : function(toAttach)
	{
		//click, mouseover, mouseout
		var containerElement = this.get_containerElement();
		if (null == containerElement)
		{
			return;
		}

		if (toAttach != false)
		{
			this._clickDelegate = Function.createDelegate(this, this._mouseClickHandler);
			this._mouseOutDelegate = Function.createDelegate(this, this._mouseOutHandler);
			this._mouseOverDelegate = Function.createDelegate(this, this._mouseOverHandler);
			$addHandler(containerElement, "mouseover", this._mouseOverDelegate);
			$addHandler(containerElement, "mouseout", this._mouseOutDelegate);
			$addHandler(containerElement, "click", this._clickDelegate);
		}
		else
		{
			$removeHandler(containerElement, "mouseover", this._mouseOverDelegate);
			$removeHandler(containerElement, "mouseout", this._mouseOutDelegate);
			$removeHandler(containerElement, "click", this._clickDelegate);
			this._clickDelegate = null;
			this._mouseOutDelegate = null;
			this._mouseOverDelegate = null;
		}
	},

	_mouseOverHandler : function(args)
	{
		if (this.isAutomaticAdvance() && this._canPause)
		{
			//Pause animation
			this.pause();
		}

		var realTarget = this._getItemFromEvent(args.target);
		if (null != realTarget)
		{
			this.raiseEvent("mouseOver", new Telerik.Web.UI.RadRotatorEventArgs(realTarget));
		}
	},

	_mouseOutHandler : function(args)
	{
		if (this.isAutomaticAdvance() && this._canPause)
		{
			//Resume animation
			this.resume();
		}

		var realTarget = this._getItemFromEvent(args.target);
		if (null != realTarget)
		{
			this.raiseEvent("mouseOut", new Telerik.Web.UI.RadRotatorEventArgs(realTarget));
		}
	},

	_mouseClickHandler : function(args)
	{
		var realTarget = this._getItemFromEvent(args.target);
		if (null != realTarget)
		{
			var clickingArgs = new Telerik.Web.UI.RadRotatorCancelEventArgs(realTarget);
			this.raiseEvent("itemClicking", clickingArgs);
			if (clickingArgs.get_cancel && clickingArgs.get_cancel())
			{
				$telerik.cancelRawEvent(args.rawEvent);
				return false;
			}
			window.setTimeout(Function.createDelegate(this, function()
			{
				this.raiseEvent("itemClicked", new Telerik.Web.UI.RadRotatorEventArgs(realTarget));
				this._postback(realTarget.get_index());
			}), 0);
		}
	},

	_postback : function(itemIndex)
	{
		if (!this._postBackReference)
			return;
		var postbackFunction = this._postBackReference.replace("arguments", itemIndex);
		eval(postbackFunction);
	},

	_getItemFromEvent : function(element)
	{
		var container = this.get_containerElement();
		var frame = null;
		while (null != element && element != container)
		{
			if (element.tagName.toLowerCase() == "li" && null != element._item && Object.getTypeName(element._item) == "Telerik.Web.UI.RadRotatorItem")
				frame = element._item;
			element = element.parentNode;
		}
		return frame;
	},

	_initializeWebServiceLoader : function()
	{
		this._webServiceLoader = new Telerik.Web.UI.WebServiceLoader(this.get_webServiceSettings());
		this._webServiceLoader.add_loadingStarted(Function.createDelegate(this, this._onItemLoadingStarted));
		this._webServiceLoader.add_loadingSuccess(Function.createDelegate(this, this._onItemLoadingSuccess));
		this._webServiceLoader.add_loadingError(Function.createDelegate(this, this._onItemLoadingError));
	},

	_loadChildrenFromWebService : function(itemIndex, itemCount)
	{
		if (!this._webServiceLoader)
		{
			this._initializeWebServiceLoader();
		}

		var params = { itemIndex: itemIndex, itemCount: itemCount };
		this._webServiceLoader.loadData(params, params);
	},

	_onItemLoadingStarted : function(sender, eventArgs)
	{
		//item.showloading
	},

	_onItemLoadingSuccess : function(sender, eventArgs)
	{
		var result = eventArgs.get_data();
		if (result && result.length > 0)
		{
			for (var i = 0; i < result.length; i++)
			{
				this.createRotatorItem(result[i]);
			}
		}
		//item.hideloading
		//item.show
	},

	_onItemLoadingError : function(sender, eventArgs)
	{
		var errorMessage = eventArgs.get_message();
		alert(errorMessage);
	},

	createRotatorItem : function(radRotatorItemData)
	{
		var container = this.get_containerElement();
		var listItem = container.ownerDocument.createElement("li");
		container.appendChild(listItem);
		listItem.innerHTML = radRotatorItemData.Html;
		var args = { cssClass: radRotatorItemData.CssClass, visible: radRotatorItemData.Visible };
		var rotatorItem = $create(Telerik.Web.UI.RadRotatorItem, args, null, null, listItem);
		listItem._item = rotatorItem;
		Array.add(this.get_items(), rotatorItem);
	},

	_getInvisibleParent : function()
	{
		var parent = this.get_element();
		while (parent && parent != document)
		{
			if ("none" == $telerik.getCurrentStyle(parent, "display", ""))
			{
				return parent;
			}
			parent = parent.parentNode;
		}
		return null;
	},

	isVisible : function()
	{
		//we are visible if no invisible parent exists
		return (this._getInvisibleParent() == null);
	},

	_fixVisibilityProblems : function(toAttach)
	{
		if (toAttach)
		{
			var parent = this._getInvisibleParent();
			if (parent)
			{
				this._onParentVisibilityChangeDelegate = Function.createDelegate(this, this._onParentVisibilityChange);
				this._invisibleParent = parent;
				if ($telerik.isIE)
				{
					$addHandler(this._invisibleParent, "propertychange", this._onParentVisibilityChangeDelegate);
				}
				else
				{
					this._invisibleParent.addEventListener("DOMAttrModified", this._onParentVisibilityChangeDelegate, false);
				}
			}
		}
		else
		{
			if (this._invisibleParent && this._onParentVisibilityChangeDelegate)
			{
				if ($telerik.isIE)
				{
					$removeHandler(this._invisibleParent, "propertychange", this._onParentVisibilityChangeDelegate);
				}
				else
				{
					this._invisibleParent.removeEventListener("DOMAttrModified", this._onParentVisibilityChangeDelegate, false);
				}
				this._onParentVisibilityChangeDelegate = null;
				this._invisibleParent = null;
			}
		}
	},

	_onParentVisibilityChange : function(e)
	{
		if ($telerik.isIE)
		{
			var e = e.rawEvent; //e is a fake MS AJAX event wrapper that misses important info!
			if (!e) return;
			if (e.propertyName == "style.display" || e.propertyName == "className")
			{
				//Update the size only once - the first time the parent is shown, and then never again!
				var display = $telerik.getCurrentStyle(this._invisibleParent, "display");
				if (display != "none")
				{
					this.repaint();
				}
			}
		}
		else
		{
			if (e.attrName == "style" || e.attrName == "class")//! class must be used, not className!!!!
			{
				var element = e.target;
				if ((e.currentTarget == e.originalTarget) && "none" != $telerik.getCurrentStyle(element, "display"))
				{
					//Timeout is needed as in fact the event is raised before actual changes are rendered
					window.setTimeout(Function.createDelegate(this, function() { this.repaint(); }), 0);
				}
			}
		}
		this._fixVisibilityProblems(false);
	},

	repaint : function()
	{
		this._createUI();
	},

	add_itemClicking : function(handler)
	{
		this.get_events().addHandler("itemClicking", handler);
	},

	remove_itemClicking : function(handler)
	{
		this.get_events().removeHandler("itemClicking", handler);
	},

	add_itemClicked : function(handler)
	{
		this.get_events().addHandler("itemClicked", handler);
	},

	remove_itemClicked : function(handler)
	{
		this.get_events().removeHandler("itemClicked", handler);
	},

	add_mouseOver : function(handler)
	{
		this.get_events().addHandler("mouseOver", handler);
	},

	remove_mouseOver : function(handler)
	{
		this.get_events().removeHandler("mouseOver", handler);
	},

	add_mouseOut : function(handler)
	{
		this.get_events().addHandler("mouseOut", handler);
	},

	remove_mouseOut : function(handler)
	{
		this.get_events().removeHandler("mouseOut", handler);
	},

	add_itemShowing : function(handler)
	{
		this.get_events().addHandler("itemShowing", handler);
	},

	remove_itemShowing : function(handler)
	{
		this.get_events().removeHandler("itemShowing", handler);
	},

	add_itemShown : function(handler)
	{
		this.get_events().addHandler("itemShown", handler);
	},

	remove_itemShown : function(handler)
	{
		this.get_events().removeHandler("itemShown", handler);
	},

	add_load : function(handler)
	{
		this.get_events().addHandler("load", handler);
	},

	remove_load : function(handler)
	{
		this.get_events().removeHandler("load", handler);
	},

	add_buttonOver : function(handler)
	{
		this.get_events().addHandler("buttonOver", handler);
	},

	remove_buttonOver : function(handler)
	{
		this.get_events().removeHandler("buttonOver", handler);
	},

	add_buttonOut : function(handler)
	{
		this.get_events().addHandler("buttonOut", handler);
	},

	remove_buttonOut : function(handler)
	{
		this.get_events().removeHandler("buttonOut", handler);
	},

	add_buttonClick : function(handler)
	{
		this.get_events().addHandler("buttonClick", handler);
	},

	remove_buttonClick : function(handler)
	{
		this.get_events().removeHandler("buttonClick", handler);
	},

	get_items : function()
	{
		return this._items;
	},

	set_items : function(value)
	{
		this._items = value;
	},

	get_webServiceSettings : function()
	{
		return this._webServiceSettings;
	},

	set_webServiceSettings : function(value)
	{
		var deserializedWebServiceSettings = Sys.Serialization.JavaScriptSerializer.deserialize(value);
		this._webServiceSettings = new Telerik.Web.UI.WebServiceSettings(deserializedWebServiceSettings);
	},

	get_skin : function()
	{
		return this._skin;
	},

	set_skin : function(value)
	{
		this._skin = value;
	}
}

Telerik.Web.UI.RadRotator.registerClass("Telerik.Web.UI.RadRotator", Telerik.Web.UI.RadWebControl);

Telerik.Web.UI.RadRotatorEventArgs = function(item)
{
	Telerik.Web.UI.RadRotatorEventArgs.initializeBase(this);
	this._item = item;
}

Telerik.Web.UI.RadRotatorEventArgs.prototype =
{
	get_item : function()
	{
		return this._item;
	}
}

Telerik.Web.UI.RadRotatorEventArgs.registerClass("Telerik.Web.UI.RadRotatorEventArgs", Sys.EventArgs);


Telerik.Web.UI.RadRotatorCancelEventArgs = function(item)
{
	Telerik.Web.UI.RadRotatorCancelEventArgs.initializeBase(this);
	this._item = item;
}

Telerik.Web.UI.RadRotatorCancelEventArgs.prototype =
{
	get_item : function()
	{
		return this._item;
	}
}

Telerik.Web.UI.RadRotatorCancelEventArgs.registerClass("Telerik.Web.UI.RadRotatorCancelEventArgs", Sys.CancelEventArgs);


Telerik.Web.UI.RadRotatorButtonEventArgs = function(button)
{
	Telerik.Web.UI.RadRotatorButtonEventArgs.initializeBase(this);
	this._button = button;
}

Telerik.Web.UI.RadRotatorButtonEventArgs.prototype =
{
	get_button : function()
	{
		return this._button;
	}
}

Telerik.Web.UI.RadRotatorButtonEventArgs.registerClass("Telerik.Web.UI.RadRotatorButtonEventArgs", Sys.CancelEventArgs);

Telerik.Web.UI.RadRotatorItem = function(element)
{
	Telerik.Web.UI.RadRotatorItem.initializeBase(this, [element]);
	this._visible = null;
	this._cssClass = null;
	this._index = -1;
}

Telerik.Web.UI.RadRotatorItem.prototype =
{
	initialize : function()
	{
		Telerik.Web.UI.RadRotatorItem.callBaseMethod(this, "initialize");
	},

	dispose : function()
	{
		Telerik.Web.UI.RadRotatorItem.callBaseMethod(this, "dispose");
	},

	get_index : function()
	{
		if (this._index == -1)
		{
			var index = 0;
			var element = this.get_element();
			var parent = element.parentNode;
			if (null != parent)
			{
				var siblings = $telerik.getChildrenByTagName(parent, "li");
				if (null != siblings)
				{
					for (index=0; index<siblings.length && siblings[index] != element;index++);
					if (index == siblings.length)
					{
						index = 0;
					}
				}
			}
			this._index = index;
		}
		return this._index;
	},

	get_visible : function()
	{
		return this._visible;
	},

	set_visible : function(value)
	{
		this._visible = value;
	},

	get_cssClass : function()
	{
		return this._cssClass;
	},

	set_cssClass : function(value)
	{
		this._cssClass = value;
	}
}

Telerik.Web.UI.RadRotatorItem.registerClass("Telerik.Web.UI.RadRotatorItem", Sys.UI.Control);

//=========================================== TEKI ================================================//
Telerik.Web.UI.RotatorScrollDirection = function() {
	/// <summary>
	/// Used to determine the possible scroll directions for a rotator.
	/// </summary>
	/// <field name="Left" type="Number" integer="true" />
	/// <field name="Right" type="Number" integer="true" />
	/// <field name="Up" type="Number" integer="true" />
	/// <field name="Down" type="Number" integer="true" />
	throw Error.invalidOperation();
}
Telerik.Web.UI.RotatorScrollDirection.prototype =
{
	Left: 1,
	Right : 2,
	Up: 4,
	Down : 8
};

Telerik.Web.UI.RotatorScrollDirection.registerEnum("Telerik.Web.UI.RotatorScrollDirection", false);

Telerik.Web.UI.RotatorAnimationType = function() {
	/// <summary>
	/// Used to determine the possible slide show animations of a rotator.
	/// </summary>
	/// <field name="None" type="Number" integer="true" />
	/// <field name="Fade" type="Number" integer="true" />
	/// <field name="Pulse" type="Number" integer="true" />
	throw Error.invalidOperation();
}
Telerik.Web.UI.RotatorAnimationType.prototype =
{
	None: 1,
	Fade : 2,
	Pulse: 3
};

Telerik.Web.UI.RotatorAnimationType.registerEnum("Telerik.Web.UI.RotatorAnimationType", false);

Telerik.Web.UI.RotatorType = function() {
	/// <summary>
	/// Used to determine the rotator type
	/// </summary>
	/// <field name="Buttons" type="Number" integer="true" />
	/// <field name="ButtonsOver" type="Number" integer="true" />
	/// <field name="AutomaticAdvance" type="Number" integer="true" />
	/// <field name="SlideShow" type="Number" integer="true" />
	/// <field name="SlideShowButtons" type="Number" integer="true" />
	/// <field name="FromCode" type="Number" integer="true" />
	throw Error.invalidOperation();
}
Telerik.Web.UI.RotatorType.prototype =
{
	AutomaticAdvance : 1,
	ButtonsOver : 2,
	Buttons : 3,
	SlideShow : 4,
	SlideShowButtons : 5,
	FromCode : 6
};

Telerik.Web.UI.RotatorType.registerEnum("Telerik.Web.UI.RotatorType", false);

/* END Telerik.Web.UI.Rotator.RadRotator.js */
if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();
(function() {var fn = function() {$get('ctl00_radScriptManager_HiddenField').value += ';;System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35:it:0d787d5c-3903-4814-ad72-296cea810318:52817a7d;Telerik.Web.UI, Version=2008.2.1001.0, Culture=neutral, PublicKeyToken=29ac1a93ec063d92:it:60087bd8-1047-43ee-968e-e1b45267bf8e:393f5085:9de5f1c7:f336b905:abac4838';Sys.Application.remove_load(fn);};Sys.Application.add_load(fn);})();
