Shadowbox: Jquery vs Mootools (v3)

Revision 3 of this benchmark created by A Goldberg on


Preparation HTML

<script src="//ajax.googleapis.com/ajax/libs/mootools/1.3/mootools-yui-compressed.js">
</script>
<script src="//ajax.googleapis.com/ajax/libs/prototype/1/prototype.js">
</script>
<script src="//www.cinsoft.net/mylib099-min.js">
</script>
<script src="//ajax.googleapis.com/ajax/libs/ext-core/3/ext-core.js">
</script>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1/dojo/dojo.xd.js">
</script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js">
</script>
<script src="//mootools.net/download/get/mootools-core-1.4.1-full-compat-yc.js">
</script>

Test runner

Ready to run.

Testing in
TestOps/sec
Jquery Shadowbox
// async test
/*
 * Shadowbox.js, version 3.0.3
 * http://shadowbox-js.com/
 *
 * Copyright 2007-2010, Michael J. I. Jackson
 * Date: 2011-05-14 07:57:32 +0000
 */
(function(window, undefined) {
  var S = {
    version: "3.0.3"
  };
  var ua = navigator.userAgent.toLowerCase();
  if (ua.indexOf("windows") > -1 || ua.indexOf("win32") > -1) {
    S.isWindows = true
  } else {
    if (ua.indexOf("macintosh") > -1 || ua.indexOf("mac os x") > -1) {
      S.isMac = true
    } else {
      if (ua.indexOf("linux") > -1) {
        S.isLinux = true
      }
    }
  }
  S.isIE = ua.indexOf("msie") > -1;
  S.isIE6 = ua.indexOf("msie 6") > -1;
  S.isIE7 = ua.indexOf("msie 7") > -1;
  S.isGecko = ua.indexOf("gecko") > -1 && ua.indexOf("safari") == -1;
  S.isWebKit = ua.indexOf("applewebkit/") > -1;
  var inlineId = /#(.+)$/,
      galleryName = /^(light|shadow)box\[(.*?)\]/i,
      inlineParam = /\s*([a-z_]*?)\s*=\s*(.+)\s*/,
      fileExtension = /[0-9a-z]+$/i,
      scriptPath = /(.+\/)shadowbox\.js/i;
  var open = false,
      initialized = false,
      lastOptions = {},
      slideDelay = 0,
      slideStart, slideTimer;
  S.current = -1;
  S.dimensions = null;
  S.ease = function(state) {
    return 1 + Math.pow(state - 1, 3)
  };
  S.errorInfo = {
    fla: {
      name: "Flash",
      url: "http://www.adobe.com/products/flashplayer/"
    },
    qt: {
      name: "QuickTime",
      url: "http://www.apple.com/quicktime/download/"
    },
    wmp: {
      name: "Windows Media Player",
      url: "http://www.microsoft.com/windows/windowsmedia/"
    },
    f4m: {
      name: "Flip4Mac",
      url: "http://www.flip4mac.com/wmv_download.htm"
    }
  };
  S.gallery = [];
  S.onReady = noop;
  S.path = null;
  S.player = null;
  S.playerId = "sb-player";
  S.options = {
    animate: true,
    animateFade: true,
    autoplayMovies: true,
    continuous: false,
    enableKeys: true,
    flashParams: {
      bgcolor: "#000000",
      allowfullscreen: true
    },
    flashVars: {},
    flashVersion: "9.0.115",
    handleOversize: "resize",
    handleUnsupported: "link",
    onChange: noop,
    onClose: noop,
    onFinish: noop,
    onOpen: noop,
    showMovieControls: true,
    skipSetup: false,
    slideshowDelay: 0,
    viewportPadding: 20
  };
  S.getCurrent = function() {
    return S.current > -1 ? S.gallery[S.current] : null
  };
  S.hasNext = function() {
    return S.gallery.length > 1 && (S.current != S.gallery.length - 1 || S.options.continuous)
  };
  S.isOpen = function() {
    return open
  };
  S.isPaused = function() {
    return slideTimer == "pause"
  };
  S.applyOptions = function(options) {
    lastOptions = apply({}, S.options);
    apply(S.options, options)
  };
  S.revertOptions = function() {
    apply(S.options, lastOptions)
  };
  S.init = function(options, callback) {
    if (initialized) {
      return
    }
    initialized = true;
    if (S.skin.options) {
      apply(S.options, S.skin.options)
    }
    if (options) {
      apply(S.options, options)
    }
    if (!S.path) {
      var path, scripts = document.getElementsByTagName("script");
      for (var i = 0, len = scripts.length; i < len; ++i) {
        path = scriptPath.exec(scripts[i].src);
        if (path) {
          S.path = path[1];
          break
        }
      }
    }
    if (callback) {
      S.onReady = callback
    }
    bindLoad()
  };
  S.open = function(obj) {
    if (open) {
      return
    }
    var gc = S.makeGallery(obj);
    S.gallery = gc[0];
    S.current = gc[1];
    obj = S.getCurrent();
    if (obj == null) {
      return
    }
    S.applyOptions(obj.options || {});
    filterGallery();
    if (S.gallery.length) {
      obj = S.getCurrent();
      if (S.options.onOpen(obj) === false) {
        return
      }
      open = true;
      S.skin.onOpen(obj, load)
    }
  };
  S.close = function() {
    if (!open) {
      return
    }
    open = false;
    if (S.player) {
      S.player.remove();
      S.player = null
    }
    if (typeof slideTimer == "number") {
      clearTimeout(slideTimer);
      slideTimer = null
    }
    slideDelay = 0;
    listenKeys(false);
    S.options.onClose(S.getCurrent());
    S.skin.onClose();
    S.revertOptions()
  };
  S.play = function() {
    if (!S.hasNext()) {
      return
    }
    if (!slideDelay) {
      slideDelay = S.options.slideshowDelay * 1000
    }
    if (slideDelay) {
      slideStart = now();
      slideTimer = setTimeout(function() {
        slideDelay = slideStart = 0;
        S.next()
      }, slideDelay);
      if (S.skin.onPlay) {
        S.skin.onPlay()
      }
    }
  };
  S.pause = function() {
    if (typeof slideTimer != "number") {
      return
    }
    slideDelay = Math.max(0, slideDelay - (now() - slideStart));
    if (slideDelay) {
      clearTimeout(slideTimer);
      slideTimer = "pause";
      if (S.skin.onPause) {
        S.skin.onPause()
      }
    }
  };
  S.change = function(index) {
    if (!(index in S.gallery)) {
      if (S.options.continuous) {
        index = (index < 0 ? S.gallery.length + index : 0);
        if (!(index in S.gallery)) {
          return
        }
      } else {
        return
      }
    }
    S.current = index;
    if (typeof slideTimer == "number") {
      clearTimeout(slideTimer);
      slideTimer = null;
      slideDelay = slideStart = 0
    }
    S.options.onChange(S.getCurrent());
    load(true)
  };
  S.next = function() {
    S.change(S.current + 1)
  };
  S.previous = function() {
    S.change(S.current - 1)
  };
  S.setDimensions = function(height, width, maxHeight, maxWidth, topBottom, leftRight, padding, preserveAspect) {
    var originalHeight = height,
        originalWidth = width;
    var extraHeight = 2 * padding + topBottom;
    if (height + extraHeight > maxHeight) {
      height = maxHeight - extraHeight
    }
    var extraWidth = 2 * padding + leftRight;
    if (width + extraWidth > maxWidth) {
      width = maxWidth - extraWidth
    }
    var changeHeight = (originalHeight - height) / originalHeight,
        changeWidth = (originalWidth - width) / originalWidth,
        oversized = (changeHeight > 0 || changeWidth > 0);
    if (preserveAspect && oversized) {
      if (changeHeight > changeWidth) {
        width = Math.round((originalWidth / originalHeight) * height)
      } else {
        if (changeWidth > changeHeight) {
          height = Math.round((originalHeight / originalWidth) * width)
        }
      }
    }
    S.dimensions = {
      height: height + topBottom,
      width: width + leftRight,
      innerHeight: height,
      innerWidth: width,
      top: Math.floor((maxHeight - (height + extraHeight)) / 2 + padding),
      left: Math.floor((maxWidth - (width + extraWidth)) / 2 + padding),
      oversized: oversized
    };
    return S.dimensions
  };
  S.makeGallery = function(obj) {
    var gallery = [],
        current = -1;
    if (typeof obj == "string") {
      obj = [obj]
    }
    if (typeof obj.length == "number") {
      each(obj, function(i, o) {
        if (o.content) {
          gallery[i] = o
        } else {
          gallery[i] = {
            content: o
          }
        }
      });
      current = 0
    } else {
      if (obj.tagName) {
        var cacheObj = S.getCache(obj);
        obj = cacheObj ? cacheObj : S.makeObject(obj)
      }
      if (obj.gallery) {
        gallery = [];
        var o;
        for (var key in S.cache) {
          o = S.cache[key];
          if (o.gallery && o.gallery == obj.gallery) {
            if (current == -1 && o.content == obj.content) {
              current = gallery.length
            }
            gallery.push(o)
          }
        }
        if (current == -1) {
          gallery.unshift(obj);
          current = 0
        }
      } else {
        gallery = [obj];
        current = 0
      }
    }
    each(gallery, function(i, o) {
      gallery[i] = apply({}, o)
    });
    return [gallery, current]
  };
  S.makeObject = function(link, options) {
    var obj = {
      content: link.href,
      title: link.getAttribute("title") || "",
      link: link
    };
    if (options) {
      options = apply({}, options);
      each(["player", "title", "height", "width", "gallery"], function(i, o) {
        if (typeof options[o] != "undefined") {
          obj[o] = options[o];
          delete options[o]
        }
      });
      obj.options = options
    } else {
      obj.options = {}
    }
    if (!obj.player) {
      obj.player = S.getPlayer(obj.content)
    }
    var rel = link.getAttribute("rel");
    if (rel) {
      var match = rel.match(galleryName);
      if (match) {
        obj.gallery = escape(match[2])
      }
      each(rel.split(";"), function(i, p) {
        match = p.match(inlineParam);
        if (match) {
          obj[match[1]] = match[2]
        }
      })
    }
    return obj
  };
  S.getPlayer = function(content) {
    if (content.indexOf("#") > -1 && content.indexOf(document.location.href) == 0) {
      return "inline"
    }
    var q = content.indexOf("?");
    if (q > -1) {
      content = content.substring(0, q)
    }
    var ext, m = content.match(fileExtension);
    if (m) {
      ext = m[0].toLowerCase()
    }
    if (ext) {
      if (S.img && S.img.ext.indexOf(ext) > -1) {
        return "img"
      }
      if (S.swf && S.swf.ext.indexOf(ext) > -1) {
        return "swf"
      }
      if (S.flv && S.flv.ext.indexOf(ext) > -1) {
        return "flv"
      }
      if (S.qt && S.qt.ext.indexOf(ext) > -1) {
        if (S.wmp && S.wmp.ext.indexOf(ext) > -1) {
          return "qtwmp"
        } else {
          return "qt"
        }
      }
      if (S.wmp && S.wmp.ext.indexOf(ext) > -1) {
        return "wmp"
      }
    }
    return "iframe"
  };

  function filterGallery() {
    var err = S.errorInfo,
        plugins = S.plugins,
        obj, remove, needed, m, format, replace, inlineEl, flashVersion;
    for (var i = 0; i < S.gallery.length; ++i) {
      obj = S.gallery[i];
      remove = false;
      needed = null;
      switch (obj.player) {
      case "flv":
      case "swf":
        if (!plugins.fla) {
          needed = "fla"
        }
        break;
      case "qt":
        if (!plugins.qt) {
          needed = "qt"
        }
        break;
      case "wmp":
        if (S.isMac) {
          if (plugins.qt && plugins.f4m) {
            obj.player = "qt"
          } else {
            needed = "qtf4m"
          }
        } else {
          if (!plugins.wmp) {
            needed = "wmp"
          }
        }
        break;
      case "qtwmp":
        if (plugins.qt) {
          obj.player = "qt"
        } else {
          if (plugins.wmp) {
            obj.player = "wmp"
          } else {
            needed = "qtwmp"
          }
        }
        break
      }
      if (needed) {
        if (S.options.handleUnsupported == "link") {
          switch (needed) {
          case "qtf4m":
            format = "shared";
            replace = [err.qt.url, err.qt.name, err.f4m.url, err.f4m.name];
            break;
          case "qtwmp":
            format = "either";
            replace = [err.qt.url, err.qt.name, err.wmp.url, err.wmp.name];
            break;
          default:
            format = "single";
            replace = [err[needed].url, err[needed].name]
          }
          obj.player = "html";
          obj.content = '<div class="sb-message">' + sprintf(S.lang.errors[format], replace) + "</div>"
        } else {
          remove = true
        }
      } else {
        if (obj.player == "inline") {
          m = inlineId.exec(obj.content);
          if (m) {
            inlineEl = get(m[1]);
            if (inlineEl) {
              obj.content = inlineEl.innerHTML
            } else {
              remove = true
            }
          } else {
            remove = true
          }
        } else {
          if (obj.player == "swf" || obj.player == "flv") {
            flashVersion = (obj.options && obj.options.flashVersion) || S.options.flashVersion;
            if (S.flash && !S.flash.hasFlashPlayerVersion(flashVersion)) {
              obj.width = 310;
              obj.height = 177
            }
          }
        }
      }
      if (remove) {
        S.gallery.splice(i, 1);
        if (i < S.current) {
          --S.current
        } else {
          if (i == S.current) {
            S.current = i > 0 ? i - 1 : i
          }
        }--i
      }
    }
  }
  function listenKeys(on) {
    if (!S.options.enableKeys) {
      return
    }(on ? addEvent : removeEvent)(document, "keydown", handleKey)
  }
  function handleKey(e) {
    if (e.metaKey || e.shiftKey || e.altKey || e.ctrlKey) {
      return
    }
    var code = keyCode(e),
        handler;
    switch (code) {
    case 81:
    case 88:
    case 27:
      handler = S.close;
      break;
    case 37:
      handler = S.previous;
      break;
    case 39:
      handler = S.next;
      break;
    case 32:
      handler = typeof slideTimer == "number" ? S.pause : S.play;
      break
    }
    if (handler) {
      preventDefault(e);
      handler()
    }
  }
  function load(changing) {
    listenKeys(false);
    var obj = S.getCurrent();
    var player = (obj.player == "inline" ? "html" : obj.player);
    if (typeof S[player] != "function") {
      throw "unknown player " + player
    }
    if (changing) {
      S.player.remove();
      S.revertOptions();
      S.applyOptions(obj.options || {})
    }
    S.player = new S[player](obj, S.playerId);
    if (S.gallery.length > 1) {
      var next = S.gallery[S.current + 1] || S.gallery[0];
      if (next.player == "img") {
        var a = new Image();
        a.src = next.content
      }
      var prev = S.gallery[S.current - 1] || S.gallery[S.gallery.length - 1];
      if (prev.player == "img") {
        var b = new Image();
        b.src = prev.content
      }
    }
    S.skin.onLoad(changing, waitReady)
  }
  function waitReady() {
    if (!open) {
      return
    }
    if (typeof S.player.ready != "undefined") {
      var timer = setInterval(function() {
        if (open) {
          if (S.player.ready) {
            clearInterval(timer);
            timer = null;
            S.skin.onReady(show)
          }
        } else {
          clearInterval(timer);
          timer = null
        }
      }, 10)
    } else {
      S.skin.onReady(show)
    }
  }
  function show() {
    if (!open) {
      return
    }
    S.player.append(S.skin.body, S.dimensions);
    S.skin.onShow(finish)
  }
  function finish() {
    if (!open) {
      return
    }
    if (S.player.onLoad) {
      S.player.onLoad()
    }
    S.options.onFinish(S.getCurrent());
    if (!S.isPaused()) {
      S.play()
    }
    listenKeys(true)
  }
  if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(obj, from) {
      var len = this.length >>> 0;
      from = from || 0;
      if (from < 0) {
        from += len
      }
      for (; from < len; ++from) {
        if (from in this && this[from] === obj) {
          return from
        }
      }
      return -1
    }
  }
  function now() {
    return (new Date).getTime()
  }
  function apply(original, extension) {
    for (var property in extension) {
      original[property] = extension[property]
    }
    return original
  }
  function each(obj, callback) {
    var i = 0,
        len = obj.length;
    for (var value = obj[0]; i < len && callback.call(value, i, value) !== false; value = obj[++i]) {}
  }
  function sprintf(str, replace) {
    return str.replace(/\{(\w+?)\}/g, function(match, i) {
      return replace[i]
    })
  }
  function noop() {}
  function get(id) {
    return document.getElementById(id)
  }
  function remove(el) {
    el.parentNode.removeChild(el)
  }
  var supportsOpacity = true,
      supportsFixed = true;

  function checkSupport() {
    var body = document.body,
        div = document.createElement("div");
    supportsOpacity = typeof div.style.opacity === "string";
    div.style.position = "fixed";
    div.style.margin = 0;
    div.style.top = "20px";
    body.appendChild(div, body.firstChild);
    supportsFixed = div.offsetTop == 20;
    body.removeChild(div)
  }
  S.getStyle = (function() {
    var opacity = /opacity=([^)]*)/,
        getComputedStyle = document.defaultView && document.defaultView.getComputedStyle;
    return function(el, style) {
      var ret;
      if (!supportsOpacity && style == "opacity" && el.currentStyle) {
        ret = opacity.test(el.currentStyle.filter || "") ? (parseFloat(RegExp.$1) / 100) + "" : "";
        return ret === "" ? "1" : ret
      }
      if (getComputedStyle) {
        var computedStyle = getComputedStyle(el, null);
        if (computedStyle) {
          ret = computedStyle[style]
        }
        if (style == "opacity" && ret == "") {
          ret = "1"
        }
      } else {
        ret = el.currentStyle[style]
      }
      return ret
    }
  })();
  S.appendHTML = function(el, html) {
    if (el.insertAdjacentHTML) {
      el.insertAdjacentHTML("BeforeEnd", html)
    } else {
      if (el.lastChild) {
        var range = el.ownerDocument.createRange();
        range.setStartAfter(el.lastChild);
        var frag = range.createContextualFragment(html);
        el.appendChild(frag)
      } else {
        el.innerHTML = html
      }
    }
  };
  S.getWindowSize = function(dimension) {
    if (document.compatMode === "CSS1Compat") {
      return document.documentElement["client" + dimension]
    }
    return document.body["client" + dimension]
  };
  S.setOpacity = function(el, opacity) {
    var style = el.style;
    if (supportsOpacity) {
      style.opacity = (opacity == 1 ? "" : opacity)
    } else {
      style.zoom = 1;
      if (opacity == 1) {
        if (typeof style.filter == "string" && (/alpha/i).test(style.filter)) {
          style.filter = style.filter.replace(/\s*[\w\.]*alpha\([^\)]*\);?/gi, "")
        }
      } else {
        style.filter = (style.filter || "").replace(/\s*[\w\.]*alpha\([^\)]*\)/gi, "") + " alpha(opacity=" + (opacity * 100) + ")"
      }
    }
  };
  S.clearOpacity = function(el) {
    S.setOpacity(el, 1)
  };

  function getTarget(e) {
    return e.target
  }
  function getPageXY(e) {
    return [e.pageX, e.pageY]
  }
  function preventDefault(e) {
    e.preventDefault()
  }
  function keyCode(e) {
    return e.keyCode
  }
  function addEvent(el, type, handler) {
    jQuery(el).bind(type, handler)
  }
  function removeEvent(el, type, handler) {
    jQuery(el).unbind(type, handler)
  }
  jQuery.fn.shadowbox = function(options) {
    return this.each(function() {
      var el = jQuery(this);
      var opts = jQuery.extend({}, options || {}, jQuery.metadata ? el.metadata() : jQuery.meta ? el.data() : {});
      var cls = this.className || "";
      opts.width = parseInt((cls.match(/w:(\d+)/) || [])[1]) || opts.width;
      opts.height = parseInt((cls.match(/h:(\d+)/) || [])[1]) || opts.height;
      Shadowbox.setup(el, opts)
    })
  };
  var loaded = false,
      DOMContentLoaded;
  if (document.addEventListener) {
    DOMContentLoaded = function() {
      document.removeEventListener("DOMContentLoaded", DOMContentLoaded, false);
      S.load()
    }
  } else {
    if (document.attachEvent) {
      DOMContentLoaded = function() {
        if (document.readyState === "complete") {
          document.detachEvent("onreadystatechange", DOMContentLoaded);
          S.load()
        }
      }
    }
  }
  function doScrollCheck() {
    if (loaded) {
      return
    }
    try {
      document.documentElement.doScroll("left")
    } catch (e) {
      setTimeout(doScrollCheck, 1);
      return
    }
    S.load()
  }
  function bindLoad() {
    if (document.readyState === "complete") {
      return S.load()
    }
    if (document.addEventListener) {
      document.addEventListener("DOMContentLoaded", DOMContentLoaded, false);
      window.addEventListener("load", S.load, false)
    } else {
      if (document.attachEvent) {
        document.attachEvent("onreadystatechange", DOMContentLoaded);
        window.attachEvent("onload", S.load);
        var topLevel = false;
        try {
          topLevel = window.frameElement === null
        } catch (e) {}
        if (document.documentElement.doScroll && topLevel) {
          doScrollCheck()
        }
      }
    }
  }
  S.load = function() {
    if (loaded) {
      return
    }
    if (!document.body) {
      return setTimeout(S.load, 13)
    }
    loaded = true;
    checkSupport();
    S.onReady();
    if (!S.options.skipSetup) {
      S.setup()
    }
    S.skin.init()
  };
  S.plugins = {};
  if (navigator.plugins && navigator.plugins.length) {
    var names = [];
    each(navigator.plugins, function(i, p) {
      names.push(p.name)
    });
    names = names.join(",");
    var f4m = names.indexOf("Flip4Mac") > -1;
    S.plugins = {
      fla: names.indexOf("Shockwave Flash") > -1,
      qt: names.indexOf("QuickTime") > -1,
      wmp: !f4m && names.indexOf("Windows Media") > -1,
      f4m: f4m
    }
  } else {
    var detectPlugin = function(name) {
        var axo;
        try {
          axo = new ActiveXObject(name)
        } catch (e) {}
        return !!axo
        };
    S.plugins = {
      fla: detectPlugin("ShockwaveFlash.ShockwaveFlash"),
      qt: detectPlugin("QuickTime.QuickTime"),
      wmp: detectPlugin("wmplayer.ocx"),
      f4m: false
    }
  }
  var relAttr = /^(light|shadow)box/i,
      expando = "shadowboxCacheKey",
      cacheKey = 1;
  S.cache = {};
  S.select = function(selector) {
    var links = [];
    if (!selector) {
      var rel;
      each(document.getElementsByTagName("a"), function(i, el) {
        rel = el.getAttribute("rel");
        if (rel && relAttr.test(rel)) {
          links.push(el)
        }
      })
    } else {
      var length = selector.length;
      if (length) {
        if (typeof selector == "string") {
          if (S.find) {
            links = S.find(selector)
          }
        } else {
          if (length == 2 && typeof selector[0] == "string" && selector[1].nodeType) {
            if (S.find) {
              links = S.find(selector[0], selector[1])
            }
          } else {
            for (var i = 0; i < length; ++i) {
              links[i] = selector[i]
            }
          }
        }
      } else {
        links.push(selector)
      }
    }
    return links
  };
  S.setup = function(selector, options) {
    each(S.select(selector), function(i, link) {
      S.addCache(link, options)
    })
  };
  S.teardown = function(selector) {
    each(S.select(selector), function(i, link) {
      S.removeCache(link)
    })
  };
  S.addCache = function(link, options) {
    var key = link[expando];
    if (key == undefined) {
      key = cacheKey++;
      link[expando] = key;
      addEvent(link, "click", handleClick)
    }
    S.cache[key] = S.makeObject(link, options)
  };
  S.removeCache = function(link) {
    removeEvent(link, "click", handleClick);
    delete S.cache[link[expando]];
    link[expando] = null
  };
  S.getCache = function(link) {
    var key = link[expando];
    return (key in S.cache && S.cache[key])
  };
  S.clearCache = function() {
    for (var key in S.cache) {
      S.removeCache(S.cache[key].link)
    }
    S.cache = {}
  };

  function handleClick(e) {
    S.open(this);
    if (S.gallery.length) {
      preventDefault(e)
    }
  }
