// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// Contributors:
// Justin Palmer (http://encytemedia.com/)
// Mark Pilgrim (http://diveintomark.org/)
// Martin Bialasinki
// 
// script.aculo.us is freely distributable under the terms of an MIT-style license.
// For details, see the script.aculo.us web site: http://script.aculo.us/ 

// converts rgb() and #xxx to #xxxxxx format, 
// returns self (or first argument) if not convertable 
String.prototype.parseColor = function() { 
 var color = '#';
 if (this.slice(0,4) == 'rgb(') { 
 var cols = this.slice(4,this.length-1).split(','); 
 var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3); 
 } else { 
 if (this.slice(0,1) == '#') { 
 if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase(); 
 if (this.length==7) color = this.toLowerCase(); 
 } 
 } 
 return (color.length==7 ? color : (arguments[0] || this)); 
};

/*--------------------------------------------------------------------------*/

Element.collectTextNodes = function(element) { 
 return $A($(element).childNodes).collect( function(node) {
 return (node.nodeType==3 ? node.nodeValue : 
 (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
 }).flatten().join('');
};

Element.collectTextNodesIgnoreClass = function(element, className) { 
 return $A($(element).childNodes).collect( function(node) {
 return (node.nodeType==3 ? node.nodeValue : 
 ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? 
 Element.collectTextNodesIgnoreClass(node, className) : ''));
 }).flatten().join('');
};

Element.setContentZoom = function(element, percent) {
 element = $(element); 
 element.setStyle({fontSize: (percent/100) + 'em'}); 
 if (Prototype.Browser.WebKit) window.scrollBy(0,0);
 return element;
};

Element.getInlineOpacity = function(element){
 return $(element).style.opacity || '';
};

Element.forceRerendering = function(element) {
 try {
 element = $(element);
 var n = document.createTextNode(' ');
 element.appendChild(n);
 element.removeChild(n);
 } catch(e) { }
};

/*--------------------------------------------------------------------------*/

var Effect = {
 _elementDoesNotExistError: {
 name: 'ElementDoesNotExistError',
 message: 'The specified DOM element does not exist, but is required for this effect to operate'
 },
 Transitions: {
 linear: Prototype.K,
 sinoidal: function(pos) {
 return (-Math.cos(pos*Math.PI)/2) + 0.5;
 },
 reverse: function(pos) {
 return 1-pos;
 },
 flicker: function(pos) {
 var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
 return pos > 1 ? 1 : pos;
 },
 wobble: function(pos) {
 return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
 },
 pulse: function(pos, pulses) { 
 pulses = pulses || 5; 
 return (
 ((pos % (1/pulses)) * pulses).round() == 0 ? 
 ((pos * pulses * 2) - (pos * pulses * 2).floor()) : 
 1 - ((pos * pulses * 2) - (pos * pulses * 2).floor())
 );
 },
 spring: function(pos) { 
 return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6)); 
 },
 none: function(pos) {
 return 0;
 },
 full: function(pos) {
 return 1;
 }
 },
 DefaultOptions: {
 duration: 1.0, // seconds
 fps: 100, // 100= assume 66fps max.
 sync: false, // true for combining
 from: 0.0,
 to: 1.0,
 delay: 0.0,
 queue: 'parallel'
 },
 tagifyText: function(element) {
 var tagifyStyle = 'position:relative';
 if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';
 
 element = $(element);
 $A(element.childNodes).each( function(child) {
 if (child.nodeType==3) {
 child.nodeValue.toArray().each( function(character) {
 element.insertBefore(
 new Element('span', {style: tagifyStyle}).update(
 character == ' ' ? String.fromCharCode(160) : character), 
 child);
 });
 Element.remove(child);
 }
 });
 },
 multiple: function(element, effect) {
 var elements;
 if (((typeof element == 'object') || 
 Object.isFunction(element)) && 
 (element.length))
 elements = element;
 else
 elements = $(element).childNodes;
 
 var options = Object.extend({
 speed: 0.1,
 delay: 0.0
 }, arguments[2] || { });
 var masterDelay = options.delay;

 $A(elements).each( function(element, index) {
 new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
 });
 },
 PAIRS: {
 'slide': ['SlideDown','SlideUp'],
 'blind': ['BlindDown','BlindUp'],
 'appear': ['Appear','Fade']
 },
 toggle: function(element, effect) {
 element = $(element);
 effect = (effect || 'appear').toLowerCase();
 var options = Object.extend({
 queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
 }, arguments[2] || { });
 Effect[element.visible() ? 
 Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
 }
};

Effect.DefaultOptions.transition = Effect.Transitions.sinoidal;

/* ------------- core effects ------------- */

Effect.ScopedQueue = Class.create(Enumerable, {
 initialize: function() {
 this.effects = [];
 this.interval = null; 
 },
 _each: function(iterator) {
 this.effects._each(iterator);
 },
 add: function(effect) {
 var timestamp = new Date().getTime();
 
 var position = Object.isString(effect.options.queue) ? 
 effect.options.queue : effect.options.queue.position;
 
 switch(position) {
 case 'front':
 // move unstarted effects after this effect 
 this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
 e.startOn += effect.finishOn;
 e.finishOn += effect.finishOn;
 });
 break;
 case 'with-last':
 timestamp = this.effects.pluck('startOn').max() || timestamp;
 break;
 case 'end':
 // start effect after last queued effect has finished
 timestamp = this.effects.pluck('finishOn').max() || timestamp;
 break;
 }
 
 effect.startOn += timestamp;
 effect.finishOn += timestamp;

 if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
 this.effects.push(effect);
 
 if (!this.interval)
 this.interval = setInterval(this.loop.bind(this), 15);
 },
 remove: function(effect) {
 this.effects = this.effects.reject(function(e) { return e==effect });
 if (this.effects.length == 0) {
 clearInterval(this.interval);
 this.interval = null;
 }
 },
 loop: function() {
 var timePos = new Date().getTime();
 for(var i=0, len=this.effects.length;i<len;i++) 
 this.effects[i] && this.effects[i].loop(timePos);
 }
});

Effect.Queues = {
 instances: $H(),
 get: function(queueName) {
 if (!Object.isString(queueName)) return queueName;
 
 return this.instances.get(queueName) ||
 this.instances.set(queueName, new Effect.ScopedQueue());
 }
};
Effect.Queue = Effect.Queues.get('global');

Effect.Base = Class.create({
 position: null,
 start: function(options) {
 function codeForEvent(options,eventName){
 return (
 (options[eventName+'Internal'] ? 'this.options.'+eventName+'Internal(this);' : '') +
 (options[eventName] ? 'this.options.'+eventName+'(this);' : '')
 );
 }
 if (options && options.transition === false) options.transition = Effect.Transitions.linear;
 this.options = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { });
 this.currentFrame = 0;
 this.state = 'idle';
 this.startOn = this.options.delay*1000;
 this.finishOn = this.startOn+(this.options.duration*1000);
 this.fromToDelta = this.options.to-this.options.from;
 this.totalTime = this.finishOn-this.startOn;
 this.totalFrames = this.options.fps*this.options.duration;
 
 eval('this.render = function(pos){ '+
 'if (this.state=="idle"){this.state="running";'+
 codeForEvent(this.options,'beforeSetup')+
 (this.setup ? 'this.setup();':'')+ 
 codeForEvent(this.options,'afterSetup')+
 '};if (this.state=="running"){'+
 'pos=this.options.transition(pos)*'+this.fromToDelta+'+'+this.options.from+';'+
 'this.position=pos;'+
 codeForEvent(this.options,'beforeUpdate')+
 (this.update ? 'this.update(pos);':'')+
 codeForEvent(this.options,'afterUpdate')+
 '}}');
 
 this.event('beforeStart');
 if (!this.options.sync)
 Effect.Queues.get(Object.isString(this.options.queue) ? 
 'global' : this.options.queue.scope).add(this);
 },
 loop: function(timePos) {
 if (timePos >= this.startOn) {
 if (timePos >= this.finishOn) {
 this.render(1.0);
 this.cancel();
 this.event('beforeFinish');
 if (this.finish) this.finish(); 
 this.event('afterFinish');
 return; 
 }
 var pos = (timePos - this.startOn) / this.totalTime,
 frame = (pos * this.totalFrames).round();
 if (frame > this.currentFrame) {
 this.render(pos);
 this.currentFrame = frame;
 }
 }
 },
 cancel: function() {
 if (!this.options.sync)
 Effect.Queues.get(Object.isString(this.options.queue) ? 
 'global' : this.options.queue.scope).remove(this);
 this.state = 'finished';
 },
 event: function(eventName) {
 if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
 if (this.options[eventName]) this.options[eventName](this);
 },
 inspect: function() {
 var data = $H();
 for(property in this)
 if (!Object.isFunction(this[property])) data.set(property, this[property]);
 return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
 }
});

Effect.Parallel = Class.create(Effect.Base, {
 initialize: function(effects) {
 this.effects = effects || [];
 this.start(arguments[1]);
 },
 update: function(position) {
 this.effects.invoke('render', position);
 },
 finish: function(position) {
 this.effects.each( function(effect) {
 effect.render(1.0);
 effect.cancel();
 effect.event('beforeFinish');
 if (effect.finish) effect.finish(position);
 effect.event('afterFinish');
 });
 }
});

Effect.Tween = Class.create(Effect.Base, {
 initialize: function(object, from, to) {
 object = Object.isString(object) ? $(object) : object;
 var args = $A(arguments), method = args.last(), 
 options = args.length == 5 ? args[3] : null;
 this.method = Object.isFunction(method) ? method.bind(object) :
 Object.isFunction(object[method]) ? object[method].bind(object) : 
 function(value) { object[method] = value };
 this.start(Object.extend({ from: from, to: to }, options || { }));
 },
 update: function(position) {
 this.method(position);
 }
});

