/* ~ common.js (8302 bytes) ~ */

function isset(avar) {
  return typeof avar != 'undefined';
}

function IsIE() {
  // window.ie_specific is set in <head> using CDATA comment so
  //   even a masked Opera won't be a problem.
  return typeof ie_specific != 'undefined';
}

function IsTheTag(element, needed_tag) {
  return typeof element == 'object' && element &&
		 element.nodeType == 1 &&
		 element.tagName.toUpperCase() == needed_tag.toUpperCase();
}

function CancelPropagationOf(event) {
	event.cancelBubble = true;    // IE
	if (event.stopPropagation) {  // W3C
    event.stopPropagation();
  }

  event.returnValue = false;
  if (event.preventDefault) {
    event.preventDefault();
  }
}

function RequestScript(url, data) {
  var request = CreateXHRequest();
  if (request) {
	var method = data ? 'POST' : 'GET';
    request.open(method, url, true);
    request.onreadystatechange = function () {
      if (request.readyState == 4 && (request.status == 200 || request.status == 304 /*not modified*/)) {
        eval(request.responseText);
      }
    }

	if (data) {
	  request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	  request.setRequestHeader('Content-Length', data.length);
	}

    request.send(data);
  } else {
    var span = document.createElement('SPAN');
    span.style.display = 'none';

	if (data) {
	  if (url.indexOf('?') == -1) {
		url += '?';
	  }
	  url += '&' + data;
	}

    span.innerHTML = 'IE workaround. ' +
                     '<sc'+'ript type="text/javascript" src="' + url + '"></scri'+'pt>';

    document.body.appendChild(span);
  }
  
  return request;
}

function CreateXHRequest() {
  var request;

  try {
    request = new XMLHttpRequest();
  } catch (e) {
    var activex = new Array("MSXML2.XMLHTTP.6.0",
                            "MSXML2.XMLHTTP.5.0",
                            "MSXML2.XMLHTTP.4.0",
                            "MSXML2.XMLHTTP.3.0",
                            "MSXML2.XMLHTTP",
                            "Microsoft.XMLHTTP");

    for (var i = 0; i < activex.length && !request; i++) {
      try {
        request = new ActiveXObject(activex[i]);
      } catch (e) {}
    }
  }

  return request ? request : null;
}

function HTMLToWrappedNodes(html, multiple_as_array) {
  if (html) {
	var wrapper = document.createElement('div');
	wrapper.innerHTML = html.replace(/^\s+/, '').replace(/\s+$/, '');

	return (wrapper.childNodes.length == 1 ? wrapper.firstChild :
			(multiple_as_array ? wrapper.childNodes : wrapper));
  } else {
	return null;
  }
}

function HTMLToNode(html) {
  return HTMLToWrappedNodes(html, true);
}

function ModifyClassNameOf(element, class_name, append) {
  if (typeof element == 'object' && element) {
      var regexp = RegExp('\\b' + class_name + '\\b', 'g');
    if (!isset(append) || append) {
      if (!regexp.test(element.className)) {
        element.className += ' ' + class_name;
      }
    } else {
      element.className = element.className.replace(regexp, '');
    }
  }
}