/*
 * Sizzle CSS Selector Engine - v1.0
 *  Copyright 2009, The Dojo Foundation
 *  Released under the MIT, BSD, and GPL Licenses.
 *  More information: http://sizzlejs.com/
 *
 * Modified for inclusion in Shadowbox.js
 */
  S.find = (function() {
    var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
        done = 0,
        toString = Object.prototype.toString,
        hasDuplicate = false,
        baseHasDuplicate = true;
    [0, 0].sort(function() {
      baseHasDuplicate = false;
      return 0
    });
    var Sizzle = function(selector, context, results, seed) {
        results = results || [];
        var origContext = context = context || document;
        if (context.nodeType !== 1 && context.nodeType !== 9) {
          return []
        }
        if (!selector || typeof selector !== "string") {
          return results
        }
        var parts = [],
            m, set, checkSet, extra, prune = true,
            contextXML = isXML(context),
            soFar = selector;
        while ((chunker.exec(""), m = chunker.exec(soFar)) !== null) {
          soFar = m[3];
          parts.push(m[1]);
          if (m[2]) {
            extra = m[3];
            break
          }
        }
        if (parts.length > 1 && origPOS.exec(selector)) {
          if (parts.length === 2 && Expr.relative[parts[0]]) {
            set = posProcess(parts[0] + parts[1], context)
          } else {
            set = Expr.relative[parts[0]] ? [context] : Sizzle(parts.shift(), context);
            while (parts.length) {
              selector = parts.shift();
              if (Expr.relative[selector]) {
                selector += parts.shift()
              }
              set = posProcess(selector, set)
            }
          }
        } else {
          if (!seed && parts.length > 1 && context.nodeType === 9 && !contextXML && Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1])) {
            var ret = Sizzle.find(parts.shift(), context, contextXML);
            context = ret.expr ? Sizzle.filter(ret.expr, ret.set)[0] : ret.set[0]
          }
          if (context) {
            var ret = seed ? {
              expr: parts.pop(),
              set: makeArray(seed)
            } : Sizzle.find(parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML);
            set = ret.expr ? Sizzle.filter(ret.expr, ret.set) : ret.set;
            if (parts.length > 0) {
              checkSet = makeArray(set)
            } else {
              prune = false
            }
            while (parts.length) {
              var cur = parts.pop(),
                  pop = cur;
              if (!Expr.relative[cur]) {
                cur = ""
              } else {
                pop = parts.pop()
              }
              if (pop == null) {
                pop = context
              }
              Expr.relative[cur](checkSet, pop, contextXML)
            }
          } else {
            checkSet = parts = []
          }
        }
        if (!checkSet) {
          checkSet = set
        }
        if (!checkSet) {
          throw "Syntax error, unrecognized expression: " + (cur || selector)
        }
        if (toString.call(checkSet) === "[object Array]") {
          if (!prune) {
            results.push.apply(results, checkSet)
          } else {
            if (context && context.nodeType === 1) {
              for (var i = 0; checkSet[i] != null; i++) {
                if (checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i]))) {
                  results.push(set[i])
                }
              }
            } else {
              for (var i = 0; checkSet[i] != null; i++) {
                if (checkSet[i] && checkSet[i].nodeType === 1) {
                  results.push(set[i])
                }
              }
            }
          }
        } else {
          makeArray(checkSet, results)
        }
        if (extra) {
          Sizzle(extra, origContext, results, seed);
          Sizzle.uniqueSort(results)
        }
        return results
        };
    Sizzle.uniqueSort = function(results) {
      if (sortOrder) {
        hasDuplicate = baseHasDuplicate;
        results.sort(sortOrder);
        if (hasDuplicate) {
          for (var i = 1; i < results.length; i++) {
            if (results[i] === results[i - 1]) {
              results.splice(i--, 1)
            }
          }
        }
      }
      return results
    };
    Sizzle.matches = function(expr, set) {
      return Sizzle(expr, null, null, set)
    };
    Sizzle.find = function(expr, context, isXML) {
      var set, match;
      if (!expr) {
        return []
      }
      for (var i = 0, l = Expr.order.length; i < l; i++) {
        var type = Expr.order[i],
            match;
        if ((match = Expr.leftMatch[type].exec(expr))) {
          var left = match[1];
          match.splice(1, 1);
          if (left.substr(left.length - 1) !== "\\") {
            match[1] = (match[1] || "").replace(/\\/g, "");
            set = Expr.find[type](match, context, isXML);
            if (set != null) {
              expr = expr.replace(Expr.match[type], "");
              break
            }
          }
        }
      }
      if (!set) {
        set = context.getElementsByTagName("*")
      }
      return {
        set: set,
        expr: expr
      }
    };
    Sizzle.filter = function(expr, set, inplace, not) {
      var old = expr,
          result = [],
          curLoop = set,
          match, anyFound, isXMLFilter = set && set[0] && isXML(set[0]);
      while (expr && set.length) {
        for (var type in Expr.filter) {
          if ((match = Expr.match[type].exec(expr)) != null) {
            var filter = Expr.filter[type],
                found, item;
            anyFound = false;
            if (curLoop === result) {
              result = []
            }
            if (Expr.preFilter[type]) {
              match = Expr.preFilter[type](match, curLoop, inplace, result, not, isXMLFilter);
              if (!match) {
                anyFound = found = true
              } else {
                if (match === true) {
                  continue
                }
              }
            }
            if (match) {
              for (var i = 0;
              (item = curLoop[i]) != null; i++) {
                if (item) {
                  found = filter(item, match, i, curLoop);
                  var pass = not ^ !! found;
                  if (inplace && found != null) {
                    if (pass) {
                      anyFound = true
                    } else {
                      curLoop[i] = false
                    }
                  } else {
                    if (pass) {
                      result.push(item);
                      anyFound = true
                    }
                  }
                }
              }
            }
            if (found !== undefined) {
              if (!inplace) {
                curLoop = result
              }
              expr = expr.replace(Expr.match[type], "");
              if (!anyFound) {
                return []
              }
              break
            }
          }
        }
        if (expr === old) {
          if (anyFound == null) {
            throw "Syntax error, unrecognized expression: " + expr
          } else {
            break
          }
        }
        old = expr
      }
      return curLoop
    };
    var Expr = Sizzle.selectors = {
      order: ["ID", "NAME", "TAG"],
      match: {
        ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
        CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
        NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
        ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
        TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
        CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
        POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
        PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
      },
      leftMatch: {},
      attrMap: {
        "class": "className",
        "for": "htmlFor"
      },
      attrHandle: {
        href: function(elem) {
          return elem.getAttribute("href")
        }
      },
      relative: {
        "+": function(checkSet, part) {
          var isPartStr = typeof part === "string",
              isTag = isPartStr && !/\W/.test(part),
              isPartStrNotTag = isPartStr && !isTag;
          if (isTag) {
            part = part.toLowerCase()
          }
          for (var i = 0, l = checkSet.length, elem; i < l; i++) {
            if ((elem = checkSet[i])) {
              while ((elem = elem.previousSibling) && elem.nodeType !== 1) {}
              checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? elem || false : elem === part
            }
          }
          if (isPartStrNotTag) {
            Sizzle.filter(part, checkSet, true)
          }
        },
        ">": function(checkSet, part) {
          var isPartStr = typeof part === "string";
          if (isPartStr && !/\W/.test(part)) {
            part = part.toLowerCase();
            for (var i = 0, l = checkSet.length; i < l; i++) {
              var elem = checkSet[i];
              if (elem) {
                var parent = elem.parentNode;
                checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false
              }
            }
          } else {
            for (var i = 0, l = checkSet.length; i < l; i++) {
              var elem = checkSet[i];
              if (elem) {
                checkSet[i] = isPartStr ? elem.parentNode : elem.parentNode === part
              }
            }
            if (isPartStr) {
              Sizzle.filter(part, checkSet, true)
            }
          }
        },
        "": function(checkSet, part, isXML) {
          var doneName = done++,
              checkFn = dirCheck;
          if (typeof part === "string" && !/\W/.test(part)) {
            var nodeCheck = part = part.toLowerCase();
            checkFn = dirNodeCheck
          }
          checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML)
        },
        "~": function(checkSet, part, isXML) {
          var doneName = done++,
              checkFn = dirCheck;
          if (typeof part === "string" && !/\W/.test(part)) {
            var nodeCheck = part = part.toLowerCase();
            checkFn = dirNodeCheck
          }
          checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML)
        }
      },
      find: {
        ID: function(match, context, isXML) {
          if (typeof context.getElementById !== "undefined" && !isXML) {
            var m = context.getElementById(match[1]);
            return m ? [m] : []
          }
        },
        NAME: function(match, context) {
          if (typeof context.getElementsByName !== "undefined") {
            var ret = [],
                results = context.getElementsByName(match[1]);
            for (var i = 0, l = results.length; i < l; i++) {
              if (results[i].getAttribute("name") === match[1]) {
                ret.push(results[i])
              }
            }
            return ret.length === 0 ? null : ret
          }
        },
        TAG: function(match, context) {
          return context.getElementsByTagName(match[1])
        }
      },
      preFilter: {
        CLASS: function(match, curLoop, inplace, result, not, isXML) {
          match = " " + match[1].replace(/\\/g, "") + " ";
          if (isXML) {
            return match
          }
          for (var i = 0, elem;
          (elem = curLoop[i]) != null; i++) {
            if (elem) {
              if (not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0)) {
                if (!inplace) {
                  result.push(elem)
                }
              } else {
                if (inplace) {
                  curLoop[i] = false
                }
              }
            }
          }
          return false
        },
        ID: function(match) {
          return match[1].replace(/\\/g, "")
        },
        TAG: function(match, curLoop) {
          return match[1].toLowerCase()
        },
        CHILD: function(match) {
          if (match[1] === "nth") {
            var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || !/\D/.test(match[2]) && "0n+" + match[2] || match[2]);
            match[2] = (test[1] + (test[2] || 1)) - 0;
            match[3] = test[3] - 0
          }
          match[0] = done++;
          return match
        },
        ATTR: function(match, curLoop, inplace, result, not, isXML) {
          var name = match[1].replace(/\\/g, "");
          if (!isXML && Expr.attrMap[name]) {
            match[1] = Expr.attrMap[name]
          }
          if (match[2] === "~=") {
            match[4] = " " + match[4] + " "
          }
          return match
        },
        PSEUDO: function(match, curLoop, inplace, result, not) {
          if (match[1] === "not") {
            if ((chunker.exec(match[3]) || "").length > 1 || /^\w/.test(match[3])) {
              match[3] = Sizzle(match[3], null, null, curLoop)
            } else {
              var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
              if (!inplace) {
                result.push.apply(result, ret)
              }
              return false
            }
          } else {
            if (Expr.match.POS.test(match[0]) || Expr.match.CHILD.test(match[0])) {
              return true
            }
          }
          return match
        },
        POS: function(match) {
          match.unshift(true);
          return match
        }
      },
      filters: {
        enabled: function(elem) {
          return elem.disabled === false && elem.type !== "hidden"
        },
        disabled: function(elem) {
          return elem.disabled === true
        },
        checked: function(elem) {
          return elem.checked === true
        },
        selected: function(elem) {
          elem.parentNode.selectedIndex;
          return elem.selected === true
        },
        parent: function(elem) {
          return !!elem.firstChild
        },
        empty: function(elem) {
          return !elem.firstChild
        },
        has: function(elem, i, match) {
          return !!Sizzle(match[3], elem).length
        },
        header: function(elem) {
          return /h\d/i.test(elem.nodeName)
        },
        text: function(elem) {
          return "text" === elem.type
        },
        radio: function(elem) {
          return "radio" === elem.type
        },
        checkbox: function(elem) {
          return "checkbox" === elem.type
        },
        file: function(elem) {
          return "file" === elem.type
        },
        password: function(elem) {
          return "password" === elem.type
        },
        submit: function(elem) {
          return "submit" === elem.type
        },
        image: function(elem) {
          return "image" === elem.type
        },
        reset: function(elem) {
          return "reset" === elem.type
        },
        button: function(elem) {
          return "button" === elem.type || elem.nodeName.toLowerCase() === "button"
        },
        input: function(elem) {
          return /input|select|textarea|button/i.test(elem.nodeName)
        }
      },
      setFilters: {
        first: function(elem, i) {
          return i === 0
        },
        last: function(elem, i, match, array) {
          return i === array.length - 1
        },
        even: function(elem, i) {
          return i % 2 === 0
        },
        odd: function(elem, i) {
          return i % 2 === 1
        },
        lt: function(elem, i, match) {
          return i < match[3] - 0
        },
        gt: function(elem, i, match) {
          return i > match[3] - 0
        },
        nth: function(elem, i, match) {
          return match[3] - 0 === i
        },
        eq: function(elem, i, match) {
          return match[3] - 0 === i
        }
      },
      filter: {
        PSEUDO: function(elem, match, i, array) {
          var name = match[1],
              filter = Expr.filters[name];
          if (filter) {
            return filter(elem, i, match, array)
          } else {
            if (name === "contains") {
              return (elem.textContent || elem.innerText || getText([elem]) || "").indexOf(match[3]) >= 0
            } else {
              if (name === "not") {
                var not = match[3];
                for (var i = 0, l = not.length; i < l; i++) {
                  if (not[i] === elem) {
                    return false
                  }
                }
                return true
              } else {
                throw "Syntax error, unrecognized expression: " + name
              }
            }
          }
        },
        CHILD: function(elem, match) {
          var type = match[1],
              node = elem;
          switch (type) {
          case "only":
          case "first":
            while ((node = node.previousSibling)) {
              if (node.nodeType === 1) {
                return false
              }
            }
            if (type === "first") {
              return true
            }
            node = elem;
          case "last":
            while ((node = node.nextSibling)) {
              if (node.nodeType === 1) {
                return false
              }
            }
            return true;
          case "nth":
            var first = match[2],
                last = match[3];
            if (first === 1 && last === 0) {
              return true
            }
            var doneName = match[0],
                parent = elem.parentNode;
            if (parent && (parent.sizcache !== doneName || !elem.nodeIndex)) {
              var count = 0;
              for (node = parent.firstChild; node; node = node.nextSibling) {
                if (node.nodeType === 1) {
                  node.nodeIndex = ++count
                }
              }
              parent.sizcache = doneName
            }
            var diff = elem.nodeIndex - last;
            if (first === 0) {
              return diff === 0
            } else {
              return (diff % first === 0 && diff / first >= 0)
            }
          }
        },
        ID: function(elem, match) {
          return elem.nodeType === 1 && elem.getAttribute("id") === match
        },
        TAG: function(elem, match) {
          return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match
        },
        CLASS: function(elem, match) {
          return (" " + (elem.className || elem.getAttribute("class")) + " ").indexOf(match) > -1
        },
        ATTR: function(elem, match) {
          var name = match[1],
              result = Expr.attrHandle[name] ? Expr.attrHandle[name](elem) : elem[name] != null ? elem[name] : elem.getAttribute(name),
              value = result + "",
              type = match[2],
              check = match[4];
          return result == null ? type === "!=" : type === "=" ? value === check : type === "*=" ? value.indexOf(check) >= 0 : type === "~=" ? (" " + value + " ").indexOf(check) >= 0 : !check ? value && result !== false : type === "!=" ? value !== check : type === "^=" ? value.indexOf(check) === 0 : type === "$=" ? value.substr(value.length - check.length) === check : type === "|=" ? value === check || value.substr(0, check.length + 1) === check + "-" : false
        },
        POS: function(elem, match, i, array) {
          var name = match[2],
              filter = Expr.setFilters[name];
          if (filter) {
            return filter(elem, i, match, array)
          }
        }
      }
    };
    var origPOS = Expr.match.POS;
    for (var type in Expr.match) {
      Expr.match[type] = new RegExp(Expr.match[type].source + /(?![^\[]*\])(?![^\(]*\))/.source);
      Expr.leftMatch[type] = new RegExp(/(^(?:.|\r|\n)*?)/.source + Expr.match[type].source)
    }
    var makeArray = function(array, results) {
        array = Array.prototype.slice.call(array, 0);
        if (results) {
          results.push.apply(results, array);
          return results
        }
        return array
        };
    try {
      Array.prototype.slice.call(document.documentElement.childNodes, 0)
    } catch (e) {
      makeArray = function(array, results) {
        var ret = results || [];
        if (toString.call(array) === "[object Array]") {
          Array.prototype.push.apply(ret, array)
        } else {
          if (typeof array.length === "number") {
            for (var i = 0, l = array.length; i < l; i++) {
              ret.push(array[i])
            }
          } else {
            for (var i = 0; array[i]; i++) {
              ret.push(array[i])
            }
          }
        }
        return ret
      }
    }
    var sortOrder;
    if (document.documentElement.compareDocumentPosition) {
      sortOrder = function(a, b) {
        if (!a.compareDocumentPosition || !b.compareDocumentPosition) {
          if (a == b) {
            hasDuplicate = true
          }
          return a.compareDocumentPosition ? -1 : 1
        }
        var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
        if (ret === 0) {
          hasDuplicate = true
        }
        return ret
      }
    } else {
      if ("sourceIndex" in document.documentElement) {
        sortOrder = function(a, b) {
          if (!a.sourceIndex || !b.sourceIndex) {
            if (a == b) {
              hasDuplicate = true
            }
            return a.sourceIndex ? -1 : 1
          }
          var ret = a.sourceIndex - b.sourceIndex;
          if (ret === 0) {
            hasDuplicate = true
          }
          return ret
        }
      } else {
        if (document.createRange) {
          sortOrder = function(a, b) {
            if (!a.ownerDocument || !b.ownerDocument) {
              if (a == b) {
                hasDuplicate = true
              }
              return a.ownerDocument ? -1 : 1
            }
            var aRange = a.ownerDocument.createRange(),
                bRange = b.ownerDocument.createRange();
            aRange.setStart(a, 0);
            aRange.setEnd(a, 0);
            bRange.setStart(b, 0);
            bRange.setEnd(b, 0);
            var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
            if (ret === 0) {
              hasDuplicate = true
            }
            return ret
          }
        }
      }
    }
    function getText(elems) {
      var ret = "",
          elem;
      for (var i = 0; elems[i]; i++) {
        elem = elems[i];
        if (elem.nodeType === 3 || elem.nodeType === 4) {
          ret += elem.nodeValue
        } else {
          if (elem.nodeType !== 8) {
            ret += getText(elem.childNodes)
          }
        }
      }
      return ret
    }(function() {
      var form = document.createElement("div"),
          id = "script" + (new Date).getTime();
      form.innerHTML = "<a name='" + id + "'/>";
      var root = document.documentElement;
      root.insertBefore(form, root.firstChild);
      if (document.getElementById(id)) {
        Expr.find.ID = function(match, context, isXML) {
          if (typeof context.getElementById !== "undefined" && !isXML) {
            var m = context.getElementById(match[1]);
            return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : []
          }
        };
        Expr.filter.ID = function(elem, match) {
          var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
          return elem.nodeType === 1 && node && node.nodeValue === match
        }
      }
      root.removeChild(form);
      root = form = null
    })();
    (function() {
      var div = document.createElement("div");
      div.appendChild(document.createComment(""));
      if (div.getElementsByTagName("*").length > 0) {
        Expr.find.TAG = function(match, context) {
          var results = context.getElementsByTagName(match[1]);
          if (match[1] === "*") {
            var tmp = [];
            for (var i = 0; results[i]; i++) {
              if (results[i].nodeType === 1) {
                tmp.push(results[i])
              }
            }
            results = tmp
          }
          return results
        }
      }
      div.innerHTML = "<a href='#'></a>";
      if (div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && div.firstChild.getAttribute("href") !== "#") {
        Expr.attrHandle.href = function(elem) {
          return elem.getAttribute("href", 2)
        }
      }
      div = null
    })();
    if (document.querySelectorAll) {
      (function() {
        var oldSizzle = Sizzle,
            div = document.createElement("div");
        div.innerHTML = "<p class='TEST'></p>";
        if (div.querySelectorAll && div.querySelectorAll(".TEST").length === 0) {
          return
        }
        Sizzle = function(query, context, extra, seed) {
          context = context || document;
          if (!seed && context.nodeType === 9 && !isXML(context)) {
            try {
              return makeArray(context.querySelectorAll(query), extra)
            } catch (e) {}
          }
          return oldSizzle(query, context, extra, seed)
        };
        for (var prop in oldSizzle) {
          Sizzle[prop] = oldSizzle[prop]
        }
        div = null
      })()
    }(function() {
      var div = document.createElement("div");
      div.innerHTML = "<div class='test e'></div><div class='test'></div>";
      if (!div.getElementsByClassName || div.getElementsByClassName("e").length === 0) {
        return
      }
      div.lastChild.className = "e";
      if (div.getElementsByClassName("e").length === 1) {
        return
      }
      Expr.order.splice(1, 0, "CLASS");
      Expr.find.CLASS = function(match, context, isXML) {
        if (typeof context.getElementsByClassName !== "undefined" && !isXML) {
          return context.getElementsByClassName(match[1])
        }
      };
      div = null
    })();

    function dirNodeCheck(dir, cur, doneName, checkSet, nodeCheck, isXML) {
      for (var i = 0, l = checkSet.length; i < l; i++) {
        var elem = checkSet[i];
        if (elem) {
          elem = elem[dir];
          var match = false;
          while (elem) {
            if (elem.sizcache === doneName) {
              match = checkSet[elem.sizset];
              break
            }
            if (elem.nodeType === 1 && !isXML) {
              elem.sizcache = doneName;
              elem.sizset = i
            }
            if (elem.nodeName.toLowerCase() === cur) {
              match = elem;
              break
            }
            elem = elem[dir]
          }
          checkSet[i] = match
        }
      }
    }
    function dirCheck(dir, cur, doneName, checkSet, nodeCheck, isXML) {
      for (var i = 0, l = checkSet.length; i < l; i++) {
        var elem = checkSet[i];
        if (elem) {
          elem = elem[dir];
          var match = false;
          while (elem) {
            if (elem.sizcache === doneName) {
              match = checkSet[elem.sizset];
              break
            }
            if (elem.nodeType === 1) {
              if (!isXML) {
                elem.sizcache = doneName;
                elem.sizset = i
              }
              if (typeof cur !== "string") {
                if (elem === cur) {
                  match = true;
                  break
                }
              } else {
                if (Sizzle.filter(cur, [elem]).length > 0) {
                  match = elem;
                  break
                }
              }
            }
            elem = elem[dir]
          }
          checkSet[i] = match
        }
      }
    }
    var contains = document.compareDocumentPosition ?
    function(a, b) {
      return a.compareDocumentPosition(b) & 16
    } : function(a, b) {
      return a !== b && (a.contains ? a.contains(b) : true)
    };
    var isXML = function(elem) {
        var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
        return documentElement ? documentElement.nodeName !== "HTML" : false
        };
    var posProcess = function(selector, context) {
        var tmpSet = [],
            later = "",
            match, root = context.nodeType ? [context] : context;
        while ((match = Expr.match.PSEUDO.exec(selector))) {
          later += match[0];
          selector = selector.replace(Expr.match.PSEUDO, "")
        }
        selector = Expr.relative[selector] ? selector + "*" : selector;
        for (var i = 0, l = root.length; i < l; i++) {
          Sizzle(selector, root[i], tmpSet)
        }
        return Sizzle.filter(later, tmpSet)
        };
    return Sizzle
  })();