Effect.Event = Class.create(Effect.Base, {
 initialize: function() {
 this.start(Object.extend({ duration: 0 }, arguments[0] || { }));
 },
 update: Prototype.emptyFunction
});

Effect.Opacity = Class.create(Effect.Base, {
 initialize: function(element) {
 this.element = $(element);
 if (!this.element) throw(Effect._elementDoesNotExistError);
 // make this work on IE on elements without 'layout'
 if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
 this.element.setStyle({zoom: 1});
 var options = Object.extend({
 from: this.element.getOpacity() || 0.0,
 to: 1.0
 }, arguments[1] || { });
 this.start(options);
 },
 update: function(position) {
 this.element.setOpacity(position);
 }
});

Effect.Move = Class.create(Effect.Base, {
 initialize: function(element) {
 this.element = $(element);
 if (!this.element) throw(Effect._elementDoesNotExistError);
 var options = Object.extend({
 x: 0,
 y: 0,
 mode: 'relative'
 }, arguments[1] || { });
 this.start(options);
 },
 setup: function() {
 this.element.makePositioned();
 this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
 this.originalTop = parseFloat(this.element.getStyle('top') || '0');
 if (this.options.mode == 'absolute') {
 this.options.x = this.options.x - this.originalLeft;
 this.options.y = this.options.y - this.originalTop;
 }
 },
 update: function(position) {
 this.element.setStyle({
 left: (this.options.x * position + this.originalLeft).round() + 'px',
 top: (this.options.y * position + this.originalTop).round() + 'px'
 });
 }
});

// for backwards compatibility
Effect.MoveBy = function(element, toTop, toLeft) {
 return new Effect.Move(element, 
 Object.extend({ x: toLeft, y: toTop }, arguments[3] || { }));
};

Effect.Scale = Class.create(Effect.Base, {
 initialize: function(element, percent) {
 this.element = $(element);
 if (!this.element) throw(Effect._elementDoesNotExistError);
 var options = Object.extend({
 scaleX: true,
 scaleY: true,
 scaleContent: true,
 scaleFromCenter: false,
 scaleMode: 'box', // 'box' or 'contents' or { } with provided values
 scaleFrom: 100.0,
 scaleTo: percent
 }, arguments[2] || { });
 this.start(options);
 },
 setup: function() {
 this.restoreAfterFinish = this.options.restoreAfterFinish || false;
 this.elementPositioning = this.element.getStyle('position');
 
 this.originalStyle = { };
 ['top','left','width','height','fontSize'].each( function(k) {
 this.originalStyle[k] = this.element.style[k];
 }.bind(this));
 
 this.originalTop = this.element.offsetTop;
 this.originalLeft = this.element.offsetLeft;
 
 var fontSize = this.element.getStyle('font-size') || '100%';
 ['em','px','%','pt'].each( function(fontSizeType) {
 if (fontSize.indexOf(fontSizeType)>0) {
 this.fontSize = parseFloat(fontSize);
 this.fontSizeType = fontSizeType;
 }
 }.bind(this));
 
 this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
 
 this.dims = null;
 if (this.options.scaleMode=='box')
 this.dims = [this.element.offsetHeight, this.element.offsetWidth];
 if (/^content/.test(this.options.scaleMode))
 this.dims = [this.element.scrollHeight, this.element.scrollWidth];
 if (!this.dims)
 this.dims = [this.options.scaleMode.originalHeight,
 this.options.scaleMode.originalWidth];
 },
 update: function(position) {
 var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
 if (this.options.scaleContent && this.fontSize)
 this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
 this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
 },
 finish: function(position) {
 if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
 },
 setDimensions: function(height, width) {
 var d = { };
 if (this.options.scaleX) d.width = width.round() + 'px';
 if (this.options.scaleY) d.height = height.round() + 'px';
 if (this.options.scaleFromCenter) {
 var topd = (height - this.dims[0])/2;
 var leftd = (width - this.dims[1])/2;
 if (this.elementPositioning == 'absolute') {
 if (this.options.scaleY) d.top = this.originalTop-topd + 'px';
 if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
 } else {
 if (this.options.scaleY) d.top = -topd + 'px';
 if (this.options.scaleX) d.left = -leftd + 'px';
 }
 }
 this.element.setStyle(d);
 }
});

Effect.Highlight = Class.create(Effect.Base, {
 initialize: function(element) {
 this.element = $(element);
 if (!this.element) throw(Effect._elementDoesNotExistError);
 var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { });
 this.start(options);
 },
 setup: function() {
 // Prevent executing on elements not in the layout flow
 if (this.element.getStyle('display')=='none') { this.cancel(); return; }
 // Disable background image during the effect
 this.oldStyle = { };
 if (!this.options.keepBackgroundImage) {
 this.oldStyle.backgroundImage = this.element.getStyle('background-image');
 this.element.setStyle({backgroundImage: 'none'});
 }
 if (!this.options.endcolor)
 this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
 if (!this.options.restorecolor)
 this.options.restorecolor = this.element.getStyle('background-color');
 // init color calculations
 this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
 this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
 },
 update: function(position) {
 this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
 return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) });
 },
 finish: function() {
 this.element.setStyle(Object.extend(this.oldStyle, {
 backgroundColor: this.options.restorecolor
 }));
 }
});

Effect.ScrollTo = function(element) {
 var options = arguments[1] || { },
 scrollOffsets = document.viewport.getScrollOffsets(),
 elementOffsets = $(element).cumulativeOffset(),
 max = (window.height || document.body.scrollHeight) - document.viewport.getHeight(); 

 if (options.offset) elementOffsets[1] += options.offset;

 return new Effect.Tween(null,
 scrollOffsets.top,
 elementOffsets[1] > max ? max : elementOffsets[1],
 options,
 function(p){ scrollTo(scrollOffsets.left, p.round()) }
 );
};

/* ------------- combination effects ------------- */

Effect.Fade = function(element) {
 element = $(element);
 var oldOpacity = element.getInlineOpacity();
 var options = Object.extend({
 from: element.getOpacity() || 1.0,
 to: 0.0,
 afterFinishInternal: function(effect) { 
 if (effect.options.to!=0) return;
 effect.element.hide().setStyle({opacity: oldOpacity}); 
 }
 }, arguments[1] || { });
 return new Effect.Opacity(element,options);
};

Effect.Appear = function(element) {
 element = $(element);
 var options = Object.extend({
 from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
 to: 1.0,
 // force Safari to render floated elements properly
 afterFinishInternal: function(effect) {
 effect.element.forceRerendering();
 },
 beforeSetup: function(effect) {
 effect.element.setOpacity(effect.options.from).show(); 
 }}, arguments[1] || { });
 return new Effect.Opacity(element,options);
};

Effect.Puff = function(element) {
 element = $(element);
 var oldStyle = { 
 opacity: element.getInlineOpacity(), 
 position: element.getStyle('position'),
 top: element.style.top,
 left: element.style.left,
 width: element.style.width,
 height: element.style.height
 };
 return new Effect.Parallel(
 [ new Effect.Scale(element, 200, 
 { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), 
 new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], 
 Object.extend({ duration: 1.0, 
 beforeSetupInternal: function(effect) {
 Position.absolutize(effect.effects[0].element)
 },
 afterFinishInternal: function(effect) {
 effect.effects[0].element.hide().setStyle(oldStyle); }
 }, arguments[1] || { })
 );
};

Effect.BlindUp = function(element) {
 element = $(element);
 element.makeClipping();
 return new Effect.Scale(element, 0,
 Object.extend({ scaleContent: false, 
 scaleX: false, 
 restoreAfterFinish: true,
 afterFinishInternal: function(effect) {
 effect.element.hide().undoClipping();
 } 
 }, arguments[1] || { })
 );
};

Effect.BlindDown = function(element) {
 element = $(element);
 var elementDimensions = element.getDimensions();
 return new Effect.Scale(element, 100, Object.extend({ 
 scaleContent: false, 
 scaleX: false,
 scaleFrom: 0,
 scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
 restoreAfterFinish: true,
 afterSetup: function(effect) {
 effect.element.makeClipping().setStyle({height: '0px'}).show(); 
 }, 
 afterFinishInternal: function(effect) {
 effect.element.undoClipping();
 }
 }, arguments[1] || { }));
};

Effect.SwitchOff = function(element) {
 element = $(element);
 var oldOpacity = element.getInlineOpacity();
 return new Effect.Appear(element, Object.extend({
 duration: 0.4,
 from: 0,
 transition: Effect.Transitions.flicker,
 afterFinishInternal: function(effect) {
 new Effect.Scale(effect.element, 1, { 
 duration: 0.3, scaleFromCenter: true,
 scaleX: false, scaleContent: false, restoreAfterFinish: true,
 beforeSetup: function(effect) { 
 effect.element.makePositioned().makeClipping();
 },
 afterFinishInternal: function(effect) {
 effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
 }
 })
 }
 }, arguments[1] || { }));
};

Effect.DropOut = function(element) {
 element = $(element);
 var oldStyle = {
 top: element.getStyle('top'),
 left: element.getStyle('left'),
 opacity: element.getInlineOpacity() };
 return new Effect.Parallel(
 [ new Effect.Move(element, {x: 0, y: 100, sync: true }), 
 new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
 Object.extend(
 { duration: 0.5,
 beforeSetup: function(effect) {
 effect.effects[0].element.makePositioned(); 
 },
 afterFinishInternal: function(effect) {
 effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
 } 
 }, arguments[1] || { }));
};

Effect.Shake = function(element) {
 element = $(element);
 var options = Object.extend({
 distance: 20,
 duration: 0.5
 }, arguments[1] || {});
 var distance = parseFloat(options.distance);
 var split = parseFloat(options.duration) / 10.0;
 var oldStyle = {
 top: element.getStyle('top'),
 left: element.getStyle('left') };
 return new Effect.Move(element,
 { x: distance, y: 0, duration: split, afterFinishInternal: function(effect) {
 new Effect.Move(effect.element,
 { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
 new Effect.Move(effect.element,
 { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
 new Effect.Move(effect.element,
 { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
 new Effect.Move(effect.element,
 { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
 new Effect.Move(effect.element,
 { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) {
 effect.element.undoPositioned().setStyle(oldStyle);
 }}) }}) }}) }}) }}) }});
};