function EscapeForString(str) {
  return str.replace(/([\r\n'\\])/g, '\\$1');
}

function Bookmark(url, title) {
  if (typeof url == 'object' && url && url.href) {
    var anchor = url;
    url = anchor.href;
    title = anchor.title;
  }

  try {
    window.external.AddFavorite(url, title);
  } catch (e) {}
}

function SetHomePage(anchor, url) {
  if (typeof anchor == 'object' && anchor && anchor.style) {
    try {
      anchor.style.behavior='url(#default#homepage)';
      url = isset(url) ? url : document.location.href;
      anchor.setHomePage(url);
    } catch (e) {}
  }
}

function ShouldBe(defined) {
  if (!isset(defined) || defined == false) {
    if (isset(console)) {
      console.trace();
    }

    throw 'Something has gone wrong.';
  }
}

function $() {
  var a = [];
  var cx = window;

  for (var i = 0, l = arguments.length; i < l; i++) {
    var element = arguments[i];

    if (typeof arguments[i] == 'string') {
      element = document.getElementById(arguments[i]);
    }

    a.push(element);
  }

  var result = (a.length > 1 ? a : a[0]);
  ShouldBe(result);
  return result;
}

// Got from http://www.tigir.com/javascript.htm
function $style(element, prop, new_value) {
  if (typeof element == 'string') {
    element = $(element);
  }

  if (new_value) {
    var old_value = element.style[prop];
    element.style[prop] = new_value;
    return old_value;
  } else {
    if (document.defaultView && document.defaultView.getComputedStyle) {
      if (prop.match(/[A-Z]/)) prop = prop.replace(/([A-Z])/g, "-$1").toLowerCase();
      return document.defaultView.getComputedStyle(element, '').getPropertyValue(prop);
    } else if (element.currentStyle) {
      while ((i = prop.indexOf("-")) != -1) {
        prop = prop.substr(0, i) + prop.substr(i + 1, 1).toUpperCase() + prop.substr(i + 2);
      }
      return element.currentStyle[prop];
    } else {
      return '';
    }
  }
}

function GetAbsoluteXOf(element) {
  var x = 0;

  while (element) {
    x += element.offsetLeft;
    element = element.offsetParent;
  }

  return x;
}

function GetAbsoluteYOf(element) {
  var y = 0;

  while (element) {
    y += element.offsetTop;
    element = element.offsetParent;
  }

  return y;
}

// alpha is in range of 0-100.
function $opacity(element, alpha) {
  alpha = parseInt(alpha);
  if (!isNaN(alpha)) {
    $style(element, 'opacity', alpha / 100);
    $style(element, 'filter', 'alpha(opacity=' + alpha + ')');
  } else {
    alpha = $style(element, 'opacity');
    return isNaN(alpha) ? 100 : alpha;
  }
}

function GetScrollX() {
  return self.pageXOffset || (document.documentElement && document.documentElement.scrollLeft) ||
         (document.body && document.body.scrollLeft);
}

function GetScrollY() {
  return self.pageYOffset || (document.documentElement && document.documentElement.scrollTop) ||
         (document.body && document.body.scrollTop);
}

function $get(id) {
  var element = $(id);

  switch (element.tagName) {
  case 'INPUT':
  case 'TEXTAREA':
    return element.value;
  default:
    return element.innerHTML;
  }
}

function $set(id, value) {
  var element = $(id);
  switch (element.tagName) {
  case 'INPUT':
  case 'TEXTAREA':
    element.value = value;
    break;
  default:
    element.innerHTML = value;
  }
}

function random(min, max) {
  min = parseInt(min);
  max = parseInt(max);
  return Math.floor( Math.random() * (max - min + 1) ) + min;
}

// got from xpoint.ru
function AddOnLoad(f) {
   var root = window.addEventListener || window.attachEvent ? window : document.addEventListener ? document : null
   if (root){
      if(root.addEventListener) root.addEventListener("load", f, false)
      else if(root.attachEvent) root.attachEvent("onload", f)
   } else {
      if(typeof window.onload == 'function') {
         var existing = window.onload
         window.onload = function() {
            existing()
            f()
         }
      } else {
         window.onload = f
      }
   }
}

function GetCookie(name) {
  var start = document.cookie.indexOf(name + "=");
  var len = start + name.length + 1;
  if (!start && name != document.cookie.substring(0, name.length)) {
	return null;
  }
  if (start == -1) {
	return null;
  }

  var end = document.cookie.indexOf(';', len);
  if (end == -1) {
	end = document.cookie.length;
  }
  return unescape( document.cookie.substring(len, end) );
}

// expires - hours.
function SetCookie( name, value, expires, path, domain, secure ) {
  // set time, it's in milliseconds
  var today = new Date();
  today.setTime( today.getTime() );

  if (expires) {
    expires = expires * 1000 * 60 * 60;
  }
  var expires_date = new Date( today.getTime() + expires );

  document.cookie = name + "=" + escape(value) +
                    ( (expires) ? ";expires=" + expires_date.toGMTString() : "" ) +
                    ( (path)    ? ";path=" + path : "" ) +
                    ( (domain)  ? ";domain=" + domain : "" ) +
                    ( (secure)  ? ";secure" : "" );
}


/* ~ display.js (16672 bytes) ~ */

function mylo(part1, part2, title) {
  var gde = '@';
  var mail = part1 + gde + part2 + '.ru';

  document.write('<' + 'a class="email" href="');
  document.write('mailto:' + mail + '?subject=Лавилин-Аптека');
  document.write('">');
  document.write((title || mail) + '<' + '/a>');
}

function BuildFormURL(prefix, fields) {
  var url = '';

  for (var i = 0; i < fields.length; i++) {
    url += '&' + prefix + '[' + fields[i] + ']=' +
            encodeURIComponent( $(prefix + '_' + fields[i]).value );
  }

  return url;
}

function AddOnBackScript(script) {
  var saver = $('js_page_mod_saver');
  if (saver) {
    if (saver.value.length > 10000) {
      saver.value = '';
    }
    saver.value += '\ntry { ' + script + ' } catch (e) {};\n';
  }
}

function SaveJSModificationOf(container) {
  if (container) {
    var dom_path = CalcDOMPathOf(container);
    AddOnBackScript(dom_path + '.innerHTML = \'' + EscapeForString(container.innerHTML) + '\';');
  }
}

  function CalcDOMPathOf(element) {
    element = $(element);
    if (element) {
      var parent = element.parentNode;

      if (IsTheTag(parent, 'html')) {
        return 'document.body';
      } else {
        var parent_index = 0;
        while (parent_index < parent.childNodes.length) {
          if (parent.childNodes[parent_index] == element) {
            var path = 'childNodes[' + parent_index + ']';

            var parent_path = CalcDOMPathOf(parent);
            if (parent_path) {
              path = parent_path + '.' + path;
            }

            return path;
          } else {
            parent_index++;
          }
        }
      }
    }

    return '';
  }

AddOnLoad(function () {
  var saver = $('js_page_mod_saver');
  if (saver) {
    eval(saver.value);
  }
});

function GetDeliveryKind() {
  for (var i = 0; i < 50; i++) {
    if ($('info_delivery_kind_' + i).checked) {
      return i;
    }
  }

  return 0;
}

function DeliveryKindOnChange() {
  $('info_metro_wrapper').style.visibility = GetDeliveryKind() == 0 ? '' : 'hidden';
}

function IsWithNotice(order_wrapper) {
  if (IsTheTag(order_wrapper, 'div') && order_wrapper.className.indexOf('order-incart-wrapper') != -1) {
    var chilren_count = 0;

      for (var i = 0; chilren_count < 2 && i < order_wrapper.childNodes.length; i++) {
        if (order_wrapper.childNodes[i].nodeType == 1) {
          chilren_count++;
        }
      }

    return chilren_count > 1;
  } else {
    return 0;
  }
}

function ClearThisEditOnFocus(edit, default_value) {
  if (edit) {
    edit.onfocus = function () {
      if (edit.value == default_value) {
        edit.value = '';
      } else {
        edit.select();
      }
    }
  }
}

// useful to emulate :hover CSS pseudo-class on IE.
function EmulateHOverOn(element) {
  function ToggleHOver(is_over) {
    ModifyClassNameOf(element, 'hovered', is_over);
  }

  element.onmousemove = function () { ToggleHOver(true); }
  element.onmouseout = function () { ToggleHOver(false); }
}

// -------------- server interaction

function HookRemoveButton(button) {
  if (IsTheTag(button, 'a')) {
    button.onmousemove = null;
    var disabled = false;

    var callback = function (html, cart_became_empty) {
      var wrapper = button.parentNode.parentNode.parentNode.parentNode;
      if (IsTheTag(wrapper, 'div') && wrapper.className.indexOf('order-incart-wrapper') != -1) {
        wrapper.innerHTML = html;
        SaveJSModificationOf(wrapper);
        ModifyClassNameOf($('cart_menu_item'), 'menu-non-empty-cart', !cart_became_empty);
        return true;
      } else {
        return false;
      }
    }

    button.onclick = function () {
      if (!disabled) {
        disabled = true;
        button.style.backgroundImage = 'url(images/order_submitting.gif)';

        var request = new ScriptRequest(button.href, callback);
        request.navigate_on_failure = true;
        request.js_param_prefix = '==';
        request.Perform();
      }

      return false;
    }
  }
}

function HookRecalcButton(button) {
  var form = button;
  while (form && !IsTheTag(form, 'form')) {
    form = form.parentNode;
  }

  if (form && IsTheTag(button, 'button') || IsTheTag(button, 'input')) {
    button.onmousemove = null;
    var disabled = false;
    var order_wrapper = form.parentNode.parentNode.parentNode.parentNode.parentNode;

    var callback = function (html) {
      if (html && IsTheTag(order_wrapper, 'div') &&
          order_wrapper.className.indexOf('order-incart-wrapper') != -1) {
        order_wrapper.innerHTML = html;
        SaveJSModificationOf(order_wrapper);
        return true;
      } else {
      return false;
      }
    }

    form.onsubmit = function () {
      if (!disabled) {
        disabled = true;

        var quantity = button.previousSibling;
        while (quantity && (!IsTheTag(quantity, 'input') || quantity.id.indexOf('quantity') == -1)) {
          quantity = quantity.previousSibling;
        }

        if (quantity) {
          if (isNaN(quantity.value)) {
            quantity.select();
            quantity.focus();
          } else {
            var url = form.action + '?recalc=1&' + quantity.name + '=' + quantity.value;

            if (!IsWithNotice(order_wrapper)) {
              url += '&no_notice=1';
            }

            var request = new ScriptRequest(url, callback);
            request.navigate_on_failure = true;
            request.on_request_failure = function () { disabled = false; form.submit(); }
            request.Perform();

            button.innerHTML = '<img src="images/order_submitting.gif"' +
                               '     alt="' + button.innerHTML + '" />';
            button.disabled = true;
          }
        }
      }

      return false;
    }
  }
}

function HookCommentButton(button) {
  if (IsTheTag(button, 'button') || IsTheTag(button, 'input')) {
    button.onmousemove = null;
    var disabled = false;
    AddOnBackScript(CalcDOMPathOf(button) + '.disabled = false;');

    var callback = function (state, message, comment) {
      var form_wrapper = $('add_comment_form_wrapper');
      if (form_wrapper) {
        if (state == 'added-ok') {
          var no_comments_heading = form_wrapper.previousSibling;
          if (IsTheTag(no_comments_heading, 'h4')) {
            no_comments_heading.parentNode.removeChild(no_comments_heading);
          }

          form_wrapper.parentNode.replaceChild(HTMLToNode(message), form_wrapper);

          var comments_follow = $('comments_follow_this');
          var new_comment = HTMLToNode(comment);
          new_comment.className += ' added-comment';
          comments_follow.parentNode.insertBefore(new_comment, comments_follow.nextSibling);

          SaveJSModificationOf(comments_follow.parentNode);
          return true;
        } else if (state == 'wrong-fill') {
          var message_element = $('new_comment_message');
          if (message_element) {
            message_element.innerHTML = message;
            SaveJSModificationOf(message_element);
            return true;
          }
        }
      }

      return false;
    }

      function GetForm() {
        var form = button;
        while (form && !IsTheTag(form, 'form')) {
          form = form.parentNode;
        }
        return form;
      }

    GetForm().onsubmit = function () {
      if (!disabled) {
        ToggleUI(false);

        var url = GetForm().action + '?' + BuildFormURL('comment', ['author', 'occupation']);
        var request = new ScriptRequest(url, callback);
        request.navigate_on_failure = true;
        request.post_data = 'comment[text]=' + encodeURIComponent( $('comment_text').value );
        request.on_end = function () { ToggleUI(true); }
        request.on_request_failure = function () { GetForm().submit(); }
        request.Perform();
      }

      return false;
    }
  }

  function ToggleUI(state) {
    disabled = !state;
    button.disabled = !state;

    var btn_wrapper = button.parentNode;
    if (IsTheTag(btn_wrapper, 'span')) {
      btn_wrapper.style.backgroundImage = state ? '' : 'url(images/order_submitting.gif)';
    }
  }
}

function HookCheckoutFormButton(button) {
  if (button) {
    button.onmousemove = null;

    if (!isset(window.checkout_button_state)) {
      window.checkout_button_state = 'initial';
    }

    callback = function (state, html) {
      var form = HTMLToWrappedNodes(html);
      if (state == 'form-fill' && form) {
        var slider = new Slider(form);
        form.style.display = 'none';
        $('body_wrapper').appendChild(form);
        slider.Expand();
        slider.enabled = false;

        AddOnBackScript('var form = HTMLToWrappedNodes(\'' + EscapeForString(html) + '\');' +
                        'window.checkout_button_state = form;' +
                        '$(\'body_wrapper\').appendChild(form);');

        ToggleUI(form);
        return true;
      } else {
        return false;
      }
    }

    button.onclick = function () {
      var state = window.checkout_button_state;

      if (state == 'initial') {
        ToggleUI('disabled');
        var request = new ScriptRequest('kassa?', callback);
        request.navigate_on_failure = true;
        request.Perform();
      } else if (state != 'disabled') {
        state.scrollIntoView(true);
      }

      return false;
    }
  }

  function ToggleUI(state) {
    window.checkout_button_state = state;
    button.style.backgroundImage = state == 'disabled' ? 'url(images/order_submitting.gif)' : '';
  }
}

function HookCheckoutButton(button) {
  if (IsTheTag(button, 'button') || IsTheTag(button, 'input')) {
    button.onmousemove = null;
    var disabled = false;
    AddOnBackScript(CalcDOMPathOf(button) + '.disabled = false;');

    var callback = function (state, html) {
      if (state == 'sent-ok') {
        var body = $('body_wrapper');
        body.innerHTML = html;
        SaveJSModificationOf(body);
        ModifyClassNameOf($('cart_menu_item'), 'menu-non-empty-cart', false);
      } else {
        var message = $('checkout_message');
        message.innerHTML = html;
        SaveJSModificationOf(message);

        ToggleUI(true);
      }

      return true;
    }

      function GetForm() {
        var form = button;
        while (form && !IsTheTag(form, 'form')) {
          form = form.parentNode;
        }
        return form;
      }

    GetForm().onsubmit = function () {
      if (!disabled) {
        ToggleUI(false);

        var url = GetForm().action + '?ready_to_go=1&' +
                  BuildFormURL('info', ['name', 'phone', 'call_time', 'email', 'metro']) +
                  '&info[delivery_kind]=' + GetDeliveryKind();

        var request = new ScriptRequest(url, callback);
        request.navigate_on_failure = true;
        request.on_end = function () { ToggleUI(true); }
        request.on_request_failure = function () { GetForm().submit(); }
        request.Perform();
      }

      return false;
    }
  }

  function ToggleUI(state) {
    disabled = !state;
    button.disabled = !state;

    var btn_wrapper = button.parentNode;
    if (IsTheTag(btn_wrapper, 'span')) {
      btn_wrapper.style.backgroundImage = state ? '' : 'url(images/order_submitting.gif)';
    }
  }
}

function HookOrderButton(element) {
  new OrderHandler(element)
}

function OrderHandler(element) {
  this.Initialize = function () {
    this.fields = {quantity: null}
    this.default_quantity = null;
    this.no_submit = false;

    this.Hook = function (element) {
      this.fields = this.FindFields(element);
      if (this.fields.qty_input) {
        var self = this;

        this.fields.submit = element;
        this.fields.wrapper.onmousemove = this.Method('MouseMoved');
        this.fields.wrapper.onmouseout = this.Method('MouseOut');

        element.onclick = function () {
          self.SubmitOrder();
          return false;
        }

        this.default_quantity = this.fields.qty_input.value;
        this.HookQuantityField(this.fields.qty_input);
      }
    }

    this.FindFields = function (submit_button) {
      var item_id = submit_button.getAttribute('rel');
      return {qty_input: $('quantity_' + item_id),
              qty_display: $('qty_display_' + item_id),
              price: $('price_' + item_id),
              total: $('total_' + item_id),
              wrapper: submit_button.parentNode.parentNode}
    }

    this.HookQuantityField = function (element) {
      element.setAttribute('autocomplete', 'off');

      var self = this;

      element.onkeyup = function (e) {
        e = e ? e : event;
        if (e.keyCode == 13) {
          self.SubmitOrder();
        } else {
          self.UpdateTotalSum();
        }
      }
    }

    this.Method = function (method_name) {
      var method = this[ method_name ];

      if (typeof method == 'function') {
        var args = Array.prototype.slice.call(arguments); // args object -> array
        args.shift();

        var self = this;
        return function () { return method.apply(self, args); }
      } else {
        this.Error('Method ' + method_name + ' does not exist.');
        return Function();
      }
    }

    this.Error = function (message) {
      if (typeof console == 'object' && console) {
        console.error(message);
      }
    }

    this.MouseMoved = function () {
      this.ToggleQuantityField(true);
    }

    this.MouseOut = function () {
      this.ToggleQuantityField(false);
    }

    this.ToggleQuantityField = function (visible) {
      var input = this.fields.qty_input;
      newvisibility = this.no_submit || visible ? 'visible' : '';

      if (input.parentNode && input.parentNode.style &&  // <= IE The Great.
          input.parentNode.style.visibility != newvisibility) {
        input.parentNode.style.visibility = newvisibility;
        this.fields.total.parentNode.style.visibility = newvisibility;

        if (visible) {
          input.select();
          input.focus();
          this.UpdateTotalSum();
        } else {
          input.value = this.default_quantity;
        }
      }
    }

    this.UpdateTotalSum = function () {
      if (this.CheckQuantity()) {
          var qty = this.Quantity();
        this.fields.qty_display.innerHTML = qty;
        this.fields.total.innerHTML = qty * this.fields.price.innerHTML;
      }
    }

    this.SubmitOrder = function () {
      if (!this.no_submit) {
        if (this.CheckQuantity()) {
          this.DisableFurtherSubmitting();
          this.SendOrder(this.Quantity());
        } else {
          this.fields.qty_input.select();
        }
      }
    }

    this.SendOrder = function (quantity) {
      var url = this.fields.submit.href + '=' + quantity;
      var self = this;
      var request = new ScriptRequest( url, function (html) { return self.OrderReqCallback(html); } );

      request.navigate_on_failure = true;
      request.js_param_prefix = '=';
      if (location.href.indexOf('zakaz') != -1 || location.href.indexOf('korzina') != -1) {
        request.js_param_prefix += '!';
      }

      request.Perform();
    }

      this.OrderReqCallback = function (html) {
        var order_wrapper = this.fields.submit.parentNode;
        if (IsTheTag(order_wrapper, 'div') &&
            order_wrapper.className.indexOf('order-add-wrapper') != -1) {
          var order_wrapper = order_wrapper.parentNode;
          order_wrapper.innerHTML = html;
          SaveJSModificationOf(order_wrapper);

          ModifyClassNameOf($('cart_menu_item'), 'menu-non-empty-cart', true);
          return true;
        } else {
          return false;
        }
      }

    this.CheckQuantity = function () {
      var qty = this.Quantity();
      return qty != '' && !isNaN(qty);
    }

    this.Quantity = function () {
      return this.fields.qty_input.value;
    }

    this.DisableFurtherSubmitting = function () {
      this.no_submit = true;
      this.fields.submit.style.backgroundImage = 'url(images/order_submitting.gif)';
    }
  }

  this.Initialize();

  if (IsTheTag(element, 'a')) {
    this.Hook(element);
  }
}


/* ~ scriptrequest.js (2214 bytes) ~ */

function ScriptRequest(url, on_receive) {
  this.timeout = 15000;

  this.cancelled = true;
  this.url = url;
  this.js_param_prefix = '&js=';
  this.post_data = null;
  this.navigate_on_failure = false;
  this.on_receive = on_receive;
  this.on_end = function () { }
  this.on_request_failure = function () { }

  this.timer = null;
  this.object_index = null;
  this.callback_name = null;

  this.Perform = function () {
    this.cancelled = false;

    var prefix = this.navigate_on_failure ? this.js_param_prefix : '';
    var url = this.url + prefix + encodeURIComponent(this.callback_name);
    this.xhrObject = RequestScript(url, this.post_data);

    var self = this;
    this.timer = setTimeout(function () { self.RequestFailed(); }, this.timeout);
  }

  this.Callback = function () {
    if (!this.cancelled) {
      this.End();

      var args = this.ArgumentsToArray(arguments);

      if (args.length) {
        if (!this.on_receive.apply(this, args)) {
          args = [];
        }
      }

      if (!args.length) {
        this.RequestFailed();
      }
    }
  }

    this.ArgumentsToArray = function (argsObject) {
      return Array.prototype.slice.call(argsObject);
    }

  this.RequestFailed = function () {
    this.End();
    if (this.navigate_on_failure) {
      location.href = this.url;
    }
    this.call_back(this.on_request_failure);
  }

  this.End = function () {
    this.cancelled = true;
    clearTimeout(this.timer);
    
    if (typeof this.xhrObject == 'object' && this.xhrObject &&
        typeof this.xhrObject.abort == 'function') {
      this.xhrObject.abort();
    }
    
    this.call_back(this.on_end);
  }

  this.call_back = function (func) {
    if (typeof func == 'function') {
      func.apply(this);
    }
  }

  this.AssignTempObject = function () {
    if (!isset(window.temp_script_request_objects)) {
      window.temp_script_request_objects = [];
    }

    this.object_index = window.temp_script_request_objects.push(this) - 1;
    this.callback_name =
      'window.temp_script_request_objects[' + this.object_index + '].Callback';
  }

  this.AssignTempObject();
}


/* ~ slider.js (15922 bytes) ~ */

function Slider(container, thumb_element) {

  this.Initialize = function () {

      this.container = null;        // the element that is being slid.
      this.thumb_element = null;    // hovering over it will cause expanding.

      this.hide = true;             // hides container after collapsing.
      // will be called before changing container's height.
      //   function(slider, new_height)  - where slider is self
      this.sliding_callback = Function();

      this.enabled = true;          // false - won't respond to Slide() but current sliding will be finished.
      // by default it's enough to hover over the thumb (clicking is an alias).
      this.thumb_only_click = false;
      this.instant_slide = false;   // set to 'once' and it will be set to false after next call to Slide()
      this.change_opacity = true;

      this.min_height = 0;
      this.max_height = 0;            // 0 = detect automatically.

      // why 'default'? see FixOptions() - an invalid value will be reset.
      this.expanding  = 'default';
      this.collapsing = 'default';
      this.hover_to_expand = 'default';
      this.hover_to_collapse = 'default';

      // update this if you add new options and want them to be handled
      //   properly in this class. for example, it's used by ClearAllTimeouts().
      this.known_options = ['expanding', 'collapsing',
                            'hover_to_expand', 'hover_to_collapse'];

    this.Setup = function () {
      for (var i = 0; i < this.known_options.length; i++) {
        this.FixOptions( this.known_options[i] );  // to make valid default values.
      }

      this.SetupSettings();
    }

    this.SetupSettings = function () {
      this.settings = new SliderSettings(this);
    }

    this.SetDefaults = function () {
      var has_thumb = this.ParseBool(this.thumb_element);

      if (has_thumb) {
        this.container.onmouseout = null;
      }

      this.hide = has_thumb;
      this.change_opacity = has_thumb;
    }

    this.SetContainer = function (container) {
      if (this.container) {
        if (this.container.style.overflowY == 'hidden') {
          this.container.style.overflowY = '';
        }
        this.container.onmousemove = null;
        this.container.onmouseout = null;
      }

      this.container = container;
      if (container) {
        if (/^(visible)?$/.test( $style(this.container, 'overflow-y') )) {
          this.container.style.overflowY = 'hidden';
        }
        this.container.onmousemove = this.Method('WaitAndExpand');
        this.container.onmouseout  = this.Method('WaitAndCollapse');
      }
    }

    this.SetThumb = function (thumb_element) {
      if (this.thumb_element) {
        this.thumb_element.onclick = null;
        if (!this.thumb_only_click) {
          this.thumb_element.onmousemove = null;
        }
      }

      this.thumb_element = thumb_element;
      if (thumb_element) {
        this.thumb_element.onclick = this.Method('Toggle');
        if (!this.thumb_only_click) {
          this.thumb_element.onmousemove = this.Method('ThumbMouseMove');
          this.thumb_element.onmouseout  = this.Method('ThumbMouseOut');
        }
      }
    }

    this.ThumbMouseMove = function () {
      if (!this.mouse_on_thumb) {
        this.mouse_on_thumb = true;
        this.WaitAndToggle(true);
      }
    }

    this.ThumbMouseOut = function () {
      this.mouse_on_thumb = false;
    }

    this.Method = function (method_name) {
      var method = this[ method_name ];

      if (typeof method == 'function') {
        var args = this.ArgumentsToArray(arguments);
        args.shift();

        var self = this;
        return function () { return method.apply(self, args); }
      } else {
        this.Error('Method ' + method_name + ' does not exist.');
        return Function();
      }
    }

      this.ArgumentsToArray = function (argsObject) {
        return Array.prototype.slice.call(argsObject);
      }

    this.WaitAndToggle = function (needs_thumb) {
      if (this.IsCollapsed()) {
        this.WaitAndExpand(needs_thumb);
      } else {
        this.WaitAndCollapse(needs_thumb);
      }
    }

    this.Toggle = function (check_thumb) {
      if (this.IsCollapsed()) {
        this.Expand(check_thumb);
      } else {
        this.Collapse(check_thumb);
      }

      return false;  // useful when used as a link onclick handler.
    }

    this.WaitAndCollapse = function (needs_thumb) {
      this.FixOptions('hover_to_collapse');
      this.SetTimeout(this.hover_to_collapse, this.Method('Collapse', needs_thumb));
    }

    this.WaitAndExpand = function (needs_thumb) {
      this.FixOptions('hover_to_expand');
      this.SetTimeout(this.hover_to_expand, this.Method('Expand', needs_thumb));
    }

    this.IsCollapsed = function () {
      var cont = this.container;
      return (typeof cont == 'object' && cont &&
               this.ContainerHeight() == this.min_height);
    }

    this.Collapse = function (check_thumb) {
      if (!check_thumb || this.mouse_on_thumb) {
        this.FixOptions('collapsing');
        this.collapsing.step = Math.abs(this.collapsing.step) * -1;

        this.Slide(this.collapsing);
      }
    }

    this.Expand = function (check_thumb) {
      if (!check_thumb || this.mouse_on_thumb) {
        this.FixOptions('expanding');
        this.Slide(this.expanding);
      }
    }

    this.FixOptions = function (options_name) {
      var options = this[options_name];

      if (typeof options != 'object' || !options) {
        options = {};
      }

      this.SetTimeout(options, false);

      if (isNaN(options.delay)) {
        var default_delays = {
          expanding: 10,
          collapsing: 10,
          hover_to_expand: 400,
          hover_to_collapse: 750
        };
        options.delay = default_delays[options_name] || 100;

        if (typeof default_delays[options_name] != 'number') {
          this.Error('Unknown options_name passed: FixOptions(' + options_name + ')');
        }
      }

      if (/ing$/.test(options_name) && // collapsing|expanding
          (isNaN(options.step) || options.step == 0)) {
        options.step = 30;
      }

      if (typeof options.done_callback != 'function') {
        options.done_callback = Function();
      }

      if (typeof options.separated_timer == 'undefined') {
        options.separated_timer =
          /^expanding|collapsing$/.test(options_name);
      }

      options.first_time = true;

      this[options_name] = options;
      return options;
    }

    this.Error = function (message) {
      if (typeof console == 'object' && console) {
        console.error(message);
      }
    }

    // -------------------- Sliding

    this.Slide = function (options) {
      if (this.CheckSettings() && this.enabled) {
          if (this.instant_slide) {
            if (options.step > 0) {
              this.ContainerHeight(this.current_max_height);
            } else {
              this.ContainerHeight(this.min_height);
            }
          }
          if (this.instant_slide == 'once') {
            this.instant_slide = false;
          }

        this.SlideTimer(options);
      }
    }

      this.CheckSettings = function () {
        if (typeof this.settings != 'object' || !this.settings) {
          this.Error('Invalid Slider.settings object! Recreating');
          this.SetupSettings();
        }

        this.settings.Apply();

        if (typeof this.container != 'object' || !this.container) {
          this.Error('Invalid Slider.container.');
          return false;
        }

          if (typeof this.thumb_element != 'object' || !this.thumb_element) {
            this.thumb_element = null;
          }

          this.enabled = this.ParseBool(this.enabled);
          if (this.instant_slide != 'once') {
            this.instant_slide = this.ParseBool(this.instant_slide);
          }
          this.change_opacity = this.ParseBool(this.change_opacity);
          this.hide = this.ParseBool(this.hide);

          if (typeof this.sliding_callback != 'function') {
            this.sliding_callback = Function();
          }

          this.min_height = isNaN(this.min_height) ? 0 : parseInt(this.min_height);

          this.max_height = isNaN(this.max_height) ? 0 : parseInt(this.max_height);
          if (this.max_height == 0) {
            this.current_max_height = this.ExpandedContainerHeight();
          } else {
            this.current_max_height = this.max_height;
          }

        return true;
      }

      this.ParseBool = function (value) {
        return (typeof value != 'undefined' &&
                 !/^(null|0|false)?$/i.test( String(value) ));
      }

    this.SlideTimer = function (options) {
      var height = this.ContainerHeight();

      if (options.step < 0 ? height > this.min_height :
                             height < this.current_max_height) {
        if (options.first_time) {
          this.Show(false);
          options.first_time = false;
        }

        var new_height = height + options.step;
        new_height = Math.min(new_height, this.current_max_height);
        new_height = Math.max(new_height, this.min_height);

        this.sliding_callback(this, new_height);
        this.ContainerHeight(new_height);

        if (this.change_opacity) {
          $opacity(this.container, this.CalcOpacityWhen(new_height));
        }

        this.SetTimeout( options, this.Method('SlideTimer', options) );
      } else {
        options.done_callback(this);
        this.StopSliding(options);
      }
    }

    this.SetTimeout = function (options, callback) {
      if (typeof options != 'object' || !options) {
        options = null;
      }

      if (options && this.ParseBool(options.separated_timer )) {
        var timer_holder = options;
      } else {
        var timer_holder = this;
      }

        clearTimeout(timer_holder.timer);
        timer_holder.timer = null;

        if (/function|string/.test(typeof callback) && options) {
          timer_holder.timer = setTimeout(callback, options.delay);
        }
    }

    this.ClearAllTimeouts = function () {
      this.SetTimeout(null, false); // null - times stored in this object.

      for (var i = 0; i < this.known_options.length; i++) {
        this.SetTimeout(this[ this.known_options[i] ], false);
      }
    }

    this.CalcOpacityWhen = function (new_height) {
      var full = this.current_max_height - this.min_height;
      return (new_height - this.min_height) / full * 100;
    }

    this.ContainerHeight = function (new_height) {
      var cont = this.container;

      if (typeof cont == 'object' && cont) {
        if (!isNaN(new_height)) {
          var old_height = cont.style.height;
          cont.style.height = new_height + 'px';
          return old_height;
        } else {
          var height = parseInt( $style(this.container, 'height') );
          height = isNaN(height) ? this.container.offsetHeight : height;
          height = isNaN(height) ? 2000 : height;

          return height;
        }
      } else {
        return 0;
      }
    }

    this.ExpandedContainerHeight = function () {
        var style = this.container.style;

      var old_height = style.height;
      if (old_height != '') {
        style.height = '';
      }
      var old_overflow =  style.overflowY;
      if (old_overflow != 'visible') {
        style.overflowY = 'visible';
      }
      var old_display =  style.display;
      if (old_display != 'block') {
        style.display = 'block';
      }

        var height = this.ContainerHeight();

      if (old_display != style.display) {
        style.display = old_display;
      }
      if (style.overflowY != old_overflow) {
        style.overflowY = old_overflow;
      }
      if (style.height != old_height) {
        style.height = old_height;
      }

        return height;
    }

    this.StopSliding = function (options) {
      this.SetTimeout(options, false);

      if (options.step < 0) {
        this.Hide();
      } else {
        this.Show();
      }
    }

    this.Show = function (finished) {
        finished = !isset(finished) || finished;

      this.ClearAllTimeouts();

      var style = this.container.style;
      if (style.display != 'block') {
        style.display = 'block';
      }

        var overflow = finished ? 'visible' : 'hidden';
      if (style.overflowY != overflow) {
        style.overflowY = overflow;
      }

      if (finished) {
        if (this.change_opacity && $opacity(this.container) != 100) {
          $opacity(this.container, 100);
        }
        if (this.max_height == 0 && style.height != '') {
          style.height = '';
        }

        this.UpdateClassNames();
      }
    }

    this.Hide = function () {
      this.ClearAllTimeouts();

      var style = this.container.style;
      if (this.hide && style.display != 'none') {
        style.display = 'none';
      }

      if (style.overflowY != 'hidden') {
        style.overflowY = 'hidden';
      }

      if (this.change_opacity && $opacity(this.container) != 0) {
        $opacity(this.container, 0);
      }

      this.UpdateClassNames();
    }

    this.UpdateClassNames = function () {
      var collapsed = this.IsCollapsed();

      this.ModifyClassNameOf(this.container,     'collapsed',  collapsed);
      this.ModifyClassNameOf(this.thumb_element, 'collapsed',  collapsed);
      this.ModifyClassNameOf(this.container,     'expanded',  !collapsed);
      this.ModifyClassNameOf(this.thumb_element, 'expanded',  !collapsed);
    }

    // copied from suggestions.js.
    this.ModifyClassNameOf = function (element, class_name, append) {
      if (typeof element == 'object' && element) {
          var regexp = RegExp('\\b' + class_name + '\\b', 'g');
        if (!isset(append) || append) {
          if (!regexp.test(element.className)) {
            element.className += ' ' + class_name;
          }
        } else {
          element.className = element.className.replace(regexp, '');
        }
      }
    }

  } // Initialize


  this.Initialize();
  this.Setup();

    this.SetThumb(thumb_element);
    this.SetContainer(container);
  this.SetDefaults();
}


function SliderSettings(slider) {
  this.slider = slider;

  this.setting_names = ['enabled', 'thumb_only_click',
                         'instant_slide', 'change_opacity'];

  this.Apply = function () {
    if (this.CheckSettings()) {
      var names = this.setting_names;
      for (var i = 0; i < names.length; i++) {
        if ((value = this.Get( names[i] )) != null) {
          this.slider[ names[i] ] = value;
        }
      }
    }
  }

    this.CheckSettings = function () {
      if (typeof this.slider != 'object' || !this.slider) {
        this.Error('Invalid SliderSettings.slider.');
        return false;
      }

      return true;
    }

    this.Error = function (message) {
      if (typeof console == 'object' && console) {
        console.error(message);
      }
    }

  // when returns null - name is non-existent or false cookie
  //   and is treated as "no user setting" so don't change it.
  this.Get = function (name) {
    if (this.CheckSettings() && /^[\w\d_]+$/.test(name)) {
      var value = GetCookie('user[sliders][' + name + ']');
      if (value != null) {
        return this.slider.ParseBool(value);
      }
    }

    return null;
  }
}