/*
 * SWFObject v2.1 <http://code.google.com/p/swfobject/>
 * Copyright (c) 2007-2008 Geoff Stearns, Michael Williams, and Bobby van der Sluis
 * This software is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
 *
 * Modified for inclusion in Shadowbox.js
 */
  S.flash = (function() {
    var swfobject = function() {
        var UNDEF = "undefined",
            OBJECT = "object",
            SHOCKWAVE_FLASH = "Shockwave Flash",
            SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash",
            FLASH_MIME_TYPE = "application/x-shockwave-flash",
            EXPRESS_INSTALL_ID = "SWFObjectExprInst",
            win = window,
            doc = document,
            nav = navigator,
            domLoadFnArr = [],
            regObjArr = [],
            objIdArr = [],
            listenersArr = [],
            script, timer = null,
            storedAltContent = null,
            storedAltContentId = null,
            isDomLoaded = false,
            isExpressInstallActive = false;
        var ua = function() {
            var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF,
                playerVersion = [0, 0, 0],
                d = null;
            if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] == OBJECT) {
              d = nav.plugins[SHOCKWAVE_FLASH].description;
              if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) {
                d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
                playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10);
                playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10);
                playerVersion[2] = /r/.test(d) ? parseInt(d.replace(/^.*r(.*)$/, "$1"), 10) : 0
              }
            } else {
              if (typeof win.ActiveXObject != UNDEF) {
                var a = null,
                    fp6Crash = false;
                try {
                  a = new ActiveXObject(SHOCKWAVE_FLASH_AX + ".7")
                } catch (e) {
                  try {
                    a = new ActiveXObject(SHOCKWAVE_FLASH_AX + ".6");
                    playerVersion = [6, 0, 21];
                    a.AllowScriptAccess = "always"
                  } catch (e) {
                    if (playerVersion[0] == 6) {
                      fp6Crash = true
                    }
                  }
                  if (!fp6Crash) {
                    try {
                      a = new ActiveXObject(SHOCKWAVE_FLASH_AX)
                    } catch (e) {}
                  }
                }
                if (!fp6Crash && a) {
                  try {
                    d = a.GetVariable("$version");
                    if (d) {
                      d = d.split(" ")[1].split(",");
                      playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)]
                    }
                  } catch (e) {}
                }
              }
            }
            var u = nav.userAgent.toLowerCase(),
                p = nav.platform.toLowerCase(),
                webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false,
                ie = false,
                windows = p ? /win/.test(p) : /win/.test(u),
                mac = p ? /mac/.test(p) : /mac/.test(u);
