var g = {
    restoreCursor : 'zoomout.cur',
    expandSteps : 10,
    expandDuration : 250,
    restoreSteps : 10,
    restoreDuration : 250,
    marginLeft : 15,
    marginRight : 15,
    marginTop : 15,
    marginBottom : 15,
    zIndexCounter : 1001,

    loadingOpacity : 0.75,
    allowMultipleInstances: true,
    numberOfImagesToPreload : 5,
    captionSlideSpeed : 0,
    padToMinWidth : false, 
    outlineWhileAnimating : 2, 
    outlineStartOffset : 3, 
    fullExpandOpacity : 1,
    showCredits : false, 
    enableKeyListener : true,

    captionId : null,
    spaceForCaption : null, 
    slideshowGroup : null, 
    minWidth: 200,
    minHeight: 200,
    allowSizeReduction: true, 
    wrapperClassName : null, 

    
    preloadTheseImages : [],
    continuePreloading: true,
    expanders : [],
    overrides : [
	    'allowSizeReduction',
	    'outlineType',
	    'outlineWhileAnimating',
	    'spaceForCaption',
	    'captionId',
	    'captionText',
	    'captionEval',
	    
	    'wrapperClassName',
	    'minWidth',
	    'minHeight',
	    'slideshowGroup'
    ],
    overlays : [],
    faders : [],

    pendingOutlines : {},
    clones : {},
    ie : (document.all && !window.opera),
    safari : navigator.userAgent.indexOf("Safari") != -1,

    $ : function (id) {
	    return document.getElementById(id);
    },

    push : function (arr, val) {
	    arr[arr.length] = val;
    },

    createElement : function (tag, attribs, styles, parent, nopad) {
	    var el = document.createElement(tag);
	    if (attribs) g.setAttribs(el, attribs);
	    if (nopad) g.setStyles(el, {padding: 0, border: 'none', margin: 0});
	    if (styles) g.setStyles(el, styles);
	    if (parent) parent.appendChild(el);	
	    return el;
    },

    setAttribs : function (el, attribs) {
	    for (var x in attribs) {
		    el[x] = attribs[x];
	    }
    },

    setStyles : function (el, styles) {
	    for (var x in styles) {
		    try { 
			    if (g.ie && x == 'opacity') el.style.filter = 'alpha(opacity='+ (styles[x] * 100) +')';
			    else el.style[x] = styles[x]; 
		    }
		    catch (e) {}
	    }
    },

    ieVersion : function () {
	    arr = navigator.appVersion.split("MSIE");
	    return parseFloat(arr[1]);
    },

    getPageSize : function () {
	    var iebody = document.compatMode && document.compatMode != "BackCompat" 
		    ? document.documentElement : document.body;
	    
	    var width = g.ie ? iebody.clientWidth : 
			    (document.documentElement.clientWidth || self.innerWidth),
		    height = g.ie ? iebody.clientHeight : self.innerHeight;
	    
	    return {
		    width: width,
		    height: height,		
		    scrollLeft: g.ie ? iebody.scrollLeft : pageXOffset,
		    scrollTop: g.ie ? iebody.scrollTop : pageYOffset
	    }
    },

    position : function(el)	{ 
	    var p = { x: el.offsetLeft, y: el.offsetTop };
	    while (el.offsetParent)	{
		    el = el.offsetParent;
		    p.x += el.offsetLeft;
		    p.y += el.offsetTop;
		    if (el != document.body && el != document.documentElement) {
			    p.x -= el.scrollLeft;
			    p.y -= el.scrollTop;
		    }
	    }
	    return p;
    },

    expand : function(a, params, custom) {
	    if (a.getParams) return params;
	    
	    try {
		    new g.Expander(a, params, custom);
		    return false;		
	    } catch (e) { return true; }
    },

    focusTopmost : function() {
	    var topZ = 0, topmostKey = -1;
	    for (i = 0; i < g.expanders.length; i++) {
		    if (g.expanders[i]) {
			    if (g.expanders[i].wrapper.style.zIndex && g.expanders[i].wrapper.style.zIndex > topZ) {
				    topZ = g.expanders[i].wrapper.style.zIndex;
				    
				    topmostKey = i;
			    }
		    }
	    }
	    if (topmostKey == -1) g.focusKey = -1;
	    else g.expanders[topmostKey].focus();
    },

    getAdjacentAnchor : function(key, op) {
	    var aAr = document.getElementsByTagName('A'), hsAr = {}, activeI = -1, j = 0;
	    for (i = 0; i < aAr.length; i++) {
		    if (g.isHsAnchor(aAr[i]) && ((g.expanders[key].slideshowGroup == g.getParam(aAr[i], 'slideshowGroup')))) {
			    hsAr[j] = aAr[i];
			    if (g.expanders[key] && aAr[i] == g.expanders[key].a) {
				    activeI = j;
			    }
			    j++;
		    }
	    }
	    return hsAr[activeI + op];
    },

    getParam : function (a, param) {
	    a.getParams = a.onclick;
	    var p = a.getParams();
	    a.getParams = null;
	    
	    return (p && typeof p[param] != 'undefined') ? p[param] : g[param];
    },

    getSrc : function (a) {
	    var src = g.getParam(a, 'src');
	    if (src) return src;
	    return a.href;
    },

    getNode : function (id) {
	    var node = g.$(id), clone = g.clones[id], a = {};
	    if (!node && !clone) return null;
	    if (!clone) {
		    clone = node.cloneNode(true);
		    clone.id = '';
		    g.clones[id] = clone;
		    return node;
	    } else {
		    return clone.cloneNode(true);
	    }
    },

    purge : function(d) {
	    if (!g.ie) return;
	    var a = d.attributes, i, l, n;
	    if (a) {
		    l = a.length;
		    for (i = 0; i < l; i += 1) {
			    n = a[i].name;
			    if (typeof d[n] === 'function') {
				    d[n] = null;
			    }
		    }
	    }
	    a = d.childNodes;
	    if (a) {
		    l = a.length;
		    for (i = 0; i < l; i += 1) {
			    g.purge(d.childNodes[i]);
		    }
	    }
    },

    previousOrNext : function (el, op) {
	    var exp = g.getExpander(el);
	    try {
		    var adj = g.upcoming =  g.getAdjacentAnchor(exp.key, op);
		    adj.onclick(); 		
	    } catch (e){}
	    try { exp.close(); } catch (e) {}	
	    return false;
    },

    previous : function (el) {
	    return g.previousOrNext(el, -1);
    },

    next : function (el) {
	    return g.previousOrNext(el, 1);	
    },

    registerOverlay : function (overlay) {
	    g.push(g.overlays, overlay);
    },

    getWrapperKey : function (element) {
	    var el, re = /^gallery-wrapper-([0-9]+)$/;
	    el = element;
	    while (el.parentNode)	{
		    if (el.id && el.id.match(re)) return el.id.replace(re, "$1");
		    el = el.parentNode;
	    }
	    el = element;
	    while (el.parentNode)	{
		    if (el.tagName && g.isHsAnchor(el)) {
			    for (key = 0; key < g.expanders.length; key++) {
				    exp = g.expanders[key];
				    if (exp && exp.a == el) return key;
			    }
		    }
		    el = el.parentNode;
	    }
    },

    getExpander : function (el) {
	    try {	
		    if (!el) return g.expanders[g.focusKey];
		    if (typeof el == 'number') return g.expanders[el];
		    if (typeof el == 'string') el = g.$(el);
		    return g.expanders[g.getWrapperKey(el)];
	    } catch (e) {}
    },

    isHsAnchor : function (a) {
	    return (a.onclick && a.onclick.toString().replace(/\s/g, ' ').match(/g.(htmlE|e)xpand/));
    },

    cleanUp : function () {
	    for (i = 0; i < g.expanders.length; i++)
		    if (g.expanders[i] && g.expanders[i].isExpanded) g.focusTopmost();
    },

    mouseClickHandler : function(e) 
    {	
	    if (!e) e = window.event;
	    if (!e.target) e.target = e.srcElement;
	    
	    var el = e.target;
	    while (el.parentNode
		    && !(/gallery-(image|move|html|resize)/.test(el.className)))
	    {
		    el = el.parentNode;
	    }
	    var exp = g.getExpander(el);

	    if (exp && e.type == 'mousedown') {
		    if (e.target.form) return;
		    var match = el.className.match(/gallery-(image|move|resize)/);
		    if (match) {
			    g.dragArgs = { exp: exp , type: match[1], left: exp.x.min, width: exp.x.span, top: exp.y.min, 
				    height: exp.y.span, clickX: e.clientX, clickY: e.clientY };
		    if (e.preventDefault) e.preventDefault(); 
			    
			    if (/gallery-(image|html)-blur/.test(exp.content.className)) {
				    exp.focus();
				    g.hasFocused = true;
			    }
			    return false;
		    }

	    } else if (e.type == 'mouseup') {
		    
		    if (g.dragArgs) {
			    
			    if (g.dragArgs.type == 'image')
				    g.dragArgs.exp.content.style.cursor = g.styleRestoreCursor;
			    
			    var hasDragged = (Math.abs(g.dragArgs.dX) + Math.abs(g.dragArgs.dY) > 0);
			    
			    if (!hasDragged &&!g.hasFocused && !/(move|resize)/.test(g.dragArgs.type)) {
				    exp.close();
			    } 
			    else if (hasDragged || (!hasDragged && g.hasHtmlexpanders)) {
				    g.dragArgs.exp.redoShowHide();
			    }
			    
			    g.hasFocused = false;
			    g.dragArgs = null;
		    
		    } else if (/gallery-image-blur/.test(el.className)) {
			    el.style.cursor = g.styleRestoreCursor;		
		    }
	    }

    },                                                              
    
    addEventListener : function (el, event, func) {
	    try {
		    el.addEventListener(event, func, false);
	    } catch (e) {
		    try {
			    el.detachEvent('on'+ event, func);
			    el.attachEvent('on'+ event, func);
		    } catch (e) {
			    el['on'+ event] = func;
		    }
	    } 
    },

    removeEventListener : function (el, event, func) {
	    try {
		    el.removeEventListener(event, func, false);
	    } catch (e) {
		    try {
			    el.detachEvent('on'+ event, func);
		    } catch (e) {
			    el['on'+ event] = null;
		    }
	    }
    },

    preloadFullImage : function (i) {
	    if (g.continuePreloading && g.preloadTheseImages[i] && g.preloadTheseImages[i] != 'undefined') {
		    var img = document.createElement('img');
		    img.onload = function() { g.preloadFullImage(i + 1); };
		    img.src = g.preloadTheseImages[i];
	    }
    },
    preloadImages : function (number) {
	    if (number && typeof number != 'object') g.numberOfImagesToPreload = number;
	    var a, re, j = 0;
	    
	    var aTags = document.getElementsByTagName('A');
	    for (i = 0; i < aTags.length; i++) {
		    a = aTags[i];
		    re = g.isHsAnchor(a);
		    if (re && re[0] == 'g.expand') {
			    if (j < g.numberOfImagesToPreload) {
				    g.preloadTheseImages[j] = g.getSrc(a); 
				    j++;
			    }
		    }
	    }
	    
	    new g.Outline(g.outlineType, function () { g.preloadFullImage(0)} );
    },


    genContainer : function () {
	    if (!g.container) {
		    g.container = g.createElement('div', 
			    null, 
			    { position: 'absolute', left: 0, top: 0, width: '100%', zIndex: g.zIndexCounter }, 
			    document.body,
			    true
		    );
		    g.loading = g.createElement('a',
			    {
				    className: 'gallery-loading',
				    title: g.loadingTitle,
				    innerHTML: g.loadingText
			    },
			    {
				    position: 'absolute',
				    opacity: g.loadingOpacity,
				    left: '-9999px',
				    zIndex: 1
			    }, g.container
		    );
	    }
    },

    fade : function (el, o, oFinal, i, dir) {
	    if (dir == null) var dir = oFinal > o ? 1 : -1;
	    o = parseFloat(o);
	    el.style.visibility = (o <= 0) ? 'hidden' : 'visible';
	    if (o < 0 || (dir == 1 && o > oFinal)) return;
	    if (i == null) i = g.faders.length;
	    if (typeof(el.i) != 'undefined' && el.i != i) {
		    clearTimeout(g.faders[el.i]);
		    o = el.tempOpacity;
	    }
	    el.i = i;
	    el.tempOpacity = o;
	    el.style.visibility = (o <= 0) ? 'hidden' : 'visible';
	    g.setStyles(el, { opacity: o });
	    g.faders[i] = setTimeout(function() { 
			    g.fade(el, Math.round((o + 0.1 * dir)*100)/100, oFinal, i, dir);
	 	    }, 25);
    },

    close : function(el) {
	    try { g.getExpander(el).close(); } catch (e) {}
	    return false;
    }
    }; 

    g.Outline =  function (outlineType, onLoad) {
	    this.onLoad = onLoad;
	    this.outlineType = outlineType;
	    var v = g.ieVersion(), tr;
	    
	    this.hasAlphaImageLoader = g.ie && v >= 5.5 && v < 7;
	    if (!outlineType) {
		    if (onLoad) onLoad();
		    return;
	    }
	    
	    g.genContainer();
	    this.table = g.createElement(
		    'table', { cellSpacing: 0 },
		    {
			    visibility: 'hidden',
			    position: 'absolute',
			    borderCollapse: 'collapse'
		    },
		    g.container,
		    true
	    );
	    this.tbody = g.createElement('tbody', null, null, this.table, 1);
	    
	    this.td = [];
	    for (var i = 0; i <= 8; i++) {
		    if (i % 3 == 0) tr = g.createElement('tr', null, { height: 'auto' }, this.tbody, true);
		    this.td[i] = g.createElement('td', null, null, tr, true);
		    var style = i != 4 ? { lineHeight: 0, fontSize: 0} : { position : 'relative' };
		    g.setStyles(this.td[i], style);
	    }
	    this.td[4].className = outlineType;
	    
	    this.preloadGraphic(); 
    };

    g.Outline.prototype = {
    preloadGraphic : function () {	
	    var src = g.graphicsDir + "outlines/"+ this.outlineType +".png";
				    
	    var appendTo = g.safari ? g.container : null;
	    this.graphic = g.createElement('img', null, { position: 'absolute', left: '-9999px', 
		    top: '-9999px' }, appendTo, true); 
	    
	    var pThis = this;
	    this.graphic.onload = function() { pThis.onGraphicLoad(); };
	    
	    this.graphic.src = src;
    },

    onGraphicLoad : function () {
	    var o = this.offset = this.graphic.width / 4,
		    pos = [[0,0],[0,-4],[-2,0],[0,-8],0,[-2,-8],[0,-2],[0,-6],[-2,-2]],
		    dim = { height: (2*o) +'px', width: (2*o) +'px' };
		    
	    for (var i = 0; i <= 8; i++) {
		    if (pos[i]) {
			    if (this.hasAlphaImageLoader) {
				    var w = (i == 1 || i == 7) ? '100%' : this.graphic.width +'px';
				    var div = g.createElement('div', null, { width: '100%', height: '100%', position: 'relative', overflow: 'hidden'}, this.td[i], true);
				    g.createElement ('div', null, { 
						    filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale, src='"+ this.graphic.src + "')", 
						    position: 'absolute',
						    width: w, 
						    height: this.graphic.height +'px',
						    left: (pos[i][0]*o)+'px',
						    top: (pos[i][1]*o)+'px'
					    }, 
				    div,
				    true);
			    } else {
				    g.setStyles(this.td[i], { background: 'url('+ this.graphic.src +') '+ (pos[i][0]*o)+'px '+(pos[i][1]*o)+'px'});
			    }
			    
			    if (window.opera && (i == 3 || i ==5)) 
				    g.createElement('div', null, dim, this.td[i], true);
			    
			    g.setStyles (this.td[i], dim);
		    }
	    }
	    
	    g.pendingOutlines[this.outlineType] = this;
	    if (this.onLoad) this.onLoad();
    },
	    
    setPosition : function (exp, x, y, w, h, vis) {
	    if (vis) this.table.style.visibility = (h >= 4 * this.offset) 
		    ? 'visible' : 'hidden';
	    this.table.style.left = (x - this.offset) +'px';
	    this.table.style.top = (y - this.offset) +'px';
	    this.table.style.width = (w + 2 * (exp.offsetBorderW + this.offset)) +'px';
	    w += 2 * (exp.offsetBorderW - this.offset);
	    h += + 2 * (exp.offsetBorderH - this.offset);
	    this.td[4].style.width = w >= 0 ? w +'px' : 0;
	    this.td[4].style.height = h >= 0 ? h +'px' : 0;
	    if (this.hasAlphaImageLoader) this.td[3].style.height 
		    = this.td[5].style.height = this.td[4].style.height;
    },
	    
    destroy : function(hide) {
	    if (hide) this.table.style.visibility = 'hidden';
	    else {
		    g.purge(this.table);
		    try { this.table.parentNode.removeChild(this.table); } catch (e) {}
	    }
    }
    };

    g.Expander = function(a, params, custom, contentType) {
	    this.a = a;
	    this.custom = custom;
	    this.contentType = contentType || 'image';
	    this.isImage = !this.isHtml;
	    
	    g.continuePreloading = false;
	    g.genContainer();
	    var key = this.key = g.expanders.length;
	    
	    for (i = 0; i < g.overrides.length; i++) {
		    var name = g.overrides[i];
		    this[name] = params && typeof params[name] != 'undefined' ?
			    params[name] : g[name];
	    }
	    
	    var el = this.thumb = (params ? g.$(params.thumbnailId) : null) 
		    || a.getElementsByTagName('IMG')[0] || a;
	    this.thumbsUserSetId = el.id || a.id;
	    
	    for (i = 0; i < g.expanders.length; i++) {
		    if (g.expanders[i] && g.expanders[i].a == a) {
			    g.expanders[i].focus();
			    return false;
		    }		
	    }	
	    for (i = 0; i < g.expanders.length; i++) {
		    if (g.expanders[i] && g.expanders[i].thumb != el && !g.expanders[i].onLoadStarted) {
			    g.expanders[i].cancelLoading();
		    }
	    }
	    g.expanders[this.key] = this;
	    
	    if (!g.allowMultipleInstances) {
		    try { g.expanders[key - 1].close(); } catch (e){}
		    try { g.expanders[g.focusKey].close(); } catch (e){} 
	    }
	    this.overlays = [];

	    var pos = g.position(el);
	    
	    this.thumbWidth = el.width ? el.width : el.offsetWidth;		
	    this.thumbHeight = el.height ? el.height : el.offsetHeight;
	    this.thumbLeft = pos.x;
	    this.thumbTop = pos.y;
	    this.thumbOffsetBorderW = (this.thumb.offsetWidth - this.thumbWidth) / 2;
	    this.thumbOffsetBorderH = (this.thumb.offsetHeight - this.thumbHeight) / 2;
	    
	    this.wrapper = g.createElement(
		    'div',
		    {
			    id: 'gallery-wrapper-'+ this.key,
			    className: this.wrapperClassName
		    },
		    {
			    visibility: 'hidden',
			    position: 'absolute',
			    zIndex: g.zIndexCounter++
		    }, null, true );
	    
	    this.wrapper.onmouseover = function (e) { 
		    try { g.expanders[key].wrapperMouseHandler(e); } catch (e) {} 
	    };
	    this.wrapper.onmouseout = function (e) { 
		    try { g.expanders[key].wrapperMouseHandler(e); } catch (e) {}
	    };
	    if (this.contentType == 'image' && this.outlineWhileAnimating == 2)
		    this.outlineWhileAnimating = 0;
	    if (g.pendingOutlines[this.outlineType]) {
		    this.connectOutline();
		    this[this.contentType +'Create']();
	    } else if (!this.outlineType) {
		    this[this.contentType +'Create']();
	    } else {
		    this.displayLoading();
		    var exp = this;
		    new g.Outline(this.outlineType, 
			    function () { 
				    exp.connectOutline();
				    exp[exp.contentType +'Create']();
			    } 
		    );
	    }
    };

    g.Expander.prototype = {

    connectOutline : function(x, y) {	
	    var w = g.pendingOutlines[this.outlineType];
	    this.objOutline = w;
	    w.table.style.zIndex = this.wrapper.style.zIndex;
	    g.pendingOutlines[this.outlineType] = null;
    },

    displayLoading : function() {
	    if (this.onLoadStarted || this.loading) return;
		    
	    this.originalCursor = this.a.style.cursor;
	    this.a.style.cursor = 'wait';
	    
	    this.loading = g.loading;
	    this.loading.href = 'javascript:g.expanders['+ this.key +'].cancelLoading()';
	    this.loading.style.top = (this.thumbTop 
		    + (this.thumbHeight - this.loading.offsetHeight) / 2) +'px';
	    var exp = this, left = (this.thumbLeft + this.thumbOffsetBorderW 
		    + (this.thumbWidth - this.loading.offsetWidth) / 2) +'px';
	    setTimeout(function () { if (exp.loading) exp.loading.style.left = left }, 100); 
    },

    imageCreate : function() {
	    var exp = this;
	    
	    var img = document.createElement('img');
        this.content = img;
        img.onload = function () { try { exp.contentLoaded(); } catch (e) {} };
        img.className = 'gallery-image';
        img.style.visibility = 'hidden'; 
        img.style.display = 'block';
	    img.style.position = 'absolute';
	    img.style.maxWidth = 'none';
        img.style.zIndex = 3;
        img.title = g.restoreTitle;
        if (g.safari) g.container.appendChild(img);
        img.src = g.getSrc(this.a);
	    
	    this.displayLoading();
    },

    contentLoaded : function() {
	    try { 
	    
		    if (!this.content) return;
		    if (this.onLoadStarted) return; 
		    else this.onLoadStarted = true;
		    
			       
		    if (this.loading) {
			    this.loading.style.left = '-9999px';
			    this.loading = null;
			    this.a.style.cursor = this.originalCursor || '';
		    }
		    this.marginBottom = g.marginBottom;	
			    this.newWidth = this.content.width;
			    this.newHeight = this.content.height;
			    this.fullExpandWidth = this.newWidth;
			    this.fullExpandHeight = this.newHeight;
			    
			    this.content.style.width = this.thumbWidth +'px';
			    this.content.style.height = this.thumbHeight +'px';		    
		    
		    this.wrapper.appendChild(this.content);
		    this.content.style.position = 'relative'; 
		    if (this.caption) this.wrapper.appendChild(this.caption);
		    this.wrapper.style.left = this.thumbLeft +'px';
		    this.wrapper.style.top = this.thumbTop +'px';
		    g.container.appendChild(this.wrapper);
		    
		    this.offsetBorderW = (this.content.offsetWidth - this.thumbWidth) / 2;
		    this.offsetBorderH = (this.content.offsetHeight - this.thumbHeight) / 2;
		    var modMarginRight = g.marginRight + 2 * this.offsetBorderW;
		    this.marginBottom += 2 * this.offsetBorderH;
		    
		    var ratio = this.newWidth / this.newHeight;
		    var minWidth = this.allowSizeReduction 
			    ? this.minWidth : this.newWidth;
		    var minHeight = this.allowSizeReduction 
			    ? this.minHeight : this.newHeight;
		    
		    var justify = { x: 'auto', y: 'auto' };
		    
		    var page = g.getPageSize();		
		    
		    this.x = { 
			    min: parseInt(this.thumbLeft) - this.offsetBorderW + this.thumbOffsetBorderW,
			    span: this.newWidth,
			    minSpan: (this.newWidth < minWidth && !g.padToMinWidth) 
				    ? this.newWidth : minWidth,
			    marginMin: g.marginLeft, 
			    marginMax: modMarginRight,
			    scroll: page.scrollLeft,
			    clientSpan: page.width,
			    thumbSpan: this.thumbWidth
		    };
		    var oldRight = this.x.min + parseInt(this.thumbWidth);
		    this.x = this.justify(this.x);
		    this.y = { 
			    min: parseInt(this.thumbTop) - this.offsetBorderH + this.thumbOffsetBorderH,
			    span: this.newHeight,
			    minSpan: this.newHeight < minHeight ? this.newHeight : minHeight,
			    marginMin: g.marginTop, 
			    marginMax: this.marginBottom, 
			    scroll: page.scrollTop,
			    clientSpan: page.height,
			    thumbSpan: this.thumbHeight
		    };
		    var oldBottom = this.y.min + parseInt(this.thumbHeight);
		    this.y = this.justify(this.y);
		    
			    this.correctRatio(ratio);
		    

		    var x = this.x;
		    var y = this.y;
		    
		    this.show();
	    } catch (e) {
		    window.location.href = g.getSrc(this.a);
	    }
    },

    justify : function (p) {
	    
	    var tgt, dim = p == this.x ? 'x' : 'y';
	    
		    var hasMovedMin = false;
		    
		    var allowReduce = true;
		    
		    p.min = Math.round(p.min - ((p.span - p.thumbSpan) / 2)); 
		    
		    if (p.min < p.scroll + p.marginMin) {
			    p.min = p.scroll + p.marginMin;
			    hasMovedMin = true;		
		    }		
		    
		    if (p.span < p.minSpan) {
			    p.span = p.minSpan;
			    allowReduce = false;
		    }
		    
		    if (p.min + p.span > p.scroll + p.clientSpan - p.marginMax) {
			    if (hasMovedMin && allowReduce) {
				    
				    p.span = p.clientSpan - p.marginMin - p.marginMax; 
				    
			    } else if (p.span < p.clientSpan - p.marginMin - p.marginMax) { 
				    p.min = p.scroll + p.clientSpan - p.span - p.marginMin - p.marginMax;
			    } else { 
				    p.min = p.scroll + p.marginMin;
				    
				    if (allowReduce) p.span = p.clientSpan - p.marginMin - p.marginMax;
				    
			    }
			    
		    }
		    
		    if (p.span < p.minSpan) {
			    p.span = p.minSpan;
			    allowReduce = false;
		    }
		    
	    
		    
	    if (p.min < p.marginMin) {
		    tmpMin = p.min;
		    p.min = p.marginMin; 
		    
		    if (allowReduce) p.span = p.span - (p.min - tmpMin);
		    
	    }
	    return p;
    },

    correctRatio : function(ratio) {
	    var x = this.x;
	    var y = this.y;
	    var changed = false;
	    if (x.span / y.span > ratio) { 
		    var tmpWidth = x.span;
		    x.span = y.span * ratio;
		    if (x.span < x.minSpan) { 
			    if (g.padToMinWidth) x.imgSpan = x.span;			
			    x.span = x.minSpan;
			    if (!x.imgSpan)
			    y.span = x.span / ratio;
		    }
		    changed = true;
	    
	    } else if (x.span / y.span < ratio) { // height greater
		    var tmpHeight = y.span;
		    y.span = x.span / ratio;
		    changed = true;
	    }
	    
	    if (changed) {
		    x.min = parseInt(this.thumbLeft) - this.offsetBorderW + this.thumbOffsetBorderW;
		    x.minSpan = x.span;
		    this.x = this.justify(x);
		    
		    y.min = parseInt(this.thumbTop) - this.offsetBorderH + this.thumbOffsetBorderH;
		    y.minSpan = y.span;
		    this.y = this.justify(y);
	    }
    },

    show : function () {
	    var imgPos = {x: this.x.min - 20, y: this.y.min - 20, w: this.x.span + 40, 
		    h: this.y.span + 40
		     + this.spaceForCaption};
	    g.hideSelects = (g.ie && g.ieVersion() < 7);
	    if (g.hideSelects) this.showHideElements('SELECT', 'hidden', imgPos);
	    
	    g.hideIframes = ((window.opera && navigator.appVersion < 9) || navigator.vendor == 'KDE' 
		    || (g.ie && g.ieVersion() < 5.5));
	    if (g.hideIframes) this.showHideElements('IFRAME', 'hidden', imgPos);
	    
	    
	    if (this.x.imgSpan) this.content.style.margin = '0 auto';
	    
	    this.changeSize(
		    1,
		    { 
			    x: this.thumbLeft + this.thumbOffsetBorderW - this.offsetBorderW,
			    y: this.thumbTop + this.thumbOffsetBorderH - this.offsetBorderH,
			    w: this.thumbWidth,
			    h: this.thumbHeight,
			    imgW: this.thumbWidth,
			    o: g.outlineStartOffset
		    },
		    {
			    x: this.x.min,
			    y: this.y.min,
			    w: this.x.span,
			    h: this.y.span,
			    imgW: this.x.imgSpan,
			    o: this.objOutline ? this.objOutline.offset : 0
		    },
		    g.expandDuration,
		    g.expandSteps
	    );
    },

    changeSize : function(up, from, to, dur, steps) {
	    
	    if (up && this.objOutline && !this.outlineWhileAnimating) 
		    this.objOutline.setPosition(this, this.x.min, this.y.min, this.x.span, this.y.span);
	    
	    else if (!up && this.objOutline) {
		    if (this.outlineWhileAnimating) this.objOutline.setPosition(this, from.x, from.y, from.w, from.h);
		    else this.objOutline.destroy();
	    }	
			    
	    if (!up) { 
		    var n = this.wrapper.childNodes.length;
		    for (i = n - 1; i >= 0 ; i--) {
			    var child = this.wrapper.childNodes[i];
			    if (child != this.content) {
				    g.purge(child);
				    this.wrapper.removeChild(child);
			    }
		    }
	    }
	    var dW = (to.w - from.w) / steps,
	    dImgW = (to.imgW - from.imgW) / steps,
	    dH = (to.h - from.h) / steps,
	    dX = (to.x - from.x) / steps,
	    dY = (to.y - from.y) / steps,
	    dO = (to.o - from.o) /steps,
	    t,
	    exp = this;
	    for (i = 1; i <= steps; i++) {
		    from.w += dW;
		    from.imgW += dImgW;
		    from.h += dH;
		    from.x += dX;
		    from.y += dY;
		    from.o += dO;
		    t = Math.round(i * (dur / steps));
		    
		    (function(){
			    var size = i < steps ? from : to, param = {}, pI = i;
			    for (var x in size) param[x] = size[x];
			    
			    setTimeout ( function() {
				    if (up && pI == 1) {
					    exp.content.style.visibility = 'visible';
					    exp.a.className += ' gallery-active-anchor';
				    }
				    exp.setSize(param);
			    }, t);				
		    })();		
	    }
	    
	    if (up) { 
			    
		    setTimeout(function() {
			    if (exp.objOutline) exp.objOutline.table.style.visibility = "visible";
		    }, t);
		    setTimeout(function() {
			    if (exp.caption) exp.writeCaption();
			    exp.afterExpand();
		    }, t +50);
	    }
	    else setTimeout(function() { exp.afterClose(); }, t);
		    
    },

    setSize : function (to) {
	    try {
			    this.wrapper.style.width = (to.w + 2*this.offsetBorderW) +'px';
			    this.content.style.width = (to.imgW || to.w) +'px';
			    this.content.style.height = to.h +'px';
				    
		    
		    
		    if (this.objOutline && this.outlineWhileAnimating) {
			    var o = this.objOutline.offset - to.o;
			    this.objOutline.setPosition(this, to.x + o, to.y + o, to.w - 2 * o, to.h - 2 * o, 1);
		    }
				    
		    g.setStyles ( this.wrapper,
			    {
				    'visibility': 'visible',
				    'left': to.x +'px',
				    'top': to.y +'px'
			    }
		    );
		    
	    } catch (e) { window.location.href = g.getSrc(this.a);	}
    },

    afterExpand : function() {
	    this.isExpanded = true;	
	    this.focus();
	    
	    this.createOverlays();
	    if (this.fullExpandWidth > this.x.span) this.createFullExpand();
	    if (!this.caption) this.prepareNextOutline();
    },


    prepareNextOutline : function() {
	    var key = this.key;
	    var outlineType = this.outlineType;
	    new g.Outline(outlineType, 
		    function () { try { g.expanders[key].preloadNext(); } catch (e) {} });
    },


    preloadNext : function() {
	    var next = g.getAdjacentAnchor(this.key, 1);	
	    if (next.onclick.toString().match(/g\.expand/)) 
		    var img = g.createElement('img', { src: g.getSrc(next) });
    },

    cancelLoading : function() {		
	    g.expanders[this.key] = null;
	    this.a.style.cursor = this.originalCursor;	
	    if (this.loading) g.loading.style.left = '-9999px';
    },                                                          
    
    showHideElements : function (tagName, visibility, imgPos) {
	    var els = document.getElementsByTagName(tagName);
	    if (els) {			
		    for (i = 0; i < els.length; i++) {
			    if (els[i].nodeName == tagName) {  
				    var hiddenBy = els[i].getAttribute('hidden-by');
				    if (visibility == 'visible' && hiddenBy) {
					    hiddenBy = hiddenBy.replace('['+ this.key +']', '');
					    els[i].setAttribute('hidden-by', hiddenBy);
					    if (!hiddenBy) els[i].style.visibility = 'visible';
				    } else if (visibility == 'hidden') { 
					    var elPos = g.position(els[i]);
					    elPos.w = els[i].offsetWidth;
					    elPos.h = els[i].offsetHeight;
				    
					    
						    var clearsX = (elPos.x + elPos.w < imgPos.x || elPos.x > imgPos.x + imgPos.w);
						    var clearsY = (elPos.y + elPos.h < imgPos.y || elPos.y > imgPos.y + imgPos.h);
					    
					    var wrapperKey = g.getWrapperKey(els[i]);
					    if (!clearsX && !clearsY && wrapperKey != this.key) { 
						    if (!hiddenBy)
							    els[i].setAttribute('hidden-by', '['+ this.key +']');
						    else if (!hiddenBy.match('['+ this.key +']'))
							    els[i].setAttribute('hidden-by', hiddenBy + '['+ this.key +']');
						    els[i].style.visibility = 'hidden';
					    } else if (hiddenBy == '['+ this.key +']' || g.focusKey == wrapperKey) { 
						    els[i].setAttribute('hidden-by', '');
						    els[i].style.visibility = 'visible';
					    } else if (hiddenBy && hiddenBy.match('['+ this.key +']')) {
						    els[i].setAttribute('hidden-by', hiddenBy.replace('['+ this.key +']', ''));
					    }
				    }   
			    }
		    }
	    }
    },

    focus : function() {
	    this.wrapper.style.zIndex = g.zIndexCounter++;        
	    if (this.objOutline) this.objOutline.table.style.zIndex 
		    = this.wrapper.style.zIndex;
	    
	    this.content.className = 'gallery-'+ this.contentType;
		    this.content.title = g.restoreTitle;
		    
		    g.styleRestoreCursor = window.opera ? 'pointer' : 'url('+ g.graphicsDir + g.restoreCursor +'), pointer';
		    if (g.ie && g.ieVersion() < 6) g.styleRestoreCursor = 'hand';
		    this.content.style.cursor = g.styleRestoreCursor;		    
    },

    move : function (e) {
	    this.x.min = e.left + e.dX;
	    this.y.min = e.top + e.dY;
	    
	    g.setStyles(this.wrapper, { left: this.x.min +'px', top: this.y.min +'px' });
	    
	    if (this.objOutline)
		    this.objOutline.setPosition(this, this.x.min, this.y.min, this.x.span, this.y.span);
	    
    },

    close : function() {
	    if (this.isClosing || !this.isExpanded) return;
	    this.isClosing = true;
	    try {
		    
		    this.content.style.cursor = 'default';
		    
		    this.changeSize(
			    0,
			    {
				    x: this.x.min,
				    y: this.y.min,
				    w: this.x.span,
				    h: parseInt(this.content.style.height),
				    imgW: this.x.imgSpan,
				    o: this.objOutline ? this.objOutline.offset : 0
			    },
			    {
				    x: this.thumbLeft - this.offsetBorderW + this.thumbOffsetBorderW,
				    y: this.thumbTop - this.offsetBorderH + this.thumbOffsetBorderH,
				    w: this.thumbWidth,
				    h: this.thumbHeight,
				    imgW: this.thumbWidth,
				    o: g.outlineStartOffset
			    },
			    g.restoreDuration,
			    g.restoreSteps
		    );
		    
	    } catch (e) { this.afterClose(); } 
    },

    createOverlay : function (o) {
	    var el = o.overlayId;
	    if (typeof el == 'string') el = g.getNode(el);
	    if (!el || typeof el == 'string') return;
	    
	    
	    var overlay = g.createElement(
		    'div',
		    null,
		    {
			    'left' : 0,
			    'top' : 0,
			    'position' : 'absolute',
			    'zIndex' : 3,
			    'visibility' : 'hidden'
		    },
		    this.wrapper,
		    true
	    );
	    if (o.opacity) g.setStyles(el, { opacity: o.opacity });
	    el.className += ' gallery-display-block';
	    overlay.appendChild(el);	
	    
	    overlay.hsPos = o.position;
	    this.positionOverlay(overlay);	
	    
	    if (o.hideOnMouseOut) overlay.setAttribute('hideOnMouseOut', true);
	    if (!o.opacity) o.opacity = 1;
	    overlay.setAttribute('opacity', o.opacity);
	    g.fade(overlay, 0, o.opacity);
	    
	    g.push(this.overlays, overlay);
    },

    positionOverlay : function(overlay) {
	    var left = this.offsetBorderW;
	    var dLeft = this.x.span - overlay.offsetWidth;
	    var top = this.offsetBorderH;
	    var dTop = parseInt(this.content.style.height) - overlay.offsetHeight;
	    
	    var p = overlay.hsPos || 'center center';
	    if (/^bottom/.test(p)) top += dTop;
	    if (/^center/.test(p)) top += dTop / 2;
	    if (/right$/.test(p)) left += dLeft;
	    if (/center$/.test(p)) left += dLeft / 2;
	    overlay.style.left = left +'px';
	    overlay.style.top = top +'px';
    },

    createOverlays : function() {
	    for (i = 0; i < g.overlays.length; i++) {
		    var o = g.overlays[i];
		    if ((!o.thumbnailId && !o.slideshowGroup) || o.thumbnailId == this.thumbsUserSetId
				    || o.slideshowGroup === this.slideshowGroup) {
			    this.createOverlay(o);
		    }
	    }
    },


    createFullExpand : function () {
	    var a = g.createElement(
		    'a',
		    {
			    href: 'javascript:g.expanders['+ this.key +'].doFullExpand();',
			    title: g.fullExpandTitle,
			    className: 'gallery-full-expand'
		    }
	    );
	    
	    this.fullExpandLabel = a;
	    this.createOverlay({ overlayId: a, position: g.fullExpandPosition, 
		    hideOnMouseOut: true, opacity: g.fullExpandOpacity });
    },

    doFullExpand : function () {
	    try {	
		    g.purge(this.fullExpandLabel);
		    this.fullExpandLabel.parentNode.removeChild(this.fullExpandLabel);
		    this.focus();
		    
		    this.x.min = parseInt(this.wrapper.style.left) - (this.fullExpandWidth - this.content.width) / 2;
		    if (this.x.min < g.marginLeft) this.x.min = g.marginLeft;		
		    this.wrapper.style.left = this.x.min +'px';
		    
		    g.setStyles(this.content, { width: this.fullExpandWidth +'px', 
			    height: this.fullExpandHeight +'px'});
		    
		    this.x.span = this.fullExpandWidth;
		    this.wrapper.style.width = (this.x.span + 2*this.offsetBorderW) +'px';
		    
		    this.y.span = this.wrapper.offsetHeight - 2 * this.offsetBorderH;
		    
		    if (this.objOutline)
			    this.objOutline.setPosition(this, this.x.min, this.y.min, this.x.span, this.y.span);
		    
		    for (var i = 0; i < this.overlays.length; i++)
			    this.positionOverlay(this.overlays[i]);
		    
		    this.redoShowHide();
		    
		    
	    
	    } catch (e) {
		    window.location.href = this.content.src;
	    }
    },

    redoShowHide : function() {
	    var imgPos = {
		    x: parseInt(this.wrapper.style.left) - 20, 
		    y: parseInt(this.wrapper.style.top) - 20, 
		    w: this.content.offsetWidth + 40, 
		    h: this.content.offsetHeight + 40 
			    + this.spaceForCaption
	    };
	    if (g.hideSelects) this.showHideElements('SELECT', 'hidden', imgPos);
	    if (g.hideIframes) this.showHideElements('IFRAME', 'hidden', imgPos);

    },

    wrapperMouseHandler : function (e) {
	    if (!e) e = window.event;
	    var over = /mouseover/i.test(e.type); 
	    if (!e.target) e.target = e.srcElement;
	    if (!e.relatedTarget) e.relatedTarget = 
		    over ? e.fromElement : e.toElement;
	    if (g.getExpander(e.relatedTarget) == this || g.dragArgs) return;
	    for (i = 0; i < this.overlays.length; i++) {
		    var o = this.overlays[i];
		    if (o.getAttribute('hideOnMouseOut')) {
			    var from = over ? 0 : o.getAttribute('opacity'),
				    to = over ? o.getAttribute('opacity') : 0;			
			    g.fade(o, from, to);
		    }
	    }
    },

    afterClose : function () {
	    this.a.className = this.a.className.replace('gallery-active-anchor', '');
	    
	    if (g.hideSelects) this.showHideElements('SELECT', 'visible');
	    if (g.hideIframes) this.showHideElements('IFRAME', 'visible');
		    if (this.objOutline && this.outlineWhileAnimating) this.objOutline.destroy();
		    g.purge(this.wrapper);
		    if (g.ie && g.ieVersion() < 5.5) this.wrapper.innerHTML = '';
		    else this.wrapper.parentNode.removeChild(this.wrapper);
	    g.expanders[this.key] = null;		
	    g.cleanUp();
    }
};
var HsExpander = g.Expander;
g.addEventListener(document, 'mousedown', g.mouseClickHandler);
g.addEventListener(document, 'mouseup', g.mouseClickHandler);
g.addEventListener(window, 'load', g.preloadImages);