Effect.SlideDown = function(element) {
 element = $(element).cleanWhitespace();
 // SlideDown need to have the content of the element wrapped in a container element with fixed height!
 var oldInnerBottom = element.down().getStyle('bottom');
 var elementDimensions = element.getDimensions();
 return new Effect.Scale(element, 100, Object.extend({ 
 scaleContent: false, 
 scaleX: false, 
 scaleFrom: window.opera ? 0 : 1,
 scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
 restoreAfterFinish: true,
 afterSetup: function(effect) {
 effect.element.makePositioned();
 effect.element.down().makePositioned();
 if (window.opera) effect.element.setStyle({top: ''});
 effect.element.makeClipping().setStyle({height: '0px'}).show(); 
 },
 afterUpdateInternal: function(effect) {
 effect.element.down().setStyle({bottom:
 (effect.dims[0] - effect.element.clientHeight) + 'px' }); 
 },
 afterFinishInternal: function(effect) {
 effect.element.undoClipping().undoPositioned();
 effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
 }, arguments[1] || { })
 );
};

Effect.SlideUp = function(element) {
 element = $(element).cleanWhitespace();
 var oldInnerBottom = element.down().getStyle('bottom');
 var elementDimensions = element.getDimensions();
 return new Effect.Scale(element, window.opera ? 0 : 1,
 Object.extend({ scaleContent: false, 
 scaleX: false, 
 scaleMode: 'box',
 scaleFrom: 100,
 scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
 restoreAfterFinish: true,
 afterSetup: function(effect) {
 effect.element.makePositioned();
 effect.element.down().makePositioned();
 if (window.opera) effect.element.setStyle({top: ''});
 effect.element.makeClipping().show();
 }, 
 afterUpdateInternal: function(effect) {
 effect.element.down().setStyle({bottom:
 (effect.dims[0] - effect.element.clientHeight) + 'px' });
 },
 afterFinishInternal: function(effect) {
 effect.element.hide().undoClipping().undoPositioned();
 effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom});
 }
 }, arguments[1] || { })
 );
};

// Bug in opera makes the TD containing this element expand for a instance after finish 
Effect.Squish = function(element) {
 return new Effect.Scale(element, window.opera ? 1 : 0, { 
 restoreAfterFinish: true,
 beforeSetup: function(effect) {
 effect.element.makeClipping(); 
 }, 
 afterFinishInternal: function(effect) {
 effect.element.hide().undoClipping(); 
 }
 });
};