/*@cc_on
                        ie = true;
                        @if (@_win32)
                                windows = true;
                        @elif (@_mac)
                                mac = true;
                        @end
                @*/
            return {
              w3cdom: w3cdom,
              pv: playerVersion,
              webkit: webkit,
              ie: ie,
              win: windows,
              mac: mac
            }
            }();
        var onDomLoad = function() {
            if (!ua.w3cdom) {
              return
            }
            addDomLoadEvent(main);
            if (ua.ie && ua.win) {
              try {
                doc.write("<script id=__ie_ondomload defer=true src=//:><\/script>");
                script = getElementById("__ie_ondomload");
                if (script) {
                  addListener(script, "onreadystatechange", checkReadyState)
                }
              } catch (e) {}
            }
            if (ua.webkit && typeof doc.readyState != UNDEF) {
              timer = setInterval(function() {
                if (/loaded|complete/.test(doc.readyState)) {
                  callDomLoadFunctions()
                }
              }, 10)
            }
            if (typeof doc.addEventListener != UNDEF) {
              doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, null)
            }
            addLoadEvent(callDomLoadFunctions)
            }();

        function checkReadyState() {
          if (script.readyState == "complete") {
            script.parentNode.removeChild(script);
            callDomLoadFunctions()
          }
        }
        function callDomLoadFunctions() {
          if (isDomLoaded) {
            return
          }
          if (ua.ie && ua.win) {
            var s = createElement("span");
            try {
              var t = doc.getElementsByTagName("body")[0].appendChild(s);
              t.parentNode.removeChild(t)
            } catch (e) {
              return
            }
          }
          isDomLoaded = true;
          if (timer) {
            clearInterval(timer);
            timer = null
          }
          var dl = domLoadFnArr.length;
          for (var i = 0; i < dl; i++) {
            domLoadFnArr[i]()
          }
        }
        function addDomLoadEvent(fn) {
          if (isDomLoaded) {
            fn()
          } else {
            domLoadFnArr[domLoadFnArr.length] = fn
          }
        }
        function addLoadEvent(fn) {
          if (typeof win.addEventListener != UNDEF) {
            win.addEventListener("load", fn, false)
          } else {
            if (typeof doc.addEventListener != UNDEF) {
              doc.addEventListener("load", fn, false)
            } else {
              if (typeof win.attachEvent != UNDEF) {
                addListener(win, "onload", fn)
              } else {
                if (typeof win.onload == "function") {
                  var fnOld = win.onload;
                  win.onload = function() {
                    fnOld();
                    fn()
                  }
                } else {
                  win.onload = fn
                }
              }
            }
          }
        }
        function main() {
          var rl = regObjArr.length;
          for (var i = 0; i < rl; i++) {
            var id = regObjArr[i].id;
            if (ua.pv[0] > 0) {
              var obj = getElementById(id);
              if (obj) {
                regObjArr[i].width = obj.getAttribute("width") ? obj.getAttribute("width") : "0";
                regObjArr[i].height = obj.getAttribute("height") ? obj.getAttribute("height") : "0";
                if (hasPlayerVersion(regObjArr[i].swfVersion)) {
                  if (ua.webkit && ua.webkit < 312) {
                    fixParams(obj)
                  }
                  setVisibility(id, true)
                } else {
                  if (regObjArr[i].expressInstall && !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac)) {
                    showExpressInstall(regObjArr[i])
                  } else {
                    displayAltContent(obj)
                  }
                }
              }
            } else {
              setVisibility(id, true)
            }
          }
        }
        function fixParams(obj) {
          var nestedObj = obj.getElementsByTagName(OBJECT)[0];
          if (nestedObj) {
            var e = createElement("embed"),
                a = nestedObj.attributes;
            if (a) {
              var al = a.length;
              for (var i = 0; i < al; i++) {
                if (a[i].nodeName == "DATA") {
                  e.setAttribute("src", a[i].nodeValue)
                } else {
                  e.setAttribute(a[i].nodeName, a[i].nodeValue)
                }
              }
            }
            var c = nestedObj.childNodes;
            if (c) {
              var cl = c.length;
              for (var j = 0; j < cl; j++) {
                if (c[j].nodeType == 1 && c[j].nodeName == "PARAM") {
                  e.setAttribute(c[j].getAttribute("name"), c[j].getAttribute("value"))
                }
              }
            }
            obj.parentNode.replaceChild(e, obj)
          }
        }
        function showExpressInstall(regObj) {
          isExpressInstallActive = true;
          var obj = getElementById(regObj.id);
          if (obj) {
            if (regObj.altContentId) {
              var ac = getElementById(regObj.altContentId);
              if (ac) {
                storedAltContent = ac;
                storedAltContentId = regObj.altContentId
              }
            } else {
              storedAltContent = abstractAltContent(obj)
            }
            if (!(/%$/.test(regObj.width)) && parseInt(regObj.width, 10) < 310) {
              regObj.width = "310"
            }
            if (!(/%$/.test(regObj.height)) && parseInt(regObj.height, 10) < 137) {
              regObj.height = "137"
            }
            doc.title = doc.title.slice(0, 47) + " - Flash Player Installation";
            var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn",
                dt = doc.title,
                fv = "MMredirectURL=" + win.location + "&MMplayerType=" + pt + "&MMdoctitle=" + dt,
                replaceId = regObj.id;
            if (ua.ie && ua.win && obj.readyState != 4) {
              var newObj = createElement("div");
              replaceId += "SWFObjectNew";
              newObj.setAttribute("id", replaceId);
              obj.parentNode.insertBefore(newObj, obj);
              obj.style.display = "none";
              var fn = function() {
                  obj.parentNode.removeChild(obj)
                  };
              addListener(win, "onload", fn)
            }
            createSWF({
              data: regObj.expressInstall,
              id: EXPRESS_INSTALL_ID,
              width: regObj.width,
              height: regObj.height
            }, {
              flashvars: fv
            }, replaceId)
          }
        }
        function displayAltContent(obj) {
          if (ua.ie && ua.win && obj.readyState != 4) {
            var el = createElement("div");
            obj.parentNode.insertBefore(el, obj);
            el.parentNode.replaceChild(abstractAltContent(obj), el);
            obj.style.display = "none";
            var fn = function() {
                obj.parentNode.removeChild(obj)
                };
            addListener(win, "onload", fn)
          } else {
            obj.parentNode.replaceChild(abstractAltContent(obj), obj)
          }
        }
        function abstractAltContent(obj) {
          var ac = createElement("div");
          if (ua.win && ua.ie) {
            ac.innerHTML = obj.innerHTML
          } else {
            var nestedObj = obj.getElementsByTagName(OBJECT)[0];
            if (nestedObj) {
              var c = nestedObj.childNodes;
              if (c) {
                var cl = c.length;
                for (var i = 0; i < cl; i++) {
                  if (!(c[i].nodeType == 1 && c[i].nodeName == "PARAM") && !(c[i].nodeType == 8)) {
                    ac.appendChild(c[i].cloneNode(true))
                  }
                }
              }
            }
          }
          return ac
        }
        function createSWF(attObj, parObj, id) {
          var r, el = getElementById(id);
          if (el) {
            if (typeof attObj.id == UNDEF) {
              attObj.id = id
            }
            if (ua.ie && ua.win) {
              var att = "";
              for (var i in attObj) {
                if (attObj[i] != Object.prototype[i]) {
                  if (i.toLowerCase() == "data") {
                    parObj.movie = attObj[i]
                  } else {
                    if (i.toLowerCase() == "styleclass") {
                      att += ' class="' + attObj[i] + '"'
                    } else {
                      if (i.toLowerCase() != "classid") {
                        att += " " + i + '="' + attObj[i] + '"'
                      }
                    }
                  }
                }
              }
              var par = "";
              for (var j in parObj) {
                if (parObj[j] != Object.prototype[j]) {
                  par += '<param name="' + j + '" value="' + parObj[j] + '" />'
                }
              }
              el.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + att + ">" + par + "</object>";
              objIdArr[objIdArr.length] = attObj.id;
              r = getElementById(attObj.id)
            } else {
              if (ua.webkit && ua.webkit < 312) {
                var e = createElement("embed");
                e.setAttribute("type", FLASH_MIME_TYPE);
                for (var k in attObj) {
                  if (attObj[k] != Object.prototype[k]) {
                    if (k.toLowerCase() == "data") {
                      e.setAttribute("src", attObj[k])
                    } else {
                      if (k.toLowerCase() == "styleclass") {
                        e.setAttribute("class", attObj[k])
                      } else {
                        if (k.toLowerCase() != "classid") {
                          e.setAttribute(k, attObj[k])
                        }
                      }
                    }
                  }
                }
                for (var l in parObj) {
                  if (parObj[l] != Object.prototype[l]) {
                    if (l.toLowerCase() != "movie") {
                      e.setAttribute(l, parObj[l])
                    }
                  }
                }
                el.parentNode.replaceChild(e, el);
                r = e
              } else {
                var o = createElement(OBJECT);
                o.setAttribute("type", FLASH_MIME_TYPE);
                for (var m in attObj) {
                  if (attObj[m] != Object.prototype[m]) {
                    if (m.toLowerCase() == "styleclass") {
                      o.setAttribute("class", attObj[m])
                    } else {
                      if (m.toLowerCase() != "classid") {
                        o.setAttribute(m, attObj[m])
                      }
                    }
                  }
                }
                for (var n in parObj) {
                  if (parObj[n] != Object.prototype[n] && n.toLowerCase() != "movie") {
                    createObjParam(o, n, parObj[n])
                  }
                }
                el.parentNode.replaceChild(o, el);
                r = o
              }
            }
          }
          return r
        }
        function createObjParam(el, pName, pValue) {
          var p = createElement("param");
          p.setAttribute("name", pName);
          p.setAttribute("value", pValue);
          el.appendChild(p)
        }
        function removeSWF(id) {
          var obj = getElementById(id);
          if (obj && (obj.nodeName == "OBJECT" || obj.nodeName == "EMBED")) {
            if (ua.ie && ua.win) {
              if (obj.readyState == 4) {
                removeObjectInIE(id)
              } else {
                win.attachEvent("onload", function() {
                  removeObjectInIE(id)
                })
              }
            } else {
              obj.parentNode.removeChild(obj)
            }
          }
        }
        function removeObjectInIE(id) {
          var obj = getElementById(id);
          if (obj) {
            for (var i in obj) {
              if (typeof obj[i] == "function") {
                obj[i] = null
              }
            }
            obj.parentNode.removeChild(obj)
          }
        }
        function getElementById(id) {
          var el = null;
          try {
            el = doc.getElementById(id)
          } catch (e) {}
          return el
        }
        function createElement(el) {
          return doc.createElement(el)
        }
        function addListener(target, eventType, fn) {
          target.attachEvent(eventType, fn);
          listenersArr[listenersArr.length] = [target, eventType, fn]
        }
        function hasPlayerVersion(rv) {
          var pv = ua.pv,
              v = rv.split(".");
          v[0] = parseInt(v[0], 10);
          v[1] = parseInt(v[1], 10) || 0;
          v[2] = parseInt(v[2], 10) || 0;
          return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false
        }
        function createCSS(sel, decl) {
          if (ua.ie && ua.mac) {
            return
          }
          var h = doc.getElementsByTagName("head")[0],
              s = createElement("style");
          s.setAttribute("type", "text/css");
          s.setAttribute("media", "screen");
          if (!(ua.ie && ua.win) && typeof doc.createTextNode != UNDEF) {
            s.appendChild(doc.createTextNode(sel + " {" + decl + "}"))
          }
          h.appendChild(s);
          if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF && doc.styleSheets.length > 0) {
            var ls = doc.styleSheets[doc.styleSheets.length - 1];
            if (typeof ls.addRule == OBJECT) {
              ls.addRule(sel, decl)
            }
          }
        }
        function setVisibility(id, isVisible) {
          var v = isVisible ? "visible" : "hidden";
          if (isDomLoaded && getElementById(id)) {
            getElementById(id).style.visibility = v
          } else {
            createCSS("#" + id, "visibility:" + v)
          }
        }
        function urlEncodeIfNecessary(s) {
          var regex = /[\\\"<>\.;]/;
          var hasBadChars = regex.exec(s) != null;
          return hasBadChars ? encodeURIComponent(s) : s
        }
        var cleanup = function() {
            if (ua.ie && ua.win) {
              window.attachEvent("onunload", function() {
                var ll = listenersArr.length;
                for (var i = 0; i < ll; i++) {
                  listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2])
                }
                var il = objIdArr.length;
                for (var j = 0; j < il; j++) {
                  removeSWF(objIdArr[j])
                }
                for (var k in ua) {
                  ua[k] = null
                }
                ua = null;
                for (var l in swfobject) {
                  swfobject[l] = null
                }
                swfobject = null
              })
            }
            }();
        return {
          registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr) {
            if (!ua.w3cdom || !objectIdStr || !swfVersionStr) {
              return
            }
            var regObj = {};
            regObj.id = objectIdStr;
            regObj.swfVersion = swfVersionStr;
            regObj.expressInstall = xiSwfUrlStr ? xiSwfUrlStr : false;
            regObjArr[regObjArr.length] = regObj;
            setVisibility(objectIdStr, false)
          },
          getObjectById: function(objectIdStr) {
            var r = null;
            if (ua.w3cdom) {
              var o = getElementById(objectIdStr);
              if (o) {
                var n = o.getElementsByTagName(OBJECT)[0];
                if (!n || (n && typeof o.SetVariable != UNDEF)) {
                  r = o
                } else {
                  if (typeof n.SetVariable != UNDEF) {
                    r = n
                  }
                }
              }
            }
            return r
          },
          embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj) {
            if (!ua.w3cdom || !swfUrlStr || !replaceElemIdStr || !widthStr || !heightStr || !swfVersionStr) {
              return
            }
            widthStr += "";
            heightStr += "";
            if (hasPlayerVersion(swfVersionStr)) {
              setVisibility(replaceElemIdStr, false);
              var att = {};
              if (attObj && typeof attObj === OBJECT) {
                for (var i in attObj) {
                  if (attObj[i] != Object.prototype[i]) {
                    att[i] = attObj[i]
                  }
                }
              }
              att.data = swfUrlStr;
              att.width = widthStr;
              att.height = heightStr;
              var par = {};
              if (parObj && typeof parObj === OBJECT) {
                for (var j in parObj) {
                  if (parObj[j] != Object.prototype[j]) {
                    par[j] = parObj[j]
                  }
                }
              }
              if (flashvarsObj && typeof flashvarsObj === OBJECT) {
                for (var k in flashvarsObj) {
                  if (flashvarsObj[k] != Object.prototype[k]) {
                    if (typeof par.flashvars != UNDEF) {
                      par.flashvars += "&" + k + "=" + flashvarsObj[k]
                    } else {
                      par.flashvars = k + "=" + flashvarsObj[k]
                    }
                  }
                }
              }
              addDomLoadEvent(function() {
                createSWF(att, par, replaceElemIdStr);
                if (att.id == replaceElemIdStr) {
                  setVisibility(replaceElemIdStr, true)
                }
              })
            } else {
              if (xiSwfUrlStr && !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac)) {
                isExpressInstallActive = true;
                setVisibility(replaceElemIdStr, false);
                addDomLoadEvent(function() {
                  var regObj = {};
                  regObj.id = regObj.altContentId = replaceElemIdStr;
                  regObj.width = widthStr;
                  regObj.height = heightStr;
                  regObj.expressInstall = xiSwfUrlStr;
                  showExpressInstall(regObj)
                })
              }
            }
          },
          getFlashPlayerVersion: function() {
            return {
              major: ua.pv[0],
              minor: ua.pv[1],
              release: ua.pv[2]
            }
          },
          hasFlashPlayerVersion: hasPlayerVersion,
          createSWF: function(attObj, parObj, replaceElemIdStr) {
            if (ua.w3cdom) {
              return createSWF(attObj, parObj, replaceElemIdStr)
            } else {
              return undefined
            }
          },
          removeSWF: function(objElemIdStr) {
            if (ua.w3cdom) {
              removeSWF(objElemIdStr)
            }
          },
          createCSS: function(sel, decl) {
            if (ua.w3cdom) {
              createCSS(sel, decl)
            }
          },
          addDomLoadEvent: addDomLoadEvent,
          addLoadEvent: addLoadEvent,
          getQueryParamValue: function(param) {
            var q = doc.location.search || doc.location.hash;
            if (param == null) {
              return urlEncodeIfNecessary(q)
            }
            if (q) {
              var pairs = q.substring(1).split("&");
              for (var i = 0; i < pairs.length; i++) {
                if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
                  return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1)))
                }
              }
            }
            return ""
          },
          expressInstallCallback: function() {
            if (isExpressInstallActive && storedAltContent) {
              var obj = getElementById(EXPRESS_INSTALL_ID);
              if (obj) {
                obj.parentNode.replaceChild(storedAltContent, obj);
                if (storedAltContentId) {
                  setVisibility(storedAltContentId, true);
                  if (ua.ie && ua.win) {
                    storedAltContent.style.display = "block"
                  }
                }
                storedAltContent = null;
                storedAltContentId = null;
                isExpressInstallActive = false
              }
            }
          }
        }
        }();
    return swfobject
  })();
  S.lang = {
    code: "en",
    of: "of",
    loading: "loading",
    cancel: "Cancel",
    next: "Next",
    previous: "Previous",
    play: "Play",
    pause: "Pause",
    close: "Close",
    errors: {
      single: 'You must install the <a href="{0}">{1}</a> browser plugin to view this content.',
      shared: 'You must install both the <a href="{0}">{1}</a> and <a href="{2}">{3}</a> browser plugins to view this content.',
      either: 'You must install either the <a href="{0}">{1}</a> or the <a href="{2}">{3}</a> browser plugin to view this content.'
    }
  };
  var pre, proxyId = "sb-drag-proxy",
      dragData, dragProxy, dragTarget;

  function resetDrag() {
    dragData = {
      x: 0,
      y: 0,
      startX: null,
      startY: null
    }
  }
  function updateProxy() {
    var dims = S.dimensions;
    apply(dragProxy.style, {
      height: dims.innerHeight + "px",
      width: dims.innerWidth + "px"
    })
  }
  function enableDrag() {
    resetDrag();
    var style = ["position:absolute", "cursor:" + (S.isGecko ? "-moz-grab" : "move"), "background-color:" + (S.isIE ? "#fff;filter:alpha(opacity=0)" : "transparent")].join(";");
    S.appendHTML(S.skin.body, '<div id="' + proxyId + '" style="' + style + '"></div>');
    dragProxy = get(proxyId);
    updateProxy();
    addEvent(dragProxy, "mousedown", startDrag)
  }
  function disableDrag() {
    if (dragProxy) {
      removeEvent(dragProxy, "mousedown", startDrag);
      remove(dragProxy);
      dragProxy = null
    }
    dragTarget = null
  }
  function startDrag(e) {
    preventDefault(e);
    var xy = getPageXY(e);
    dragData.startX = xy[0];
    dragData.startY = xy[1];
    dragTarget = get(S.player.id);
    addEvent(document, "mousemove", positionDrag);
    addEvent(document, "mouseup", endDrag);
    if (S.isGecko) {
      dragProxy.style.cursor = "-moz-grabbing"
    }
  }
  function positionDrag(e) {
    var player = S.player,
        dims = S.dimensions,
        xy = getPageXY(e);
    var moveX = xy[0] - dragData.startX;
    dragData.startX += moveX;
    dragData.x = Math.max(Math.min(0, dragData.x + moveX), dims.innerWidth - player.width);
    var moveY = xy[1] - dragData.startY;
    dragData.startY += moveY;
    dragData.y = Math.max(Math.min(0, dragData.y + moveY), dims.innerHeight - player.height);
    apply(dragTarget.style, {
      left: dragData.x + "px",
      top: dragData.y + "px"
    })
  }
  function endDrag() {
    removeEvent(document, "mousemove", positionDrag);
    removeEvent(document, "mouseup", endDrag);
    if (S.isGecko) {
      dragProxy.style.cursor = "-moz-grab"
    }
  }
  S.img = function(obj, id) {
    this.obj = obj;
    this.id = id;
    this.ready = false;
    var self = this;
    pre = new Image();
    pre.onload = function() {
      self.height = obj.height ? parseInt(obj.height, 10) : pre.height;
      self.width = obj.width ? parseInt(obj.width, 10) : pre.width;
      self.ready = true;
      pre.onload = null;
      pre = null
    };
    pre.src = obj.content
  };
  S.img.ext = ["bmp", "gif", "jpg", "jpeg", "png"];
  S.img.prototype = {
    append: function(body, dims) {
      var img = document.createElement("img");
      img.id = this.id;
      img.src = this.obj.content;
      img.style.position = "absolute";
      var height, width;
      if (dims.oversized && S.options.handleOversize == "resize") {
        height = dims.innerHeight;
        width = dims.innerWidth
      } else {
        height = this.height;
        width = this.width
      }
      img.setAttribute("height", height);
      img.setAttribute("width", width);
      body.appendChild(img)
    },
    remove: function() {
      var el = get(this.id);
      if (el) {
        remove(el)
      }
      disableDrag();
      if (pre) {
        pre.onload = null;
        pre = null
      }
    },
    onLoad: function() {
      var dims = S.dimensions;
      if (dims.oversized && S.options.handleOversize == "drag") {
        enableDrag()
      }
    },
    onWindowResize: function() {
      var dims = S.dimensions;
      switch (S.options.handleOversize) {
      case "resize":
        var el = get(this.id);
        el.height = dims.innerHeight;
        el.width = dims.innerWidth;
        break;
      case "drag":
        if (dragTarget) {
          var top = parseInt(S.getStyle(dragTarget, "top")),
              left = parseInt(S.getStyle(dragTarget, "left"));
          if (top + this.height < dims.innerHeight) {
            dragTarget.style.top = dims.innerHeight - this.height + "px"
          }
          if (left + this.width < dims.innerWidth) {
            dragTarget.style.left = dims.innerWidth - this.width + "px"
          }
          updateProxy()
        }
        break
      }
    }
  };
  S.iframe = function(obj, id) {
    this.obj = obj;
    this.id = id;
    var overlay = get("sb-overlay");
    this.height = obj.height ? parseInt(obj.height, 10) : overlay.offsetHeight;
    this.width = obj.width ? parseInt(obj.width, 10) : overlay.offsetWidth
  };
  S.iframe.prototype = {
    append: function(body, dims) {
      var html = '<iframe id="' + this.id + '" name="' + this.id + '" height="100%" width="100%" frameborder="0" marginwidth="0" marginheight="0" style="visibility:hidden" onload="this.style.visibility=\'visible\'" scrolling="auto"';
      if (S.isIE) {
        html += ' allowtransparency="true"';
        if (S.isIE6) {
          html += " src=\"javascript:false;document.write('');\""
        }
      }
      html += "></iframe>";
      body.innerHTML = html
    },
    remove: function() {
      var el = get(this.id);
      if (el) {
        remove(el);
        if (S.isGecko) {
          delete window.frames[this.id]
        }
      }
    },
    onLoad: function() {
      var win = S.isIE ? get(this.id).contentWindow : window.frames[this.id];
      win.location.href = this.obj.content
    }
  };
  S.html = function(obj, id) {
    this.obj = obj;
    this.id = id;
    this.height = obj.height ? parseInt(obj.height, 10) : 300;
    this.width = obj.width ? parseInt(obj.width, 10) : 500
  };
  S.html.prototype = {
    append: function(body, dims) {
      var div = document.createElement("div");
      div.id = this.id;
      div.className = "html";
      div.innerHTML = this.obj.content;
      body.appendChild(div)
    },
    remove: function() {
      var el = get(this.id);
      if (el) {
        remove(el)
      }
    }
  };
  S.swf = function(obj, id) {
    this.obj = obj;
    this.id = id;
    this.height = obj.height ? parseInt(obj.height, 10) : 300;
    this.width = obj.width ? parseInt(obj.width, 10) : 300
  };
  S.swf.ext = ["swf"];
  S.swf.prototype = {
    append: function(body, dims) {
      var tmp = document.createElement("div");
      tmp.id = this.id;
      body.appendChild(tmp);
      var height = dims.innerHeight,
          width = dims.innerWidth,
          swf = this.obj.content,
          version = S.options.flashVersion,
          express = S.path + "expressInstall.swf",
          flashvars = S.options.flashVars,
          params = S.options.flashParams;
      S.flash.embedSWF(swf, this.id, width, height, version, express, flashvars, params)
    },
    remove: function() {
      S.flash.expressInstallCallback();
      S.flash.removeSWF(this.id)
    },
    onWindowResize: function() {
      var dims = S.dimensions,
          el = get(this.id);
      el.height = dims.innerHeight;
      el.width = dims.innerWidth
    }
  };
  var jwControllerHeight = 20;
  S.flv = function(obj, id) {
    this.obj = obj;
    this.id = id;
    this.height = obj.height ? parseInt(obj.height, 10) : 300;
    if (S.options.showMovieControls) {
      this.height += jwControllerHeight
    }
    this.width = obj.width ? parseInt(obj.width, 10) : 300
  };
  S.flv.ext = ["flv", "m4v"];
  S.flv.prototype = {
    append: function(body, dims) {
      var tmp = document.createElement("div");
      tmp.id = this.id;
      body.appendChild(tmp);
      var height = dims.innerHeight,
          width = dims.innerWidth,
          swf = S.path + "player.swf",
          version = S.options.flashVersion,
          express = S.path + "expressInstall.swf",
          flashvars = apply({
          file: this.obj.content,
          height: height,
          width: width,
          autostart: (S.options.autoplayMovies ? "true" : "false"),
          controlbar: (S.options.showMovieControls ? "bottom" : "none"),
          backcolor: "0x000000",
          frontcolor: "0xCCCCCC",
          lightcolor: "0x557722"
        }, S.options.flashVars),
          params = S.options.flashParams;
      S.flash.embedSWF(swf, this.id, width, height, version, express, flashvars, params)
    },
    remove: function() {
      S.flash.expressInstallCallback();
      S.flash.removeSWF(this.id)
    },
    onWindowResize: function() {
      var dims = S.dimensions,
          el = get(this.id);
      el.height = dims.innerHeight;
      el.width = dims.innerWidth
    }
  };
  var qtControllerHeight = 16;
  S.qt = function(obj, id) {
    this.obj = obj;
    this.id = id;
    this.height = obj.height ? parseInt(obj.height, 10) : 300;
    if (S.options.showMovieControls) {
      this.height += qtControllerHeight
    }
    this.width = obj.width ? parseInt(obj.width, 10) : 300
  };
  S.qt.ext = ["dv", "mov", "moov", "movie", "mp4", "avi", "mpg", "mpeg"];
  S.qt.prototype = {
    append: function(body, dims) {
      var opt = S.options,
          autoplay = String(opt.autoplayMovies),
          controls = String(opt.showMovieControls);
      var html = "<object",
          movie = {
          id: this.id,
          name: this.id,
          height: this.height,
          width: this.width,
          kioskmode: "true"
          };
      if (S.isIE) {
        movie.classid = "clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B";
        movie.codebase = "http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0"
      } else {
        movie.type = "video/quicktime";
        movie.data = this.obj.content
      }
      for (var m in movie) {
        html += " " + m + '="' + movie[m] + '"'
      }
      html += ">";
      var params = {
        src: this.obj.content,
        scale: "aspect",
        controller: controls,
        autoplay: autoplay
      };
      for (var p in params) {
        html += '<param name="' + p + '" value="' + params[p] + '">'
      }
      html += "</object>";
      body.innerHTML = html
    },
    remove: function() {
      try {
        document[this.id].Stop()
      } catch (e) {}
      var el = get(this.id);
      if (el) {
        remove(el)
      }
    }
  };
  var wmpControllerHeight = (S.isIE ? 70 : 45);
  S.wmp = function(obj, id) {
    this.obj = obj;
    this.id = id;
    this.height = obj.height ? parseInt(obj.height, 10) : 300;
    if (S.options.showMovieControls) {
      this.height += wmpControllerHeight
    }
    this.width = obj.width ? parseInt(obj.width, 10) : 300
  };
  S.wmp.ext = ["asf", "avi", "mpg", "mpeg", "wm", "wmv"];
  S.wmp.prototype = {
    append: function(body, dims) {
      var opt = S.options,
          autoplay = opt.autoplayMovies ? 1 : 0;
      var movie = '<object id="' + this.id + '" name="' + this.id + '" height="' + this.height + '" width="' + this.width + '"',
          params = {
          autostart: opt.autoplayMovies ? 1 : 0
          };
      if (S.isIE) {
        movie += ' classid="clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6"';
        params.url = this.obj.content;
        params.uimode = opt.showMovieControls ? "full" : "none"
      } else {
        movie += ' type="video/x-ms-wmv"';
        movie += ' data="' + this.obj.content + '"';
        params.showcontrols = opt.showMovieControls ? 1 : 0
      }
      movie += ">";
      for (var p in params) {
        movie += '<param name="' + p + '" value="' + params[p] + '">'
      }
      movie += "</object>";
      body.innerHTML = movie
    },
    remove: function() {
      if (S.isIE) {
        try {
          window[this.id].controls.stop();
          window[this.id].URL = "movie" + now() + ".wmv";
          window[this.id] = function() {}
        } catch (e) {}
      }
      var el = get(this.id);
      if (el) {
        setTimeout(function() {
          remove(el)
        }, 10)
      }
    }
  };
  var overlayOn = false,
      visibilityCache = [],
      pngIds = ["sb-nav-close", "sb-nav-next", "sb-nav-play", "sb-nav-pause", "sb-nav-previous"],
      container, overlay, wrapper, doWindowResize = true;

  function animate(el, property, to, duration, callback) {
    var isOpacity = (property == "opacity"),
        anim = isOpacity ? S.setOpacity : function(el, value) {
        el.style[property] = "" + value + "px"
        };
    if (duration == 0 || (!isOpacity && !S.options.animate) || (isOpacity && !S.options.animateFade)) {
      anim(el, to);
      if (callback) {
        callback()
      }
      return
    }
    var from = parseFloat(S.getStyle(el, property)) || 0;
    var delta = to - from;
    if (delta == 0) {
      if (callback) {
        callback()
      }
      return
    }
    duration *= 1000;
    var begin = now(),
        ease = S.ease,
        end = begin + duration,
        time;
    var interval = setInterval(function() {
      time = now();
      if (time >= end) {
        clearInterval(interval);
        interval = null;
        anim(el, to);
        if (callback) {
          callback()
        }
      } else {
        anim(el, from + ease((time - begin) / duration) * delta)
      }
    }, 10)
  }
  function setSize() {
    container.style.height = S.getWindowSize("Height") + "px";
    container.style.width = S.getWindowSize("Width") + "px"
  }
  function setPosition() {
    container.style.top = document.documentElement.scrollTop + "px";
    container.style.left = document.documentElement.scrollLeft + "px"
  }
  function toggleTroubleElements(on) {
    if (on) {
      each(visibilityCache, function(i, el) {
        el[0].style.visibility = el[1] || ""
      })
    } else {
      visibilityCache = [];
      each(S.options.troubleElements, function(i, tag) {
        each(document.getElementsByTagName(tag), function(j, el) {
          visibilityCache.push([el, el.style.visibility]);
          el.style.visibility = "hidden"
        })
      })
    }
  }
  function toggleNav(id, on) {
    var el = get("sb-nav-" + id);
    if (el) {
      el.style.display = on ? "" : "none"
    }
  }
  function toggleLoading(on, callback) {
    var loading = get("sb-loading"),
        playerName = S.getCurrent().player,
        anim = (playerName == "img" || playerName == "html");
    if (on) {
      S.setOpacity(loading, 0);
      loading.style.display = "block";
      var wrapped = function() {
          S.clearOpacity(loading);
          if (callback) {
            callback()
          }
          };
      if (anim) {
        animate(loading, "opacity", 1, S.options.fadeDuration, wrapped)
      } else {
        wrapped()
      }
    } else {
      var wrapped = function() {
          loading.style.display = "none";
          S.clearOpacity(loading);
          if (callback) {
            callback()
          }
          };
      if (anim) {
        animate(loading, "opacity", 0, S.options.fadeDuration, wrapped)
      } else {
        wrapped()
      }
    }
  }
  function buildBars(callback) {
    var obj = S.getCurrent();
    get("sb-title-inner").innerHTML = obj.title || "";
    var close, next, play, pause, previous;
    if (S.options.displayNav) {
      close = true;
      var len = S.gallery.length;
      if (len > 1) {
        if (S.options.continuous) {
          next = previous = true
        } else {
          next = (len - 1) > S.current;
          previous = S.current > 0
        }
      }
      if (S.options.slideshowDelay > 0 && S.hasNext()) {
        pause = !S.isPaused();
        play = !pause
      }
    } else {
      close = next = play = pause = previous = false
    }
    toggleNav("close", close);
    toggleNav("next", next);
    toggleNav("play", play);
    toggleNav("pause", pause);
    toggleNav("previous", previous);
    var counter = "";
    if (S.options.displayCounter && S.gallery.length > 1) {
      var len = S.gallery.length;
      if (S.options.counterType == "skip") {
        var i = 0,
            end = len,
            limit = parseInt(S.options.counterLimit) || 0;
        if (limit < len && limit > 2) {
          var h = Math.floor(limit / 2);
          i = S.current - h;
          if (i < 0) {
            i += len
          }
          end = S.current + (limit - h);
          if (end > len) {
            end -= len
          }
        }
        while (i != end) {
          if (i == len) {
            i = 0
          }
          counter += '<a onclick="Shadowbox.change(' + i + ');"';
          if (i == S.current) {
            counter += ' class="sb-counter-current"'
          }
          counter += ">" + (++i) + "</a>"
        }
      } else {
        counter = [S.current + 1, S.lang.of, len].join(" ")
      }
    }
    get("sb-counter").innerHTML = counter;
    callback()
  }
  function showBars(callback) {
    var titleInner = get("sb-title-inner"),
        infoInner = get("sb-info-inner"),
        duration = 0.35;
    titleInner.style.visibility = infoInner.style.visibility = "";
    if (titleInner.innerHTML != "") {
      animate(titleInner, "marginTop", 0, duration)
    }
    animate(infoInner, "marginTop", 0, duration, callback)
  }
  function hideBars(anim, callback) {
    var title = get("sb-title"),
        info = get("sb-info"),
        titleHeight = title.offsetHeight,
        infoHeight = info.offsetHeight,
        titleInner = get("sb-title-inner"),
        infoInner = get("sb-info-inner"),
        duration = (anim ? 0.35 : 0);
    animate(titleInner, "marginTop", titleHeight, duration);
    animate(infoInner, "marginTop", infoHeight * -1, duration, function() {
      titleInner.style.visibility = infoInner.style.visibility = "hidden";
      callback()
    })
  }
  function adjustHeight(height, top, anim, callback) {
    var wrapperInner = get("sb-wrapper-inner"),
        duration = (anim ? S.options.resizeDuration : 0);
    animate(wrapper, "top", top, duration);
    animate(wrapperInner, "height", height, duration, callback)
  }
  function adjustWidth(width, left, anim, callback) {
    var duration = (anim ? S.options.resizeDuration : 0);
    animate(wrapper, "left", left, duration);
    animate(wrapper, "width", width, duration, callback)
  }
  function setDimensions(height, width) {
    var bodyInner = get("sb-body-inner"),
        height = parseInt(height),
        width = parseInt(width),
        topBottom = wrapper.offsetHeight - bodyInner.offsetHeight,
        leftRight = wrapper.offsetWidth - bodyInner.offsetWidth,
        maxHeight = overlay.offsetHeight,
        maxWidth = overlay.offsetWidth,
        padding = parseInt(S.options.viewportPadding) || 20,
        preserveAspect = (S.player && S.options.handleOversize != "drag");
    return S.setDimensions(height, width, maxHeight, maxWidth, topBottom, leftRight, padding, preserveAspect)
  }
  var K = {};
  K.markup = '<div id="sb-container"><div id="sb-overlay"></div><div id="sb-wrapper"><div id="sb-title"><div id="sb-title-inner"></div></div><div id="sb-wrapper-inner"><div id="sb-body"><div id="sb-body-inner"></div><div id="sb-loading"><div id="sb-loading-inner"><span>{loading}</span></div></div></div></div><div id="sb-info"><div id="sb-info-inner"><div id="sb-counter"></div><div id="sb-nav"><a id="sb-nav-close" title="{close}" onclick="Shadowbox.close()"></a><a id="sb-nav-next" title="{next}" onclick="Shadowbox.next()"></a><a id="sb-nav-play" title="{play}" onclick="Shadowbox.play()"></a><a id="sb-nav-pause" title="{pause}" onclick="Shadowbox.pause()"></a><a id="sb-nav-previous" title="{previous}" onclick="Shadowbox.previous()"></a></div></div></div></div></div>';
  K.options = {
    animSequence: "sync",
    counterLimit: 10,
    counterType: "default",
    displayCounter: true,
    displayNav: true,
    fadeDuration: 0.35,
    initialHeight: 160,
    initialWidth: 320,
    modal: false,
    overlayColor: "#000",
    overlayOpacity: 0.5,
    resizeDuration: 0.35,
    showOverlay: true,
    troubleElements: ["select", "object", "embed", "canvas"]
  };
  K.init = function() {
    S.appendHTML(document.body, sprintf(K.markup, S.lang));
    K.body = get("sb-body-inner");
    container = get("sb-container");
    overlay = get("sb-overlay");
    wrapper = get("sb-wrapper");
    if (!supportsFixed) {
      container.style.position = "absolute"
    }
    if (!supportsOpacity) {
      var el, m, re = /url\("(.*\.png)"\)/;
      each(pngIds, function(i, id) {
        el = get(id);
        if (el) {
          m = S.getStyle(el, "backgroundImage").match(re);
          if (m) {
            el.style.backgroundImage = "none";
            el.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,src=" + m[1] + ",sizingMethod=scale);"
          }
        }
      })
    }
    var timer;
    addEvent(window, "resize", function() {
      if (timer) {
        clearTimeout(timer);
        timer = null
      }
      if (open) {
        timer = setTimeout(K.onWindowResize, 10)
      }
    })
  };
  K.onOpen = function(obj, callback) {
    doWindowResize = false;
    container.style.display = "block";
    setSize();
    var dims = setDimensions(S.options.initialHeight, S.options.initialWidth);
    adjustHeight(dims.innerHeight, dims.top);
    adjustWidth(dims.width, dims.left);
    if (S.options.showOverlay) {
      overlay.style.backgroundColor = S.options.overlayColor;
      S.setOpacity(overlay, 0);
      if (!S.options.modal) {
        addEvent(overlay, "click", S.close)
      }
      overlayOn = true
    }
    if (!supportsFixed) {
      setPosition();
      addEvent(window, "scroll", setPosition)
    }
    toggleTroubleElements();
    container.style.visibility = "visible";
    if (overlayOn) {
      animate(overlay, "opacity", S.options.overlayOpacity, S.options.fadeDuration, callback)
    } else {
      callback()
    }
  };
  K.onLoad = function(changing, callback) {
    toggleLoading(true);
    while (K.body.firstChild) {
      remove(K.body.firstChild)
    }
    hideBars(changing, function() {
      if (!open) {
        return
      }
      if (!changing) {
        wrapper.style.visibility = "visible"
      }
      buildBars(callback)
    })
  };
  K.onReady = function(callback) {
    if (!open) {
      return
    }
    var player = S.player,
        dims = setDimensions(player.height, player.width);
    var wrapped = function() {
        showBars(callback)
        };
    switch (S.options.animSequence) {
    case "hw":
      adjustHeight(dims.innerHeight, dims.top, true, function() {
        adjustWidth(dims.width, dims.left, true, wrapped)
      });
      break;
    case "wh":
      adjustWidth(dims.width, dims.left, true, function() {
        adjustHeight(dims.innerHeight, dims.top, true, wrapped)
      });
      break;
    default:
      adjustWidth(dims.width, dims.left, true);
      adjustHeight(dims.innerHeight, dims.top, true, wrapped)
    }
  };
  K.onShow = function(callback) {
    toggleLoading(false, callback);
    doWindowResize = true
  };
  K.onClose = function() {
    if (!supportsFixed) {
      removeEvent(window, "scroll", setPosition)
    }
    removeEvent(overlay, "click", S.close);
    wrapper.style.visibility = "hidden";
    var callback = function() {
        container.style.visibility = "hidden";
        container.style.display = "none";
        toggleTroubleElements(true)
        };
    if (overlayOn) {
      animate(overlay, "opacity", 0, S.options.fadeDuration, callback)
    } else {
      callback()
    }
  };
  K.onPlay = function() {
    toggleNav("play", false);
    toggleNav("pause", true)
  };
  K.onPause = function() {
    toggleNav("pause", false);
    toggleNav("play", true)
  };
  K.onWindowResize = function() {
    if (!doWindowResize) {
      return
    }
    setSize();
    var player = S.player,
        dims = setDimensions(player.height, player.width);
    adjustWidth(dims.width, dims.left);
    adjustHeight(dims.innerHeight, dims.top);
    if (player.onWindowResize) {
      player.onWindowResize()
    }
  };
  S.skin = K;
  window.Shadowbox = S
})(window);
ready
Mootools Shadowbox
/*
 * Shadowbox.js, version 3.0.3
 * http://shadowbox-js.com/
 *
 * Copyright 2007-2010, Michael J. I. Jackson
 * Date: 2011-05-14 19:14:25 +0000
 */
