/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */
/*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */

window.matchMedia = window.matchMedia || (function( doc, undefined ) {

  "use strict";

  var bool,
      docElem = doc.documentElement,
      refNode = docElem.firstElementChild || docElem.firstChild,
      // fakeBody required for <FF4 when executed in <head>
      fakeBody = doc.createElement( "body" ),
      div = doc.createElement( "div" );

  div.id = "mq-test-1";
  div.style.cssText = "position:absolute;top:-100em";
  fakeBody.style.background = "none";
  fakeBody.appendChild(div);

  return function(q){

    div.innerHTML = "&shy;<style media=\"" + q + "\"> #mq-test-1 { width: 42px; }</style>";

    docElem.insertBefore( fakeBody, refNode );
    bool = div.offsetWidth === 42;
    docElem.removeChild( fakeBody );

    return {
      matches: bool,
      media: q
    };

  };

}( document ));





/*! Respond.js v1.1.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs  */
(function( win ){

  "use strict";

  //exposed namespace
  var respond = {};
  win.respond = respond;
  
  //define update even in native-mq-supporting browsers, to avoid errors
  respond.update = function(){};
  
  //expose media query support flag for external use
  respond.mediaQueriesSupported = win.matchMedia && win.matchMedia( "only all" ).matches;
  
  //if media queries are supported, exit here
  if( respond.mediaQueriesSupported ){
    return;
  }
  
  //define vars
  var doc = win.document,
    docElem = doc.documentElement,
    mediastyles = [],
    rules = [],
    appendedEls = [],
    parsedSheets = {},
    resizeThrottle = 30,
    head = doc.getElementsByTagName( "head" )[0] || docElem,
    base = doc.getElementsByTagName( "base" )[0],
    links = head.getElementsByTagName( "link" ),
    requestQueue = [],
    
    //loop stylesheets, send text content to translate
    ripCSS = function(){

      for( var i = 0; i < links.length; i++ ){
        var sheet = links[ i ],
        href = sheet.href,
        media = sheet.media,
        isCSS = sheet.rel && sheet.rel.toLowerCase() === "stylesheet";

        //only links plz and prevent re-parsing
        if( !!href && isCSS && !parsedSheets[ href ] ){
          // selectivizr exposes css through the rawCssText expando
          if (sheet.styleSheet && sheet.styleSheet.rawCssText) {
            translate( sheet.styleSheet.rawCssText, href, media );
            parsedSheets[ href ] = true;
          } else {
            if( (!/^([a-zA-Z:]*\/\/)/.test( href ) && !base) ||
              href.replace( RegExp.$1, "" ).split( "/" )[0] === win.location.host ){
              requestQueue.push( {
                href: href,
                media: media
              } );
            }
          }
        }
      }
      makeRequests();
    },
    
    //recurse through request queue, get css text
    makeRequests  = function(){
      if( requestQueue.length ){
        var thisRequest = requestQueue.shift();
        
        ajax( thisRequest.href, function( styles ){
          translate( styles, thisRequest.href, thisRequest.media );
          parsedSheets[ thisRequest.href ] = true;

          // by wrapping recursive function call in setTimeout 
          // we prevent "Stack overflow" error in IE7
          win.setTimeout(function(){ makeRequests(); },0);
        } );
      }
    },
    
    //find media blocks in css text, convert to style blocks
    translate = function( styles, href, media ){
      var qs = styles.match(  /@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi ),
        ql = qs && qs.length || 0;

      //try to get CSS path
      href = href.substring( 0, href.lastIndexOf( "/" ) );

      var repUrls = function( css ){
          return css.replace( /(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g, "$1" + href + "$2$3" );
        },
        useMedia = !ql && media;

      //if path exists, tack on trailing slash
      if( href.length ){ href += "/"; } 
        
      //if no internal queries exist, but media attr does, use that 
      //note: this currently lacks support for situations where a media attr is specified on a link AND
        //its associated stylesheet has internal CSS media queries.
        //In those cases, the media attribute will currently be ignored.
      if( useMedia ){
        ql = 1;
      }

      for( var i = 0; i < ql; i++ ){
        var fullq, thisq, eachq, eql;

        //media attr
        if( useMedia ){
          fullq = media;
          rules.push( repUrls( styles ) );
        }
        //parse for styles
        else{
          fullq = qs[ i ].match( /@media *([^\{]+)\{([\S\s]+?)$/ ) && RegExp.$1;
          rules.push( RegExp.$2 && repUrls( RegExp.$2 ) );
        }
        
        eachq = fullq.split( "," );
        eql = eachq.length;
          
        for( var j = 0; j < eql; j++ ){
          thisq = eachq[ j ];
          mediastyles.push( { 
            media : thisq.split( "(" )[ 0 ].match( /(only\s+)?([a-zA-Z]+)\s?/ ) && RegExp.$2 || "all",
            rules : rules.length - 1,
            hasquery : thisq.indexOf("(") > -1,
            minw : thisq.match( /\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" ), 
            maxw : thisq.match( /\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" )
          } );
        } 
      }

      applyMedia();
    },
        
    lastCall,
    
    resizeDefer,
    
    // returns the value of 1em in pixels
    getEmValue = function() {
      var ret,
        div = doc.createElement('div'),
        body = doc.body,
        fakeUsed = false;
                  
      div.style.cssText = "position:absolute;font-size:1em;width:1em";
          
      if( !body ){
        body = fakeUsed = doc.createElement( "body" );
        body.style.background = "none";
      }
          
      body.appendChild( div );
                
      docElem.insertBefore( body, docElem.firstChild );
                
      ret = div.offsetWidth;
                
      if( fakeUsed ){
        docElem.removeChild( body );
      }
      else {
        body.removeChild( div );
      }
      
      //also update eminpx before returning
      ret = eminpx = parseFloat(ret);
                
      return ret;
    },
    
    //cached container for 1em value, populated the first time it's needed 
    eminpx,
    
    //enable/disable styles
    applyMedia = function( fromResize ){
      var name = "clientWidth",
        docElemProp = docElem[ name ],
        currWidth = doc.compatMode === "CSS1Compat" && docElemProp || doc.body[ name ] || docElemProp,
        styleBlocks = {},
        lastLink = links[ links.length-1 ],
        now = (new Date()).getTime();

      //throttle resize calls 
      if( fromResize && lastCall && now - lastCall < resizeThrottle ){
        win.clearTimeout( resizeDefer );
        resizeDefer = win.setTimeout( applyMedia, resizeThrottle );
        return;
      }
      else {
        lastCall = now;
      }
                    
      for( var i in mediastyles ){
        if( mediastyles.hasOwnProperty( i ) ){
          var thisstyle = mediastyles[ i ],
            min = thisstyle.minw,
            max = thisstyle.maxw,
            minnull = min === null,
            maxnull = max === null,
            em = "em";
          
          if( !!min ){
            min = parseFloat( min ) * ( min.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 );
          }
          if( !!max ){
            max = parseFloat( max ) * ( max.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 );
          }
          
          // if there's no media query at all (the () part), or min or max is not null, and if either is present, they're true
          if( !thisstyle.hasquery || ( !minnull || !maxnull ) && ( minnull || currWidth >= min ) && ( maxnull || currWidth <= max ) ){
            if( !styleBlocks[ thisstyle.media ] ){
              styleBlocks[ thisstyle.media ] = [];
            }
            styleBlocks[ thisstyle.media ].push( rules[ thisstyle.rules ] );
          }
        }
      }
      
      //remove any existing respond style element(s)
      for( var j in appendedEls ){
        if( appendedEls.hasOwnProperty( j ) ){
          if( appendedEls[ j ] && appendedEls[ j ].parentNode === head ){
            head.removeChild( appendedEls[ j ] );
          }
        }
      }
      
      //inject active styles, grouped by media type
      for( var k in styleBlocks ){
        if( styleBlocks.hasOwnProperty( k ) ){
          var ss = doc.createElement( "style" ),
            css = styleBlocks[ k ].join( "\n" );
          
          ss.type = "text/css"; 
          ss.media = k;
          
          //originally, ss was appended to a documentFragment and sheets were appended in bulk.
          //this caused crashes in IE in a number of circumstances, such as when the HTML element had a bg image set, so appending beforehand seems best. Thanks to @dvelyk for the initial research on this one!
          head.insertBefore( ss, lastLink.nextSibling );
          
          if ( ss.styleSheet ){ 
            ss.styleSheet.cssText = css;
          }
          else {
            ss.appendChild( doc.createTextNode( css ) );
          }

          //push to appendedEls to track for later removal
          appendedEls.push( ss );
        }
      }
    },
    //tweaked Ajax functions from Quirksmode
    ajax = function( url, callback ) {
      var req = xmlHttp();
      if (!req){
        return;
      } 
      req.open( "GET", url, true );
      req.onreadystatechange = function () {
        if ( req.readyState !== 4 || req.status !== 200 && req.status !== 304 ){
          return;
        }
        callback( req.responseText );
      };
      if ( req.readyState === 4 ){
        return;
      }
      req.send( null );
    },
    //define ajax obj 
    xmlHttp = (function() {
      var xmlhttpmethod = false;  
      try {
        xmlhttpmethod = new win.XMLHttpRequest();
      }
      catch( e ){
        xmlhttpmethod = new win.ActiveXObject( "Microsoft.XMLHTTP" );
      }
      return function(){
        return xmlhttpmethod;
      };
    })();
  
  //translate CSS
  ripCSS();
  
  //expose update for re-running respond later on
  respond.update = ripCSS;
  
  //adjust on resize
  function callMedia(){
    applyMedia( true );
  }
  if( win.addEventListener ){
    win.addEventListener( "resize", callMedia, false );
  }
  else if( win.attachEvent ){
    win.attachEvent( "onresize", callMedia );
  }
})(this);

/*! responsive-nav.js v1.0.14
 * https://github.com/viljamis/responsive-nav.js
 * http://responsive-nav.com
 *
 * Copyright (c) 2013 @viljamis
 * Available under the MIT license
 */

/* jshint strict:false, forin:false, noarg:true, noempty:true, eqeqeq:true,
boss:true, bitwise:true, browser:true, devel:true, indent:2 */
/* exported responsiveNav */

var responsiveNav = (function (window, document) {

  var computed = !!window.getComputedStyle;

  // getComputedStyle polyfill
  if (!window.getComputedStyle) {
    window.getComputedStyle = function(el) {
      this.el = el;
      this.getPropertyValue = function(prop) {
        var re = /(\-([a-z]){1})/g;
        if (prop === "float") {
          prop = "styleFloat";
        }
        if (re.test(prop)) {
          prop = prop.replace(re, function () {
            return arguments[2].toUpperCase();
          });
        }
        return el.currentStyle[prop] ? el.currentStyle[prop] : null;
      };
      return this;
    };
  }

  var nav,
    opts,
    navToggle,
    docEl = document.documentElement,
    head = document.getElementsByTagName("head")[0],
    styleElement = document.createElement("style"),
    navOpen = false,

    // fn arg can be an object or a function, thanks to handleEvent
    // read more at: http://www.thecssninja.com/javascript/handleevent
    addEvent = function (el, evt, fn, bubble) {
      if ("addEventListener" in el) {
        // BBOS6 doesn't support handleEvent, catch and polyfill
        try {
          el.addEventListener(evt, fn, bubble);
        } catch (e) {
          if (typeof fn === "object" && fn.handleEvent) {
            el.addEventListener(evt, function (e) {
              // Bind fn as this and set first arg as event object
              fn.handleEvent.call(fn, e);
            }, bubble);
          } else {
            throw e;
          }
        }
      } else if ("attachEvent" in el) {
        // check if the callback is an object and contains handleEvent
        if (typeof fn === "object" && fn.handleEvent) {
          el.attachEvent("on" + evt, function () {
            // Bind fn as this
            fn.handleEvent.call(fn);
          });
        } else {
          el.attachEvent("on" + evt, fn);
        }
      }
    },

    removeEvent = function (el, evt, fn, bubble) {
      if ("removeEventListener" in el) {
        try {
          el.removeEventListener(evt, fn, bubble);
        } catch (e) {
          if (typeof fn === "object" && fn.handleEvent) {
            el.removeEventListener(evt, function (e) {
              fn.handleEvent.call(fn, e);
            }, bubble);
          } else {
            throw e;
          }
        }
      } else if ("detachEvent" in el) {
        if (typeof fn === "object" && fn.handleEvent) {
          el.detachEvent("on" + evt, function () {
            fn.handleEvent.call(fn);
          });
        } else {
          el.detachEvent("on" + evt, fn);
        }
      }
    },

    getFirstChild = function (e) {
      var firstChild = e.firstChild;
      // skip TextNodes
      while (firstChild !== null && firstChild.nodeType !== 1) {
        firstChild = firstChild.nextSibling;
      }
      return firstChild;
    },

    setAttributes = function (el, attrs) {
      for (var key in attrs) {
        el.setAttribute(key, attrs[key]);
      }
    },

    addClass = function (el, cls) {
      el.className += " " + cls;
      el.className = el.className.replace(/(^\s*)|(\s*$)/g,"");
    },

    removeClass = function (el, cls) {
      var reg = new RegExp("(\\s|^)" + cls + "(\\s|$)");
      el.className = el.className.replace(reg, " ").replace(/(^\s*)|(\s*$)/g,"");
    },

    ResponsiveNav = function (el, options) {
      var i;

      // Default options
      this.options = {
        animate: true,        // Boolean: Use CSS3 transitions, true or false
        transition: 400,      // Integer: Speed of the transition, in milliseconds
        label: "Menu",        // String: Label for the navigation toggle
        insert: "after",      // String: Insert the toggle before or after the navigation
        customToggle: "",     // Selector: Specify the ID of a custom toggle
        openPos: "relative",  // String: Position of the opened nav, relative or static
        jsClass: "js",        // String: 'JS enabled' class which is added to <html> el
        init: function(){},   // Function: Init callback
        open: function(){},   // Function: Open callback
        close: function(){}   // Function: Close callback
      };

      // User defined options
      for (i in options) {
        this.options[i] = options[i];
      }

      // Adds "js" class for <html>
      addClass(docEl, this.options.jsClass);

      // Wrapper
      this.wrapperEl = el.replace("#", "");
      if (document.getElementById(this.wrapperEl)) {
        this.wrapper = document.getElementById(this.wrapperEl);
      } else {
        // If el doesn't exists, stop here.
        throw new Error("The nav element you are trying to select doesn't exist");
      }

      // Inner wrapper
      this.wrapper.inner = getFirstChild(this.wrapper);

      // For minification
      opts = this.options;
      nav = this.wrapper;

      // Init
      this._init(this);
    };

  ResponsiveNav.prototype = {
    // Public methods
    destroy: function () {
      this._removeStyles();
      removeClass(nav, "closed");
      removeClass(nav, "opened");
      nav.removeAttribute("style");
      nav.removeAttribute("aria-hidden");
      nav = null;
      _instance = null;

      removeEvent(window, "load", this, false);
      removeEvent(window, "resize", this, false);
      removeEvent(navToggle, "mousedown", this, false);
      removeEvent(navToggle, "touchstart", this, false);
      removeEvent(navToggle, "touchend", this, false);
      removeEvent(navToggle, "keyup", this, false);
      removeEvent(navToggle, "click", this, false);

      if (!opts.customToggle) {
        navToggle.parentNode.removeChild(navToggle);
      } else {
        navToggle.removeAttribute("aria-hidden");
      }
    },

    toggle: function () {
      if (!navOpen) {
        removeClass(nav, "closed");
        addClass(nav, "opened");
        nav.style.position = opts.openPos;
        setAttributes(nav, {"aria-hidden": "false"});

        navOpen = true;
        opts.open();
      } else {
        removeClass(nav, "opened");
        addClass(nav, "closed");
        setAttributes(nav, {"aria-hidden": "true"});

        if (opts.animate) {
          setTimeout(function () {
            nav.style.position = "relative";
          }, opts.transition + 10);
        } else {
          nav.style.position = "relative";
        }

        navOpen = false;
        opts.close();
      }
    },

    handleEvent: function (e) {
      var evt = e || window.event;

      switch (evt.type) {
      case "mousedown":
        this._onmousedown(evt);
        break;
      case "touchstart":
        this._ontouchstart(evt);
        break;
      case "touchend":
        this._ontouchend(evt);
        break;
      case "keyup":
        this._onkeyup(evt);
        break;
      case "click":
        this._onclick(evt);
        break;
      case "load":
        this._transitions(evt);
        this._resize(evt);
        break;
      case "resize":
        this._resize(evt);
        break;
      }
    },

    // Private methods
    _init: function () {
      addClass(nav, "closed");
      this._createToggle();

      addEvent(window, "load", this, false);
      addEvent(window, "resize", this, false);
      addEvent(navToggle, "mousedown", this, false);
      addEvent(navToggle, "touchstart", this, false);
      addEvent(navToggle, "touchend", this, false);
      addEvent(navToggle, "keyup", this, false);
      addEvent(navToggle, "click", this, false);
    },

    _createStyles: function () {
      if (!styleElement.parentNode) {
        head.appendChild(styleElement);
      }
    },

    _removeStyles: function () {
      if (styleElement.parentNode) {
        styleElement.parentNode.removeChild(styleElement);
      }
    },

    _createToggle: function () {
      if (!opts.customToggle) {
        var toggle = document.createElement("a");
        toggle.innerHTML = opts.label;
        setAttributes(toggle, {
          "href": "#",
          "id": "nav-toggle"
        });

        if (opts.insert === "after") {
          nav.parentNode.insertBefore(toggle, nav.nextSibling);
        } else {
          nav.parentNode.insertBefore(toggle, nav);
        }

        navToggle = document.getElementById("nav-toggle");
      } else {
        var toggleEl = opts.customToggle.replace("#", "");

        if (document.getElementById(toggleEl)) {
          navToggle = document.getElementById(toggleEl);
        } else {
          throw new Error("The custom nav toggle you are trying to select doesn't exist");
        }
      }
    },

    _preventDefault: function(e) {
      if (e.preventDefault) {
        e.preventDefault();
        e.stopPropagation();
      } else {
        e.returnValue = false;
      }
    },

    _onmousedown: function (e) {
      var evt = e || window.event;
      // If the user isn't right clicking:
      if (!(evt.which === 3 || evt.button === 2)) {
        this._preventDefault(e);
        this.toggle(e);
      }
    },

    _ontouchstart: function (e) {
      // Touchstart event fires before
      // the mousedown and can wipe it
      navToggle.onmousedown = null;
      this._preventDefault(e);
      this.toggle(e);
    },

    _ontouchend: function () {
      // Prevents ghost click from happening on some Android browsers
      var that = this;
      nav.addEventListener("click", that._preventDefault, true);
      setTimeout(function () {
        nav.removeEventListener("click", that._preventDefault, true);
      }, opts.transition);
    },

    _onkeyup: function (e) {
      var evt = e || window.event;
      if (evt.keyCode === 13) {
        this.toggle(e);
      }
    },

    _onclick: function (e) {
      // For older browsers (looking at IE)
      this._preventDefault(e);
    },

    _transitions: function () {
      if (opts.animate) {
        var objStyle = nav.style,
          transition = "max-height " + opts.transition + "ms";

        objStyle.WebkitTransition = transition;
        objStyle.MozTransition = transition;
        objStyle.OTransition = transition;
        objStyle.transition = transition;
      }
    },

    _calcHeight: function () {
      var savedHeight = nav.inner.offsetHeight,
        innerStyles = "#" + this.wrapperEl + ".opened{max-height:" + savedHeight + "px}";

      // Hide from old IE
      if (computed) {
        styleElement.innerHTML = innerStyles;
        innerStyles = "";
      }
    },

    _resize: function () {
      if (window.getComputedStyle(navToggle, null).getPropertyValue("display") !== "none") {
        setAttributes(navToggle, {"aria-hidden": "false"});

        // If the navigation is hidden
        if (nav.className.match(/(^|\s)closed(\s|$)/)) {
          setAttributes(nav, {"aria-hidden": "true"});
          nav.style.position = "absolute";
        }

        this._createStyles();
        this._calcHeight();
      } else {
        setAttributes(navToggle, {"aria-hidden": "true"});
        setAttributes(nav, {"aria-hidden": "false"});
        nav.style.position = opts.openPos;
        this._removeStyles();
      }

      // Init callback
      opts.init();
    }

  };

  var _instance;
  function rn (el, options) {
    if (!_instance) {
      _instance = new ResponsiveNav(el, options);
    }
    return _instance;
  }

  return rn;
})(window, document);


/*global jQuery */
/*jshint multistr:true browser:true */
/*!
* FitVids 1.0
*
* Copyright 2011, Chris Coyier - http://css-tricks.com + Dave Rupert - http://daverupert.com
* Credit to Thierry Koblentz - http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/
* Released under the WTFPL license - http://sam.zoy.org/wtfpl/
*
* Date: Thu Sept 01 18:00:00 2011 -0500
*/

(function( $ ){

  "use strict";

  $.fn.fitVids = function( options ) {
    var settings = {
      customSelector: null
    };

    var div = document.createElement('div'),
        ref = document.getElementsByTagName('base')[0] || document.getElementsByTagName('script')[0];

    div.className = 'fit-vids-style';
    div.innerHTML = '&shy;<style>         \
      .fluid-width-video-wrapper {        \
         width: 100%;                     \
         position: relative;              \
         padding: 0;                      \
      }                                   \
                                          \
      .fluid-width-video-wrapper iframe,  \
      .fluid-width-video-wrapper object,  \
      .fluid-width-video-wrapper embed {  \
         position: absolute;              \
         top: 0;                          \
         left: 0;                         \
         width: 100%;                     \
         height: 100%;                    \
      }                                   \
    </style>';

    ref.parentNode.insertBefore(div,ref);

    if ( options ) {
      $.extend( settings, options );
    }

    return this.each(function(){
      var selectors = [
        "iframe[src*='player.vimeo.com']",
        "iframe[src*='www.youtube.com']",
        "iframe[src*='www.youtube-nocookie.com']",
        "iframe[src*='www.kickstarter.com']",
        "object",
        "embed"
      ];

      if (settings.customSelector) {
        selectors.push(settings.customSelector);
      }

      var $allVideos = $(this).find(selectors.join(','));

      $allVideos.each(function(){
        var $this = $(this);
        if (this.tagName.toLowerCase() === 'embed' && $this.parent('object').length || $this.parent('.fluid-width-video-wrapper').length) { return; }
        var height = ( this.tagName.toLowerCase() === 'object' || ($this.attr('height') && !isNaN(parseInt($this.attr('height'), 10))) ) ? parseInt($this.attr('height'), 10) : $this.height(),
            width = !isNaN(parseInt($this.attr('width'), 10)) ? parseInt($this.attr('width'), 10) : $this.width(),
            aspectRatio = height / width;
        if(!$this.attr('id')){
          var videoID = 'fitvid' + Math.floor(Math.random()*999999);
          $this.attr('id', videoID);
        }
        $this.wrap('<div class="fluid-width-video-wrapper"></div>').parent('.fluid-width-video-wrapper').css('padding-top', (aspectRatio * 100)+"%");
        $this.removeAttr('height').removeAttr('width');
      });
    });
  };
})( jQuery );

/**
 * jquery.dlmenu.js v1.0.1
 * http://www.codrops.com
 *
 * Licensed under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 * 
 * Copyright 2013, Codrops
 * http://www.codrops.com
 */
;( function( $, window, undefined ) {

  'use strict';

  // global
  var Modernizr = window.Modernizr, $body = $( 'body' );

  $.DLMenu = function( options, element ) {
    this.$el = $( element );
    this._init( options );
  };

  // the options
  $.DLMenu.defaults = {
    // classes for the animation effects
    animationClasses : { classin : 'dl-animate-in-1', classout : 'dl-animate-out-1' },
    // callback: click a link that has a sub menu
    // el is the link element (li); name is the level name
    onLevelClick : function( el, name ) { return false; },
    // callback: click a link that does not have a sub menu
    // el is the link element (li); ev is the event obj
    onLinkClick : function( el, ev ) { return false; }
  };

  $.DLMenu.prototype = {
    _init : function( options ) {

      // options
      this.options = $.extend( true, {}, $.DLMenu.defaults, options );
      // cache some elements and initialize some variables
      this._config();
      
      var animEndEventNames = {
          'WebkitAnimation' : 'webkitAnimationEnd',
          'OAnimation' : 'oAnimationEnd',
          'msAnimation' : 'MSAnimationEnd',
          'animation' : 'animationend'
        },
        transEndEventNames = {
          'WebkitTransition' : 'webkitTransitionEnd',
          'MozTransition' : 'transitionend',
          'OTransition' : 'oTransitionEnd',
          'msTransition' : 'MSTransitionEnd',
          'transition' : 'transitionend'
        };
      // animation end event name
      this.animEndEventName = animEndEventNames[ Modernizr.prefixed( 'animation' ) ] + '.dlmenu';
      // transition end event name
      this.transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ] + '.dlmenu',
      // support for css animations and css transitions
      this.supportAnimations = Modernizr.cssanimations,
      this.supportTransitions = Modernizr.csstransitions;

      this._initEvents();

    },
    _config : function() {
      this.open = false;
      this.$trigger = this.$el.children( '.dl-trigger' );
      this.$menu = this.$el.children( 'ul.dl-menu' );
      this.$menuitems = this.$menu.find( 'li:not(.dl-back)' );
      this.$el.find( 'ul.dl-submenu' ).prepend( '<li class="dl-back"><a href="#">back</a></li>' );
      this.$back = this.$menu.find( 'li.dl-back' );
    },
    _initEvents : function() {

      var self = this;

      this.$trigger.on( 'click.dlmenu', function() {
        
        if( self.open ) {
          self._closeMenu();
        } 
        else {
          self._openMenu();
        }
        return false;

      } );

      this.$menuitems.on( 'click.dlmenu', function( event ) {
        
        event.stopPropagation();

        var $item = $(this),
          $submenu = $item.children( 'ul.dl-submenu' );

        if( $submenu.length > 0 ) {

          var $flyin = $submenu.clone().css( 'opacity', 0 ).insertAfter( self.$menu ),
            onAnimationEndFn = function() {
              self.$menu.off( self.animEndEventName ).removeClass( self.options.animationClasses.classout ).addClass( 'dl-subview' );
              $item.addClass( 'dl-subviewopen' ).parents( '.dl-subviewopen:first' ).removeClass( 'dl-subviewopen' ).addClass( 'dl-subview' );
              $flyin.remove();
            };

          setTimeout( function() {
            $flyin.addClass( self.options.animationClasses.classin );
            self.$menu.addClass( self.options.animationClasses.classout );
            if( self.supportAnimations ) {
              self.$menu.on( self.animEndEventName, onAnimationEndFn );
            }
            else {
              onAnimationEndFn.call();
            }

            self.options.onLevelClick( $item, $item.children( 'a:first' ).text() );
          } );

          return false;

        }
        else {
          self.options.onLinkClick( $item, event );
        }

      } );

      this.$back.on( 'click.dlmenu', function( event ) {
        
        var $this = $( this ),
          $submenu = $this.parents( 'ul.dl-submenu:first' ),
          $item = $submenu.parent(),

          $flyin = $submenu.clone().insertAfter( self.$menu );

        var onAnimationEndFn = function() {
          self.$menu.off( self.animEndEventName ).removeClass( self.options.animationClasses.classin );
          $flyin.remove();
        };

        setTimeout( function() {
          $flyin.addClass( self.options.animationClasses.classout );
          self.$menu.addClass( self.options.animationClasses.classin );
          if( self.supportAnimations ) {
            self.$menu.on( self.animEndEventName, onAnimationEndFn );
          }
          else {
            onAnimationEndFn.call();
          }

          $item.removeClass( 'dl-subviewopen' );
          
          var $subview = $this.parents( '.dl-subview:first' );
          if( $subview.is( 'li' ) ) {
            $subview.addClass( 'dl-subviewopen' );
          }
          $subview.removeClass( 'dl-subview' );
        } );

        return false;

      } );
      
    },
    closeMenu : function() {
      if( this.open ) {
        this._closeMenu();
      }
    },
    _closeMenu : function() {
      var self = this,
        onTransitionEndFn = function() {
          self.$menu.off( self.transEndEventName );
          self._resetMenu();
        };
      
      this.$menu.removeClass( 'dl-menuopen' );
      this.$menu.addClass( 'dl-menu-toggle' );
      this.$trigger.removeClass( 'dl-active' );
      
      if( this.supportTransitions ) {
        this.$menu.on( this.transEndEventName, onTransitionEndFn );
      }
      else {
        onTransitionEndFn.call();
      }

      this.open = false;
    },
    openMenu : function() {
      if( !this.open ) {
        this._openMenu();
      }
    },
    _openMenu : function() {
      var self = this;
      // clicking somewhere else makes the menu close
      $body.off( 'click' ).on( 'click.dlmenu', function() {
        self._closeMenu() ;
      } );
      this.$menu.addClass( 'dl-menuopen dl-menu-toggle' ).on( this.transEndEventName, function() {
        $( this ).removeClass( 'dl-menu-toggle' );
      } );
      this.$trigger.addClass( 'dl-active' );
      this.open = true;
    },
    // resets the menu to its original state (first level of options)
    _resetMenu : function() {
      this.$menu.removeClass( 'dl-subview' );
      this.$menuitems.removeClass( 'dl-subview dl-subviewopen' );
    }
  };

  var logError = function( message ) {
    if ( window.console ) {
      window.console.error( message );
    }
  };

  $.fn.dlmenu = function( options ) {
    if ( typeof options === 'string' ) {
      var args = Array.prototype.slice.call( arguments, 1 );
      this.each(function() {
        var instance = $.data( this, 'dlmenu' );
        if ( !instance ) {
          logError( "cannot call methods on dlmenu prior to initialization; " +
          "attempted to call method '" + options + "'" );
          return;
        }
        if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) {
          logError( "no such method '" + options + "' for dlmenu instance" );
          return;
        }
        instance[ options ].apply( instance, args );
      });
    } 
    else {
      this.each(function() {  
        var instance = $.data( this, 'dlmenu' );
        if ( instance ) {
          instance._init();
        }
        else {
          instance = $.data( this, 'dlmenu', new $.DLMenu( options, this ) );
        }
      });
    }
    return this;
  };

} )( jQuery, window );

/*! Plugin options and other jQuery stuff */

// dl-menu options
$(function() {
  $( '#dl-menu' ).dlmenu({
    animationClasses : { classin : 'dl-animate-in', classout : 'dl-animate-out' }
  });
});

// FitVids options
$(function() {
	$("article").fitVids();
});

$(".close-menu").click(function () {
  $(".menu").toggleClass("disabled");
  $(".links").toggleClass("enabled");
});

$(".about").click(function () {
  $("#about").css('display','block');
});

$(".close-about").click(function () {
  $("#about").css('display','');
});