Effect.Grow = function(element) {
 element = $(element);
 var options = Object.extend({
 direction: 'center',
 moveTransition: Effect.Transitions.sinoidal,
 scaleTransition: Effect.Transitions.sinoidal,
 opacityTransition: Effect.Transitions.full
 }, arguments[1] || { });
 var oldStyle = {
 top: element.style.top,
 left: element.style.left,
 height: element.style.height,
 width: element.style.width,
 opacity: element.getInlineOpacity() };

 var dims = element.getDimensions(); 
 var initialMoveX, initialMoveY;
 var moveX, moveY;
 
 switch (options.direction) {
 case 'top-left':
 initialMoveX = initialMoveY = moveX = moveY = 0; 
 break;
 case 'top-right':
 initialMoveX = dims.width;
 initialMoveY = moveY = 0;
 moveX = -dims.width;
 break;
 case 'bottom-left':
 initialMoveX = moveX = 0;
 initialMoveY = dims.height;
 moveY = -dims.height;
 break;
 case 'bottom-right':
 initialMoveX = dims.width;
 initialMoveY = dims.height;
 moveX = -dims.width;
 moveY = -dims.height;
 break;
 case 'center':
 initialMoveX = dims.width / 2;
 initialMoveY = dims.height / 2;
 moveX = -dims.width / 2;
 moveY = -dims.height / 2;
 break;
 }
 
 return new Effect.Move(element, {
 x: initialMoveX,
 y: initialMoveY,
 duration: 0.01, 
 beforeSetup: function(effect) {
 effect.element.hide().makeClipping().makePositioned();
 },
 afterFinishInternal: function(effect) {
 new Effect.Parallel(
 [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
 new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
 new Effect.Scale(effect.element, 100, {
 scaleMode: { originalHeight: dims.height, originalWidth: dims.width }, 
 sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
 ], Object.extend({
 beforeSetup: function(effect) {
 effect.effects[0].element.setStyle({height: '0px'}).show(); 
 },
 afterFinishInternal: function(effect) {
 effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle); 
 }
 }, options)
 )
 }
 });
};

Effect.Shrink = function(element) {
 element = $(element);
 var options = Object.extend({
 direction: 'center',
 moveTransition: Effect.Transitions.sinoidal,
 scaleTransition: Effect.Transitions.sinoidal,
 opacityTransition: Effect.Transitions.none
 }, arguments[1] || { });
 var oldStyle = {
 top: element.style.top,
 left: element.style.left,
 height: element.style.height,
 width: element.style.width,
 opacity: element.getInlineOpacity() };

 var dims = element.getDimensions();
 var moveX, moveY;
 
 switch (options.direction) {
 case 'top-left':
 moveX = moveY = 0;
 break;
 case 'top-right':
 moveX = dims.width;
 moveY = 0;
 break;
 case 'bottom-left':
 moveX = 0;
 moveY = dims.height;
 break;
 case 'bottom-right':
 moveX = dims.width;
 moveY = dims.height;
 break;
 case 'center': 
 moveX = dims.width / 2;
 moveY = dims.height / 2;
 break;
 }
 
 return new Effect.Parallel(
 [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
 new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
 new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
 ], Object.extend({ 
 beforeStartInternal: function(effect) {
 effect.effects[0].element.makePositioned().makeClipping(); 
 },
 afterFinishInternal: function(effect) {
 effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
 }, options)
 );
};

Effect.Pulsate = function(element) {
 element = $(element);
 var options = arguments[1] || { };
 var oldOpacity = element.getInlineOpacity();
 var transition = options.transition || Effect.Transitions.sinoidal;
 var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
 reverser.bind(transition);
 return new Effect.Opacity(element, 
 Object.extend(Object.extend({ duration: 2.0, from: 0,
 afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
 }, options), {transition: reverser}));
};

Effect.Fold = function(element) {
 element = $(element);
 var oldStyle = {
 top: element.style.top,
 left: element.style.left,
 width: element.style.width,
 height: element.style.height };
 element.makeClipping();
 return new Effect.Scale(element, 5, Object.extend({ 
 scaleContent: false,
 scaleX: false,
 afterFinishInternal: function(effect) {
 new Effect.Scale(element, 1, { 
 scaleContent: false, 
 scaleY: false,
 afterFinishInternal: function(effect) {
 effect.element.hide().undoClipping().setStyle(oldStyle);
 } });
 }}, arguments[1] || { }));
};

Effect.Morph = Class.create(Effect.Base, {
 initialize: function(element) {
 this.element = $(element);
 if (!this.element) throw(Effect._elementDoesNotExistError);
 var options = Object.extend({
 style: { }
 }, arguments[1] || { });
 
 if (!Object.isString(options.style)) this.style = $H(options.style);
 else {
 if (options.style.include(':'))
 this.style = options.style.parseStyle();
 else {
 this.element.addClassName(options.style);
 this.style = $H(this.element.getStyles());
 this.element.removeClassName(options.style);
 var css = this.element.getStyles();
 this.style = this.style.reject(function(style) {
 return style.value == css[style.key];
 });
 options.afterFinishInternal = function(effect) {
 effect.element.addClassName(effect.options.style);
 effect.transforms.each(function(transform) {
 effect.element.style[transform.style] = '';
 });
 }
 }
 }
 this.start(options);
 },
 
 setup: function(){
 function parseColor(color){
 if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
 color = color.parseColor();
 return $R(0,2).map(function(i){
 return parseInt( color.slice(i*2+1,i*2+3), 16 ) 
 });
 }
 this.transforms = this.style.map(function(pair){
 var property = pair[0], value = pair[1], unit = null;

 if (value.parseColor('#zzzzzz') != '#zzzzzz') {
 value = value.parseColor();
 unit = 'color';
 } else if (property == 'opacity') {
 value = parseFloat(value);
 if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
 this.element.setStyle({zoom: 1});
 } else if (Element.CSS_LENGTH.test(value)) {
 var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
 value = parseFloat(components[1]);
 unit = (components.length == 3) ? components[2] : null;
 }

 var originalValue = this.element.getStyle(property);
 return { 
 style: property.camelize(), 
 originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0), 
 targetValue: unit=='color' ? parseColor(value) : value,
 unit: unit
 };
 }.bind(this)).reject(function(transform){
 return (
 (transform.originalValue == transform.targetValue) ||
 (
 transform.unit != 'color' &&
 (isNaN(transform.originalValue) || isNaN(transform.targetValue))
 )
 )
 });
 },
 update: function(position) {
 var style = { }, transform, i = this.transforms.length;
 while(i--)
 style[(transform = this.transforms[i]).style] = 
 transform.unit=='color' ? '#'+
 (Math.round(transform.originalValue[0]+
 (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
 (Math.round(transform.originalValue[1]+
 (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() +
 (Math.round(transform.originalValue[2]+
 (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
 (transform.originalValue +
 (transform.targetValue - transform.originalValue) * position).toFixed(3) + 
 (transform.unit === null ? '' : transform.unit);
 this.element.setStyle(style, true);
 }
});

Effect.Transform = Class.create({
 initialize: function(tracks){
 this.tracks = [];
 this.options = arguments[1] || { };
 this.addTracks(tracks);
 },
 addTracks: function(tracks){
 tracks.each(function(track){
 track = $H(track);
 var data = track.values().first();
 this.tracks.push($H({
 ids: track.keys().first(),
 effect: Effect.Morph,
 options: { style: data }
 }));
 }.bind(this));
 return this;
 },
 play: function(){
 return new Effect.Parallel(
 this.tracks.map(function(track){
 var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options');
 var elements = [$(ids) || $$(ids)].flatten();
 return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) });
 }).flatten(),
 this.options
 );
 }
});

Element.CSS_PROPERTIES = $w(
 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' + 
 'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
 'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
 'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
 'fontSize fontWeight height left letterSpacing lineHeight ' +
 'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
 'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
 'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
 'right textIndent top width wordSpacing zIndex');
 
Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;

String.__parseStyleElement = document.createElement('div');
String.prototype.parseStyle = function(){
 var style, styleRules = $H();
 if (Prototype.Browser.WebKit)
 style = new Element('div',{style:this}).style;
 else {
 String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>';
 style = String.__parseStyleElement.childNodes[0].style;
 }
 
 Element.CSS_PROPERTIES.each(function(property){
 if (style[property]) styleRules.set(property, style[property]); 
 });
 
 if (Prototype.Browser.IE && this.include('opacity'))
 styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);

 return styleRules;
};

if (document.defaultView && document.defaultView.getComputedStyle) {
 Element.getStyles = function(element) {
 var css = document.defaultView.getComputedStyle($(element), null);
 return Element.CSS_PROPERTIES.inject({ }, function(styles, property) {
 styles[property] = css[property];
 return styles;
 });
 };
} else {
 Element.getStyles = function(element) {
 element = $(element);
 var css = element.currentStyle, styles;
 styles = Element.CSS_PROPERTIES.inject({ }, function(hash, property) {
 hash.set(property, css[property]);
 return hash;
 });
 if (!styles.opacity) styles.set('opacity', element.getOpacity());
 return styles;
 };
};

Effect.Methods = {
 morph: function(element, style) {
 element = $(element);
 new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { }));
 return element;
 },
 visualEffect: function(element, effect, options) {
 element = $(element)
 var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
 new Effect[klass](element, options);
 return element;
 },
 highlight: function(element, options) {
 element = $(element);
 new Effect.Highlight(element, options);
 return element;
 }
};

$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
 'pulsate shake puff squish switchOff dropOut').each(
 function(effect) { 
 Effect.Methods[effect] = function(element, options){
 element = $(element);
 Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
 return element;
 }
 }
);

$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each( 
 function(f) { Effect.Methods[f] = Element[f]; }
);

Element.addMethods(Effect.Methods);
function addToBag(product_id,domain)
{
 var qty;
 _addToCart = "/checkout/cart/add/product/"+product_id+"/ajax/1/";
 _quantity = ($('qty')) ? ((qty = $('qty').getValue() ) ? 'qty/' + qty : '') : '';

 new Ajax.Updater('your_bag_items_list', _addToCart+_quantity,
 {
 onCreate: function()
 {
 if($('bag_loading')) $('your_bag_items_list').update('<li>'+$('bag_loading').innerHTML+'</li>');
 },

 onComplete: function()
 {
 updateTopBag(domain);
 bagCarousel = new UI.Carousel("your_bag_items");
 }
 });
}

function updateTopBag(domain)
{
 new Ajax.Request('/checkout/cart/topcart/',
 {
 onSuccess: function(transport)
 {
 var json = transport.responseText.evalJSON();
 $('top_bag_content').update(json.Total.count + ' Items - £' + json.Total.price);
 if($('bag_price') && $('bag_count'))
 {
 $('bag_price').update('£ ' + json.Total.price);
 $('bag_count').update(json.Total.count + ' Items | <a href="/checkout/cart/delete/ajax/1/deleteall/1">Remove all</a>');
 }
 }
 });
}//***********************************************************************************************************************************/
// LyteBox v3.22
//
// Author: Markus F. Hay
// Website: http://www.dolem.com/lytebox
// Date: October 2, 2007
// License: Creative Commons Attribution 3.0 License (http://creativecommons.org/licenses/by/3.0/)
// Browsers: Tested successfully on WinXP with the following browsers (using no DOCTYPE and Strict/Transitional/Loose DOCTYPES):
// * Firefox: 2.0.0.7, 1.5.0.12
// * Internet Explorer: 7.0, 6.0 SP2, 5.5 SP2
// * Opera: 9.23
//
// Releases: For up-to-date and complete release information, visit http://www.dolem.com/forum/showthread.php?tid=62
// * v3.22 (10/02/07)
// * v3.21 (09/30/07)
// * v3.20 (07/12/07)
// * v3.10 (05/28/07)
// * v3.00 (05/15/07)
// * v2.02 (11/13/06)
//
// Credit: LyteBox was originally derived from the Lightbox class (v2.02) that was written by Lokesh Dhakar. For more
// information please visit http://huddletogether.com/projects/lightbox2/
//***********************************************************************************************************************************/
Array.prototype.removeDuplicates = function () { for (var i = 1; i < this.length; i++) { if (this[i][0] == this[i-1][0]) { this.splice(i,1); } } }
Array.prototype.empty = function () { for (var i = 0; i <= this.length; i++) { this.shift(); } }
String.prototype.trim = function () { return this.replace(/^\s+|\s+$/g, ''); }

function LyteBox() {
 /*** Start Global Configuration ***/
 this.theme = 'grey'; // themes: grey (default), red, green, blue, gold
 this.hideFlash = true; // controls whether or not Flash objects should be hidden
 this.outerBorder = true; // controls whether to show the outer grey (or theme) border
 this.resizeSpeed = 8; // controls the speed of the image resizing (1=slowest and 10=fastest)
 this.maxOpacity = 80; // higher opacity = darker overlay, lower opacity = lighter overlay
 this.navType = 1; // 1 = "Prev/Next" buttons on top left and left (default), 2 = "<< prev | next >>" links next to image number
 this.autoResize = true; // controls whether or not images should be resized if larger than the browser window dimensions
 this.doAnimations = true; // controls whether or not "animate" Lytebox, i.e. resize transition between images, fade in/out effects, etc.

 this.borderSize = 12; // if you adjust the padding in the CSS, you will need to update this variable -- otherwise, leave this alone...
 /*** End Global Configuration ***/

 /*** Configure Slideshow Options ***/
 this.slideInterval = 4000; // Change value (milliseconds) to increase/decrease the time between "slides" (10000 = 10 seconds)
 this.showNavigation = true; // true to display Next/Prev buttons/text during slideshow, false to hide
 this.showClose = true; // true to display the Close button, false to hide
 this.showDetails = true; // true to display image details (caption, count), false to hide
 this.showPlayPause = true; // true to display pause/play buttons next to close button, false to hide
 this.autoEnd = true; // true to automatically close Lytebox after the last image is reached, false to keep open
 this.pauseOnNextClick = false; // true to pause the slideshow when the "Next" button is clicked
 this.pauseOnPrevClick = true; // true to pause the slideshow when the "Prev" button is clicked
 /*** End Slideshow Configuration ***/

 if(this.resizeSpeed > 10) { this.resizeSpeed = 10; }
 if(this.resizeSpeed < 1) { resizeSpeed = 1; }
 this.resizeDuration = (11 - this.resizeSpeed) * 0.15;
 this.resizeWTimerArray = new Array();
 this.resizeWTimerCount = 0;
 this.resizeHTimerArray = new Array();
 this.resizeHTimerCount = 0;
 this.showContentTimerArray = new Array();
 this.showContentTimerCount = 0;
 this.overlayTimerArray = new Array();
 this.overlayTimerCount = 0;
 this.imageTimerArray = new Array();
 this.imageTimerCount = 0;
 this.timerIDArray = new Array();
 this.timerIDCount = 0;
 this.slideshowIDArray = new Array();
 this.slideshowIDCount = 0;
 this.imageArray = new Array();
 this.activeImage = null;
 this.slideArray = new Array();
 this.activeSlide = null;
 this.frameArray = new Array();
 this.activeFrame = null;
 this.checkFrame();
 this.isSlideshow = false;
 this.isLyteframe = false;
 /*@cc_on
 /*@if (@_jscript)
 this.ie = (document.all && !window.opera) ? true : false;
 /*@else @*/
 this.ie = false;
 /*@end
 @*/
 this.ie7 = (this.ie && window.XMLHttpRequest);
 this.initialize();
}
LyteBox.prototype.initialize = function() {
 this.updateLyteboxItems();
 var objBody = this.doc.getElementsByTagName("body").item(0);
 if (this.doc.getElementById('lbOverlay')) {
 objBody.removeChild(this.doc.getElementById("lbOverlay"));
 objBody.removeChild(this.doc.getElementById("lbMain"));
 }
 var objOverlay = this.doc.createElement("div");
 objOverlay.setAttribute('id','lbOverlay');
 objOverlay.setAttribute((this.ie ? 'className' : 'class'), this.theme);
 if ((this.ie && !this.ie7) || (this.ie7 && this.doc.compatMode == 'BackCompat')) {
 objOverlay.style.position = 'absolute';
 }
 objOverlay.style.display = 'none';
 objBody.appendChild(objOverlay);
 var objLytebox = this.doc.createElement("div");
 objLytebox.setAttribute('id','lbMain');
 objLytebox.style.display = 'none';
 objBody.appendChild(objLytebox);
 var objOuterContainer = this.doc.createElement("div");
 objOuterContainer.setAttribute('id','lbOuterContainer');
 objOuterContainer.setAttribute((this.ie ? 'className' : 'class'), this.theme);
 objLytebox.appendChild(objOuterContainer);
 var objIframeContainer = this.doc.createElement("div");
 objIframeContainer.setAttribute('id','lbIframeContainer');
 objIframeContainer.style.display = 'none';
 objOuterContainer.appendChild(objIframeContainer);
 var objIframe = this.doc.createElement("iframe");
 objIframe.setAttribute('id','lbIframe');
 objIframe.setAttribute('name','lbIframe');
 objIframe.style.display = 'none';
 objIframeContainer.appendChild(objIframe);
 var objImageContainer = this.doc.createElement("div");
 objImageContainer.setAttribute('id','lbImageContainer');
 objOuterContainer.appendChild(objImageContainer);
 var objLyteboxImage = this.doc.createElement("img");
 objLyteboxImage.setAttribute('id','lbImage');
 objImageContainer.appendChild(objLyteboxImage);
 var objLoading = this.doc.createElement("div");
 objLoading.setAttribute('id','lbLoading');
 objOuterContainer.appendChild(objLoading);
 var objDetailsContainer = this.doc.createElement("div");
 objDetailsContainer.setAttribute('id','lbDetailsContainer');
 objDetailsContainer.setAttribute((this.ie ? 'className' : 'class'), this.theme);
 objLytebox.appendChild(objDetailsContainer);

 objDetailsContainer.appendChild($('linkToSalon'));

 var objDetailsData =this.doc.createElement("div");
 objDetailsData.setAttribute('id','lbDetailsData');
 objDetailsData.setAttribute((this.ie ? 'className' : 'class'), this.theme);
 objDetailsContainer.appendChild(objDetailsData);
 var objDetails = this.doc.createElement("div");
 objDetails.setAttribute('id','lbDetails');
 objDetailsData.appendChild(objDetails);
 var objCaption = this.doc.createElement("span");
 objCaption.setAttribute('id','lbCaption');
 objDetails.appendChild(objCaption);
 var objHoverNav = this.doc.createElement("div");
 objHoverNav.setAttribute('id','lbHoverNav');
 objImageContainer.appendChild(objHoverNav);
 var objBottomNav = this.doc.createElement("div");
 objBottomNav.setAttribute('id','lbBottomNav');
 objDetailsData.appendChild(objBottomNav);
 var objPrev = this.doc.createElement("a");
 objPrev.setAttribute('id','lbPrev');
 objPrev.setAttribute((this.ie ? 'className' : 'class'), this.theme);
 objPrev.setAttribute('href','#');
 objHoverNav.appendChild(objPrev);
 var objNext = this.doc.createElement("a");
 objNext.setAttribute('id','lbNext');
 objNext.setAttribute((this.ie ? 'className' : 'class'), this.theme);
 objNext.setAttribute('href','#');
 objHoverNav.appendChild(objNext);
 var objNumberDisplay = this.doc.createElement("span");
 objNumberDisplay.setAttribute('id','lbNumberDisplay');
 objDetails.appendChild(objNumberDisplay);
 var objNavDisplay = this.doc.createElement("span");
 objNavDisplay.setAttribute('id','lbNavDisplay');
 objNavDisplay.style.display = 'none';
 objDetails.appendChild(objNavDisplay);
 var objClose = this.doc.createElement("a");
 objClose.setAttribute('id','lbClose');
 objClose.setAttribute((this.ie ? 'className' : 'class'), this.theme);
 objClose.setAttribute('href','#');
 objBottomNav.appendChild(objClose);
 var objPause = this.doc.createElement("a");
 objPause.setAttribute('id','lbPause');
 objPause.setAttribute((this.ie ? 'className' : 'class'), this.theme);
 objPause.setAttribute('href','#');
 objPause.style.display = 'none';
 objBottomNav.appendChild(objPause);
 var objPlay = this.doc.createElement("a");
 objPlay.setAttribute('id','lbPlay');
 objPlay.setAttribute((this.ie ? 'className' : 'class'), this.theme);
 objPlay.setAttribute('href','#');
 objPlay.style.display = 'none';
 objBottomNav.appendChild(objPlay);
};
LyteBox.prototype.updateLyteboxItems = function() {
 var anchors = (this.isFrame) ? window.parent.frames[window.name].document.getElementsByTagName('a') : document.getElementsByTagName('a');
 for (var i = 0; i < anchors.length; i++) {
 var anchor = anchors[i];
 var relAttribute = String(anchor.getAttribute('rel'));
 if (anchor.getAttribute('href')) {
 if (relAttribute.toLowerCase().match('lytebox')) {
 anchor.onclick = function () { myLytebox.start(this, false, false); return false; }
 } else if (relAttribute.toLowerCase().match('lyteshow')) {
 anchor.onclick = function () { myLytebox.start(this, true, false); return false; }
 } else if (relAttribute.toLowerCase().match('lyteframe')) {
 anchor.onclick = function () { myLytebox.start(this, false, true); return false; }
 }
 }
 }
};
LyteBox.prototype.start = function(imageLink, doSlide, doFrame) {
 if (this.ie && !this.ie7) { this.toggleSelects('hide'); }
 if (this.hideFlash) { this.toggleFlash('hide'); }
 this.isLyteframe = (doFrame ? true : false);
 var pageSize = this.getPageSize();
 var objOverlay = this.doc.getElementById('lbOverlay');
 var objBody = this.doc.getElementsByTagName("body").item(0);
 objOverlay.style.height = pageSize[1] + "px";
 objOverlay.style.display = '';
 this.appear('lbOverlay', (this.doAnimations ? 0 : this.maxOpacity));
 var anchors = (this.isFrame) ? window.parent.frames[window.name].document.getElementsByTagName('a') : document.getElementsByTagName('a');
 if (this.isLyteframe) {
 this.frameArray = [];
 this.frameNum = 0;
 if ((imageLink.getAttribute('rel') == 'lyteframe')) {
 var rev = imageLink.getAttribute('rev');
 this.frameArray.push(new Array(imageLink.getAttribute('href'), imageLink.getAttribute('title'), (rev == null || rev == '' ? 'width: 400px; height: 400px; scrolling: auto;' : rev)));
 } else {
 if (imageLink.getAttribute('rel').indexOf('lyteframe') != -1) {
 for (var i = 0; i < anchors.length; i++) {
 var anchor = anchors[i];
 if (anchor.getAttribute('href') && (anchor.getAttribute('rel') == imageLink.getAttribute('rel'))) {
 var rev = anchor.getAttribute('rev');
 this.frameArray.push(new Array(anchor.getAttribute('href'), anchor.getAttribute('title'), (rev == null || rev == '' ? 'width: 400px; height: 400px; scrolling: auto;' : rev)));
 }
 }
 this.frameArray.removeDuplicates();
 while(this.frameArray[this.frameNum][0] != imageLink.getAttribute('href')) { this.frameNum++; }
 }
 }
 } else {
 this.imageArray = [];
 this.imageNum = 0;
 this.slideArray = [];
 this.slideNum = 0;
 if ((imageLink.getAttribute('rel') == 'lytebox')) {
 this.imageArray.push(new Array(imageLink.getAttribute('href'), imageLink.getAttribute('title')));
 } else {
 if (imageLink.getAttribute('rel').indexOf('lytebox') != -1) {
 for (var i = 0; i < anchors.length; i++) {
 var anchor = anchors[i];
 if (anchor.getAttribute('href') && (anchor.getAttribute('rel') == imageLink.getAttribute('rel'))) {
 this.imageArray.push(new Array(anchor.getAttribute('href'), anchor.getAttribute('title')));
 }
 }
 this.imageArray.removeDuplicates();
 while(this.imageArray[this.imageNum][0] != imageLink.getAttribute('href')) { this.imageNum++; }
 }
 if (imageLink.getAttribute('rel').indexOf('lyteshow') != -1) {
 for (var i = 0; i < anchors.length; i++) {
 var anchor = anchors[i];
 if (anchor.getAttribute('href') && (anchor.getAttribute('rel') == imageLink.getAttribute('rel'))) {
 this.slideArray.push(new Array(anchor.getAttribute('href'), anchor.getAttribute('title')));
 }
 }
 this.slideArray.removeDuplicates();
 while(this.slideArray[this.slideNum][0] != imageLink.getAttribute('href')) { this.slideNum++; }
 }
 }
 }
 var object = this.doc.getElementById('lbMain');
 object.style.top = (this.getPageScroll() + (pageSize[3] / 15)) + "px";
 object.style.display = '';
 if (!this.outerBorder) {
 this.doc.getElementById('lbOuterContainer').style.border = 'none';
 this.doc.getElementById('lbDetailsContainer').style.border = 'none';
 } else {
 this.doc.getElementById('lbOuterContainer').style.borderBottom = '';
 this.doc.getElementById('lbOuterContainer').setAttribute((this.ie ? 'className' : 'class'), this.theme);
 }
 this.doc.getElementById('lbOverlay').onclick = function() { myLytebox.end(); return false; }
 this.doc.getElementById('lbMain').onclick = function(e) {
 var e = e;
 if (!e) {
 if (window.parent.frames[window.name] && (parent.document.getElementsByTagName('frameset').length <= 0)) {
 e = window.parent.window.event;
 } else {
 e = window.event;
 }
 }
 var id = (e.target ? e.target.id : e.srcElement.id);
 if (id == 'lbMain') { myLytebox.end(); return false; }
 }
 this.doc.getElementById('lbClose').onclick = function() { myLytebox.end(); return false; }
 this.doc.getElementById('lbPause').onclick = function() { myLytebox.togglePlayPause("lbPause", "lbPlay"); return false; }
 this.doc.getElementById('lbPlay').onclick = function() { myLytebox.togglePlayPause("lbPlay", "lbPause"); return false; }
 this.isSlideshow = doSlide;
 this.isPaused = (this.slideNum != 0 ? true : false);
 if (this.isSlideshow && this.showPlayPause && this.isPaused) {
 this.doc.getElementById('lbPlay').style.display = '';
 this.doc.getElementById('lbPause').style.display = 'none';
 }
 if (this.isLyteframe) {
 this.changeContent(this.frameNum);
 } else {
 if (this.isSlideshow) {
 this.changeContent(this.slideNum);
 } else {
 this.changeContent(this.imageNum);
 }
 }
};
LyteBox.prototype.changeContent = function(imageNum) {
 if (this.isSlideshow) {
 for (var i = 0; i < this.slideshowIDCount; i++) { window.clearTimeout(this.slideshowIDArray[i]); }
 }
 this.activeImage = this.activeSlide = this.activeFrame = imageNum;
 if (!this.outerBorder) {
 this.doc.getElementById('lbOuterContainer').style.border = 'none';
 this.doc.getElementById('lbDetailsContainer').style.border = 'none';
 } else {
 this.doc.getElementById('lbOuterContainer').style.borderBottom = '';
 this.doc.getElementById('lbOuterContainer').setAttribute((this.ie ? 'className' : 'class'), this.theme);
 }
 this.doc.getElementById('lbLoading').style.display = '';
 this.doc.getElementById('lbImage').style.display = 'none';
 this.doc.getElementById('lbIframe').style.display = 'none';
 this.doc.getElementById('lbPrev').style.display = 'none';
 this.doc.getElementById('lbNext').style.display = 'none';
 this.doc.getElementById('lbIframeContainer').style.display = 'none';
 this.doc.getElementById('lbDetailsContainer').style.display = 'none';
 this.doc.getElementById('lbNumberDisplay').style.display = 'none';
 if (this.navType == 2 || this.isLyteframe) {
 object = this.doc.getElementById('lbNavDisplay');
 object.innerHTML = '&nbsp;&nbsp;&nbsp;<span id="lbPrev2_Off" style="display: none;" class="' + this.theme + '">&laquo; prev</span><a href="#" id="lbPrev2" class="' + this.theme + '" style="display: none;">&laquo; prev</a> <b id="lbSpacer" class="' + this.theme + '">||</b> <span id="lbNext2_Off" style="display: none;" class="' + this.theme + '">next &raquo;</span><a href="#" id="lbNext2" class="' + this.theme + '" style="display: none;">next &raquo;</a>';
 object.style.display = 'none';
 }
 if (this.isLyteframe) {
 var iframe = myLytebox.doc.getElementById('lbIframe');
 var styles = this.frameArray[this.activeFrame][2];
 var aStyles = styles.split(';');
 for (var i = 0; i < aStyles.length; i++) {
 if (aStyles[i].indexOf('width:') >= 0) {
 var w = aStyles[i].replace('width:', '');
 iframe.width = w.trim();
 } else if (aStyles[i].indexOf('height:') >= 0) {
 var h = aStyles[i].replace('height:', '');
 iframe.height = h.trim();
 } else if (aStyles[i].indexOf('scrolling:') >= 0) {
 var s = aStyles[i].replace('scrolling:', '');
 iframe.scrolling = s.trim();
 } else if (aStyles[i].indexOf('border:') >= 0) {
 // Not implemented yet, as there are cross-platform issues with setting the border (from a GUI standpoint)
 //var b = aStyles[i].replace('border:', '');
 //iframe.style.border = b.trim();
 }
 }
 this.resizeContainer(parseInt(iframe.width), parseInt(iframe.height));
 } else {
 imgPreloader = new Image();
 imgPreloader.onload = function() {
 var imageWidth = imgPreloader.width;
 var imageHeight = imgPreloader.height;
 if (myLytebox.autoResize) {
 var pagesize = myLytebox.getPageSize();
 var x = pagesize[2] - 150;
 var y = pagesize[3] - 150;
 if (imageWidth > x) {
 imageHeight = Math.round(imageHeight * (x / imageWidth));
 imageWidth = x;
 if (imageHeight > y) {
 imageWidth = Math.round(imageWidth * (y / imageHeight));
 imageHeight = y;
 }
 } else if (imageHeight > y) {
 imageWidth = Math.round(imageWidth * (y / imageHeight));
 imageHeight = y;
 if (imageWidth > x) {
 imageHeight = Math.round(imageHeight * (x / imageWidth));
 imageWidth = x;
 }
 }
 }
 var lbImage = myLytebox.doc.getElementById('lbImage')
 lbImage.src = (myLytebox.isSlideshow ? myLytebox.slideArray[myLytebox.activeSlide][0] : myLytebox.imageArray[myLytebox.activeImage][0]);
 lbImage.width = imageWidth;
 lbImage.height = imageHeight;
 myLytebox.resizeContainer(imageWidth, imageHeight);
 imgPreloader.onload = function() {};
 }
 imgPreloader.src = (this.isSlideshow ? this.slideArray[this.activeSlide][0] : this.imageArray[this.activeImage][0]);
 }
};
LyteBox.prototype.resizeContainer = function(imgWidth, imgHeight) {
 this.wCur = this.doc.getElementById('lbOuterContainer').offsetWidth;
 this.hCur = this.doc.getElementById('lbOuterContainer').offsetHeight;
 this.xScale = ((imgWidth + (this.borderSize * 2)) / this.wCur) * 100;
 this.yScale = ((imgHeight + (this.borderSize * 2)) / this.hCur) * 100;
 var wDiff = (this.wCur - this.borderSize * 2) - imgWidth;
 var hDiff = (this.hCur - this.borderSize * 2) - imgHeight;
 if (!(hDiff == 0)) {
 this.hDone = false;
 this.resizeH('lbOuterContainer', this.hCur, imgHeight + this.borderSize*2, this.getPixelRate(this.hCur, imgHeight));
 } else {
 this.hDone = true;
 }
 if (!(wDiff == 0)) {
 this.wDone = false;
 this.resizeW('lbOuterContainer', this.wCur, imgWidth + this.borderSize*2, this.getPixelRate(this.wCur, imgWidth));
 } else {
 this.wDone = true;
 }
 if ((hDiff == 0) && (wDiff == 0)) {
 if (this.ie){ this.pause(250); } else { this.pause(100); }
 }
 this.doc.getElementById('lbPrev').style.height = imgHeight + "px";
 this.doc.getElementById('lbNext').style.height = imgHeight + "px";
 this.doc.getElementById('lbDetailsContainer').style.width = (imgWidth + (this.borderSize * 2) + (this.ie && this.doc.compatMode == "BackCompat" && this.outerBorder ? 2 : 0)) + "px";
 this.showContent();
};
LyteBox.prototype.showContent = function() {
 if (this.wDone && this.hDone) {
 for (var i = 0; i < this.showContentTimerCount; i++) { window.clearTimeout(this.showContentTimerArray[i]); }
 if (this.outerBorder) {
 this.doc.getElementById('lbOuterContainer').style.borderBottom = 'none';
 }
 this.doc.getElementById('lbLoading').style.display = 'none';
 if (this.isLyteframe) {
 this.doc.getElementById('lbIframe').style.display = '';
 this.appear('lbIframe', (this.doAnimations ? 0 : 100));
 } else {
 this.doc.getElementById('lbImage').style.display = '';
 this.appear('lbImage', (this.doAnimations ? 0 : 100));
 this.preloadNeighborImages();
 }
 if (this.isSlideshow) {
 if(this.activeSlide == (this.slideArray.length - 1)) {
 if (this.autoEnd) {
 this.slideshowIDArray[this.slideshowIDCount++] = setTimeout("myLytebox.end('slideshow')", this.slideInterval);
 }
 } else {
 if (!this.isPaused) {
 this.slideshowIDArray[this.slideshowIDCount++] = setTimeout("myLytebox.changeContent("+(this.activeSlide+1)+")", this.slideInterval);
 }
 }
 this.doc.getElementById('lbHoverNav').style.display = (this.showNavigation && this.navType == 1 ? '' : 'none');
 this.doc.getElementById('lbClose').style.display = (this.showClose ? '' : 'none');
 this.doc.getElementById('lbDetails').style.display = (this.showDetails ? '' : 'none');
 this.doc.getElementById('lbPause').style.display = (this.showPlayPause && !this.isPaused ? '' : 'none');
 this.doc.getElementById('lbPlay').style.display = (this.showPlayPause && !this.isPaused ? 'none' : '');
 this.doc.getElementById('lbNavDisplay').style.display = (this.showNavigation && this.navType == 2 ? '' : 'none');

 } else {
 this.doc.getElementById('lbHoverNav').style.display = (this.navType == 1 && !this.isLyteframe ? '' : 'none');
 if ((this.navType == 2 && !this.isLyteframe && this.imageArray.length > 1) || (this.frameArray.length > 1 && this.isLyteframe)) {
 this.doc.getElementById('lbNavDisplay').style.display = '';
 } else {
 this.doc.getElementById('lbNavDisplay').style.display = 'none';
 }
 this.doc.getElementById('lbClose').style.display = '';
 this.doc.getElementById('lbDetails').style.display = '';
 this.doc.getElementById('lbPause').style.display = 'none';
 this.doc.getElementById('lbPlay').style.display = 'none';
 }
 this.doc.getElementById('lbImageContainer').style.display = (this.isLyteframe ? 'none' : '');
 this.doc.getElementById('lbIframeContainer').style.display = (this.isLyteframe ? '' : 'none');
 this.doc.getElementById('linkToSalon').style.display = '';
 try {
 this.doc.getElementById('lbIframe').src = this.frameArray[this.activeFrame][0];
 } catch(e) { }
 } else {
 this.showContentTimerArray[this.showContentTimerCount++] = setTimeout("myLytebox.showContent()", 200);
 }
};
LyteBox.prototype.updateDetails = function() {
 var object = this.doc.getElementById('lbCaption');
 var sTitle = (this.isSlideshow ? this.slideArray[this.activeSlide][1] : (this.isLyteframe ? this.frameArray[this.activeFrame][1] : this.imageArray[this.activeImage][1]));
 object.style.display = '';
 object.innerHTML = (sTitle == null ? '' : sTitle);
 this.updateNav();
 this.doc.getElementById('lbDetailsContainer').style.display = '';
 object = this.doc.getElementById('lbNumberDisplay');
 if (this.isSlideshow && this.slideArray.length > 1) {
 object.style.display = '';
 object.innerHTML = "Image " + eval(this.activeSlide + 1) + " of " + this.slideArray.length;
 this.doc.getElementById('lbNavDisplay').style.display = (this.navType == 2 && this.showNavigation ? '' : 'none');
 } else if (this.imageArray.length > 1 && !this.isLyteframe) {
 object.style.display = '';
 object.innerHTML = "Image " + eval(this.activeImage + 1) + " of " + this.imageArray.length;
 this.doc.getElementById('lbNavDisplay').style.display = (this.navType == 2 ? '' : 'none');
 } else if (this.frameArray.length > 1 && this.isLyteframe) {
 object.style.display = '';
 object.innerHTML = "Page " + eval(this.activeFrame + 1) + " of " + this.frameArray.length;
 this.doc.getElementById('lbNavDisplay').style.display = '';
 } else {
 this.doc.getElementById('lbNavDisplay').style.display = 'none';
 }
 this.appear('lbDetailsContainer', (this.doAnimations ? 0 : 100));
};
LyteBox.prototype.updateNav = function() {
 if (this.isSlideshow) {
 if (this.activeSlide != 0) {
 var object = (this.navType == 2 ? this.doc.getElementById('lbPrev2') : this.doc.getElementById('lbPrev'));
 object.style.display = '';
 object.onclick = function() {
 if (myLytebox.pauseOnPrevClick) { myLytebox.togglePlayPause("lbPause", "lbPlay"); }
 myLytebox.changeContent(myLytebox.activeSlide - 1); return false;
 }
 } else {
 if (this.navType == 2) { this.doc.getElementById('lbPrev2_Off').style.display = ''; }
 }
 if (this.activeSlide != (this.slideArray.length - 1)) {
 var object = (this.navType == 2 ? this.doc.getElementById('lbNext2') : this.doc.getElementById('lbNext'));
 object.style.display = '';
 object.onclick = function() {
 if (myLytebox.pauseOnNextClick) { myLytebox.togglePlayPause("lbPause", "lbPlay"); }
 myLytebox.changeContent(myLytebox.activeSlide + 1); return false;
 }
 } else {
 if (this.navType == 2) { this.doc.getElementById('lbNext2_Off').style.display = ''; }
 }
 } else if (this.isLyteframe) {
 if(this.activeFrame != 0) {
 var object = this.doc.getElementById('lbPrev2');
 object.style.display = '';
 object.onclick = function() {
 myLytebox.changeContent(myLytebox.activeFrame - 1); return false;
 }
 } else {
 this.doc.getElementById('lbPrev2_Off').style.display = '';
 }
 if(this.activeFrame != (this.frameArray.length - 1)) {
 var object = this.doc.getElementById('lbNext2');
 object.style.display = '';
 object.onclick = function() {
 myLytebox.changeContent(myLytebox.activeFrame + 1); return false;
 }
 } else {
 this.doc.getElementById('lbNext2_Off').style.display = '';
 }
 } else {
 if(this.activeImage != 0) {
 var object = (this.navType == 2 ? this.doc.getElementById('lbPrev2') : this.doc.getElementById('lbPrev'));
 object.style.display = '';
 object.onclick = function() {
 myLytebox.changeContent(myLytebox.activeImage - 1); return false;
 }
 } else {
 if (this.navType == 2) { this.doc.getElementById('lbPrev2_Off').style.display = ''; }
 }
 if(this.activeImage != (this.imageArray.length - 1)) {
 var object = (this.navType == 2 ? this.doc.getElementById('lbNext2') : this.doc.getElementById('lbNext'));
 object.style.display = '';
 object.onclick = function() {
 myLytebox.changeContent(myLytebox.activeImage + 1); return false;
 }
 } else {
 if (this.navType == 2) { this.doc.getElementById('lbNext2_Off').style.display = ''; }
 }
 }
 this.enableKeyboardNav();
};
LyteBox.prototype.enableKeyboardNav = function() { document.onkeydown = this.keyboardAction; };
LyteBox.prototype.disableKeyboardNav = function() { document.onkeydown = ''; };
LyteBox.prototype.keyboardAction = function(e) {
 var keycode = key = escape = null;
 keycode = (e == null) ? event.keyCode : e.which;
 key = String.fromCharCode(keycode).toLowerCase();
 escape = (e == null) ? 27 : e.DOM_VK_ESCAPE;
 if ((key == 'x') || (key == 'c') || (keycode == escape)) {
 myLytebox.end();
 } else if ((key == 'p') || (keycode == 37)) {
 if (myLytebox.isSlideshow) {
 if(myLytebox.activeSlide != 0) {
 myLytebox.disableKeyboardNav();
 myLytebox.changeContent(myLytebox.activeSlide - 1);
 }
 } else if (myLytebox.isLyteframe) {
 if(myLytebox.activeFrame != 0) {
 myLytebox.disableKeyboardNav();
 myLytebox.changeContent(myLytebox.activeFrame - 1);
 }
 } else {
 if(myLytebox.activeImage != 0) {
 myLytebox.disableKeyboardNav();
 myLytebox.changeContent(myLytebox.activeImage - 1);
 }
 }
 } else if ((key == 'n') || (keycode == 39)) {
 if (myLytebox.isSlideshow) {
 if(myLytebox.activeSlide != (myLytebox.slideArray.length - 1)) {
 myLytebox.disableKeyboardNav();
 myLytebox.changeContent(myLytebox.activeSlide + 1);
 }
 } else if (myLytebox.isLyteframe) {
 if(myLytebox.activeFrame != (myLytebox.frameArray.length - 1)) {
 myLytebox.disableKeyboardNav();
 myLytebox.changeContent(myLytebox.activeFrame + 1);
 }
 } else {
 if(myLytebox.activeImage != (myLytebox.imageArray.length - 1)) {
 myLytebox.disableKeyboardNav();
 myLytebox.changeContent(myLytebox.activeImage + 1);
 }
 }
 }
};
LyteBox.prototype.preloadNeighborImages = function() {
 if (this.isSlideshow) {
 if ((this.slideArray.length - 1) > this.activeSlide) {
 preloadNextImage = new Image();
 preloadNextImage.src = this.slideArray[this.activeSlide + 1][0];
 }
 if(this.activeSlide > 0) {
 preloadPrevImage = new Image();
 preloadPrevImage.src = this.slideArray[this.activeSlide - 1][0];
 }
 } else {
 if ((this.imageArray.length - 1) > this.activeImage) {
 preloadNextImage = new Image();
 preloadNextImage.src = this.imageArray[this.activeImage + 1][0];
 }
 if(this.activeImage > 0) {
 preloadPrevImage = new Image();
 preloadPrevImage.src = this.imageArray[this.activeImage - 1][0];
 }
 }
};
LyteBox.prototype.togglePlayPause = function(hideID, showID) {
 if (this.isSlideshow && hideID == "lbPause") {
 for (var i = 0; i < this.slideshowIDCount; i++) { window.clearTimeout(this.slideshowIDArray[i]); }
 }
 this.doc.getElementById(hideID).style.display = 'none';
 this.doc.getElementById(showID).style.display = '';
 if (hideID == "lbPlay") {
 this.isPaused = false;
 if (this.activeSlide == (this.slideArray.length - 1)) {
 this.end();
 } else {
 this.changeContent(this.activeSlide + 1);
 }
 } else {
 this.isPaused = true;
 }
};
LyteBox.prototype.end = function(caller) {
 var closeClick = (caller == 'slideshow' ? false : true);
 if (this.isSlideshow && this.isPaused && !closeClick) { return; }
 this.disableKeyboardNav();
 this.doc.getElementById('lbMain').style.display = 'none';
 this.fade('lbOverlay', (this.doAnimations ? this.maxOpacity : 0));
 this.toggleSelects('visible');
 if (this.hideFlash) { this.toggleFlash('visible'); }
 if (this.isSlideshow) {
 for (var i = 0; i < this.slideshowIDCount; i++) { window.clearTimeout(this.slideshowIDArray[i]); }
 }
 if (this.isLyteframe) {
 this.initialize();
 }
};
LyteBox.prototype.checkFrame = function() {
 if (window.parent.frames[window.name] && (parent.document.getElementsByTagName('frameset').length <= 0)) {
 this.isFrame = true;
 this.lytebox = "window.parent." + window.name + ".myLytebox";
 this.doc = parent.document;
 } else {
 this.isFrame = false;
 this.lytebox = "myLytebox";
 this.doc = document;
 }
};
LyteBox.prototype.getPixelRate = function(cur, img) {
 var diff = (img > cur) ? img - cur : cur - img;
 if (diff >= 0 && diff <= 100) { return 10; }
 if (diff > 100 && diff <= 200) { return 15; }
 if (diff > 200 && diff <= 300) { return 20; }
 if (diff > 300 && diff <= 400) { return 25; }
 if (diff > 400 && diff <= 500) { return 30; }
 if (diff > 500 && diff <= 600) { return 35; }
 if (diff > 600 && diff <= 700) { return 40; }
 if (diff > 700) { return 45; }
};
LyteBox.prototype.appear = function(id, opacity) {
 var object = this.doc.getElementById(id).style;
 object.opacity = (opacity / 100);
 object.MozOpacity = (opacity / 100);
 object.KhtmlOpacity = (opacity / 100);
 object.filter = "alpha(opacity=" + (opacity + 10) + ")";
 if (opacity == 100 && (id == 'lbImage' || id == 'lbIframe')) {
 try { object.removeAttribute("filter"); } catch(e) {} /* Fix added for IE Alpha Opacity Filter bug. */
 this.updateDetails();
 } else if (opacity >= this.maxOpacity && id == 'lbOverlay') {
 for (var i = 0; i < this.overlayTimerCount; i++) { window.clearTimeout(this.overlayTimerArray[i]); }
 return;
 } else if (opacity >= 100 && id == 'lbDetailsContainer') {
 try { object.removeAttribute("filter"); } catch(e) {} /* Fix added for IE Alpha Opacity Filter bug. */
 for (var i = 0; i < this.imageTimerCount; i++) { window.clearTimeout(this.imageTimerArray[i]); }
 this.doc.getElementById('lbOverlay').style.height = this.getPageSize()[1] + "px";
 } else {
 if (id == 'lbOverlay') {
 this.overlayTimerArray[this.overlayTimerCount++] = setTimeout("myLytebox.appear('" + id + "', " + (opacity+20) + ")", 1);
 } else {
 this.imageTimerArray[this.imageTimerCount++] = setTimeout("myLytebox.appear('" + id + "', " + (opacity+10) + ")", 1);
 }
 }
};
LyteBox.prototype.fade = function(id, opacity) {
 var object = this.doc.getElementById(id).style;
 object.opacity = (opacity / 100);
 object.MozOpacity = (opacity / 100);
 object.KhtmlOpacity = (opacity / 100);
 object.filter = "alpha(opacity=" + opacity + ")";
 if (opacity <= 0) {
 try {
 object.display = 'none';
 } catch(err) { }
 } else if (id == 'lbOverlay') {
 this.overlayTimerArray[this.overlayTimerCount++] = setTimeout("myLytebox.fade('" + id + "', " + (opacity-20) + ")", 1);
 } else {
 this.timerIDArray[this.timerIDCount++] = setTimeout("myLytebox.fade('" + id + "', " + (opacity-10) + ")", 1);
 }
};
LyteBox.prototype.resizeW = function(id, curW, maxW, pixelrate, speed) {
 if (!this.hDone) {
 this.resizeWTimerArray[this.resizeWTimerCount++] = setTimeout("myLytebox.resizeW('" + id + "', " + curW + ", " + maxW + ", " + pixelrate + ")", 100);
 return;
 }
 var object = this.doc.getElementById(id);
 var timer = speed ? speed : (this.resizeDuration/2);
 var newW = (this.doAnimations ? curW : maxW);
 object.style.width = (newW) + "px";
 if (newW < maxW) {
 newW += (newW + pixelrate >= maxW) ? (maxW - newW) : pixelrate;
 } else if (newW > maxW) {
 newW -= (newW - pixelrate <= maxW) ? (newW - maxW) : pixelrate;
 }
 this.resizeWTimerArray[this.resizeWTimerCount++] = setTimeout("myLytebox.resizeW('" + id + "', " + newW + ", " + maxW + ", " + pixelrate + ", " + (timer+0.02) + ")", timer+0.02);
 if (parseInt(object.style.width) == maxW) {
 this.wDone = true;
 for (var i = 0; i < this.resizeWTimerCount; i++) { window.clearTimeout(this.resizeWTimerArray[i]); }
 }
};
LyteBox.prototype.resizeH = function(id, curH, maxH, pixelrate, speed) {
 var timer = speed ? speed : (this.resizeDuration/2);
 var object = this.doc.getElementById(id);
 var newH = (this.doAnimations ? curH : maxH);
 object.style.height = (newH) + "px";
 if (newH < maxH) {
 newH += (newH + pixelrate >= maxH) ? (maxH - newH) : pixelrate;
 } else if (newH > maxH) {
 newH -= (newH - pixelrate <= maxH) ? (newH - maxH) : pixelrate;
 }
 this.resizeHTimerArray[this.resizeHTimerCount++] = setTimeout("myLytebox.resizeH('" + id + "', " + newH + ", " + maxH + ", " + pixelrate + ", " + (timer+.02) + ")", timer+.02);
 if (parseInt(object.style.height) == maxH) {
 this.hDone = true;
 for (var i = 0; i < this.resizeHTimerCount; i++) { window.clearTimeout(this.resizeHTimerArray[i]); }
 }
};
LyteBox.prototype.getPageScroll = function() {
 if (self.pageYOffset) {
 return this.isFrame ? parent.pageYOffset : self.pageYOffset;
 } else if (this.doc.documentElement && this.doc.documentElement.scrollTop){
 return this.doc.documentElement.scrollTop;
 } else if (document.body) {
 return this.doc.body.scrollTop;
 }
};
LyteBox.prototype.getPageSize = function() {
 var xScroll, yScroll, windowWidth, windowHeight;
 if (window.innerHeight && window.scrollMaxY) {
 xScroll = this.doc.scrollWidth;
 yScroll = (this.isFrame ? parent.innerHeight : self.innerHeight) + (this.isFrame ? parent.scrollMaxY : self.scrollMaxY);
 } else if (this.doc.body.scrollHeight > this.doc.body.offsetHeight){
 xScroll = this.doc.body.scrollWidth;
 yScroll = this.doc.body.scrollHeight;
 } else {
 xScroll = this.doc.getElementsByTagName("html").item(0).offsetWidth;
 yScroll = this.doc.getElementsByTagName("html").item(0).offsetHeight;
 xScroll = (xScroll < this.doc.body.offsetWidth) ? this.doc.body.offsetWidth : xScroll;
 yScroll = (yScroll < this.doc.body.offsetHeight) ? this.doc.body.offsetHeight : yScroll;
 }
 if (self.innerHeight) {
 windowWidth = (this.isFrame) ? parent.innerWidth : self.innerWidth;
 windowHeight = (this.isFrame) ? parent.innerHeight : self.innerHeight;
 } else if (document.documentElement && document.documentElement.clientHeight) {
 windowWidth = this.doc.documentElement.clientWidth;
 windowHeight = this.doc.documentElement.clientHeight;
 } else if (document.body) {
 windowWidth = this.doc.getElementsByTagName("html").item(0).clientWidth;
 windowHeight = this.doc.getElementsByTagName("html").item(0).clientHeight;
 windowWidth = (windowWidth == 0) ? this.doc.body.clientWidth : windowWidth;
 windowHeight = (windowHeight == 0) ? this.doc.body.clientHeight : windowHeight;
 }
 var pageHeight = (yScroll < windowHeight) ? windowHeight : yScroll;
 var pageWidth = (xScroll < windowWidth) ? windowWidth : xScroll;
 return new Array(pageWidth, pageHeight, windowWidth, windowHeight);
};
LyteBox.prototype.toggleFlash = function(state) {
 var objects = this.doc.getElementsByTagName("object");
 for (var i = 0; i < objects.length; i++) {
 objects[i].style.visibility = (state == "hide") ? 'hidden' : 'visible';
 }
 var embeds = this.doc.getElementsByTagName("embed");
 for (var i = 0; i < embeds.length; i++) {
 embeds[i].style.visibility = (state == "hide") ? 'hidden' : 'visible';
 }
 if (this.isFrame) {
 for (var i = 0; i < parent.frames.length; i++) {
 try {
 objects = parent.frames[i].window.document.getElementsByTagName("object");
 for (var j = 0; j < objects.length; j++) {
 objects[j].style.visibility = (state == "hide") ? 'hidden' : 'visible';
 }
 } catch(e) { }
 try {
 embeds = parent.frames[i].window.document.getElementsByTagName("embed");
 for (var j = 0; j < embeds.length; j++) {
 embeds[j].style.visibility = (state == "hide") ? 'hidden' : 'visible';
 }
 } catch(e) { }
 }
 }
};
LyteBox.prototype.toggleSelects = function(state) {
 var selects = this.doc.getElementsByTagName("select");
 for (var i = 0; i < selects.length; i++ ) {
 selects[i].style.visibility = (state == "hide") ? 'hidden' : 'visible';
 }
 if (this.isFrame) {
 for (var i = 0; i < parent.frames.length; i++) {
 try {
 selects = parent.frames[i].window.document.getElementsByTagName("select");
 for (var j = 0; j < selects.length; j++) {
 selects[j].style.visibility = (state == "hide") ? 'hidden' : 'visible';
 }
 } catch(e) { }
 }
 }
};
LyteBox.prototype.pause = function(numberMillis) {
 var now = new Date();
 var exitTime = now.getTime() + numberMillis;
 while (true) {
 now = new Date();
 if (now.getTime() > exitTime) { return; }
 }
};
if (window.addEventListener) {
 window.addEventListener("load",initLytebox,false);
} else if (window.attachEvent) {
 window.attachEvent("onload",initLytebox);
} else {
 window.onload = function() {initLytebox();}
}
function initLytebox() { myLytebox = new LyteBox(); }