(function(window, undefined) {
  var S = {
    version: "3.0.3"
  };
  var ua = navigator.userAgent.toLowerCase();
  if (ua.indexOf("windows") > -1 || ua.indexOf("win32") > -1) {
    S.isWindows = true
  } else {
    if (ua.indexOf("macintosh") > -1 || ua.indexOf("mac os x") > -1) {
      S.isMac = true
    } else {
      if (ua.indexOf("linux") > -1) {
        S.isLinux = true
      }
    }
  }
  S.isIE = ua.indexOf("msie") > -1;
  S.isIE6 = ua.indexOf("msie 6") > -1;
  S.isIE7 = ua.indexOf("msie 7") > -1;
  S.isGecko = ua.indexOf("gecko") > -1 && ua.indexOf("safari") == -1;
  S.isWebKit = ua.indexOf("applewebkit/") > -1;
  var inlineId = /#(.+)$/,
      galleryName = /^(light|shadow)box\[(.*?)\]/i,
      inlineParam = /\s*([a-z_]*?)\s*=\s*(.+)\s*/,
      fileExtension = /[0-9a-z]+$/i,
      scriptPath = /(.+\/)shadowbox\.js/i;
  var open = false,
      initialized = false,
      lastOptions = {},
      slideDelay = 0,
      slideStart, slideTimer;
  S.current = -1;
  S.dimensions = null;
  S.ease = function(state) {
    return 1 + Math.pow(state - 1, 3)
  };
  S.errorInfo = {
    fla: {
      name: "Flash",
      url: "http://www.adobe.com/products/flashplayer/"
    },
    qt: {
      name: "QuickTime",
      url: "http://www.apple.com/quicktime/download/"
    },
    wmp: {
      name: "Windows Media Player",
      url: "http://www.microsoft.com/windows/windowsmedia/"
    },
    f4m: {
      name: "Flip4Mac",
      url: "http://www.flip4mac.com/wmv_download.htm"
    }
  };
  S.gallery = [];
  S.onReady = noop;
  S.path = null;
  S.player = null;
  S.playerId = "sb-player";
  S.options = {
    animate: true,
    animateFade: true,
    autoplayMovies: true,
    continuous: false,
    enableKeys: true,
    flashParams: {
      bgcolor: "#000000",
      allowfullscreen: true
    },
    flashVars: {},
    flashVersion: "9.0.115",
    handleOversize: "resize",
    handleUnsupported: "link",
    onChange: noop,
    onClose: noop,
    onFinish: noop,
    onOpen: noop,
    showMovieControls: true,
    skipSetup: false,
    slideshowDelay: 0,
    viewportPadding: 20
  };
  S.getCurrent = function() {
    return S.current > -1 ? S.gallery[S.current] : null
  };
  S.hasNext = function() {
    return S.gallery.length > 1 && (S.current != S.gallery.length - 1 || S.options.continuous)
  };
  S.isOpen = function() {
    return open
  };
  S.isPaused = function() {
    return slideTimer == "pause"
  };
  S.applyOptions = function(options) {
    lastOptions = apply({}, S.options);
    apply(S.options, options)
  };
  S.revertOptions = function() {
    apply(S.options, lastOptions)
  };
  S.init = function(options, callback) {
    if (initialized) {
      return
    }
    initialized = true;
    if (S.skin.options) {
      apply(S.options, S.skin.options)
    }
    if (options) {
      apply(S.options, options)
    }
    if (!S.path) {
      var path, scripts = document.getElementsByTagName("script");
      for (var i = 0, len = scripts.length; i < len; ++i) {
        path = scriptPath.exec(scripts[i].src);
        if (path) {
          S.path = path[1];
          break
        }
      }
    }
    if (callback) {
      S.onReady = callback
    }
    bindLoad()
  };
  S.open = function(obj) {
    if (open) {
      return
    }
    var gc = S.makeGallery(obj);
    S.gallery = gc[0];
    S.current = gc[1];
    obj = S.getCurrent();
    if (obj == null) {
      return
    }
    S.applyOptions(obj.options || {});
    filterGallery();
    if (S.gallery.length) {
      obj = S.getCurrent();
      if (S.options.onOpen(obj) === false) {
        return
      }
      open = true;
      S.skin.onOpen(obj, load)
    }
  };
  S.close = function() {
    if (!open) {
      return
    }
    open = false;
    if (S.player) {
      S.player.remove();
      S.player = null
    }
    if (typeof slideTimer == "number") {
      clearTimeout(slideTimer);
      slideTimer = null
    }
    slideDelay = 0;
    listenKeys(false);
    S.options.onClose(S.getCurrent());
    S.skin.onClose();
    S.revertOptions()
  };
  S.play = function() {
    if (!S.hasNext()) {
      return
    }
    if (!slideDelay) {
      slideDelay = S.options.slideshowDelay * 1000
    }
    if (slideDelay) {
      slideStart = now();
      slideTimer = setTimeout(function() {
        slideDelay = slideStart = 0;
        S.next()
      }, slideDelay);
      if (S.skin.onPlay) {
        S.skin.onPlay()
      }
    }
  };
  S.pause = function() {
    if (typeof slideTimer != "number") {
      return
    }
    slideDelay = Math.max(0, slideDelay - (now() - slideStart));
    if (slideDelay) {
      clearTimeout(slideTimer);
      slideTimer = "pause";
      if (S.skin.onPause) {
        S.skin.onPause()
      }
    }
  };
  S.change = function(index) {
    if (!(index in S.gallery)) {
      if (S.options.continuous) {
        index = (index < 0 ? S.gallery.length + index : 0);
        if (!(index in S.gallery)) {
          return
        }
      } else {
        return
      }
    }
    S.current = index;
    if (typeof slideTimer == "number") {
      clearTimeout(slideTimer);
      slideTimer = null;
      slideDelay = slideStart = 0
    }
    S.options.onChange(S.getCurrent());
    load(true)
  };
  S.next = function() {
    S.change(S.current + 1)
  };
  S.previous = function() {
    S.change(S.current - 1)
  };
  S.setDimensions = function(height, width, maxHeight, maxWidth, topBottom, leftRight, padding, preserveAspect) {
    var originalHeight = height,
        originalWidth = width;
    var extraHeight = 2 * padding + topBottom;
    if (height + extraHeight > maxHeight) {
      height = maxHeight - extraHeight
    }
    var extraWidth = 2 * padding + leftRight;
    if (width + extraWidth > maxWidth) {
      width = maxWidth - extraWidth
    }
    var changeHeight = (originalHeight - height) / originalHeight,
        changeWidth = (originalWidth - width) / originalWidth,
        oversized = (changeHeight > 0 || changeWidth > 0);
    if (preserveAspect && oversized) {
      if (changeHeight > changeWidth) {
        width = Math.round((originalWidth / originalHeight) * height)
      } else {
        if (changeWidth > changeHeight) {
          height = Math.round((originalHeight / originalWidth) * width)
        }
      }
    }
    S.dimensions = {
      height: height + topBottom,
      width: width + leftRight,
      innerHeight: height,
      innerWidth: width,
      top: Math.floor((maxHeight - (height + extraHeight)) / 2 + padding),
      left: Math.floor((maxWidth - (width + extraWidth)) / 2 + padding),
      oversized: oversized
    };
    return S.dimensions
  };
  S.makeGallery = function(obj) {
    var gallery = [],
        current = -1;
    if (typeof obj == "string") {
      obj = [obj]
    }
    if (typeof obj.length == "number") {
      each(obj, function(i, o) {
        if (o.content) {
          gallery[i] = o
        } else {
          gallery[i] = {
            content: o
          }
        }
      });
      current = 0
    } else {
      if (obj.tagName) {
        var cacheObj = S.getCache(obj);
        obj = cacheObj ? cacheObj : S.makeObject(obj)
      }
      if (obj.gallery) {
        gallery = [];
        var o;
        for (var key in S.cache) {
          o = S.cache[key];
          if (o.gallery && o.gallery == obj.gallery) {
            if (current == -1 && o.content == obj.content) {
              current = gallery.length
            }
            gallery.push(o)
          }
        }
        if (current == -1) {
          gallery.unshift(obj);
          current = 0
        }
      } else {
        gallery = [obj];
        current = 0
      }
    }
    each(gallery, function(i, o) {
      gallery[i] = apply({}, o)
    });
    return [gallery, current]
  };
  S.makeObject = function(link, options) {
    var obj = {
      content: link.href,
      title: link.getAttribute("title") || "",
      link: link
    };
    if (options) {
      options = apply({}, options);
      each(["player", "title", "height", "width", "gallery"], function(i, o) {
        if (typeof options[o] != "undefined") {
          obj[o] = options[o];
          delete options[o]
        }
      });
      obj.options = options
    } else {
      obj.options = {}
    }
    if (!obj.player) {
      obj.player = S.getPlayer(obj.content)
    }
    var rel = link.getAttribute("rel");
    if (rel) {
      var match = rel.match(galleryName);
      if (match) {
        obj.gallery = escape(match[2])
      }
      each(rel.split(";"), function(i, p) {
        match = p.match(inlineParam);
        if (match) {
          obj[match[1]] = match[2]
        }
      })
    }
    return obj
  };
  S.getPlayer = function(content) {
    if (content.indexOf("#") > -1 && content.indexOf(document.location.href) == 0) {
      return "inline"
    }
    var q = content.indexOf("?");
    if (q > -1) {
      content = content.substring(0, q)
    }
    var ext, m = content.match(fileExtension);
    if (m) {
      ext = m[0].toLowerCase()
    }
    if (ext) {
      if (S.img && S.img.ext.indexOf(ext) > -1) {
        return "img"
      }
      if (S.swf && S.swf.ext.indexOf(ext) > -1) {
        return "swf"
      }
      if (S.flv && S.flv.ext.indexOf(ext) > -1) {
        return "flv"
      }
      if (S.qt && S.qt.ext.indexOf(ext) > -1) {
        if (S.wmp && S.wmp.ext.indexOf(ext) > -1) {
          return "qtwmp"
        } else {
          return "qt"
        }
      }
      if (S.wmp && S.wmp.ext.indexOf(ext) > -1) {
        return "wmp"
      }
    }
    return "iframe"
  };

  function filterGallery() {
    var err = S.errorInfo,
        plugins = S.plugins,
        obj, remove, needed, m, format, replace, inlineEl, flashVersion;
    for (var i = 0; i < S.gallery.length; ++i) {
      obj = S.gallery[i];
      remove = false;
      needed = null;
      switch (obj.player) {
      case "flv":
      case "swf":
        if (!plugins.fla) {
          needed = "fla"
        }
        break;
      case "qt":
        if (!plugins.qt) {
          needed = "qt"
        }
        break;
      case "wmp":
        if (S.isMac) {
          if (plugins.qt && plugins.f4m) {
            obj.player = "qt"
          } else {
            needed = "qtf4m"
          }
        } else {
          if (!plugins.wmp) {
            needed = "wmp"
          }
        }
        break;
      case "qtwmp":
        if (plugins.qt) {
          obj.player = "qt"
        } else {
          if (plugins.wmp) {
            obj.player = "wmp"
          } else {
            needed = "qtwmp"
          }
        }
        break
      }
      if (needed) {
        if (S.options.handleUnsupported == "link") {
          switch (needed) {
          case "qtf4m":
            format = "shared";
            replace = [err.qt.url, err.qt.name, err.f4m.url, err.f4m.name];
            break;
          case "qtwmp":
            format = "either";
            replace = [err.qt.url, err.qt.name, err.wmp.url, err.wmp.name];
            break;
          default:
            format = "single";
            replace = [err[needed].url, err[needed].name]
          }
          obj.player = "html";
          obj.content = '<div class="sb-message">' + sprintf(S.lang.errors[format], replace) + "</div>"
        } else {
          remove = true
        }
      } else {
        if (obj.player == "inline") {
          m = inlineId.exec(obj.content);
          if (m) {
            inlineEl = get(m[1]);
            if (inlineEl) {
              obj.content = inlineEl.innerHTML
            } else {
              remove = true
            }
          } else {
            remove = true
          }
        } else {
          if (obj.player == "swf" || obj.player == "flv") {
            flashVersion = (obj.options && obj.options.flashVersion) || S.options.flashVersion;
            if (S.flash && !S.flash.hasFlashPlayerVersion(flashVersion)) {
              obj.width = 310;
              obj.height = 177
            }
          }
        }
      }
      if (remove) {
        S.gallery.splice(i, 1);
        if (i < S.current) {
          --S.current
        } else {
          if (i == S.current) {
            S.current = i > 0 ? i - 1 : i
          }
        }--i
      }
    }
  }
  function listenKeys(on) {
    if (!S.options.enableKeys) {
      return
    }(on ? addEvent : removeEvent)(document, "keydown", handleKey)
  }
  function handleKey(e) {
    if (e.metaKey || e.shiftKey || e.altKey || e.ctrlKey) {
      return
    }
    var code = keyCode(e),
        handler;
    switch (code) {
    case 81:
    case 88:
    case 27:
      handler = S.close;
      break;
    case 37:
      handler = S.previous;
      break;
    case 39:
      handler = S.next;
      break;
    case 32:
      handler = typeof slideTimer == "number" ? S.pause : S.play;
      break
    }
    if (handler) {
      preventDefault(e);
      handler()
    }
  }
  function load(changing) {
    listenKeys(false);
    var obj = S.getCurrent();
    var player = (obj.player == "inline" ? "html" : obj.player);
    if (typeof S[player] != "function") {
      throw "unknown player " + player
    }
    if (changing) {
      S.player.remove();
      S.revertOptions();
      S.applyOptions(obj.options || {})
    }
    S.player = new S[player](obj, S.playerId);
    if (S.gallery.length > 1) {
      var next = S.gallery[S.current + 1] || S.gallery[0];
      if (next.player == "img") {
        var a = new Image();
        a.src = next.content
      }
      var prev = S.gallery[S.current - 1] || S.gallery[S.gallery.length - 1];
      if (prev.player == "img") {
        var b = new Image();
        b.src = prev.content
      }
    }
    S.skin.onLoad(changing, waitReady)
  }
  function waitReady() {
    if (!open) {
      return
    }
    if (typeof S.player.ready != "undefined") {
      var timer = setInterval(function() {
        if (open) {
          if (S.player.ready) {
            clearInterval(timer);
            timer = null;
            S.skin.onReady(show)
          }
        } else {
          clearInterval(timer);
          timer = null
        }
      }, 10)
    } else {
      S.skin.onReady(show)
    }
  }
  function show() {
    if (!open) {
      return
    }
    S.player.append(S.skin.body, S.dimensions);
    S.skin.onShow(finish)
  }
  function finish() {
    if (!open) {
      return
    }
    if (S.player.onLoad) {
      S.player.onLoad()
    }
    S.options.onFinish(S.getCurrent());
    if (!S.isPaused()) {
      S.play()
    }
    listenKeys(true)
  }
  if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(obj, from) {
      var len = this.length >>> 0;
      from = from || 0;
      if (from < 0) {
        from += len
      }
      for (; from < len; ++from) {
        if (from in this && this[from] === obj) {
          return from
        }
      }
      return -1
    }
  }
  function now() {
    return (new Date).getTime()
  }
  function apply(original, extension) {
    for (var property in extension) {
      original[property] = extension[property]
    }
    return original
  }
  function each(obj, callback) {
    var i = 0,
        len = obj.length;
    for (var value = obj[0]; i < len && callback.call(value, i, value) !== false; value = obj[++i]) {}
  }
  function sprintf(str, replace) {
    return str.replace(/\{(\w+?)\}/g, function(match, i) {
      return replace[i]
    })
  }
  function noop() {}
  function get(id) {
    return document.getElementById(id)
  }
  function remove(el) {
    el.parentNode.removeChild(el)
  }
  var supportsOpacity = true,
      supportsFixed = true;

  function checkSupport() {
    var body = document.body,
        div = document.createElement("div");
    supportsOpacity = typeof div.style.opacity === "string";
    div.style.position = "fixed";
    div.style.margin = 0;
    div.style.top = "20px";
    body.appendChild(div, body.firstChild);
    supportsFixed = div.offsetTop == 20;
    body.removeChild(div)
  }
  S.getStyle = (function() {
    var opacity = /opacity=([^)]*)/,
        getComputedStyle = document.defaultView && document.defaultView.getComputedStyle;
    return function(el, style) {
      var ret;
      if (!supportsOpacity && style == "opacity" && el.currentStyle) {
        ret = opacity.test(el.currentStyle.filter || "") ? (parseFloat(RegExp.$1) / 100) + "" : "";
        return ret === "" ? "1" : ret
      }
      if (getComputedStyle) {
        var computedStyle = getComputedStyle(el, null);
        if (computedStyle) {
          ret = computedStyle[style]
        }
        if (style == "opacity" && ret == "") {
          ret = "1"
        }
      } else {
        ret = el.currentStyle[style]
      }
      return ret
    }
  })();
  S.appendHTML = function(el, html) {
    if (el.insertAdjacentHTML) {
      el.insertAdjacentHTML("BeforeEnd", html)
    } else {
      if (el.lastChild) {
        var range = el.ownerDocument.createRange();
        range.setStartAfter(el.lastChild);
        var frag = range.createContextualFragment(html);
        el.appendChild(frag)
      } else {
        el.innerHTML = html
      }
    }
  };
  S.getWindowSize = function(dimension) {
    if (document.compatMode === "CSS1Compat") {
      return document.documentElement["client" + dimension]
    }
    return document.body["client" + dimension]
  };
  S.setOpacity = function(el, opacity) {
    var style = el.style;
    if (supportsOpacity) {
      style.opacity = (opacity == 1 ? "" : opacity)
    } else {
      style.zoom = 1;
      if (opacity == 1) {
        if (typeof style.filter == "string" && (/alpha/i).test(style.filter)) {
          style.filter = style.filter.replace(/\s*[\w\.]*alpha\([^\)]*\);?/gi, "")
        }
      } else {
        style.filter = (style.filter || "").replace(/\s*[\w\.]*alpha\([^\)]*\)/gi, "") + " alpha(opacity=" + (opacity * 100) + ")"
      }
    }
  };
  S.clearOpacity = function(el) {
    S.setOpacity(el, 1)
  };

  function getTarget(e) {
    return e.target
  }
  function getPageXY(e) {
    return [e.page.x, e.page.y]
  }
  function preventDefault(e) {
    e.preventDefault()
  }
  function keyCode(e) {
    return e.code
  }
  function addEvent(el, type, handler) {
    $(el).addEvent(type, handler)
  }
  function removeEvent(el, type, handler) {
    $(el).removeEvent(type, handler)
  }
  var loaded = false,
      DOMContentLoaded;
  if (document.addEventListener) {
    DOMContentLoaded = function() {
      document.removeEventListener("DOMContentLoaded", DOMContentLoaded, false);
      S.load()
    }
  } else {
    if (document.attachEvent) {
      DOMContentLoaded = function() {
        if (document.readyState === "complete") {
          document.detachEvent("onreadystatechange", DOMContentLoaded);
          S.load()
        }
      }
    }
  }
  function doScrollCheck() {
    if (loaded) {
      return
    }
    try {
      document.documentElement.doScroll("left")
    } catch (e) {
      setTimeout(doScrollCheck, 1);
      return
    }
    S.load()
  }
  function bindLoad() {
    if (document.readyState === "complete") {
      return S.load()
    }
    if (document.addEventListener) {
      document.addEventListener("DOMContentLoaded", DOMContentLoaded, false);
      window.addEventListener("load", S.load, false)
    } else {
      if (document.attachEvent) {
        document.attachEvent("onreadystatechange", DOMContentLoaded);
        window.attachEvent("onload", S.load);
        var topLevel = false;
        try {
          topLevel = window.frameElement === null
        } catch (e) {}
        if (document.documentElement.doScroll && topLevel) {
          doScrollCheck()
        }
      }
    }
  }
  S.load = function() {
    if (loaded) {
      return
    }
    if (!document.body) {
      return setTimeout(S.load, 13)
    }
    loaded = true;
    checkSupport();
    S.onReady();
    if (!S.options.skipSetup) {
      S.setup()
    }
    S.skin.init()
  };
  S.plugins = {};
  if (navigator.plugins && navigator.plugins.length) {
    var names = [];
    each(navigator.plugins, function(i, p) {
      names.push(p.name)
    });
    names = names.join(",");
    var f4m = names.indexOf("Flip4Mac") > -1;
    S.plugins = {
      fla: names.indexOf("Shockwave Flash") > -1,
      qt: names.indexOf("QuickTime") > -1,
      wmp: !f4m && names.indexOf("Windows Media") > -1,
      f4m: f4m
    }
  } else {
    var detectPlugin = function(name) {
        var axo;
        try {
          axo = new ActiveXObject(name)
        } catch (e) {}
        return !!axo
        };
    S.plugins = {
      fla: detectPlugin("ShockwaveFlash.ShockwaveFlash"),
      qt: detectPlugin("QuickTime.QuickTime"),
      wmp: detectPlugin("wmplayer.ocx"),
      f4m: false
    }
  }
  var relAttr = /^(light|shadow)box/i,
      expando = "shadowboxCacheKey",
      cacheKey = 1;
  S.cache = {};
  S.select = function(selector) {
    var links = [];
    if (!selector) {
      var rel;
      each(document.getElementsByTagName("a"), function(i, el) {
        rel = el.getAttribute("rel");
        if (rel && relAttr.test(rel)) {
          links.push(el)
        }
      })
    } else {
      var length = selector.length;
      if (length) {
        if (typeof selector == "string") {
          if (S.find) {
            links = S.find(selector)
          }
        } else {
          if (length == 2 && typeof selector[0] == "string" && selector[1].nodeType) {
            if (S.find) {
              links = S.find(selector[0], selector[1])
            }
          } else {
            for (var i = 0; i < length; ++i) {
              links[i] = selector[i]
            }
          }
        }
      } else {
        links.push(selector)
      }
    }
    return links
  };
  S.setup = function(selector, options) {
    each(S.select(selector), function(i, link) {
      S.addCache(link, options)
    })
  };
  S.teardown = function(selector) {
    each(S.select(selector), function(i, link) {
      S.removeCache(link)
    })
  };
  S.addCache = function(link, options) {
    var key = link[expando];
    if (key == undefined) {
      key = cacheKey++;
      link[expando] = key;
      addEvent(link, "click", handleClick)
    }
    S.cache[key] = S.makeObject(link, options)
  };
  S.removeCache = function(link) {
    removeEvent(link, "click", handleClick);
    delete S.cache[link[expando]];
    link[expando] = null
  };
  S.getCache = function(link) {
    var key = link[expando];
    return (key in S.cache && S.cache[key])
  };
  S.clearCache = function() {
    for (var key in S.cache) {
      S.removeCache(S.cache[key].link)
    }
    S.cache = {}
  };

  function handleClick(e) {
    S.open(this);
    if (S.gallery.length) {
      preventDefault(e)
    }
  }
/*
 * Sizzle CSS Selector Engine - v1.0
 *  Copyright 2009, The Dojo Foundation
 *  Released under the MIT, BSD, and GPL Licenses.
 *  More information: http://sizzlejs.com/
 *
 * Modified for inclusion in Shadowbox.js
 */
  S.find = (function() {
    var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
        done = 0,
        toString = Object.prototype.toString,
        hasDuplicate = false,
        baseHasDuplicate = true;
    [0, 0].sort(function() {
      baseHasDuplicate = false;
      return 0
    });
    var Sizzle = function(selector, context, results, seed) {
        results = results || [];
        var origContext = context = context || document;
        if (context.nodeType !== 1 && context.nodeType !== 9) {
          return []
        }
        if (!selector || typeof selector !== "string") {
          return results
        }
        var parts = [],
            m, set, checkSet, extra, prune = true,
            contextXML = isXML(context),
            soFar = selector;
        while ((chunker.exec(""), m = chunker.exec(soFar)) !== null) {
          soFar = m[3];
          parts.push(m[1]);
          if (m[2]) {
            extra = m[3];
            break
          }
        }
        if (parts.length > 1 && origPOS.exec(selector)) {
          if (parts.length === 2 && Expr.relative[parts[0]]) {
            set = posProcess(parts[0] + parts[1], context)
          } else {
            set = Expr.relative[parts[0]] ? [context] : Sizzle(parts.shift(), context);
            while (parts.length) {
              selector = parts.shift();
              if (Expr.relative[selector]) {
                selector += parts.shift()
              }
              set = posProcess(selector, set)
            }
          }
        } else {
          if (!seed && parts.length > 1 && context.nodeType === 9 && !contextXML && Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1])) {
            var ret = Sizzle.find(parts.shift(), context, contextXML);
            context = ret.expr ? Sizzle.filter(ret.expr, ret.set)[0] : ret.set[0]
          }
          if (context) {
            var ret = seed ? {
              expr: parts.pop(),
              set: makeArray(seed)
            } : Sizzle.find(parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML);
            set = ret.expr ? Sizzle.filter(ret.expr, ret.set) : ret.set;
            if (parts.length > 0) {
              checkSet = makeArray(set)
            } else {
              prune = false
            }
            while (parts.length) {
              var cur = parts.pop(),
                  pop = cur;
              if (!Expr.relative[cur]) {
                cur = ""
              } else {
                pop = parts.pop()
              }
              if (pop == null) {
                pop = context
              }
              Expr.relative[cur](checkSet, pop, contextXML)
            }
          } else {
            checkSet = parts = []
          }
        }
        if (!checkSet) {
          checkSet = set
        }
        if (!checkSet) {
          throw "Syntax error, unrecognized expression: " + (cur || selector)
        }
        if (toString.call(checkSet) === "[object Array]") {
          if (!prune) {
            results.push.apply(results, checkSet)
          } else {
            if (context && context.nodeType === 1) {
              for (var i = 0; checkSet[i] != null; i++) {
                if (checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i]))) {
                  results.push(set[i])
                }
              }
            } else {
              for (var i = 0; checkSet[i] != null; i++) {
                if (checkSet[i] && checkSet[i].nodeType === 1) {
                  results.push(set[i])
                }
              }
            }
          }
        } else {
          makeArray(checkSet, results)
        }
        if (extra) {
          Sizzle(extra, origContext, results, seed);
          Sizzle.uniqueSort(results)
        }
        return results
        };
    Sizzle.uniqueSort = function(results) {
      if (sortOrder) {
        hasDuplicate = baseHasDuplicate;
        results.sort(sortOrder);
        if (hasDuplicate) {
          for (var i = 1; i < results.length; i++) {
            if (results[i] === results[i - 1]) {
              results.splice(i--, 1)
            }
          }
        }
      }
      return results
    };
    Sizzle.matches = function(expr, set) {
      return Sizzle(expr, null, null, set)
    };
    Sizzle.find = function(expr, context, isXML) {
      var set, match;
      if (!expr) {
        return []
      }
      for (var i = 0, l = Expr.order.length; i < l; i++) {
        var type = Expr.order[i],
            match;
        if ((match = Expr.leftMatch[type].exec(expr))) {
          var left = match[1];
          match.splice(1, 1);
          if (left.substr(left.length - 1) !== "\\") {
            match[1] = (match[1] || "").replace(/\\/g, "");
            set = Expr.find[type](match, context, isXML);
            if (set != null) {
              expr = expr.replace(Expr.match[type], "");
              break
            }
          }
        }
      }
      if (!set) {
        set = context.getElementsByTagName("*")
      }
      return {
        set: set,
        expr: expr
      }
    };
    Sizzle.filter = function(expr, set, inplace, not) {
      var old = expr,
          result = [],
          curLoop = set,
          match, anyFound, isXMLFilter = set && set[0] && isXML(set[0]);
      while (expr && set.length) {
        for (var type in Expr.filter) {
          if ((match = Expr.match[type].exec(expr)) != null) {
            var filter = Expr.filter[type],
                found, item;
            anyFound = false;
            if (curLoop === result) {
              result = []
            }
            if (Expr.preFilter[type]) {
              match = Expr.preFilter[type](match, curLoop, inplace, result, not, isXMLFilter);
              if (!match) {
                anyFound = found = true
              } else {
                if (match === true) {
                  continue
                }
              }
            }
            if (match) {
              for (var i = 0;
              (item = curLoop[i]) != null; i++) {
                if (item) {
                  found = filter(item, match, i, curLoop);
                  var pass = not ^ !! found;
                  if (inplace && found != null) {
                    if (pass) {
                      anyFound = true
                    } else {
                      curLoop[i] = false
                    }
                  } else {
                    if (pass) {
                      result.push(item);
                      anyFound = true
                    }
                  }
                }
              }
            }
            if (found !== undefined) {
              if (!inplace) {
                curLoop = result
              }
              expr = expr.replace(Expr.match[type], "");
              if (!anyFound) {
                return []
              }
              break
            }
          }
        }
        if (expr === old) {
          if (anyFound == null) {
            throw "Syntax error, unrecognized expression: " + expr
          } else {
            break
          }
        }
        old = expr
      }
      return curLoop
    };
    var Expr = Sizzle.selectors = {
      order: ["ID", "NAME", "TAG"],
      match: {
        ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
        CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
        NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
        ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
        TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
        CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
        POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
        PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
      },
      leftMatch: {},
      attrMap: {
        "class": "className",
        "for": "htmlFor"
      },
      attrHandle: {
        href: function(elem) {
          return elem.getAttribute("href")
        }
      },
      relative: {
        "+": function(checkSet, part) {
          var isPartStr = typeof part === "string",
              isTag = isPartStr && !/\W/.test(part),
              isPartStrNotTag = isPartStr && !isTag;
          if (isTag) {
            part = part.toLowerCase()
          }
          for (var i = 0, l = checkSet.length, elem; i < l; i++) {
            if ((elem = checkSet[i])) {
              while ((elem = elem.previousSibling) && elem.nodeType !== 1) {}
              checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? elem || false : elem === part
            }
          }
          if (isPartStrNotTag) {
            Sizzle.filter(part, checkSet, true)
          }
        },
        ">": function(checkSet, part) {
          var isPartStr = typeof part === "string";
          if (isPartStr && !/\W/.test(part)) {
            part = part.toLowerCase();
            for (var i = 0, l = checkSet.length; i < l; i++) {
              var elem = checkSet[i];
              if (elem) {
                var parent = elem.parentNode;
                checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false
              }
            }
          } else {
            for (var i = 0, l = checkSet.length; i < l; i++) {
              var elem = checkSet[i];
              if (elem) {
                checkSet[i] = isPartStr ? elem.parentNode : elem.parentNode === part
              }
            }
            if (isPartStr) {
              Sizzle.filter(part, checkSet, true)
            }
          }
        },
        "": function(checkSet, part, isXML) {
          var doneName = done++,
              checkFn = dirCheck;
          if (typeof part === "string" && !/\W/.test(part)) {
            var nodeCheck = part = part.toLowerCase();
            checkFn = dirNodeCheck
          }
          checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML)
        },
        "~": function(checkSet, part, isXML) {
          var doneName = done++,
              checkFn = dirCheck;
          if (typeof part === "string" && !/\W/.test(part)) {
            var nodeCheck = part = part.toLowerCase();
            checkFn = dirNodeCheck
          }
          checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML)
        }
      },
      find: {
        ID: function(match, context, isXML) {
          if (typeof context.getElementById !== "undefined" && !isXML) {
            var m = context.getElementById(match[1]);
            return m ? [m] : []
          }
        },
        NAME: function(match, context) {
          if (typeof context.getElementsByName !== "undefined") {
            var ret = [],
                results = context.getElementsByName(match[1]);
            for (var i = 0, l = results.length; i < l; i++) {
              if (results[i].getAttribute("name") === match[1]) {
                ret.push(results[i])
              }
            }
            return ret.length === 0 ? null : ret
          }
        },
        TAG: function(match, context) {
          return context.getElementsByTagName(match[1])
        }
      },
      preFilter: {
        CLASS: function(match, curLoop, inplace, result, not, isXML) {
          match = " " + match[1].replace(/\\/g, "") + " ";
          if (isXML) {
            return match
          }
          for (var i = 0, elem;
          (elem = curLoop[i]) != null; i++) {
            if (elem) {
              if (not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0)) {
                if (!inplace) {
                  result.push(elem)
                }
              } else {
                if (inplace) {
                  curLoop[i] = false
                }
              }
            }
          }
          return false
        },
        ID: function(match) {
          return match[1].replace(/\\/g, "")
        },
        TAG: function(match, curLoop) {
          return match[1].toLowerCase()
        },
        CHILD: function(match) {
          if (match[1] === "nth") {
            var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || !/\D/.test(match[2]) && "0n+" + match[2] || match[2]);
            match[2] = (test[1] + (test[2] || 1)) - 0;
            match[3] = test[3] - 0
          }
          match[0] = done++;
          return match
        },
        ATTR: function(match, curLoop, inplace, result, not, isXML) {
          var name = match[1].replace(/\\/g, "");
          if (!isXML && Expr.attrMap[name]) {
            match[1] = Expr.attrMap[name]
          }
          if (match[2] === "~=") {
            match[4] = " " + match[4] + " "
          }
          return match
        },
        PSEUDO: function(match, curLoop, inplace, result, not) {
          if (match[1] === "not") {
            if ((chunker.exec(match[3]) || "").length > 1 || /^\w/.test(match[3])) {
              match[3] = Sizzle(match[3], null, null, curLoop)
            } else {
              var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
              if (!inplace) {
                result.push.apply(result, ret)
              }
              return false
            }
          } else {
            if (Expr.match.POS.test(match[0]) || Expr.match.CHILD.test(match[0])) {
              return true
            }
          }
          return match
        },
        POS: function(match) {
          match.unshift(true);
          return match
        }
      },
      filters: {
        enabled: function(elem) {
          return elem.disabled === false && elem.type !== "hidden"
        },
        disabled: function(elem) {
          return elem.disabled === true
        },
        checked: function(elem) {
          return elem.checked === true
        },
        selected: function(elem) {
          elem.parentNode.selectedIndex;
          return elem.selected === true
        },
        parent: function(elem) {
          return !!elem.firstChild
        },
        empty: function(elem) {
          return !elem.firstChild
        },
        has: function(elem, i, match) {
          return !!Sizzle(match[3], elem).length
        },
        header: function(elem) {
          return /h\d/i.test(elem.nodeName)
        },
        text: function(elem) {
          return "text" === elem.type
        },
        radio: function(elem) {
          return "radio" === elem.type
        },
        checkbox: function(elem) {
          return "checkbox" === elem.type
        },
        file: function(elem) {
          return "file" === elem.type
        },
        password: function(elem) {
          return "password" === elem.type
        },
        submit: function(elem) {
          return "submit" === elem.type
        },
        image: function(elem) {
          return "image" === elem.type
        },
        reset: function(elem) {
          return "reset" === elem.type
        },
        button: function(elem) {
          return "button" === elem.type || elem.nodeName.toLowerCase() === "button"
        },
        input: function(elem) {
          return /input|select|textarea|button/i.test(elem.nodeName)
        }
      },
      setFilters: {
        first: function(elem, i) {
          return i === 0
        },
        last: function(elem, i, match, array) {
          return i === array.length - 1
        },
        even: function(elem, i) {
          return i % 2 === 0
        },
        odd: function(elem, i) {
          return i % 2 === 1
        },
        lt: function(elem, i, match) {
          return i < match[3] - 0
        },
        gt: function(elem, i, match) {
          return i > match[3] - 0
        },
        nth: function(elem, i, match) {
          return match[3] - 0 === i
        },
        eq: function(elem, i, match) {
          return match[3] - 0 === i
        }
      },
      filter: {
        PSEUDO: function(elem, match, i, array) {
          var name = match[1],
              filter = Expr.filters[name];
          if (filter) {
            return filter(elem, i, match, array)
          } else {
            if (name === "contains") {
              return (elem.textContent || elem.innerText || getText([elem]) || "").indexOf(match[3]) >= 0
            } else {
              if (name === "not") {
                var not = match[3];
                for (var i = 0, l = not.length; i < l; i++) {
                  if (not[i] === elem) {
                    return false
                  }
                }
                return true
              } else {
                throw "Syntax error, unrecognized expression: " + name
              }
            }
          }
        },
        CHILD: function(elem, match) {
          var type = match[1],
              node = elem;
          switch (type) {
          case "only":
          case "first":
            while ((node = node.previousSibling)) {
              if (node.nodeType === 1) {
                return false
              }
            }
            if (type === "first") {
              return true
            }
            node = elem;
          case "last":
            while ((node = node.nextSibling)) {
              if (node.nodeType === 1) {
                return false
              }
            }
            return true;
          case "nth":
            var first = match[2],
                last = match[3];
            if (first === 1 && last === 0) {
              return true
            }
            var doneName = match[0],
                parent = elem.parentNode;
            if (parent && (parent.sizcache !== doneName || !elem.nodeIndex)) {
              var count = 0;
              for (node = parent.firstChild; node; node = node.nextSibling) {
                if (node.nodeType === 1) {
                  node.nodeIndex = ++count
                }
              }
              parent.sizcache = doneName
            }
            var diff = elem.nodeIndex - last;
            if (first === 0) {
              return diff === 0
            } else {
              return (diff % first === 0 && diff / first >= 0)
            }
          }
        },
        ID: function(elem, match) {
          return elem.nodeType === 1 && elem.getAttribute("id") === match
        },
        TAG: function(elem, match) {
          return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match
        },
        CLASS: function(elem, match) {
          return (" " + (elem.className || elem.getAttribute("class")) + " ").indexOf(match) > -1
        },
        ATTR: function(elem, match) {
          var name = match[1],
              result = Expr.attrHandle[name] ? Expr.attrHandle[name](elem) : elem[name] != null ? elem[name] : elem.getAttribute(name),
              value = result + "",
              type = match[2],
              check = match[4];
          return result == null ? type === "!=" : type === "=" ? value === check : type === "*=" ? value.indexOf(check) >= 0 : type === "~=" ? (" " + value + " ").indexOf(check) >= 0 : !check ? value && result !== false : type === "!=" ? value !== check : type === "^=" ? value.indexOf(check) === 0 : type === "$=" ? value.substr(value.length - check.length) === check : type === "|=" ? value === check || value.substr(0, check.length + 1) === check + "-" : false
        },
        POS: function(elem, match, i, array) {
          var name = match[2],
              filter = Expr.setFilters[name];
          if (filter) {
            return filter(elem, i, match, array)
          }
        }
      }
    };
    var origPOS = Expr.match.POS;
    for (var type in Expr.match) {
      Expr.match[type] = new RegExp(Expr.match[type].source + /(?![^\[]*\])(?![^\(]*\))/.source);
      Expr.leftMatch[type] = new RegExp(/(^(?:.|\r|\n)*?)/.source + Expr.match[type].source)
    }
    var makeArray = function(array, results) {
        array = Array.prototype.slice.call(array, 0);
        if (results) {
          results.push.apply(results, array);
          return results
        }
        return array
        };
    try {
      Array.prototype.slice.call(document.documentElement.childNodes, 0)
    } catch (e) {
      makeArray = function(array, results) {
        var ret = results || [];
        if (toString.call(array) === "[object Array]") {
          Array.prototype.push.apply(ret, array)
        } else {
          if (typeof array.length === "number") {
            for (var i = 0, l = array.length; i < l; i++) {
              ret.push(array[i])
            }
          } else {
            for (var i = 0; array[i]; i++) {
              ret.push(array[i])
            }
          }
        }
        return ret
      }
    }
    var sortOrder;
    if (document.documentElement.compareDocumentPosition) {
      sortOrder = function(a, b) {
        if (!a.compareDocumentPosition || !b.compareDocumentPosition) {
          if (a == b) {
            hasDuplicate = true
          }
          return a.compareDocumentPosition ? -1 : 1
        }
        var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
        if (ret === 0) {
          hasDuplicate = true
        }
        return ret
      }
    } else {
      if ("sourceIndex" in document.documentElement) {
        sortOrder = function(a, b) {
          if (!a.sourceIndex || !b.sourceIndex) {
            if (a == b) {
              hasDuplicate = true
            }
            return a.sourceIndex ? -1 : 1
          }
          var ret = a.sourceIndex - b.sourceIndex;
          if (ret === 0) {
            hasDuplicate = true
          }
          return ret
        }
      } else {
        if (document.createRange) {
          sortOrder = function(a, b) {
            if (!a.ownerDocument || !b.ownerDocument) {
              if (a == b) {
                hasDuplicate = true
              }
              return a.ownerDocument ? -1 : 1
            }
            var aRange = a.ownerDocument.createRange(),
                bRange = b.ownerDocument.createRange();
            aRange.setStart(a, 0);
            aRange.setEnd(a, 0);
            bRange.setStart(b, 0);
            bRange.setEnd(b, 0);
            var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
            if (ret === 0) {
              hasDuplicate = true
            }
            return ret
          }
        }
      }
    }
    function getText(elems) {
      var ret = "",
          elem;
      for (var i = 0; elems[i]; i++) {
        elem = elems[i];
        if (elem.nodeType === 3 || elem.nodeType === 4) {
          ret += elem.nodeValue
        } else {
          if (elem.nodeType !== 8) {
            ret += getText(elem.childNodes)
          }
        }
      }
      return ret
    }(function() {
      var form = document.createElement("div"),
          id = "script" + (new Date).getTime();
      form.innerHTML = "<a name='" + id + "'/>";
      var root = document.documentElement;
      root.insertBefore(form, root.firstChild);
      if (document.getElementById(id)) {
        Expr.find.ID = function(match, context, isXML) {
          if (typeof context.getElementById !== "undefined" && !isXML) {
            var m = context.getElementById(match[1]);
            return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : []
          }
        };
        Expr.filter.ID = function(elem, match) {
          var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
          return elem.nodeType === 1 && node && node.nodeValue === match
        }
      }
      root.removeChild(form);
      root = form = null
    })();
    (function() {
      var div = document.createElement("div");
      div.appendChild(document.createComment(""));
      if (div.getElementsByTagName("*").length > 0) {
        Expr.find.TAG = function(match, context) {
          var results = context.getElementsByTagName(match[1]);
          if (match[1] === "*") {
            var tmp = [];
            for (var i = 0; results[i]; i++) {
              if (results[i].nodeType === 1) {
                tmp.push(results[i])
              }
            }
            results = tmp
          }
          return results
        }
      }
      div.innerHTML = "<a href='#'></a>";
      if (div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && div.firstChild.getAttribute("href") !== "#") {
        Expr.attrHandle.href = function(elem) {
          return elem.getAttribute("href", 2)
        }
      }
      div = null
    })();
    if (document.querySelectorAll) {
      (function() {
        var oldSizzle = Sizzle,
            div = document.createElement("div");
        div.innerHTML = "<p class='TEST'></p>";
        if (div.querySelectorAll && div.querySelectorAll(".TEST").length === 0) {
          return
        }
        Sizzle = function(query, context, extra, seed) {
          context = context || document;
          if (!seed && context.nodeType === 9 && !isXML(context)) {
            try {
              return makeArray(context.querySelectorAll(query), extra)
            } catch (e) {}
          }
          return oldSizzle(query, context, extra, seed)
        };
        for (var prop in oldSizzle) {
          Sizzle[prop] = oldSizzle[prop]
        }
        div = null
      })()
    }(function() {
      var div = document.createElement("div");
      div.innerHTML = "<div class='test e'></div><div class='test'></div>";
      if (!div.getElementsByClassName || div.getElementsByClassName("e").length === 0) {
        return
      }
      div.lastChild.className = "e";
      if (div.getElementsByClassName("e").length === 1) {
        return
      }
      Expr.order.splice(1, 0, "CLASS");
      Expr.find.CLASS = function(match, context, isXML) {
        if (typeof context.getElementsByClassName !== "undefined" && !isXML) {
          return context.getElementsByClassName(match[1])
        }
      };
      div = null
    })();

    function dirNodeCheck(dir, cur, doneName, checkSet, nodeCheck, isXML) {
      for (var i = 0, l = checkSet.length; i < l; i++) {
        var elem = checkSet[i];
        if (elem) {
          elem = elem[dir];
          var match = false;
          while (elem) {
            if (elem.sizcache === doneName) {
              match = checkSet[elem.sizset];
              break
            }
            if (elem.nodeType === 1 && !isXML) {
              elem.sizcache = doneName;
              elem.sizset = i
            }
            if (elem.nodeName.toLowerCase() === cur) {
              match = elem;
              break
            }
            elem = elem[dir]
          }
          checkSet[i] = match
        }
      }
    }
    function dirCheck(dir, cur, doneName, checkSet, nodeCheck, isXML) {
      for (var i = 0, l = checkSet.length; i < l; i++) {
        var elem = checkSet[i];
        if (elem) {
          elem = elem[dir];
          var match = false;
          while (elem) {
            if (elem.sizcache === doneName) {
              match = checkSet[elem.sizset];
              break
            }
            if (elem.nodeType === 1) {
              if (!isXML) {
                elem.sizcache = doneName;
                elem.sizset = i
              }
              if (typeof cur !== "string") {
                if (elem === cur) {
                  match = true;
                  break
                }
              } else {
                if (Sizzle.filter(cur, [elem]).length > 0) {
                  match = elem;
                  break
                }
              }
            }
            elem = elem[dir]
          }
          checkSet[i] = match
        }
      }
    }
    var contains = document.compareDocumentPosition ?
    function(a, b) {
      return a.compareDocumentPosition(b) & 16
    } : function(a, b) {
      return a !== b && (a.contains ? a.contains(b) : true)
    };
    var isXML = function(elem) {
        var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
        return documentElement ? documentElement.nodeName !== "HTML" : false
        };
    var posProcess = function(selector, context) {
        var tmpSet = [],
            later = "",
            match, root = context.nodeType ? [context] : context;
        while ((match = Expr.match.PSEUDO.exec(selector))) {
          later += match[0];
          selector = selector.replace(Expr.match.PSEUDO, "")
        }
        selector = Expr.relative[selector] ? selector + "*" : selector;
        for (var i = 0, l = root.length; i < l; i++) {
          Sizzle(selector, root[i], tmpSet)
        }
        return Sizzle.filter(later, tmpSet)
        };
    return Sizzle
  })();
/*
 * SWFObject v2.1 <http://code.google.com/p/swfobject/>
 * Copyright (c) 2007-2008 Geoff Stearns, Michael Williams, and Bobby van der Sluis
 * This software is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
 *
 * Modified for inclusion in Shadowbox.js
 */
  S.flash = (function() {
    var swfobject = function() {
        var UNDEF = "undefined",
            OBJECT = "object",
            SHOCKWAVE_FLASH = "Shockwave Flash",
            SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash",
            FLASH_MIME_TYPE = "application/x-shockwave-flash",
            EXPRESS_INSTALL_ID = "SWFObjectExprInst",
            win = window,
            doc = document,
            nav = navigator,
            domLoadFnArr = [],
            regObjArr = [],
            objIdArr = [],
            listenersArr = [],
            script, timer = null,
            storedAltContent = null,
            storedAltContentId = null,
            isDomLoaded = false,
            isExpressInstallActive = false;
        var ua = function() {
            var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF,
                playerVersion = [0, 0, 0],
                d = null;
            if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] == OBJECT) {
              d = nav.plugins[SHOCKWAVE_FLASH].description;
              if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) {
                d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
                playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10);
                playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10);
                playerVersion[2] = /r/.test(d) ? parseInt(d.replace(/^.*r(.*)$/, "$1"), 10) : 0
              }
            } else {
              if (typeof win.ActiveXObject != UNDEF) {
                var a = null,
                    fp6Crash = false;
                try {
                  a = new ActiveXObject(SHOCKWAVE_FLASH_AX + ".7")
                } catch (e) {
                  try {
                    a = new ActiveXObject(SHOCKWAVE_FLASH_AX + ".6");
                    playerVersion = [6, 0, 21];
                    a.AllowScriptAccess = "always"
                  } catch (e) {
                    if (playerVersion[0] == 6) {
                      fp6Crash = true
                    }
                  }
                  if (!fp6Crash) {
                    try {
                      a = new ActiveXObject(SHOCKWAVE_FLASH_AX)
                    } catch (e) {}
                  }
                }
                if (!fp6Crash && a) {
                  try {
                    d = a.GetVariable("$version");
                    if (d) {
                      d = d.split(" ")[1].split(",");
                      playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)]
                    }
                  } catch (e) {}
                }
              }
            }
            var u = nav.userAgent.toLowerCase(),
                p = nav.platform.toLowerCase(),
                webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false,
                ie = false,
                windows = p ? /win/.test(p) : /win/.test(u),
                mac = p ? /mac/.test(p) : /mac/.test(u);
/*@cc_on
                        ie = true;
                        @if (@_win32)
                                windows = true;
                        @elif (@_mac)
                                mac = true;
                        @end
                @*/
            return {
              w3cdom: w3cdom,
              pv: playerVersion,
              webkit: webkit,
              ie: ie,
              win: windows,
              mac: mac
            }
            }();
        var onDomLoad = function() {
            if (!ua.w3cdom) {
              return
            }
            addDomLoadEvent(main);
            if (ua.ie && ua.win) {
              try {
                doc.write("<script id=__ie_ondomload defer=true src=//:><\/script>");
                script = getElementById("__ie_ondomload");
                if (script) {
                  addListener(script, "onreadystatechange", checkReadyState)
                }
              } catch (e) {}
            }
            if (ua.webkit && typeof doc.readyState != UNDEF) {
              timer = setInterval(function() {
                if (/loaded|complete/.test(doc.readyState)) {
                  callDomLoadFunctions()
                }
              }, 10)
            }
            if (typeof doc.addEventListener != UNDEF) {
              doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, null)
            }
            addLoadEvent(callDomLoadFunctions)
            }();

        function checkReadyState() {
          if (script.readyState == "complete") {
            script.parentNode.removeChild(script);
            callDomLoadFunctions()
          }
        }
        function callDomLoadFunctions() {
          if (isDomLoaded) {
            return
          }
          if (ua.ie && ua.win) {
            var s = createElement("span");
            try {
              var t = doc.getElementsByTagName("body")[0].appendChild(s);
              t.parentNode.removeChild(t)
            } catch (e) {
              return
            }
          }
          isDomLoaded = true;
          if (timer) {
            clearInterval(timer);
            timer = null
          }
          var dl = domLoadFnArr.length;
          for (var i = 0; i < dl; i++) {
            domLoadFnArr[i]()
          }
        }
        function addDomLoadEvent(fn) {
          if (isDomLoaded) {
            fn()
          } else {
            domLoadFnArr[domLoadFnArr.length] = fn
          }
        }
        function addLoadEvent(fn) {
          if (typeof win.addEventListener != UNDEF) {
            win.addEventListener("load", fn, false)
          } else {
            if (typeof doc.addEventListener != UNDEF) {
              doc.addEventListener("load", fn, false)
            } else {
              if (typeof win.attachEvent != UNDEF) {
                addListener(win, "onload", fn)
              } else {
                if (typeof win.onload == "function") {
                  var fnOld = win.onload;
                  win.onload = function() {
                    fnOld();
                    fn()
                  }
                } else {
                  win.onload = fn
                }
              }
            }
          }
        }
        function main() {
          var rl = regObjArr.length;
          for (var i = 0; i < rl; i++) {
            var id = regObjArr[i].id;
            if (ua.pv[0] > 0) {
              var obj = getElementById(id);
              if (obj) {
                regObjArr[i].width = obj.getAttribute("width") ? obj.getAttribute("width") : "0";
                regObjArr[i].height = obj.getAttribute("height") ? obj.getAttribute("height") : "0";
                if (hasPlayerVersion(regObjArr[i].swfVersion)) {
                  if (ua.webkit && ua.webkit < 312) {
                    fixParams(obj)
                  }
                  setVisibility(id, true)
                } else {
                  if (regObjArr[i].expressInstall && !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac)) {
                    showExpressInstall(regObjArr[i])
                  } else {
                    displayAltContent(obj)
                  }
                }
              }
            } else {
              setVisibility(id, true)
            }
          }
        }
        function fixParams(obj) {
          var nestedObj = obj.getElementsByTagName(OBJECT)[0];
          if (nestedObj) {
            var e = createElement("embed"),
                a = nestedObj.attributes;
            if (a) {
              var al = a.length;
              for (var i = 0; i < al; i++) {
                if (a[i].nodeName == "DATA") {
                  e.setAttribute("src", a[i].nodeValue)
                } else {
                  e.setAttribute(a[i].nodeName, a[i].nodeValue)
                }
              }
            }
            var c = nestedObj.childNodes;
            if (c) {
              var cl = c.length;
              for (var j = 0; j < cl; j++) {
                if (c[j].nodeType == 1 && c[j].nodeName == "PARAM") {
                  e.setAttribute(c[j].getAttribute("name"), c[j].getAttribute("value"))
                }
              }
            }
            obj.parentNode.replaceChild(e, obj)
          }
        }
        function showExpressInstall(regObj) {
          isExpressInstallActive = true;
          var obj = getElementById(regObj.id);
          if (obj) {
            if (regObj.altContentId) {
              var ac = getElementById(regObj.altContentId);
              if (ac) {
                storedAltContent = ac;
                storedAltContentId = regObj.altContentId
              }
            } else {
              storedAltContent = abstractAltContent(obj)
            }
            if (!(/%$/.test(regObj.width)) && parseInt(regObj.width, 10) < 310) {
              regObj.width = "310"
            }
            if (!(/%$/.test(regObj.height)) && parseInt(regObj.height, 10) < 137) {
              regObj.height = "137"
            }
            doc.title = doc.title.slice(0, 47) + " - Flash Player Installation";
            var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn",
                dt = doc.title,
                fv = "MMredirectURL=" + win.location + "&MMplayerType=" + pt + "&MMdoctitle=" + dt,
                replaceId = regObj.id;
            if (ua.ie && ua.win && obj.readyState != 4) {
              var newObj = createElement("div");
              replaceId += "SWFObjectNew";
              newObj.setAttribute("id", replaceId);
              obj.parentNode.insertBefore(newObj, obj);
              obj.style.display = "none";
              var fn = function() {
                  obj.parentNode.removeChild(obj)
                  };
              addListener(win, "onload", fn)
            }
            createSWF({
              data: regObj.expressInstall,
              id: EXPRESS_INSTALL_ID,
              width: regObj.width,
              height: regObj.height
            }, {
              flashvars: fv
            }, replaceId)
          }
        }
        function displayAltContent(obj) {
          if (ua.ie && ua.win && obj.readyState != 4) {
            var el = createElement("div");
            obj.parentNode.insertBefore(el, obj);
            el.parentNode.replaceChild(abstractAltContent(obj), el);
            obj.style.display = "none";
            var fn = function() {
                obj.parentNode.removeChild(obj)
                };
            addListener(win, "onload", fn)
          } else {
            obj.parentNode.replaceChild(abstractAltContent(obj), obj)
          }
        }
        function abstractAltContent(obj) {
          var ac = createElement("div");
          if (ua.win && ua.ie) {
            ac.innerHTML = obj.innerHTML
          } else {
            var nestedObj = obj.getElementsByTagName(OBJECT)[0];
            if (nestedObj) {
              var c = nestedObj.childNodes;
              if (c) {
                var cl = c.length;
                for (var i = 0; i < cl; i++) {
                  if (!(c[i].nodeType == 1 && c[i].nodeName == "PARAM") && !(c[i].nodeType == 8)) {
                    ac.appendChild(c[i].cloneNode(true))
                  }
                }
              }
            }
          }
          return ac
        }
        function createSWF(attObj, parObj, id) {
          var r, el = getElementById(id);
          if (el) {
            if (typeof attObj.id == UNDEF) {
              attObj.id = id
            }
            if (ua.ie && ua.win) {
              var att = "";
              for (var i in attObj) {
                if (attObj[i] != Object.prototype[i]) {
                  if (i.toLowerCase() == "data") {
                    parObj.movie = attObj[i]
                  } else {
                    if (i.toLowerCase() == "styleclass") {
                      att += ' class="' + attObj[i] + '"'
                    } else {
                      if (i.toLowerCase() != "classid") {
                        att += " " + i + '="' + attObj[i] + '"'
                      }
                    }
                  }
                }
              }
              var par = "";
              for (var j in parObj) {
                if (parObj[j] != Object.prototype[j]) {
                  par += '<param name="' + j + '" value="' + parObj[j] + '" />'
                }
              }
              el.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + att + ">" + par + "</object>";
              objIdArr[objIdArr.length] = attObj.id;
              r = getElementById(attObj.id)
            } else {
              if (ua.webkit && ua.webkit < 312) {
                var e = createElement("embed");
                e.setAttribute("type", FLASH_MIME_TYPE);
                for (var k in attObj) {
                  if (attObj[k] != Object.prototype[k]) {
                    if (k.toLowerCase() == "data") {
                      e.setAttribute("src", attObj[k])
                    } else {
                      if (k.toLowerCase() == "styleclass") {
                        e.setAttribute("class", attObj[k])
                      } else {
                        if (k.toLowerCase() != "classid") {
                          e.setAttribute(k, attObj[k])
                        }
                      }
                    }
                  }
                }
                for (var l in parObj) {
                  if (parObj[l] != Object.prototype[l]) {
                    if (l.toLowerCase() != "movie") {
                      e.setAttribute(l, parObj[l])
                    }
                  }
                }
                el.parentNode.replaceChild(e, el);
                r = e
              } else {
                var o = createElement(OBJECT);
                o.setAttribute("type", FLASH_MIME_TYPE);
                for (var m in attObj) {
                  if (attObj[m] != Object.prototype[m]) {
                    if (m.toLowerCase() == "styleclass") {
                      o.setAttribute("class", attObj[m])
                    } else {
                      if (m.toLowerCase() != "classid") {
                        o.setAttribute(m, attObj[m])
                      }
                    }
                  }
                }
                for (var n in parObj) {
                  if (parObj[n] != Object.prototype[n] && n.toLowerCase() != "movie") {
                    createObjParam(o, n, parObj[n])
                  }
                }
                el.parentNode.replaceChild(o, el);
                r = o
              }
            }
          }
          return r
        }
        function createObjParam(el, pName, pValue) {
          var p = createElement("param");
          p.setAttribute("name", pName);
          p.setAttribute("value", pValue);
          el.appendChild(p)
        }
        function removeSWF(id) {
          var obj = getElementById(id);
          if (obj && (obj.nodeName == "OBJECT" || obj.nodeName == "EMBED")) {
            if (ua.ie && ua.win) {
              if (obj.readyState == 4) {
                removeObjectInIE(id)
              } else {
                win.attachEvent("onload", function() {
                  removeObjectInIE(id)
                })
              }
            } else {
              obj.parentNode.removeChild(obj)
            }
          }
        }
        function removeObjectInIE(id) {
          var obj = getElementById(id);
          if (obj) {
            for (var i in obj) {
              if (typeof obj[i] == "function") {
                obj[i] = null
              }
            }
            obj.parentNode.removeChild(obj)
          }
        }
        function getElementById(id) {
          var el = null;
          try {
            el = doc.getElementById(id)
          } catch (e) {}
          return el
        }
        function createElement(el) {
          return doc.createElement(el)
        }
        function addListener(target, eventType, fn) {
          target.attachEvent(eventType, fn);
          listenersArr[listenersArr.length] = [target, eventType, fn]
        }
        function hasPlayerVersion(rv) {
          var pv = ua.pv,
              v = rv.split(".");
          v[0] = parseInt(v[0], 10);
          v[1] = parseInt(v[1], 10) || 0;
          v[2] = parseInt(v[2], 10) || 0;
          return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false
        }
        function createCSS(sel, decl) {
          if (ua.ie && ua.mac) {
            return
          }
          var h = doc.getElementsByTagName("head")[0],
              s = createElement("style");
          s.setAttribute("type", "text/css");
          s.setAttribute("media", "screen");
          if (!(ua.ie && ua.win) && typeof doc.createTextNode != UNDEF) {
            s.appendChild(doc.createTextNode(sel + " {" + decl + "}"))
          }
          h.appendChild(s);
          if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF && doc.styleSheets.length > 0) {
            var ls = doc.styleSheets[doc.styleSheets.length - 1];
            if (typeof ls.addRule == OBJECT) {
              ls.addRule(sel, decl)
            }
          }
        }
        function setVisibility(id, isVisible) {
          var v = isVisible ? "visible" : "hidden";
          if (isDomLoaded && getElementById(id)) {
            getElementById(id).style.visibility = v
          } else {
            createCSS("#" + id, "visibility:" + v)
          }
        }
        function urlEncodeIfNecessary(s) {
          var regex = /[\\\"<>\.;]/;
          var hasBadChars = regex.exec(s) != null;
          return hasBadChars ? encodeURIComponent(s) : s
        }
        var cleanup = function() {
            if (ua.ie && ua.win) {
              window.attachEvent("onunload", function() {
                var ll = listenersArr.length;
                for (var i = 0; i < ll; i++) {
                  listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2])
                }
                var il = objIdArr.length;
                for (var j = 0; j < il; j++) {
                  removeSWF(objIdArr[j])
                }
                for (var k in ua) {
                  ua[k] = null
                }
                ua = null;
                for (var l in swfobject) {
                  swfobject[l] = null
                }
                swfobject = null
              })
            }
            }();
        return {
          registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr) {
            if (!ua.w3cdom || !objectIdStr || !swfVersionStr) {
              return
            }
            var regObj = {};
            regObj.id = objectIdStr;
            regObj.swfVersion = swfVersionStr;
            regObj.expressInstall = xiSwfUrlStr ? xiSwfUrlStr : false;
            regObjArr[regObjArr.length] = regObj;
            setVisibility(objectIdStr, false)
          },
          getObjectById: function(objectIdStr) {
            var r = null;
            if (ua.w3cdom) {
              var o = getElementById(objectIdStr);
              if (o) {
                var n = o.getElementsByTagName(OBJECT)[0];
                if (!n || (n && typeof o.SetVariable != UNDEF)) {
                  r = o
                } else {
                  if (typeof n.SetVariable != UNDEF) {
                    r = n
                  }
                }
              }
            }
            return r
          },
          embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj) {
            if (!ua.w3cdom || !swfUrlStr || !replaceElemIdStr || !widthStr || !heightStr || !swfVersionStr) {
              return
            }
            widthStr += "";
            heightStr += "";
            if (hasPlayerVersion(swfVersionStr)) {
              setVisibility(replaceElemIdStr, false);
              var att = {};
              if (attObj && typeof attObj === OBJECT) {
                for (var i in attObj) {
                  if (attObj[i] != Object.prototype[i]) {
                    att[i] = attObj[i]
                  }
                }
              }
              att.data = swfUrlStr;
              att.width = widthStr;
              att.height = heightStr;
              var par = {};
              if (parObj && typeof parObj === OBJECT) {
                for (var j in parObj) {
                  if (parObj[j] != Object.prototype[j]) {
                    par[j] = parObj[j]
                  }
                }
              }
              if (flashvarsObj && typeof flashvarsObj === OBJECT) {
                for (var k in flashvarsObj) {
                  if (flashvarsObj[k] != Object.prototype[k]) {
                    if (typeof par.flashvars != UNDEF) {
                      par.flashvars += "&" + k + "=" + flashvarsObj[k]
                    } else {
                      par.flashvars = k + "=" + flashvarsObj[k]
                    }
                  }
                }
              }
              addDomLoadEvent(function() {
                createSWF(att, par, replaceElemIdStr);
                if (att.id == replaceElemIdStr) {
                  setVisibility(replaceElemIdStr, true)
                }
              })
            } else {
              if (xiSwfUrlStr && !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac)) {
                isExpressInstallActive = true;
                setVisibility(replaceElemIdStr, false);
                addDomLoadEvent(function() {
                  var regObj = {};
                  regObj.id = regObj.altContentId = replaceElemIdStr;
                  regObj.width = widthStr;
                  regObj.height = heightStr;
                  regObj.expressInstall = xiSwfUrlStr;
                  showExpressInstall(regObj)
                })
              }
            }
          },
          getFlashPlayerVersion: function() {
            return {
              major: ua.pv[0],
              minor: ua.pv[1],
              release: ua.pv[2]
            }
          },
          hasFlashPlayerVersion: hasPlayerVersion,
          createSWF: function(attObj, parObj, replaceElemIdStr) {
            if (ua.w3cdom) {
              return createSWF(attObj, parObj, replaceElemIdStr)
            } else {
              return undefined
            }
          },
          removeSWF: function(objElemIdStr) {
            if (ua.w3cdom) {
              removeSWF(objElemIdStr)
            }
          },
          createCSS: function(sel, decl) {
            if (ua.w3cdom) {
              createCSS(sel, decl)
            }
          },
          addDomLoadEvent: addDomLoadEvent,
          addLoadEvent: addLoadEvent,
          getQueryParamValue: function(param) {
            var q = doc.location.search || doc.location.hash;
            if (param == null) {
              return urlEncodeIfNecessary(q)
            }
            if (q) {
              var pairs = q.substring(1).split("&");
              for (var i = 0; i < pairs.length; i++) {
                if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
                  return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1)))
                }
              }
            }
            return ""
          },
          expressInstallCallback: function() {
            if (isExpressInstallActive && storedAltContent) {
              var obj = getElementById(EXPRESS_INSTALL_ID);
              if (obj) {
                obj.parentNode.replaceChild(storedAltContent, obj);
                if (storedAltContentId) {
                  setVisibility(storedAltContentId, true);
                  if (ua.ie && ua.win) {
                    storedAltContent.style.display = "block"
                  }
                }
                storedAltContent = null;
                storedAltContentId = null;
                isExpressInstallActive = false
              }
            }
          }
        }
        }();
    return swfobject
  })();
  S.lang = {
    code: "en",
    of: "of",
    loading: "loading",
    cancel: "Cancel",
    next: "Next",
    previous: "Previous",
    play: "Play",
    pause: "Pause",
    close: "Close",
    errors: {
      single: 'You must install the <a href="{0}">{1}</a> browser plugin to view this content.',
      shared: 'You must install both the <a href="{0}">{1}</a> and <a href="{2}">{3}</a> browser plugins to view this content.',
      either: 'You must install either the <a href="{0}">{1}</a> or the <a href="{2}">{3}</a> browser plugin to view this content.'
    }
  };
  var pre, proxyId = "sb-drag-proxy",
      dragData, dragProxy, dragTarget;

  function resetDrag() {
    dragData = {
      x: 0,
      y: 0,
      startX: null,
      startY: null
    }
  }
  function updateProxy() {
    var dims = S.dimensions;
    apply(dragProxy.style, {
      height: dims.innerHeight + "px",
      width: dims.innerWidth + "px"
    })
  }
  function enableDrag() {
    resetDrag();
    var style = ["position:absolute", "cursor:" + (S.isGecko ? "-moz-grab" : "move"), "background-color:" + (S.isIE ? "#fff;filter:alpha(opacity=0)" : "transparent")].join(";");
    S.appendHTML(S.skin.body, '<div id="' + proxyId + '" style="' + style + '"></div>');
    dragProxy = get(proxyId);
    updateProxy();
    addEvent(dragProxy, "mousedown", startDrag)
  }
  function disableDrag() {
    if (dragProxy) {
      removeEvent(dragProxy, "mousedown", startDrag);
      remove(dragProxy);
      dragProxy = null
    }
    dragTarget = null
  }
  function startDrag(e) {
    preventDefault(e);
    var xy = getPageXY(e);
    dragData.startX = xy[0];
    dragData.startY = xy[1];
    dragTarget = get(S.player.id);
    addEvent(document, "mousemove", positionDrag);
    addEvent(document, "mouseup", endDrag);
    if (S.isGecko) {
      dragProxy.style.cursor = "-moz-grabbing"
    }
  }
  function positionDrag(e) {
    var player = S.player,
        dims = S.dimensions,
        xy = getPageXY(e);
    var moveX = xy[0] - dragData.startX;
    dragData.startX += moveX;
    dragData.x = Math.max(Math.min(0, dragData.x + moveX), dims.innerWidth - player.width);
    var moveY = xy[1] - dragData.startY;
    dragData.startY += moveY;
    dragData.y = Math.max(Math.min(0, dragData.y + moveY), dims.innerHeight - player.height);
    apply(dragTarget.style, {
      left: dragData.x + "px",
      top: dragData.y + "px"
    })
  }
  function endDrag() {
    removeEvent(document, "mousemove", positionDrag);
    removeEvent(document, "mouseup", endDrag);
    if (S.isGecko) {
      dragProxy.style.cursor = "-moz-grab"
    }
  }
  S.img = function(obj, id) {
    this.obj = obj;
    this.id = id;
    this.ready = false;
    var self = this;
    pre = new Image();
    pre.onload = function() {
      self.height = obj.height ? parseInt(obj.height, 10) : pre.height;
      self.width = obj.width ? parseInt(obj.width, 10) : pre.width;
      self.ready = true;
      pre.onload = null;
      pre = null
    };
    pre.src = obj.content
  };
  S.img.ext = ["bmp", "gif", "jpg", "jpeg", "png"];
  S.img.prototype = {
    append: function(body, dims) {
      var img = document.createElement("img");
      img.id = this.id;
      img.src = this.obj.content;
      img.style.position = "absolute";
      var height, width;
      if (dims.oversized && S.options.handleOversize == "resize") {
        height = dims.innerHeight;
        width = dims.innerWidth
      } else {
        height = this.height;
        width = this.width
      }
      img.setAttribute("height", height);
      img.setAttribute("width", width);
      body.appendChild(img)
    },
    remove: function() {
      var el = get(this.id);
      if (el) {
        remove(el)
      }
      disableDrag();
      if (pre) {
        pre.onload = null;
        pre = null
      }
    },
    onLoad: function() {
      var dims = S.dimensions;
      if (dims.oversized && S.options.handleOversize == "drag") {
        enableDrag()
      }
    },
    onWindowResize: function() {
      var dims = S.dimensions;
      switch (S.options.handleOversize) {
      case "resize":
        var el = get(this.id);
        el.height = dims.innerHeight;
        el.width = dims.innerWidth;
        break;
      case "drag":
        if (dragTarget) {
          var top = parseInt(S.getStyle(dragTarget, "top")),
              left = parseInt(S.getStyle(dragTarget, "left"));
          if (top + this.height < dims.innerHeight) {
            dragTarget.style.top = dims.innerHeight - this.height + "px"
          }
          if (left + this.width < dims.innerWidth) {
            dragTarget.style.left = dims.innerWidth - this.width + "px"
          }
          updateProxy()
        }
        break
      }
    }
  };
  S.iframe = function(obj, id) {
    this.obj = obj;
    this.id = id;
    var overlay = get("sb-overlay");
    this.height = obj.height ? parseInt(obj.height, 10) : overlay.offsetHeight;
    this.width = obj.width ? parseInt(obj.width, 10) : overlay.offsetWidth
  };
  S.iframe.prototype = {
    append: function(body, dims) {
      var html = '<iframe id="' + this.id + '" name="' + this.id + '" height="100%" width="100%" frameborder="0" marginwidth="0" marginheight="0" style="visibility:hidden" onload="this.style.visibility=\'visible\'" scrolling="auto"';
      if (S.isIE) {
        html += ' allowtransparency="true"';
        if (S.isIE6) {
          html += " src=\"javascript:false;document.write('');\""
        }
      }
      html += "></iframe>";
      body.innerHTML = html
    },
    remove: function() {
      var el = get(this.id);
      if (el) {
        remove(el);
        if (S.isGecko) {
          delete window.frames[this.id]
        }
      }
    },
    onLoad: function() {
      var win = S.isIE ? get(this.id).contentWindow : window.frames[this.id];
      win.location.href = this.obj.content
    }
  };
  S.html = function(obj, id) {
    this.obj = obj;
    this.id = id;
    this.height = obj.height ? parseInt(obj.height, 10) : 300;
    this.width = obj.width ? parseInt(obj.width, 10) : 500
  };
  S.html.prototype = {
    append: function(body, dims) {
      var div = document.createElement("div");
      div.id = this.id;
      div.className = "html";
      div.innerHTML = this.obj.content;
      body.appendChild(div)
    },
    remove: function() {
      var el = get(this.id);
      if (el) {
        remove(el)
      }
    }
  };
  S.swf = function(obj, id) {
    this.obj = obj;
    this.id = id;
    this.height = obj.height ? parseInt(obj.height, 10) : 300;
    this.width = obj.width ? parseInt(obj.width, 10) : 300
  };
  S.swf.ext = ["swf"];
  S.swf.prototype = {
    append: function(body, dims) {
      var tmp = document.createElement("div");
      tmp.id = this.id;
      body.appendChild(tmp);
      var height = dims.innerHeight,
          width = dims.innerWidth,
          swf = this.obj.content,
          version = S.options.flashVersion,
          express = S.path + "expressInstall.swf",
          flashvars = S.options.flashVars,
          params = S.options.flashParams;
      S.flash.embedSWF(swf, this.id, width, height, version, express, flashvars, params)
    },
    remove: function() {
      S.flash.expressInstallCallback();
      S.flash.removeSWF(this.id)
    },
    onWindowResize: function() {
      var dims = S.dimensions,
          el = get(this.id);
      el.height = dims.innerHeight;
      el.width = dims.innerWidth
    }
  };
  var jwControllerHeight = 20;
  S.flv = function(obj, id) {
    this.obj = obj;
    this.id = id;
    this.height = obj.height ? parseInt(obj.height, 10) : 300;
    if (S.options.showMovieControls) {
      this.height += jwControllerHeight
    }
    this.width = obj.width ? parseInt(obj.width, 10) : 300
  };
  S.flv.ext = ["flv", "m4v"];
  S.flv.prototype = {
    append: function(body, dims) {
      var tmp = document.createElement("div");
      tmp.id = this.id;
      body.appendChild(tmp);
      var height = dims.innerHeight,
          width = dims.innerWidth,
          swf = S.path + "player.swf",
          version = S.options.flashVersion,
          express = S.path + "expressInstall.swf",
          flashvars = apply({
          file: this.obj.content,
          height: height,
          width: width,
          autostart: (S.options.autoplayMovies ? "true" : "false"),
          controlbar: (S.options.showMovieControls ? "bottom" : "none"),
          backcolor: "0x000000",
          frontcolor: "0xCCCCCC",
          lightcolor: "0x557722"
        }, S.options.flashVars),
          params = S.options.flashParams;
      S.flash.embedSWF(swf, this.id, width, height, version, express, flashvars, params)
    },
    remove: function() {
      S.flash.expressInstallCallback();
      S.flash.removeSWF(this.id)
    },
    onWindowResize: function() {
      var dims = S.dimensions,
          el = get(this.id);
      el.height = dims.innerHeight;
      el.width = dims.innerWidth
    }
  };
  var qtControllerHeight = 16;
  S.qt = function(obj, id) {
    this.obj = obj;
    this.id = id;
    this.height = obj.height ? parseInt(obj.height, 10) : 300;
    if (S.options.showMovieControls) {
      this.height += qtControllerHeight
    }
    this.width = obj.width ? parseInt(obj.width, 10) : 300
  };
  S.qt.ext = ["dv", "mov", "moov", "movie", "mp4", "avi", "mpg", "mpeg"];
  S.qt.prototype = {
    append: function(body, dims) {
      var opt = S.options,
          autoplay = String(opt.autoplayMovies),
          controls = String(opt.showMovieControls);
      var html = "<object",
          movie = {
          id: this.id,
          name: this.id,
          height: this.height,
          width: this.width,
          kioskmode: "true"
          };
      if (S.isIE) {
        movie.classid = "clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B";
        movie.codebase = "http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0"
      } else {
        movie.type = "video/quicktime";
        movie.data = this.obj.content
      }
      for (var m in movie) {
        html += " " + m + '="' + movie[m] + '"'
      }
      html += ">";
      var params = {
        src: this.obj.content,
        scale: "aspect",
        controller: controls,
        autoplay: autoplay
      };
      for (var p in params) {
        html += '<param name="' + p + '" value="' + params[p] + '">'
      }
      html += "</object>";
      body.innerHTML = html
    },
    remove: function() {
      try {
        document[this.id].Stop()
      } catch (e) {}
      var el = get(this.id);
      if (el) {
        remove(el)
      }
    }
  };
  var wmpControllerHeight = (S.isIE ? 70 : 45);
  S.wmp = function(obj, id) {
    this.obj = obj;
    this.id = id;
    this.height = obj.height ? parseInt(obj.height, 10) : 300;
    if (S.options.showMovieControls) {
      this.height += wmpControllerHeight
    }
    this.width = obj.width ? parseInt(obj.width, 10) : 300
  };
  S.wmp.ext = ["asf", "avi", "mpg", "mpeg", "wm", "wmv"];
  S.wmp.prototype = {
    append: function(body, dims) {
      var opt = S.options,
          autoplay = opt.autoplayMovies ? 1 : 0;
      var movie = '<object id="' + this.id + '" name="' + this.id + '" height="' + this.height + '" width="' + this.width + '"',
          params = {
          autostart: opt.autoplayMovies ? 1 : 0
          };
      if (S.isIE) {
        movie += ' classid="clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6"';
        params.url = this.obj.content;
        params.uimode = opt.showMovieControls ? "full" : "none"
      } else {
        movie += ' type="video/x-ms-wmv"';
        movie += ' data="' + this.obj.content + '"';
        params.showcontrols = opt.showMovieControls ? 1 : 0
      }
      movie += ">";
      for (var p in params) {
        movie += '<param name="' + p + '" value="' + params[p] + '">'
      }
      movie += "</object>";
      body.innerHTML = movie
    },
    remove: function() {
      if (S.isIE) {
        try {
          window[this.id].controls.stop();
          window[this.id].URL = "movie" + now() + ".wmv";
          window[this.id] = function() {}
        } catch (e) {}
      }
      var el = get(this.id);
      if (el) {
        setTimeout(function() {
          remove(el)
        }, 10)
      }
    }
  };
  var overlayOn = false,
      visibilityCache = [],
      pngIds = ["sb-nav-close", "sb-nav-next", "sb-nav-play", "sb-nav-pause", "sb-nav-previous"],
      container, overlay, wrapper, doWindowResize = true;

  function animate(el, property, to, duration, callback) {
    var isOpacity = (property == "opacity"),
        anim = isOpacity ? S.setOpacity : function(el, value) {
        el.style[property] = "" + value + "px"
        };
    if (duration == 0 || (!isOpacity && !S.options.animate) || (isOpacity && !S.options.animateFade)) {
      anim(el, to);
      if (callback) {
        callback()
      }
      return
    }
    var from = parseFloat(S.getStyle(el, property)) || 0;
    var delta = to - from;
    if (delta == 0) {
      if (callback) {
        callback()
      }
      return
    }
    duration *= 1000;
    var begin = now(),
        ease = S.ease,
        end = begin + duration,
        time;
    var interval = setInterval(function() {
      time = now();
      if (time >= end) {
        clearInterval(interval);
        interval = null;
        anim(el, to);
        if (callback) {
          callback()
        }
      } else {
        anim(el, from + ease((time - begin) / duration) * delta)
      }
    }, 10)
  }
  function setSize() {
    container.style.height = S.getWindowSize("Height") + "px";
    container.style.width = S.getWindowSize("Width") + "px"
  }
  function setPosition() {
    container.style.top = document.documentElement.scrollTop + "px";
    container.style.left = document.documentElement.scrollLeft + "px"
  }
  function toggleTroubleElements(on) {
    if (on) {
      each(visibilityCache, function(i, el) {
        el[0].style.visibility = el[1] || ""
      })
    } else {
      visibilityCache = [];
      each(S.options.troubleElements, function(i, tag) {
        each(document.getElementsByTagName(tag), function(j, el) {
          visibilityCache.push([el, el.style.visibility]);
          el.style.visibility = "hidden"
        })
      })
    }
  }
  function toggleNav(id, on) {
    var el = get("sb-nav-" + id);
    if (el) {
      el.style.display = on ? "" : "none"
    }
  }
  function toggleLoading(on, callback) {
    var loading = get("sb-loading"),
        playerName = S.getCurrent().player,
        anim = (playerName == "img" || playerName == "html");
    if (on) {
      S.setOpacity(loading, 0);
      loading.style.display = "block";
      var wrapped = function() {
          S.clearOpacity(loading);
          if (callback) {
            callback()
          }
          };
      if (anim) {
        animate(loading, "opacity", 1, S.options.fadeDuration, wrapped)
      } else {
        wrapped()
      }
    } else {
      var wrapped = function() {
          loading.style.display = "none";
          S.clearOpacity(loading);
          if (callback) {
            callback()
          }
          };
      if (anim) {
        animate(loading, "opacity", 0, S.options.fadeDuration, wrapped)
      } else {
        wrapped()
      }
    }
  }
  function buildBars(callback) {
    var obj = S.getCurrent();
    get("sb-title-inner").innerHTML = obj.title || "";
    var close, next, play, pause, previous;
    if (S.options.displayNav) {
      close = true;
      var len = S.gallery.length;
      if (len > 1) {
        if (S.options.continuous) {
          next = previous = true
        } else {
          next = (len - 1) > S.current;
          previous = S.current > 0
        }
      }
      if (S.options.slideshowDelay > 0 && S.hasNext()) {
        pause = !S.isPaused();
        play = !pause
      }
    } else {
      close = next = play = pause = previous = false
    }
    toggleNav("close", close);
    toggleNav("next", next);
    toggleNav("play", play);
    toggleNav("pause", pause);
    toggleNav("previous", previous);
    var counter = "";
    if (S.options.displayCounter && S.gallery.length > 1) {
      var len = S.gallery.length;
      if (S.options.counterType == "skip") {
        var i = 0,
            end = len,
            limit = parseInt(S.options.counterLimit) || 0;
        if (limit < len && limit > 2) {
          var h = Math.floor(limit / 2);
          i = S.current - h;
          if (i < 0) {
            i += len
          }
          end = S.current + (limit - h);
          if (end > len) {
            end -= len
          }
        }
        while (i != end) {
          if (i == len) {
            i = 0
          }
          counter += '<a onclick="Shadowbox.change(' + i + ');"';
          if (i == S.current) {
            counter += ' class="sb-counter-current"'
          }
          counter += ">" + (++i) + "</a>"
        }
      } else {
        counter = [S.current + 1, S.lang.of, len].join(" ")
      }
    }
    get("sb-counter").innerHTML = counter;
    callback()
  }
  function showBars(callback) {
    var titleInner = get("sb-title-inner"),
        infoInner = get("sb-info-inner"),
        duration = 0.35;
    titleInner.style.visibility = infoInner.style.visibility = "";
    if (titleInner.innerHTML != "") {
      animate(titleInner, "marginTop", 0, duration)
    }
    animate(infoInner, "marginTop", 0, duration, callback)
  }
  function hideBars(anim, callback) {
    var title = get("sb-title"),
        info = get("sb-info"),
        titleHeight = title.offsetHeight,
        infoHeight = info.offsetHeight,
        titleInner = get("sb-title-inner"),
        infoInner = get("sb-info-inner"),
        duration = (anim ? 0.35 : 0);
    animate(titleInner, "marginTop", titleHeight, duration);
    animate(infoInner, "marginTop", infoHeight * -1, duration, function() {
      titleInner.style.visibility = infoInner.style.visibility = "hidden";
      callback()
    })
  }
  function adjustHeight(height, top, anim, callback) {
    var wrapperInner = get("sb-wrapper-inner"),
        duration = (anim ? S.options.resizeDuration : 0);
    animate(wrapper, "top", top, duration);
    animate(wrapperInner, "height", height, duration, callback)
  }
  function adjustWidth(width, left, anim, callback) {
    var duration = (anim ? S.options.resizeDuration : 0);
    animate(wrapper, "left", left, duration);
    animate(wrapper, "width", width, duration, callback)
  }
  function setDimensions(height, width) {
    var bodyInner = get("sb-body-inner"),
        height = parseInt(height),
        width = parseInt(width),
        topBottom = wrapper.offsetHeight - bodyInner.offsetHeight,
        leftRight = wrapper.offsetWidth - bodyInner.offsetWidth,
        maxHeight = overlay.offsetHeight,
        maxWidth = overlay.offsetWidth,
        padding = parseInt(S.options.viewportPadding) || 20,
        preserveAspect = (S.player && S.options.handleOversize != "drag");
    return S.setDimensions(height, width, maxHeight, maxWidth, topBottom, leftRight, padding, preserveAspect)
  }
  var K = {};
  K.markup = '<div id="sb-container"><div id="sb-overlay"></div><div id="sb-wrapper"><div id="sb-title"><div id="sb-title-inner"></div></div><div id="sb-wrapper-inner"><div id="sb-body"><div id="sb-body-inner"></div><div id="sb-loading"><div id="sb-loading-inner"><span>{loading}</span></div></div></div></div><div id="sb-info"><div id="sb-info-inner"><div id="sb-counter"></div><div id="sb-nav"><a id="sb-nav-close" title="{close}" onclick="Shadowbox.close()"></a><a id="sb-nav-next" title="{next}" onclick="Shadowbox.next()"></a><a id="sb-nav-play" title="{play}" onclick="Shadowbox.play()"></a><a id="sb-nav-pause" title="{pause}" onclick="Shadowbox.pause()"></a><a id="sb-nav-previous" title="{previous}" onclick="Shadowbox.previous()"></a></div></div></div></div></div>';
  K.options = {
    animSequence: "sync",
    counterLimit: 10,
    counterType: "default",
    displayCounter: true,
    displayNav: true,
    fadeDuration: 0.35,
    initialHeight: 160,
    initialWidth: 320,
    modal: false,
    overlayColor: "#000",
    overlayOpacity: 0.5,
    resizeDuration: 0.35,
    showOverlay: true,
    troubleElements: ["select", "object", "embed", "canvas"]
  };
  K.init = function() {
    S.appendHTML(document.body, sprintf(K.markup, S.lang));
    K.body = get("sb-body-inner");
    container = get("sb-container");
    overlay = get("sb-overlay");
    wrapper = get("sb-wrapper");
    if (!supportsFixed) {
      container.style.position = "absolute"
    }
    if (!supportsOpacity) {
      var el, m, re = /url\("(.*\.png)"\)/;
      each(pngIds, function(i, id) {
        el = get(id);
        if (el) {
          m = S.getStyle(el, "backgroundImage").match(re);
          if (m) {
            el.style.backgroundImage = "none";
            el.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,src=" + m[1] + ",sizingMethod=scale);"
          }
        }
      })
    }
    var timer;
    addEvent(window, "resize", function() {
      if (timer) {
        clearTimeout(timer);
        timer = null
      }
      if (open) {
        timer = setTimeout(K.onWindowResize, 10)
      }
    })
  };
  K.onOpen = function(obj, callback) {
    doWindowResize = false;
    container.style.display = "block";
    setSize();
    var dims = setDimensions(S.options.initialHeight, S.options.initialWidth);
    adjustHeight(dims.innerHeight, dims.top);
    adjustWidth(dims.width, dims.left);
    if (S.options.showOverlay) {
      overlay.style.backgroundColor = S.options.overlayColor;
      S.setOpacity(overlay, 0);
      if (!S.options.modal) {
        addEvent(overlay, "click", S.close)
      }
      overlayOn = true
    }
    if (!supportsFixed) {
      setPosition();
      addEvent(window, "scroll", setPosition)
    }
    toggleTroubleElements();
    container.style.visibility = "visible";
    if (overlayOn) {
      animate(overlay, "opacity", S.options.overlayOpacity, S.options.fadeDuration, callback)
    } else {
      callback()
    }
  };
  K.onLoad = function(changing, callback) {
    toggleLoading(true);
    while (K.body.firstChild) {
      remove(K.body.firstChild)
    }
    hideBars(changing, function() {
      if (!open) {
        return
      }
      if (!changing) {
        wrapper.style.visibility = "visible"
      }
      buildBars(callback)
    })
  };
  K.onReady = function(callback) {
    if (!open) {
      return
    }
    var player = S.player,
        dims = setDimensions(player.height, player.width);
    var wrapped = function() {
        showBars(callback)
        };
    switch (S.options.animSequence) {
    case "hw":
      adjustHeight(dims.innerHeight, dims.top, true, function() {
        adjustWidth(dims.width, dims.left, true, wrapped)
      });
      break;
    case "wh":
      adjustWidth(dims.width, dims.left, true, function() {
        adjustHeight(dims.innerHeight, dims.top, true, wrapped)
      });
      break;
    default:
      adjustWidth(dims.width, dims.left, true);
      adjustHeight(dims.innerHeight, dims.top, true, wrapped)
    }
  };
  K.onShow = function(callback) {
    toggleLoading(false, callback);
    doWindowResize = true
  };
  K.onClose = function() {
    if (!supportsFixed) {
      removeEvent(window, "scroll", setPosition)
    }
    removeEvent(overlay, "click", S.close);
    wrapper.style.visibility = "hidden";
    var callback = function() {
        container.style.visibility = "hidden";
        container.style.display = "none";
        toggleTroubleElements(true)
        };
    if (overlayOn) {
      animate(overlay, "opacity", 0, S.options.fadeDuration, callback)
    } else {
      callback()
    }
  };
  K.onPlay = function() {
    toggleNav("play", false);
    toggleNav("pause", true)
  };
  K.onPause = function() {
    toggleNav("pause", false);
    toggleNav("play", true)
  };
  K.onWindowResize = function() {
    if (!doWindowResize) {
      return
    }
    setSize();
    var player = S.player,
        dims = setDimensions(player.height, player.width);
    adjustWidth(dims.width, dims.left);
    adjustHeight(dims.innerHeight, dims.top);
    if (player.onWindowResize) {
      player.onWindowResize()
    }
  };
  S.skin = K;
  window.Shadowbox = S
})(window);
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.