/* ========================================================================
 * Bootstrap: tooltip.js v3.3.4
 * http://getbootstrap.com/javascript/#tooltip
 * Inspired by the original jQuery.tipsy by Jason Frame
 * ========================================================================
 * Copyright 2011-2015 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * ======================================================================== */


+function ($) {
  'use strict';

  // TOOLTIP PUBLIC CLASS DEFINITION
  // ===============================

  var Tooltip = function (element, options) {
    this.type       = null
    this.options    = null
    this.enabled    = null
    this.timeout    = null
    this.hoverState = null
    this.$element   = null

    this.init('tooltip', element, options)
  }

  Tooltip.VERSION  = '3.3.4'

  Tooltip.TRANSITION_DURATION = 150

  Tooltip.DEFAULTS = {
    animation: true,
    placement: 'top',
    selector: false,
    template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
    trigger: 'hover focus',
    title: '',
    delay: 0,
    html: false,
    container: false,
    viewport: {
      selector: 'body',
      padding: 0
    }
  }

  Tooltip.prototype.init = function (type, element, options) {
    this.enabled   = true
    this.type      = type
    this.$element  = $(element)
    this.options   = this.getOptions(options)
    this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)

    if (this.$element[0] instanceof document.constructor && !this.options.selector) {
      throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
    }

    var triggers = this.options.trigger.split(' ')

    for (var i = triggers.length; i--;) {
      var trigger = triggers[i]

      if (trigger == 'click') {
        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
      } else if (trigger != 'manual') {
        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'
        var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'

        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
      }
    }

    this.options.selector ?
      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
      this.fixTitle()
  }

  Tooltip.prototype.getDefaults = function () {
    return Tooltip.DEFAULTS
  }

  Tooltip.prototype.getOptions = function (options) {
    options = $.extend({}, this.getDefaults(), this.$element.data(), options)

    if (options.delay && typeof options.delay == 'number') {
      options.delay = {
        show: options.delay,
        hide: options.delay
      }
    }

    return options
  }

  Tooltip.prototype.getDelegateOptions = function () {
    var options  = {}
    var defaults = this.getDefaults()

    this._options && $.each(this._options, function (key, value) {
      if (defaults[key] != value) options[key] = value
    })

    return options
  }

  Tooltip.prototype.enter = function (obj) {
    var self = obj instanceof this.constructor ?
      obj : $(obj.currentTarget).data('bs.' + this.type)

    if (self && self.$tip && self.$tip.is(':visible')) {
      self.hoverState = 'in'
      return
    }

    if (!self) {
      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
      $(obj.currentTarget).data('bs.' + this.type, self)
    }

    clearTimeout(self.timeout)

    self.hoverState = 'in'

    if (!self.options.delay || !self.options.delay.show) return self.show()

    self.timeout = setTimeout(function () {
      if (self.hoverState == 'in') self.show()
    }, self.options.delay.show)
  }

  Tooltip.prototype.leave = function (obj) {
    var self = obj instanceof this.constructor ?
      obj : $(obj.currentTarget).data('bs.' + this.type)

    if (!self) {
      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
      $(obj.currentTarget).data('bs.' + this.type, self)
    }

    clearTimeout(self.timeout)

    self.hoverState = 'out'

    if (!self.options.delay || !self.options.delay.hide) return self.hide()

    self.timeout = setTimeout(function () {
      if (self.hoverState == 'out') self.hide()
    }, self.options.delay.hide)
  }

  Tooltip.prototype.show = function () {
    var e = $.Event('show.bs.' + this.type)

    if (this.hasContent() && this.enabled) {
      this.$element.trigger(e)

      var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
      if (e.isDefaultPrevented() || !inDom) return
      var that = this

      var $tip = this.tip()

      var tipId = this.getUID(this.type)

      this.setContent()
      $tip.attr('id', tipId)
      this.$element.attr('aria-describedby', tipId)

      if (this.options.animation) $tip.addClass('fade')

      var placement = typeof this.options.placement == 'function' ?
        this.options.placement.call(this, $tip[0], this.$element[0]) :
        this.options.placement

      var autoToken = /\s?auto?\s?/i
      var autoPlace = autoToken.test(placement)
      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'

      $tip
        .detach()
        .css({ top: 0, left: 0, display: 'block' })
        .addClass(placement)
        .data('bs.' + this.type, this)

      this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)

      var pos          = this.getPosition()
      var actualWidth  = $tip[0].offsetWidth
      var actualHeight = $tip[0].offsetHeight

      if (autoPlace) {
        var orgPlacement = placement
        var $container   = this.options.container ? $(this.options.container) : this.$element.parent()
        var containerDim = this.getPosition($container)

        placement = placement == 'bottom' && pos.bottom + actualHeight > containerDim.bottom ? 'top'    :
                    placement == 'top'    && pos.top    - actualHeight < containerDim.top    ? 'bottom' :
                    placement == 'right'  && pos.right  + actualWidth  > containerDim.width  ? 'left'   :
                    placement == 'left'   && pos.left   - actualWidth  < containerDim.left   ? 'right'  :
                    placement

        $tip
          .removeClass(orgPlacement)
          .addClass(placement)
      }

      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)

      this.applyPlacement(calculatedOffset, placement)

      var complete = function () {
        var prevHoverState = that.hoverState
        that.$element.trigger('shown.bs.' + that.type)
        that.hoverState = null

        if (prevHoverState == 'out') that.leave(that)
      }

      $.support.transition && this.$tip.hasClass('fade') ?
        $tip
          .one('bsTransitionEnd', complete)
          .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
        complete()
    }
  }

  Tooltip.prototype.applyPlacement = function (offset, placement) {
    var $tip   = this.tip()
    var width  = $tip[0].offsetWidth
    var height = $tip[0].offsetHeight

    // manually read margins because getBoundingClientRect includes difference
    var marginTop = parseInt($tip.css('margin-top'), 10)
    var marginLeft = parseInt($tip.css('margin-left'), 10)

    // we must check for NaN for ie 8/9
    if (isNaN(marginTop))  marginTop  = 0
    if (isNaN(marginLeft)) marginLeft = 0

    offset.top  = offset.top  + marginTop
    offset.left = offset.left + marginLeft

    // $.fn.offset doesn't round pixel values
    // so we use setOffset directly with our own function B-0
    $.offset.setOffset($tip[0], $.extend({
      using: function (props) {
        $tip.css({
          top: Math.round(props.top),
          left: Math.round(props.left)
        })
      }
    }, offset), 0)

    $tip.addClass('in')

    // check to see if placing tip in new offset caused the tip to resize itself
    var actualWidth  = $tip[0].offsetWidth
    var actualHeight = $tip[0].offsetHeight

    if (placement == 'top' && actualHeight != height) {
      offset.top = offset.top + height - actualHeight
    }

    var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)

    if (delta.left) offset.left += delta.left
    else offset.top += delta.top

    var isVertical          = /top|bottom/.test(placement)
    var arrowDelta          = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
    var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'

    $tip.offset(offset)
    this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
  }

  Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
    this.arrow()
      .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
      .css(isVertical ? 'top' : 'left', '')
  }

  Tooltip.prototype.setContent = function () {
    var $tip  = this.tip()
    var title = this.getTitle()

    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
    $tip.removeClass('fade in top bottom left right')
  }

  Tooltip.prototype.hide = function (callback) {
    var that = this
    var $tip = $(this.$tip)
    var e    = $.Event('hide.bs.' + this.type)

    function complete() {
      if (that.hoverState != 'in') $tip.detach()
      that.$element
        .removeAttr('aria-describedby')
        .trigger('hidden.bs.' + that.type)
      callback && callback()
    }

    this.$element.trigger(e)

    if (e.isDefaultPrevented()) return

    $tip.removeClass('in')

    $.support.transition && $tip.hasClass('fade') ?
      $tip
        .one('bsTransitionEnd', complete)
        .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
      complete()

    this.hoverState = null

    return this
  }

  Tooltip.prototype.fixTitle = function () {
    var $e = this.$element
    if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') {
      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
    }
  }

  Tooltip.prototype.hasContent = function () {
    return this.getTitle()
  }

  Tooltip.prototype.getPosition = function ($element) {
    $element   = $element || this.$element

    var el     = $element[0]
    var isBody = el.tagName == 'BODY'

    var elRect    = el.getBoundingClientRect()
    if (elRect.width == null) {
      // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
      elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
    }
    var elOffset  = isBody ? { top: 0, left: 0 } : $element.offset()
    var scroll    = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
    var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null

    return $.extend({}, elRect, scroll, outerDims, elOffset)
  }

  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2 } :
           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }

  }

  Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
    var delta = { top: 0, left: 0 }
    if (!this.$viewport) return delta

    var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
    var viewportDimensions = this.getPosition(this.$viewport)

    if (/right|left/.test(placement)) {
      var topEdgeOffset    = pos.top - viewportPadding - viewportDimensions.scroll
      var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
      if (topEdgeOffset < viewportDimensions.top) { // top overflow
        delta.top = viewportDimensions.top - topEdgeOffset
      } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
        delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
      }
    } else {
      var leftEdgeOffset  = pos.left - viewportPadding
      var rightEdgeOffset = pos.left + viewportPadding + actualWidth
      if (leftEdgeOffset < viewportDimensions.left) { // left overflow
        delta.left = viewportDimensions.left - leftEdgeOffset
      } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow
        delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
      }
    }

    return delta
  }

  Tooltip.prototype.getTitle = function () {
    var title
    var $e = this.$element
    var o  = this.options

    title = $e.attr('data-original-title')
      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)

    return title
  }

  Tooltip.prototype.getUID = function (prefix) {
    do prefix += ~~(Math.random() * 1000000)
    while (document.getElementById(prefix))
    return prefix
  }

  Tooltip.prototype.tip = function () {
    return (this.$tip = this.$tip || $(this.options.template))
  }

  Tooltip.prototype.arrow = function () {
    return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
  }

  Tooltip.prototype.enable = function () {
    this.enabled = true
  }

  Tooltip.prototype.disable = function () {
    this.enabled = false
  }

  Tooltip.prototype.toggleEnabled = function () {
    this.enabled = !this.enabled
  }

  Tooltip.prototype.toggle = function (e) {
    var self = this
    if (e) {
      self = $(e.currentTarget).data('bs.' + this.type)
      if (!self) {
        self = new this.constructor(e.currentTarget, this.getDelegateOptions())
        $(e.currentTarget).data('bs.' + this.type, self)
      }
    }

    self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
  }

  Tooltip.prototype.destroy = function () {
    var that = this
    clearTimeout(this.timeout)
    this.hide(function () {
      that.$element.off('.' + that.type).removeData('bs.' + that.type)
    })
  }


  // TOOLTIP PLUGIN DEFINITION
  // =========================

  function Plugin(option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.tooltip')
      var options = typeof option == 'object' && option

      if (!data && /destroy|hide/.test(option)) return
      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  var old = $.fn.tooltip

  $.fn.tooltip             = Plugin
  $.fn.tooltip.Constructor = Tooltip


  // TOOLTIP NO CONFLICT
  // ===================

  $.fn.tooltip.noConflict = function () {
    $.fn.tooltip = old
    return this
  }

}(jQuery);

/* ========================================================================
 * Bootstrap: popover.js v3.3.4
 * http://getbootstrap.com/javascript/#popovers
 * ========================================================================
 * Copyright 2011-2015 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * ======================================================================== */


+function ($) {
  'use strict';

  // POPOVER PUBLIC CLASS DEFINITION
  // ===============================

  var Popover = function (element, options) {
    this.init('popover', element, options)
  }

  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')

  Popover.VERSION  = '3.3.4'

  Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
    placement: 'right',
    trigger: 'click',
    content: '',
    template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
  })


  // NOTE: POPOVER EXTENDS tooltip.js
  // ================================

  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)

  Popover.prototype.constructor = Popover

  Popover.prototype.getDefaults = function () {
    return Popover.DEFAULTS
  }

  Popover.prototype.setContent = function () {
    var $tip    = this.tip()
    var title   = this.getTitle()
    var content = this.getContent()

    $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
    $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
      this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
    ](content)

    $tip.removeClass('fade top bottom left right in')

    // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
    // this manually by checking the contents.
    if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
  }

  Popover.prototype.hasContent = function () {
    return this.getTitle() || this.getContent()
  }

  Popover.prototype.getContent = function () {
    var $e = this.$element
    var o  = this.options

    return $e.attr('data-content')
      || (typeof o.content == 'function' ?
            o.content.call($e[0]) :
            o.content)
  }

  Popover.prototype.arrow = function () {
    return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
  }


  // POPOVER PLUGIN DEFINITION
  // =========================

  function Plugin(option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.popover')
      var options = typeof option == 'object' && option

      if (!data && /destroy|hide/.test(option)) return
      if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  var old = $.fn.popover

  $.fn.popover             = Plugin
  $.fn.popover.Constructor = Popover


  // POPOVER NO CONFLICT
  // ===================

  $.fn.popover.noConflict = function () {
    $.fn.popover = old
    return this
  }

}(jQuery);

/* ========================================================================
 * Bootstrap: collapse.js v3.3.4
 * http://getbootstrap.com/javascript/#collapse
 * ========================================================================
 * Copyright 2011-2015 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * ======================================================================== */


+function ($) {
  'use strict';

  // COLLAPSE PUBLIC CLASS DEFINITION
  // ================================

  var Collapse = function (element, options) {
    this.$element      = $(element)
    this.options       = $.extend({}, Collapse.DEFAULTS, options)
    this.$trigger      = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
                           '[data-toggle="collapse"][data-target="#' + element.id + '"]')
    this.transitioning = null

    if (this.options.parent) {
      this.$parent = this.getParent()
    } else {
      this.addAriaAndCollapsedClass(this.$element, this.$trigger)
    }

    if (this.options.toggle) this.toggle()
  }

  Collapse.VERSION  = '3.3.4'

  Collapse.TRANSITION_DURATION = 350

  Collapse.DEFAULTS = {
    toggle: true
  }

  Collapse.prototype.dimension = function () {
    var hasWidth = this.$element.hasClass('width')
    return hasWidth ? 'width' : 'height'
  }

  Collapse.prototype.show = function () {
    if (this.transitioning || this.$element.hasClass('in')) return

    var activesData
    var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
    
    if (actives && actives.length) {
      activesData = actives.data('bs.collapse')
      if (activesData && activesData.transitioning) return
    }

    var startEvent = $.Event('show.bs.collapse')
    this.$element.trigger(startEvent)
    if (startEvent.isDefaultPrevented()) return

    if (actives && actives.length) {
      Plugin.call(actives, 'hide')
      activesData || actives.data('bs.collapse', null)
    }

    var dimension = this.dimension()

    this.$element
      .removeClass('collapse')
      .addClass('collapsing')[dimension](0)
      .attr('aria-expanded', true)

    this.$trigger
      .removeClass('collapsed')
      .attr('aria-expanded', true)
      

    this.transitioning = 1

    var complete = function () {
      this.$element
        .removeClass('collapsing')
        .addClass('collapse in')[dimension]('')
      this.transitioning = 0
      this.$element
        .trigger('shown.bs.collapse')
    }

    if (!$.support.transition) return complete.call(this)

    var scrollSize = $.camelCase(['scroll', dimension].join('-'))

    this.$element
      .one('bsTransitionEnd', $.proxy(complete, this))
      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
  }

  Collapse.prototype.hide = function () {
    if (this.transitioning || !this.$element.hasClass('in')) return

    var startEvent = $.Event('hide.bs.collapse')
    this.$element.trigger(startEvent)
    if (startEvent.isDefaultPrevented()) return

    var dimension = this.dimension()

    this.$element[dimension](this.$element[dimension]())[0].offsetHeight

    this.$element
      .addClass('collapsing')
      .removeClass('collapse in')
      .attr('aria-expanded', false)

    this.$trigger
      .addClass('collapsed')
      .attr('aria-expanded', false)
      

    this.transitioning = 1

    var complete = function () {
      this.transitioning = 0
      this.$element
        .removeClass('collapsing')
        .addClass('collapse')
        .trigger('hidden.bs.collapse')
    }

    if (!$.support.transition) return complete.call(this)

    this.$element
      [dimension](0)
      .one('bsTransitionEnd', $.proxy(complete, this))
      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
  }

  Collapse.prototype.toggle = function () {
    this[this.$element.hasClass('in') ? 'hide' : 'show']()
  }

  Collapse.prototype.getParent = function () {
    return $(this.options.parent)
      .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
      .each($.proxy(function (i, element) {
        var $element = $(element)
        this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
      }, this))
      .end()
  }

  Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
    var isOpen = $element.hasClass('in')

    $element.attr('aria-expanded', isOpen)

      if (isOpen) {
          $trigger
              .removeClass('collapsed')
      } else {
          $trigger
              .addClass('collapsed')
      }
    $trigger.attr('aria-expanded', isOpen)
  }

  function getTargetFromTrigger($trigger) {
    var href
    var target = $trigger.attr('data-target')
      || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7

    return $(target)
  }


  // COLLAPSE PLUGIN DEFINITION
  // ==========================

  function Plugin(option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.collapse')
      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)

      if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  var old = $.fn.collapse

  $.fn.collapse             = Plugin
  $.fn.collapse.Constructor = Collapse


  // COLLAPSE NO CONFLICT
  // ====================

  $.fn.collapse.noConflict = function () {
    $.fn.collapse = old
    return this
  }


  // COLLAPSE DATA-API
  // =================

  $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
    var $this   = $(this)

    if (!$this.attr('data-target')) e.preventDefault()

    var $target = getTargetFromTrigger($this)
    var data    = $target.data('bs.collapse')
    var option  = data ? 'toggle' : $this.data()

    Plugin.call($target, option)
  })

}(jQuery);

/* ========================================================================
 * Bootstrap: button.js v3.3.4
 * http://getbootstrap.com/javascript/#buttons
 * ========================================================================
 * Copyright 2011-2015 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * ======================================================================== */


+function ($) {
  'use strict';

  // BUTTON PUBLIC CLASS DEFINITION
  // ==============================

  var Button = function (element, options) {
    this.$element  = $(element)
    this.options   = $.extend({}, Button.DEFAULTS, options)
    this.isLoading = false
  }

  Button.VERSION  = '3.3.4'

  Button.DEFAULTS = {
    loadingText: 'loading...'
  }

  Button.prototype.setState = function (state) {
    var d    = 'disabled'
    var $el  = this.$element
    var val  = $el.is('input') ? 'val' : 'html'
    var data = $el.data()

    state = state + 'Text'

    if (data.resetText == null) $el.data('resetText', $el[val]())

    // push to event loop to allow forms to submit
    setTimeout($.proxy(function () {
      $el[val](data[state] == null ? this.options[state] : data[state])

      if (state == 'loadingText') {
        this.isLoading = true
        $el.addClass(d).attr(d, d)
      } else if (this.isLoading) {
        this.isLoading = false
        $el.removeClass(d).removeAttr(d)
      }
    }, this), 0)
  }

  Button.prototype.toggle = function () {
    var changed = true
    var $parent = this.$element.closest('[data-toggle="buttons"]')

    if ($parent.length) {
      var $input = this.$element.find('input')
      if ($input.prop('type') == 'radio') {
        if ($input.prop('checked') && this.$element.hasClass('active')) changed = false
        else $parent.find('.active').removeClass('active')
      }
      if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')
    } else {
      this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
    }

    if (changed) this.$element.toggleClass('active')
  }


  // BUTTON PLUGIN DEFINITION
  // ========================

  function Plugin(option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.button')
      var options = typeof option == 'object' && option

      if (!data) $this.data('bs.button', (data = new Button(this, options)))

      if (option == 'toggle') data.toggle()
      else if (option) data.setState(option)
    })
  }

  var old = $.fn.button

  $.fn.button             = Plugin
  $.fn.button.Constructor = Button


  // BUTTON NO CONFLICT
  // ==================

  $.fn.button.noConflict = function () {
    $.fn.button = old
    return this
  }


  // BUTTON DATA-API
  // ===============

  $(document)
    .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
      var $btn = $(e.target)
      if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
      Plugin.call($btn, 'toggle')
      e.preventDefault()
    })
    .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
      $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
    })

}(jQuery);

/* ========================================================================
 * Bootstrap: dropdown.js v3.3.4
 * http://getbootstrap.com/javascript/#dropdowns
 * ========================================================================
 * Copyright 2011-2015 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * ======================================================================== */


+function ($) {
  'use strict';

  // DROPDOWN CLASS DEFINITION
  // =========================

  var backdrop = '.dropdown-backdrop'
  var toggle   = '[data-toggle="dropdown"]'
  var Dropdown = function (element) {
    $(element).on('click.bs.dropdown', this.toggle)
  }

  Dropdown.VERSION = '3.3.4'

  Dropdown.prototype.toggle = function (e) {
    var $this = $(this)

    if ($this.is('.disabled, :disabled')) return

    var $parent  = getParent($this)
    var isActive = $parent.hasClass('open')

    clearMenus()

    if (!isActive) {
      if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
        // if mobile we use a backdrop because click events don't delegate
        $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
      }

      var relatedTarget = { relatedTarget: this }
      $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))

      if (e.isDefaultPrevented()) return

      $this
        .trigger('focus')
        .attr('aria-expanded', 'true')

      $parent
        .toggleClass('open')
        .trigger('shown.bs.dropdown', relatedTarget)
    }

    return false
  }

  Dropdown.prototype.keydown = function (e) {
    if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return

    var $this = $(this)

    e.preventDefault()
    e.stopPropagation()

    if ($this.is('.disabled, :disabled')) return

    var $parent  = getParent($this)
    var isActive = $parent.hasClass('open')

    if ((!isActive && e.which != 27) || (isActive && e.which == 27)) {
      if (e.which == 27) $parent.find(toggle).trigger('focus')
      return $this.trigger('click')
    }

    var desc = ' li:not(.disabled):visible a'
    var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc)

    if (!$items.length) return

    var index = $items.index(e.target)

    if (e.which == 38 && index > 0)                 index--                        // up
    if (e.which == 40 && index < $items.length - 1) index++                        // down
    if (!~index)                                      index = 0

    $items.eq(index).trigger('focus')
  }

  function clearMenus(e) {
    if (e && e.which === 3) return
    $(backdrop).remove()
    $(toggle).each(function () {
      var $this         = $(this)
      var $parent       = getParent($this)
      var relatedTarget = { relatedTarget: this }

      if (!$parent.hasClass('open')) return

      $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))

      if (e.isDefaultPrevented()) return

      $this.attr('aria-expanded', 'false')
      $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
    })
  }

  function getParent($this) {
    var selector = $this.attr('data-target')

    if (!selector) {
      selector = $this.attr('href')
      selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
    }

    var $parent = selector && $(selector)

    return $parent && $parent.length ? $parent : $this.parent()
  }


  // DROPDOWN PLUGIN DEFINITION
  // ==========================

  function Plugin(option) {
    return this.each(function () {
      var $this = $(this)
      var data  = $this.data('bs.dropdown')

      if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
      if (typeof option == 'string') data[option].call($this)
    })
  }

  var old = $.fn.dropdown

  $.fn.dropdown             = Plugin
  $.fn.dropdown.Constructor = Dropdown


  // DROPDOWN NO CONFLICT
  // ====================

  $.fn.dropdown.noConflict = function () {
    $.fn.dropdown = old
    return this
  }


  // APPLY TO STANDARD DROPDOWN ELEMENTS
  // ===================================

  $(document)
    .on('click.bs.dropdown.data-api', clearMenus)
    .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
    .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
    .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
    .on('keydown.bs.dropdown.data-api', '[role="menu"]', Dropdown.prototype.keydown)
    .on('keydown.bs.dropdown.data-api', '[role="listbox"]', Dropdown.prototype.keydown)

}(jQuery);

/* ========================================================================
 * Bootstrap: tab.js v3.3.4
 * http://getbootstrap.com/javascript/#tabs
 * ========================================================================
 * Copyright 2011-2015 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * ======================================================================== */


+function ($) {
  'use strict';

  // TAB CLASS DEFINITION
  // ====================

  var Tab = function (element) {
    this.element = $(element)
  }

  Tab.VERSION = '3.3.4'

  Tab.TRANSITION_DURATION = 150

  Tab.prototype.show = function () {
    var $this    = this.element
    var $ul      = $this.closest('ul:not(.dropdown-menu)')
    var selector = $this.data('target')

    if (!selector) {
      selector = $this.attr('href')
      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
    }

    if ($this.parent('li').hasClass('active')) return

    var $previous = $ul.find('.active:last a')
    var hideEvent = $.Event('hide.bs.tab', {
      relatedTarget: $this[0]
    })
    var showEvent = $.Event('show.bs.tab', {
      relatedTarget: $previous[0]
    })

    $previous.trigger(hideEvent)
    $this.trigger(showEvent)

    if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return

    var $target = $(selector)

    this.activate($this.closest('li'), $ul)
    this.activate($target, $target.parent(), function () {
      $previous.trigger({
        type: 'hidden.bs.tab',
        relatedTarget: $this[0]
      })
      $this.trigger({
        type: 'shown.bs.tab',
        relatedTarget: $previous[0]
      })
    })
  }

  Tab.prototype.activate = function (element, container, callback) {
    var $active    = container.find('> .active')
    var transition = callback
      && $.support.transition
      && (($active.length && $active.hasClass('fade')) || !!container.find('> .fade').length)

    function next() {
      $active
        .removeClass('active')
        .find('> .dropdown-menu > .active')
          .removeClass('active')
        .end()
        .find('[data-toggle="tab"]')
          .attr('aria-expanded', false)

      element
        .addClass('active')
        .find('[data-toggle="tab"]')
          .attr('aria-expanded', true)

      if (transition) {
        element[0].offsetWidth // reflow for transition
        element.addClass('in')
      } else {
        element.removeClass('fade')
      }

      if (element.parent('.dropdown-menu').length) {
        element
          .closest('li.dropdown')
            .addClass('active')
          .end()
          .find('[data-toggle="tab"]')
            .attr('aria-expanded', true)
      }

      callback && callback()
    }

    $active.length && transition ?
      $active
        .one('bsTransitionEnd', next)
        .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
      next()

    $active.removeClass('in')
  }


  // TAB PLUGIN DEFINITION
  // =====================

  function Plugin(option) {
    return this.each(function () {
      var $this = $(this)
      var data  = $this.data('bs.tab')

      if (!data) $this.data('bs.tab', (data = new Tab(this)))
      if (typeof option == 'string') data[option]()
    })
  }

  var old = $.fn.tab

  $.fn.tab             = Plugin
  $.fn.tab.Constructor = Tab


  // TAB NO CONFLICT
  // ===============

  $.fn.tab.noConflict = function () {
    $.fn.tab = old
    return this
  }


  // TAB DATA-API
  // ============

  var clickHandler = function (e) {
    e.preventDefault()
    Plugin.call($(this), 'show')
  }

  $(document)
    .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
    .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)

}(jQuery);


/*
* Notify plugin form plugin
* Use this plugin to alert the user to a current action
* Has success and errors states
* Depends:
*   jquery.ui.core.js
*   jquery.ui.widget.js
*/

(function ($) {

    var alertHtml = '<div class="pop-alert"><div class="alert"><a class="close">×</a> <span></span></div></div>';
    var defaults = {
        message: '',
        state: 'success',
        displayTime: 1000, //in ms
        selfClose: true
    };

    $.widget("nl.notify", {
        options: {
        },

        _create: function () {

            var self = this;
            
        },
        
        note: function (opts) {

            var options = $.extend(defaults, opts);
            
            var alert = $(alertHtml);

            $('span', alert).append(options.message);

            alert.addClass("alert-" + options.state);

            $(document.body).prepend(alert);

            var hideTimeout = setTimeout(function () {
                if (options.selfClose) {
                    alert.remove();
                }
            }, options.displayTime);


            $('.close', alert).click(function (e) {
                e.preventDefault();
                alert.remove();
                clearTimeout(hideTimeout);
            });
            
        },

       
        destroy: function () {
            this._trigger("destroy", { type: "destroy" }, { options: this.options });
            $.Widget.prototype.destroy.call(this);
        },

        _setOption: function (key, value) {
            $.Widget.prototype._setOption.apply(this, arguments);
        }

    });

})(jQuery);

//___________.__               .__         __________                    
//\__    ___/|__| _____   ____ |  | ___.__.\______   \____ ______ 
//  |    |   |  |/     \_/ __ \|  |<   |  | |     ___/  _ \\____ \
//  |    |   |  |  Y Y  \  ___/|  |_\___  | |    |  (  <_> )  |_> >
//  |____|   |__|__|_|  /\___  >____/ ____| |____|   \____/|   __/
//                    \/     \/     \/                     |__|       

// PURPOSE -----
// Looks through the page's markup to identify links that have popover content
// It then binds the links and hides the content.
// Finally, creates and positions popovers when the links are clicked.

// IN ----------
// An optional object literal specifying script settings.

// OUT ---------
// Returns an object with the following methods:
// close: closes popovers matching the jQuery selector passed to the function.
// activate: activates the popover link matching the jQuery selector passed to the function.

// INFO --------
// Forked from BigFoot.js which is developed and maintained by Chris Sauve (http://pxldot.com)
// and has Documentation, license, and other information at http://cmsauve.com/projects/bigfoot.


(function ($) {

    $.timelyPop = function (options) {


        //    _________       __    __  .__                      
        //   /   _____/ _____/  |__/  |_|__| ____    ____  ______
        //   \_____  \_/ __ \   __\   __\  |/    \  / ___\/  ___/
        //   /        \  ___/|  |  |  | |  |   |  \/ /_/  >___ \ 
        //  /_______  /\___  >__|  |__| |__|___|  /\___  /____  >
        //          \/     \/                   \//_____/     \/ 
        //                                                       
        var timelyPop;

        var settings = $.extend(
            {
                actionOriginalTP: "hide", // "delete", "hide", or "ignore"
                activateCallback: function () { },
                activateOnHover: false,
                allowMultipleTP: false,
                appendPopoversTo: undefined,
                breakpoints: {},
                deleteOnUnhover: false,
                hoverDelay: 250,
                popoverDeleteDelay: 300,
                popoverCreateDelay: 100,
                positionNextToBlock: true,
                positionContent: true,
                preventPageScroll: true,
                scope: false,

                contentMarkup:  "<aside class=\"timelypop-content bottom\" data-popover-id=\"{{TIMELYPOPID}}\">" +
                                    "<div class=\"timelypop-main-wrapper\">" +
                                        "<div class=\"timelypop-header\">" +
                                            "{{TIMELYPOPHEADER}}" +
                                            "<a class=\"timelypop-close\" href=\"javascript:void(0);\">×</a>" +
                                        "</div>" +
                                        "<div class=\"timelypop-content-wrapper\">" +
                                            "{{TIMELYPOPCONTENT}}" +
                                        "</div>" +
                                    "</div>" +
                                    "<div class=\"timelypop-tooltip\"></div>" +
                                "</aside>"
            }, options);


        function isTouchDevice() {
            return (('ontouchstart' in window)
                 || (navigator.MaxTouchPoints > 0)
                 || (navigator.msMaxTouchPoints > 0));
        }

        //  .___       .__  __   
        //  |   | ____ |__|/  |_ 
        //  |   |/    \|  \   __\
        //  |   |   |  \  ||  |  
        //  |___|___|  /__||__|  
        //           \/          
        
        // FUNCTION ----
        // popover button/ content initializer (run on doc.ready)

        // PURPOSE -----
        // Finds the likely popover links and then uses their target to find the content
        
        var timelyPopInit = function () {

            // Get all of the possible footnote links
            var linkSearchQuery;
            linkSearchQuery = !settings.scope ? "a.timelypop" : settings.scope + " a.timelypop";

            // Filter down to links that:
            // - have a rel attribute of popover
            var $popoverAnchors = $(linkSearchQuery).filter(function () {
                var $this = $(this);
                var relAttr = $this.attr("rel");
                return (relAttr).match(/(popover)/gi);
            }); // End of popover link .filter()
            
            $popoverAnchors.each(function(index) {
                var currentLink = $(this);
                currentLink.attr('data-popover-id', index);
            }); // end of loop through footnotes

        };

        
        //     _____          __  .__               __          
        //    /  _  \   _____/  |_|__|__  _______ _/  |_  ____  
        //   /  /_\  \_/ ___\   __\  \  \/ /\__  \\   __\/ __ \ 
        //  /    |    \  \___|  | |  |\   /  / __ \|  | \  ___/ 
        //  \____|__  /\___  >__| |__| \_/  (____  /__|  \___  >
        //          \/     \/                    \/          \/ 
        //                                                      


        // FUNCTION ----
        // buttonHover

        // PURPOSE -----
        // To activate the popover of a hovered popover link
        // Also removes other popovers, if allowMultipleTP is false

        // IN ----------
        // Event that contains the target of the mouseenter event
         
        var buttonHover = function (e) {
            
            if (settings.activateOnHover) {
                var $buttonHovered = $(e.target).closest(".timelypop"),
                    dataIdentifier = "[data-popover-id=\"" + $buttonHovered.attr("data-popover-id") + "\"]";

                if ($buttonHovered.hasClass("active")) return;

                $buttonHovered.addClass("hover-instantiated");

                // Delete other popovers, unless overriden in the settings
                if (!settings.allowMultipleTP) {
                    //var otherPopoverSelector = ".timelypop-content:not(" + dataIdentifier + ")";
                    removePopovers();
                }
                createPopover(".timelypop" + dataIdentifier).addClass("hover-instantiated");
            }
        };


        // FUNCTION ----
        // touchClick

        // PURPOSE -----
        // Activates the button the was clicked/ taps
        // Also removes other popovers, if allowMultipleTP is false
        // Finally, removes all popovers if something popover related was clicked/ tapped

        // IN ----------
        // Event that contains the target of the tap/click event
        var lastClick = new Date();

        var touchClick = function (e) {
            
            var $target = $(e.target),
                $nearButton = $target.closest(".timelypop"),
                $nearPopover = $target.closest(".timelypop-content"),
                $nearClose = $target.closest(".timelypop-close"),
                thisClick = new Date(),
                isDouble = false,
                popoversVisible = $(".timelypop-content").length > 0;

            //Check if this is actually a double click (common android issue firing both a click and a touch)
            if (thisClick - lastClick < 500 & popoversVisible) {
                isDouble = true;
            }
            
            lastClick = thisClick;
            if ($nearClose.length > 0) {
                if (popoversVisible) {
                    removePopovers();
                }
            } else if ($nearButton.length > 0 && !isDouble) {
                // Button was clicked
                // Cancel the link, if it exists
                var ignoreClick = $nearButton.attr('data-popover-ignore-click') != 'false';
                if (ignoreClick) e.preventDefault();

                // Do the button clicking
                clickButton($nearButton);

            } else if ($nearPopover.length < 1 && !isDouble) {
                // Something other than a button or popover was pressed
                if (popoversVisible) {
                    removePopovers();
                }
            }
            
        };


        // FUNCTION ----
        // clickButton

        // PURPOSE -----
        // Handles the logic of clicking/ tapping the popover link
        // That is, activates the popover if it isn't already active (+ deactivate others, if appropriate)
        // or, deactivates the popover if it is already active

        // IN ----------
        // Button being clicked/ pressed

        var clickButton = function ($button) {

            // Cancel blur
            $button.blur();

            // Get the identifier of the footnote
            var dataIdentifier = "data-popover-id=\"" + $button.attr("data-popover-id") + "\"";

            // Only create popover if it's not already active
            // If it's activating, ignore the new activation until the popover is fully formed.
            if ($button.hasClass("changing")) {

                return;

            } else if (!$button.hasClass("active")) {

                $button.addClass("changing");
                setTimeout(function () {
                    $button.removeClass("changing");
                }, settings.popoverCreateDelay);
                createPopover(".timelypop[" + dataIdentifier + "]");
                $button.addClass("click-instantiated");

                // Delete all other footnote popovers if we are only allowing one
                if (!settings.allowMultipleTP) {
                    removePopovers(".timelypop-content:not([" + dataIdentifier + "])");
                }

            } else {

                // A fully instantiated popover; either remove it or all popovers, depending on settings
                if (!settings.allowMultipleTP) {
                    removePopovers();
                } else {
                    removePopovers(".timelypop-content[" + dataIdentifier + "]");
                }

            }
        };


        // FUNCTION ----
        // createPopover

        // PURPOSE -----
        // Instantiates the popover of the link matching the passed selector.
        // This includes replacing any variables in the content markup, decoding any special characters,
        // Adding the new element to the page, calling the position function, and adding the scroll handler

        // IN ----------
        // Selector of links that are to be activated

        // OUT ---------
        // All popovers activated by the function

        var createPopover = function (selector) {

            selector = selector || ".timelypop";

            // Activate all matching if multiple footnotes are allowed
            // Or only the first matching element otherwise
            var $buttons;
            if (typeof (selector) !== "string" && settings.allowMultipleTP) {
                $buttons = selector;
            } else if (typeof (selector) !== "string") {
                $buttons = selector.first();
            } else if (settings.allowMultipleTP) {
                $buttons = $(selector).closest(".timelypop");
            } else {
                $buttons = $(selector + ":first").closest(".timelypop");
            }

            var $popoversCreated = $();

            $buttons.each(function () {
                var $this = $(this),
                    content = '',
                    $content,
                    $nearestBlock;

                try {
                    
                    // Gets the easy replacements out of the way (try is there to ignore the "replacing undefined" error if it's activated too freuqnetly)
                    content = settings.contentMarkup
                                .replace(/\{\{TIMELYPOPID\}\}/g, $this.attr("data-popover-id"))
                                .replace(/\{\{TIMELYPOPCONTENT\}\}/g, $this.attr("data-popover-content"))
                                .replace(/\{\{TIMELYPOPHEADER\}\}/g, $this.attr("data-popover-header"))
                                .replace(/&gtsym;/, "&gt;").replace(/&ltsym;/, "&lt;");
                    
                } finally {

                    // Create content and activate user-defined callback on it
                    $content = $(content);
                    try { settings.activateCallback($content); } catch (err) { }
                    
                    if (!settings.appendPopoversTo) {
                        // Insert content after next block-level element, or after the nearest popover
                        $nearestBlock = $this.closest("p, div, pre, li, ul, section, article, main, aside");
                        $content.insertAfter($nearestBlock);
                    } else {
                        $content.appendTo(settings.appendPopoversTo + ":first");
                    }

                    // Instantiate the max-height for storage and use in repositioning
                    $content.attr("data-timelypop-max-height", $content.height());

                    repositionFeet();
                    $this.addClass("active");

                    // Bind the scroll handler to the popover
                    $content.find(".timelypop-content-wrapper").bindScrollHandler();
                    $popoversCreated = $popoversCreated.add($content);
                }
            });

            // Add active class after a delay to give it time to transition
            setTimeout(function () {
                $popoversCreated.addClass("active");
            }, settings.popoverCreateDelay);

            return $popoversCreated;
        };


        // FUNCTION ----
        // bindScrollHandler

        // PURPOSE -----
        // Prevents scrolling of the page when you reach the top/ bottom
        // of scrolling a scrollable popover

        // IN ----------
        // Run on popover(s) that are to have the event bound

        // SOURCE ------
        // adapted from: http://stackoverflow.com/questions/16323770/stop-page-from-scrolling-if-hovering-div

        $.fn.bindScrollHandler = function () {
            // Don't even bother checking if option is set to false
            if (!settings.preventPageScroll) { return; }

            $(this).on("DOMMouseScroll mousewheel", function (e) {

                var $this = $(this),
                    scrollTop = $this.scrollTop(),
                    scrollHeight = $this[0].scrollHeight,
                    height = parseInt($this.css("height")),
                    $popover = $this.closest(".timelypop-content");

                // Fix for Safari 7 not properly calculating scrollHeight()
                // Just add the class as soon as there is any scrolling
                if ($this.scrollTop() > 0 && $this.scrollTop() < 10) {
                    $popover.addClass("scrollable");
                }

                // Return if the element isn't scrollable
                if (!$popover.hasClass("scrollable")) { return; }

                var delta = (e.type == 'DOMMouseScroll' ?
                             e.originalEvent.detail * -40 :
                             e.originalEvent.wheelDelta), // Get the change in scroll position
                    up = delta > 0; // Decide whether the scroll was up or down

                var prevent = function () {
                    e.stopPropagation();
                    e.preventDefault();
                    e.returnValue = false;
                    return false;
                };

                if (!up && -delta > scrollHeight - height - scrollTop) {

                    // Scrolling down, but this will take us past the bottom.
                    $this.scrollTop(scrollHeight);
                    $popover.addClass("fully-scrolled"); // Give a class for removal of scroll-related styles
                    return prevent();
                } else if (up && delta > scrollTop) {

                    // Scrolling up, but this will take us past the top.
                    $this.scrollTop(0);
                    $popover.removeClass("fully-scrolled");
                    return prevent();
                } else {
                    $popover.removeClass("fully-scrolled");
                }
            });
        };



        //  ________                        __  .__               __          
        //  \______ \   ____ _____    _____/  |_|__|__  _______ _/  |_  ____  
        //   |    |  \_/ __ \\__  \ _/ ___\   __\  \  \/ /\__  \\   __\/ __ \ 
        //   |    `   \  ___/ / __ \\  \___|  | |  |\   /  / __ \|  | \  ___/ 
        //  /_______  /\___  >____  /\___  >__| |__| \_/  (____  /__|  \___  >
        //          \/     \/     \/     \/                    \/          \/ 
        //                                                                    

        // FUNCTION ----
        // unhoverFeet

        // PURPOSE -----
        // Removes the unhovered popover content if deleteOnUnhover is true

        // IN ----------
        // Event that contains the target of the mouseout event

        var unhoverFeet = function (e) {
            if (settings.deleteOnUnhover && settings.activateOnHover) {
                setTimeout(function () {
                    // If the new element is NOT a descendant of the footnote button
                    var $target = $(e.target).closest(".timelypop-content, .timelypop");
                    if ($(".timelypop:hover, .timelypop-content:hover").length < 1) {
                        removePopovers();
                    }
                }, settings.hoverDelay);
            }
        };


        // FUNCTION ----
        // escapeKeypress

        // PURPOSE -----
        // Removes all popovers on keypress

        // IN ----------
        // Event that contains the key that was pressed

        var escapeKeypress = function (e) {
            if (e.keyCode == 27) {
                removePopovers();
            }
        };


        // FUNCTION ----
        // removePopovers

        // PURPOSE -----
        // Removes/ adds appropriate classes to the footnote content and button
        // After a delay (to allow for transitions) it removes the actual footnote content

        // IN ----------
        // Selector of footnotes to deactivate and timeout before deleting actual elements

        // OUT ---------
        // Footnote buttons that were deactivated

        var removePopovers = function (popovers, timeout) {
            popovers = popovers || ".timelypop-content";
            timeout = timeout || settings.popoverDeleteDelay;
            var $buttonsClosed = $();

            $(popovers).each(function () {
                var $this = $(this);
                var footnoteId = $this.attr("data-popover-id");
                var $linkedButton = $(".timelypop[data-popover-id=\"" + footnoteId + "\"]");

                if (!$linkedButton.hasClass("changing")) {

                    $buttonsClosed = $buttonsClosed.add($linkedButton);
                    $linkedButton.removeClass("active hover-instantiated click-instantiated").addClass("changing");
                    $this.removeClass("active").addClass("disapearing");

                    // Gets rid of the footnote after the timeout
                    setTimeout(function () {
                        $this.remove();
                        $linkedButton.removeClass("changing");
                    }, timeout);
                }
            });

            return $buttonsClosed;
        };



        //  __________                           .__  __  .__               
        //  \______   \ ____ ______   ____  _____|__|/  |_|__| ____   ____  
        //   |       _// __ \\____ \ /  _ \/  ___/  \   __\  |/  _ \ /    \ 
        //   |    |   \  ___/|  |_> >  <_> )___ \|  ||  | |  (  <_> )   |  \
        //   |____|_  /\___  >   __/ \____/____  >__||__| |__|\____/|___|  /
        //          \/     \/|__|              \/                        \/ 
        //                                                                  

        // FUNCTION ----
        // repositionFeet

        // PURPOSE -----
        // Positions each footnote relative to its button

        var repositionFeet = function () {
            if (settings.positionContent) {

                $(".timelypop-content").each(function () {
                    
                    // Element Definitions
                    var $this = $(this),
                        dataIdentifier = "data-popover-id=\"" + $this.attr("data-popover-id") + "\"",
                        $contentWrapper = $this.find(".timelypop-content-wrapper"),
                        $button = $(".timelypop[" + dataIdentifier + "]"),
                            placement;

                    // Spacing Information
                    var roomLeft = roomCalc($button),
                        contentWidth = parseFloat($this.css("width")),
                        marginSize = parseFloat($this.css("margin-top")),
                        maxHeightInCSS = +($this.attr("data-timelypop-max-height")),
                        totalHeightInCSS = 2 * marginSize + maxHeightInCSS,
                        maxHeightOnScreen = 10000;

                    // Position tooltip on top if:
                    // total space on bottom is not enough to hold footnote AND
                    // top room is larger than bottom room
                    if (roomLeft.bottomRoom < totalHeightInCSS && roomLeft.topRoom > roomLeft.bottomRoom) {
                        $this.css({ "top": "auto", "bottom": roomLeft.bottomRoom + "px" }).addClass("top").removeClass("bottom");
                        maxHeightOnScreen = roomLeft.topRoom - marginSize - 15;
                        $this.css({ "transform-origin": (roomLeft.leftRelative * 100) + "% 100%" });
                    } else {
                        $this.css({ "bottom": "auto", "top": roomLeft.topRoom + "px" }).addClass("bottom").removeClass("top");
                        maxHeightOnScreen = roomLeft.bottomRoom - marginSize - 15;
                        $this.css({ "transform-origin": (roomLeft.leftRelative * 100) + "% 0%" });
                    }

                    // Sets the max height so that there is no footnote overflow
                    $this.find(".timelypop-content-wrapper").css({ "max-height": Math.min(maxHeightOnScreen, maxHeightInCSS) + "px" });

                    
                    var popLeft = (roomLeft.leftRoom - (roomLeft.leftRelative * contentWidth));
                    var adj = 0;

                    if (popLeft < 20) {
                        adj = popLeft - 2;
                        popLeft = 2;
                    }

                    // Positions the popover
                    $this.css({ "left": popLeft + "px" });

                    // Position the tooltip
                    positionTooltip($this, roomLeft.leftRelative, adj);
                    

                    // Give scrollable class if the content hight is larger than the container
                    if (parseInt($this.css("height")) < $this.find(".timelypop-content-wrapper")[0].scrollHeight) {
                        $this.addClass("scrollable");
                    }
                });
            }
        };


        // FUNCTION ----
        // positionTooltip

        // PURPOSE -----
        // Positions the tooltip at the same relative horizontal position as the button

        // IN ----------
        // Footnote popover to get the tooltip of and the relative horizontal position (as a decimal)

        var positionTooltip = function ($popover, leftRelative, leftMarg) {
            leftRelative = leftRelative || 0.5; // default to 50%
            var $tooltip = $popover.find(".timelypop-tooltip");
            if ($tooltip.length > 0) {
                $tooltip.css({ "left": leftRelative * 100 + "%" });
                if (leftMarg > 0) {
                    $tooltip.css({"margin-left": leftMarg + "px" });
                }
            }
        };


        // FUNCTION ----
        // roomCalc

        // PURPOSE -----
        // Calculates area on the top, left, bottom and right of the element
        // Also calculates the relative position to the left and top of the screen

        // IN ----------
        // Element to calculate screen position of

        // OUT ---------
        // Object containing room on all sides and top/ left relative positions
        // All measurements are relative to the middle of the element

        var roomCalc = function ($el) {
            var topLeft = { x: window.pageXOffset, y: window.pageYOffset },
                bottomRight = { x: topLeft.x + window.innerWidth, y: topLeft.y + window.innerHeight },
                zoom = window.innerHeight / document.documentElement.clientHeight;

            var elWidth = parseFloat($el.outerWidth()),
                elHeight = parseFloat($el.outerHeight()),
                w = viewportSize(),
                topRoom = $el.offset().top - $(window).scrollTop() + elHeight / 2,
                leftRoom = $el.offset().left + elWidth / 2;

            // console.log($el[0].getBoundingClientRect());

            // console.log("Window scrolltop: ", $(window).scrollTop());
            // console.log("El offset: ", $el.offset().top);

            // var $leftGuide = $("<div class='guide top-left'></div>").appendTo("body");
            // $leftGuide.css({"width": leftRoom + "px", "height": (topRoom) + "px", "top": topLeft.y*zoom + "px"});

            return {
                topRoom: Math.floor(topRoom),
                bottomRoom: Math.floor(w.height - topRoom),
                leftRoom: Math.floor(leftRoom),
                rightRoom: Math.floor(w.width - leftRoom),
                leftRelative: leftRoom / w.width,
                topRelative: topRoom / w.height
            };
        };


        // FUNCTION ----
        // viewportSize

        // PURPOSE -----
        // Calculates the height and width of the viewport

        // OUT ---------
        // Object with .width and .height properties

        var viewportSize = function () {
            var test = document.createElement("div");

            var topLeft = { x: window.pageXOffset, y: window.pageYOffset },
                bottomRight = { x: topLeft.x + window.innerWidth, y: topLeft.y + window.innerHeight },
                zoom = window.innerWidth / document.documentElement.clientWidth;

            // console.log("topLeft: x=", topLeft.x, " y=", topLeft.y);

            test.style.cssText = "position: fixed;top: 0;left: 0;bottom: 0;right: 0;";
            document.documentElement.insertBefore(test, document.documentElement.firstChild);

            var dims = { width: test.offsetWidth, height: test.offsetHeight };
            document.documentElement.removeChild(test);

            return dims;
        };



        //  __________                        __                  .__        __          
        //  \______   \_______   ____ _____  |  | ________   ____ |__| _____/  |_  ______
        //   |    |  _/\_  __ \_/ __ \\__  \ |  |/ /\____ \ /  _ \|  |/    \   __\/  ___/
        //   |    |   \ |  | \/\  ___/ / __ \|    < |  |_> >  <_> )  |   |  \  |  \___ \ 
        //   |______  / |__|    \___  >____  /__|_ \|   __/ \____/|__|___|  /__| /____  >
        //          \/              \/     \/     \/|__|                  \/          \/ 
        //                                                                               

        // FUNCTION ----
        // addBreakpoint

        // PURPOSE -----
        // Adds a breakpoint within the HTML at which a user-defined function
        // will be called. The minimum requirement is that a min/ max size is
        // provided; after that point, the footnote will stop being positioned
        // (i.e., to allow for bottom-fixed footnotes on small screens).

        // IN ----------
        // size: Size to break at. Can be simple (i.e., ">10px" or "<10em"), full
        // media query (i.e., "(max-width: 400px)"), or a MediaQueryList object.
        // deleteDelay: the delay by which to wait when closing/ reopening footnotes
        // on breakpoint changes. Defaults to settings.popoverDeleteDelay.
        // removeOpen: whether or not to close (and reopen) footnotes that are open
        // at the time the breakpoint changes. Defaults to true.
        // trueCallback: function to call when the media query is initially matched.
        // will be passed the removeOpen option and a copy of the timelyPop object.
        // falseCallback: function to call when the media query is initially not matched.
        // The same variables are passed in.

        // OUT ---------
        // Object indicating whether the breakpoint was added and, if so, the MQList object
        // and listener function.

        var addBreakpoint = function (size, deleteDelay, removeOpen,
                                trueCallback, falseCallback) {

            if (!window.matchMedia) return false;

            // Set defaults
            deleteDelay = deleteDelay || settings.popoverDeleteDelay;
            if (removeOpen === null || removeOpen !== false) removeOpen = true;

            var mql, minMax, s;

            // If they passed a string representation
            if (typeof (size) === "string") {

                // Repalce special strings with corresponding widths
                if (size.toLowerCase() === "iphone") {
                    s = "<320px";
                } else if (size.toLowerCase() === "ipad") {
                    s = "<768px";
                } else {
                    s = size;
                }

                // Check on the nature of the string (simple or full media query)
                if (s.charAt(0) === ">") {
                    minMax = "min";
                } else if (s.charAt(0) === "<") {
                    minMax = "max";
                } else {
                    minMax = null;
                }

                // Create the media query
                var query = minMax ? "(" + minMax + "-width: " + s.substring(1) + ")" : s;
                mql = window.matchMedia(query);

            } else {

                // Assumption is that a MediaQueryList object was passed.
                mql = size;
            }

            // If a non-MQList object is passed on the media is invalid
            if (mql.media && mql.media === "invalid") return {
                added: false,
                mq: mql,
                listener: null
            };

            // Determine whether to close/ remove popovers on the true/false callbacks
            var trueDefaultPositionSetting = minMax === "min",
                falseDefaultPositionSetting = minMax === "max";

            // Create default trueCallback
            trueCallback = trueCallback ||
                            makeDefaultCallbacks(
                                removeOpen, deleteDelay,
                                trueDefaultPositionSetting, function ($popover) {
                                    $popover.addClass("fixed-bottom");
                                }
                            );

            // Create default falseCallback
            falseCallback = falseCallback ||
                            makeDefaultCallbacks(
                                removeOpen, deleteDelay,
                                falseDefaultPositionSetting, function () { }
                            );

            // MQ Listener function
            var mqListener = function (mq) {
                if (mq.matches) {
                    trueCallback(removeOpen, timelyPop);
                } else {
                    falseCallback(removeOpen, timelyPop);
                }
            };

            // Attach listener and call it for the initial match/ non-match
            if (!mql.addListener) return false;
            mql.addListener(mqListener);
            mqListener(mql);

            // Add to the breakpoints setting
            settings.breakpoints[size] = {
                added: true,
                mq: mql,
                listener: mqListener
            };

            return settings.breakpoints[size];

        };


        // FUNCTION ----
        // makeDefaultCallbacks

        // PURPOSE -----
        // Creates the default callbacks to attach to the MQ events.

        // IN ----------
        // See above for the first three variables.
        // callback: The function to be assigned to the "activateCallback" setting
        // (called when creating new footnotes)

        // OUT ---------
        // Default MQ matches/ non-matches function.

        var makeDefaultCallbacks = function (removeOpen, deleteDelay, positioningBool, callback) {
            return function (removeOpen, timelyPop) {
                var $closedPopovers;

                if (removeOpen) {
                    $closedPopovers = timelyPop.close();
                    timelyPop.updateSetting("activateCallback", callback);
                }
                setTimeout(function () {
                    timelyPop.updateSetting("positionContent", positioningBool);
                  //  if (removeOpen) timelyPop.activate($closedPopovers);
                }, deleteDelay);
            };
        };


        // FUNCTION ----
        // removeBreakpoint

        // PURPOSE -----
        // Removes a previously-created breakpoint, calling the false condition
        // before doing so (or, a user-provided function instead).

        // IN ----------
        // target: the media query to remove, either by passing the string used to create
        // the breakpoint initially, or by passing the associated MediaQueryList object.
        // callback: the (optional) function to call before removing the listener.

        // OUT ---------
        // true if a media query was found and deleted, false otherwise.

        var removeBreakpoint = function (target, callback) {
            var mq = null,
                b, mqFound = false;
            if (typeof (target) === "string") {
                mqFound = settings.breakpoints[target] !== undefined;
            } else {
                for (b in settings.breakpoints) {
                    if (settings.breakpoints.hasOwnProperty(b) && settings.breakpoints[b].mq === target) {
                        mqFound = true;
                        break;
                    }
                }
            }

            if (mqFound) {
                var breakpoint = settings.breakpoints[b || target];
                // Calls the non-matching callback one last time
                if (callback) {
                    callback({ matches: false });
                } else {
                    breakpoint.listener({ matches: false });
                }
                breakpoint.mq.removeListener(breakpoint.listener);
                delete settings.breakpoints[b || target];
            }

            return mqFound;
        };



        //  ________   __  .__                  
        //  \_____  \_/  |_|  |__   ___________ 
        //   /   |   \   __\  |  \_/ __ \_  __ \
        //  /    |    \  | |   Y  \  ___/|  | \/
        //  \_______  /__| |___|  /\___  >__|   
        //          \/          \/     \/       
        //                                      

        // FUNCTION ----
        // updateSetting

        // PURPOSE -----
        // Updates the specified setting(s) with the value(s) you pass

        // IN ----------
        // Setting to adjust and new value for the setting (or an object
        // with all setting-new value pairs)

        // OUT ---------
        // Returns the old value for the setting (or an object with old settings
        // for each assigned property, if more than one were set)

        var updateSetting = function (newSettings, value) {

            var oldValue;

            if (typeof (newSettings) === "string") {

                oldValue = settings[newSettings];
                settings[newSettings] = value;

            } else {

                oldValue = {};

                for (var prop in newSettings) {
                    if (newSettings.hasOwnProperty(prop)) {
                        oldValue[prop] = settings[prop];
                        settings[prop] = newSettings[prop];
                    }
                }

            }

            return oldValue;
        };


        // FUNCTION ----
        // getSetting

        // PURPOSE -----
        // Returns the settings object

        var getSetting = function (setting) {

            return settings[setting];
        };



        //  __________.__            .___.__                
        //  \______   \__| ____    __| _/|__| ____    ____  
        //   |    |  _/  |/    \  / __ | |  |/    \  / ___\ 
        //   |    |   \  |   |  \/ /_/ | |  |   |  \/ /_/  >
        //   |______  /__|___|  /\____ | |__|___|  /\___  / 
        //          \/        \/      \/         \//_____/  
        //                                                  

        $(document).ready(function () {

            timelyPopInit();

            $(document).off('.timelypop');
            $(document).on("mouseenter.timelypop", ".timelypop", buttonHover);
            $(document).on("touchend.timelypop click.timelypop", touchClick);
            $(document).on("mouseout.timelypop", ".hover-instantiated", unhoverFeet);

            $(document).on("keyup.timelypop", escapeKeypress);
            $(window).on("scroll.timelypop resize.timelypop", repositionFeet);
        });



        //  __________        __                       
        //  \______   \ _____/  |_ __ _________  ____  
        //   |       _// __ \   __\  |  \_  __ \/    \ 
        //   |    |   \  ___/|  | |  |  /|  | \/   |  \
        //   |____|_  /\___  >__| |____/ |__|  |___|  /
        //          \/     \/                       \/ 
        //                                             

        timelyPop = {
            close: function (footnotes, timeout) {
                return removePopovers(footnotes, timeout);
            },
            activate: function (button) {
                return createPopover(button);
            },
            reposition: function () {
                return repositionFeet();
            },
            addBreakpoint: function (size, deleteDelay, removeOpen, trueCallback, falseCallback) {
                return addBreakpoint(size, deleteDelay, removeOpen, trueCallback, falseCallback);
            },
            removeBreakpoint: function (target, callback) {
                return removeBreakpoint(target, callback);
            },
            getSetting: function (setting) {
                return getSetting(setting);
            },
            updateSetting: function (setting, newValue) {
                return updateSetting(setting, newValue);
            }
        };

        return timelyPop;
    };

})(jQuery);
/*
 * jQuery showLoading plugin v1.0
 * 
 * Copyright (c) 2009 Jim Keller
 * Context - http://www.contextllc.com
 * 
 * Dual licensed under the MIT and GPL licenses.
 *
 */

jQuery.fn.showLoading = function (options) {

    var indicatorID;
    var settings = {
        'addClass': '',
        'beforeShow': '',
        'afterShow': '',
        'hPos': 'center',
        'vPos': 'center',
        'indicatorZIndex': 5001,
        'overlayZIndex': 5000,
        'parent': '',
        'marginTop': 0,
        'marginLeft': 0,
        'overlayWidth': null,
        'overlayHeight': null,
        'overlayClass': ''

    };

    jQuery.extend(settings, options);

    var loadingDiv = jQuery('<div></div>');
    var loadingDivInner = jQuery('<svg class="circular" viewBox="25 25 50 50"><circle class="path" cx="50" cy="50" r="20" fill="none" stroke-width="2" stroke-miterlimit="10"/></svg>');
    var overlayDiv = jQuery('<div></div>').addClass(settings.overlayClass);

    //
    // Set up ID and classes
    //
    if (settings.indicatorID) {
        indicatorID = settings.indicatorID;
    }
    else {
        indicatorID = jQuery(this).attr('id');
    }

    jQuery(loadingDiv).attr('id', 'loading-indicator-' + indicatorID);
    jQuery(loadingDiv).addClass('loading-indicator');

    if (settings.addClass) {
        jQuery(loadingDiv).addClass(settings.addClass);
    }

    if (!$.timelyBrowser.msie || $.timelyBrowser.version > 9) {
        loadingDiv.addClass('fancy');
    }



    //
    // Create the overlay
    //
    jQuery(overlayDiv).css('display', 'none');

    // Append to body, otherwise position() doesn't work on Webkit-based browsers
    jQuery(document.body).append(overlayDiv);

    //
    // Set overlay classes
    //
    jQuery(overlayDiv).attr('id', 'loading-indicator-' + indicatorID + '-overlay');

    jQuery(overlayDiv).addClass('loading-indicator-overlay');

    if (settings.addClass) {
        jQuery(overlayDiv).addClass(settings.addClass + '-overlay');
    }

    //
    // Set overlay position
    //

    var overlay_width;
    var overlay_height;

    var border_top_width = jQuery(this).css('border-top-width');
    var border_left_width = jQuery(this).css('border-left-width');

    //
    // IE will return values like 'medium' as the default border, 
    // but we need a number
    //
    border_top_width = isNaN(parseInt(border_top_width)) ? 0 : border_top_width;
    border_left_width = isNaN(parseInt(border_left_width)) ? 0 : border_left_width;

    var overlay_left_pos = jQuery(this).offset().left + parseInt(border_left_width);
    var overlay_top_pos = jQuery(this).offset().top + parseInt(border_top_width);

    if (settings.overlayWidth !== null) {
        overlay_width = settings.overlayWidth;
    }
    else {
        overlay_width = parseInt(jQuery(this).width()) + parseInt(jQuery(this).css('padding-right')) + parseInt(jQuery(this).css('padding-left'));
    }

    if (settings.overlayHeight !== null) {
        overlay_height = settings.overlayWidth;
    }
    else {
        overlay_height = parseInt(jQuery(this).height()) + parseInt(jQuery(this).css('padding-top')) + parseInt(jQuery(this).css('padding-bottom'));
    }


    jQuery(overlayDiv).css('width', overlay_width.toString() + 'px');
    jQuery(overlayDiv).css('height', overlay_height.toString() + 'px');

    jQuery(overlayDiv).css('left', overlay_left_pos.toString() + 'px');
    jQuery(overlayDiv).css('position', 'absolute');

    jQuery(overlayDiv).css('top', overlay_top_pos.toString() + 'px');
    jQuery(overlayDiv).css('z-index', settings.overlayZIndex);

    //
    // Set any custom overlay CSS		
    //
    if (settings.overlayCSS) {
        jQuery(overlayDiv).css(settings.overlayCSS);
    }


    //
    // We have to append the element to the body first
    // or .width() won't work in Webkit-based browsers (e.g. Chrome, Safari)
    //
    jQuery(loadingDiv).css('display', 'none');
    loadingDiv.append(loadingDivInner);
    jQuery(document.body).append(loadingDiv);

    jQuery(loadingDiv).css('position', 'absolute');
    jQuery(loadingDiv).css('z-index', settings.indicatorZIndex);

    //
    // Set top margin
    //

    var indicatorTop = overlay_top_pos;

    if (settings.marginTop) {
        indicatorTop += parseInt(settings.marginTop);
    }

    var indicatorLeft = overlay_left_pos;

    if (settings.marginLeft) {
        indicatorLeft += parseInt(settings.marginTop);
    }


    //
    // set horizontal position
    //
    if (settings.hPos.toString().toLowerCase() == 'center') {
        jQuery(loadingDiv).css('left', (indicatorLeft + ((jQuery(overlayDiv).width() - parseInt(jQuery(loadingDiv).width())) / 2)).toString() + 'px');
    }
    else if (settings.hPos.toString().toLowerCase() == 'left') {
        jQuery(loadingDiv).css('left', (indicatorLeft + parseInt(jQuery(overlayDiv).css('margin-left'))).toString() + 'px');
    }
    else if (settings.hPos.toString().toLowerCase() == 'right') {
        jQuery(loadingDiv).css('left', (indicatorLeft + (jQuery(overlayDiv).width() - parseInt(jQuery(loadingDiv).width()))).toString() + 'px');
    }
    else {
        jQuery(loadingDiv).css('left', (indicatorLeft + parseInt(settings.hPos)).toString() + 'px');
    }

    //
    // set vertical position
    //
    if (settings.vPos.toString().toLowerCase() == 'center') {
        jQuery(loadingDiv).css('top', (indicatorTop + ((jQuery(overlayDiv).height() - parseInt(jQuery(loadingDiv).height())) / 2)).toString() + 'px');
    }
    else if (settings.vPos.toString().toLowerCase() == 'top') {
        jQuery(loadingDiv).css('top', indicatorTop.toString() + 'px');
    }
    else if (settings.vPos.toString().toLowerCase() == 'bottom') {
        jQuery(loadingDiv).css('top', (indicatorTop + (jQuery(overlayDiv).height() - parseInt(jQuery(loadingDiv).height()))).toString() + 'px');
    }
    else {
        jQuery(loadingDiv).css('top', (indicatorTop + parseInt(settings.vPos)).toString() + 'px');
    }




    //
    // Set any custom css for loading indicator
    //
    if (settings.css) {
        jQuery(loadingDiv).css(settings.css);
    }


    //
    // Set up callback options
    //
    var callback_options =
        {
            'overlay': overlayDiv,
            'indicator': loadingDiv,
            'element': this
        };

    //
    // beforeShow callback
    //
    if (typeof (settings.beforeShow) == 'function') {
        settings.beforeShow(callback_options);
    }

    //
    // Show the overlay
    //
    jQuery(overlayDiv).show();

    //
    // Show the loading indicator
    //
    jQuery(loadingDiv).show();

    //
    // afterShow callback
    //
    if (typeof (settings.afterShow) == 'function') {
        settings.afterShow(callback_options);
    }

    return this;
};


jQuery.fn.hideLoading = function (options) {


    var settings = {};

    jQuery.extend(settings, options);

    if (settings.indicatorID) {
        indicatorID = settings.indicatorID;
    }
    else {
        indicatorID = jQuery(this).attr('id');
    }

    jQuery(document.body).find('#loading-indicator-' + indicatorID).remove();
    jQuery(document.body).find('#loading-indicator-' + indicatorID + '-overlay').remove();

    return this;
};

/*! jstz - v1.0.5 - 2013-03-18 */
(function (e) { var t = function () { "use strict"; var e = "s", n = function (e) { var t = -e.getTimezoneOffset(); return t !== null ? t : 0 }, r = function (e, t, n) { var r = new Date; return e !== undefined && r.setFullYear(e), r.setDate(n), r.setMonth(t), r }, i = function (e) { return n(r(e, 0, 2)) }, s = function (e) { return n(r(e, 5, 2)) }, o = function (e) { var t = e.getMonth() > 7 ? s(e.getFullYear()) : i(e.getFullYear()), r = n(e); return t - r !== 0 }, u = function () { var t = i(), n = s(), r = i() - s(); return r < 0 ? t + ",1" : r > 0 ? n + ",1," + e : t + ",0" }, a = function () { var e = u(); return new t.TimeZone(t.olson.timezones[e]) }, f = function (e) { var t = new Date(2010, 6, 15, 1, 0, 0, 0), n = { "America/Denver": new Date(2011, 2, 13, 3, 0, 0, 0), "America/Mazatlan": new Date(2011, 3, 3, 3, 0, 0, 0), "America/Chicago": new Date(2011, 2, 13, 3, 0, 0, 0), "America/Mexico_City": new Date(2011, 3, 3, 3, 0, 0, 0), "America/Asuncion": new Date(2012, 9, 7, 3, 0, 0, 0), "America/Santiago": new Date(2012, 9, 3, 3, 0, 0, 0), "America/Campo_Grande": new Date(2012, 9, 21, 5, 0, 0, 0), "America/Montevideo": new Date(2011, 9, 2, 3, 0, 0, 0), "America/Sao_Paulo": new Date(2011, 9, 16, 5, 0, 0, 0), "America/Los_Angeles": new Date(2011, 2, 13, 8, 0, 0, 0), "America/Santa_Isabel": new Date(2011, 3, 5, 8, 0, 0, 0), "America/Havana": new Date(2012, 2, 10, 2, 0, 0, 0), "America/New_York": new Date(2012, 2, 10, 7, 0, 0, 0), "Asia/Beirut": new Date(2011, 2, 27, 1, 0, 0, 0), "Europe/Helsinki": new Date(2011, 2, 27, 4, 0, 0, 0), "Europe/Istanbul": new Date(2011, 2, 28, 5, 0, 0, 0), "Asia/Damascus": new Date(2011, 3, 1, 2, 0, 0, 0), "Asia/Jerusalem": new Date(2011, 3, 1, 6, 0, 0, 0), "Asia/Gaza": new Date(2009, 2, 28, 0, 30, 0, 0), "Africa/Cairo": new Date(2009, 3, 25, 0, 30, 0, 0), "Pacific/Auckland": new Date(2011, 8, 26, 7, 0, 0, 0), "Pacific/Fiji": new Date(2010, 11, 29, 23, 0, 0, 0), "America/Halifax": new Date(2011, 2, 13, 6, 0, 0, 0), "America/Goose_Bay": new Date(2011, 2, 13, 2, 1, 0, 0), "America/Miquelon": new Date(2011, 2, 13, 5, 0, 0, 0), "America/Godthab": new Date(2011, 2, 27, 1, 0, 0, 0), "Europe/Moscow": t, "Asia/Yekaterinburg": t, "Asia/Omsk": t, "Asia/Krasnoyarsk": t, "Asia/Irkutsk": t, "Asia/Yakutsk": t, "Asia/Vladivostok": t, "Asia/Kamchatka": t, "Europe/Minsk": t, "Australia/Perth": new Date(2008, 10, 1, 1, 0, 0, 0) }; return n[e] }; return { determine: a, date_is_dst: o, dst_start_for: f } }(); t.TimeZone = function (e) { "use strict"; var n = { "America/Denver": ["America/Denver", "America/Mazatlan"], "America/Chicago": ["America/Chicago", "America/Mexico_City"], "America/Santiago": ["America/Santiago", "America/Asuncion", "America/Campo_Grande"], "America/Montevideo": ["America/Montevideo", "America/Sao_Paulo"], "Asia/Beirut": ["Asia/Beirut", "Europe/Helsinki", "Europe/Istanbul", "Asia/Damascus", "Asia/Jerusalem", "Asia/Gaza"], "Pacific/Auckland": ["Pacific/Auckland", "Pacific/Fiji"], "America/Los_Angeles": ["America/Los_Angeles", "America/Santa_Isabel"], "America/New_York": ["America/Havana", "America/New_York"], "America/Halifax": ["America/Goose_Bay", "America/Halifax"], "America/Godthab": ["America/Miquelon", "America/Godthab"], "Asia/Dubai": ["Europe/Moscow"], "Asia/Dhaka": ["Asia/Yekaterinburg"], "Asia/Jakarta": ["Asia/Omsk"], "Asia/Shanghai": ["Asia/Krasnoyarsk", "Australia/Perth"], "Asia/Tokyo": ["Asia/Irkutsk"], "Australia/Brisbane": ["Asia/Yakutsk"], "Pacific/Noumea": ["Asia/Vladivostok"], "Pacific/Tarawa": ["Asia/Kamchatka"], "Africa/Johannesburg": ["Asia/Gaza", "Africa/Cairo"], "Asia/Baghdad": ["Europe/Minsk"] }, r = e, i = function () { var e = n[r], i = e.length, s = 0, o = e[0]; for (; s < i; s += 1) { o = e[s]; if (t.date_is_dst(t.dst_start_for(o))) { r = o; return } } }, s = function () { return typeof n[r] != "undefined" }; return s() && i(), { name: function () { return r } } }, t.olson = {}, t.olson.timezones = { "-720,0": "Pacific/Majuro", "-660,0": "Pacific/Pago_Pago", "-600,1": "America/Adak", "-600,0": "Pacific/Honolulu", "-570,0": "Pacific/Marquesas", "-540,0": "Pacific/Gambier", "-540,1": "America/Anchorage", "-480,1": "America/Los_Angeles", "-480,0": "Pacific/Pitcairn", "-420,0": "America/Phoenix", "-420,1": "America/Denver", "-360,0": "America/Guatemala", "-360,1": "America/Chicago", "-360,1,s": "Pacific/Easter", "-300,0": "America/Bogota", "-300,1": "America/New_York", "-270,0": "America/Caracas", "-240,1": "America/Halifax", "-240,0": "America/Santo_Domingo", "-240,1,s": "America/Santiago", "-210,1": "America/St_Johns", "-180,1": "America/Godthab", "-180,0": "America/Argentina/Buenos_Aires", "-180,1,s": "America/Montevideo", "-120,0": "America/Noronha", "-120,1": "America/Noronha", "-60,1": "Atlantic/Azores", "-60,0": "Atlantic/Cape_Verde", "0,0": "UTC", "0,1": "Europe/London", "60,1": "Europe/Berlin", "60,0": "Africa/Lagos", "60,1,s": "Africa/Windhoek", "120,1": "Asia/Beirut", "120,0": "Africa/Johannesburg", "180,0": "Asia/Baghdad", "180,1": "Europe/Moscow", "210,1": "Asia/Tehran", "240,0": "Asia/Dubai", "240,1": "Asia/Baku", "270,0": "Asia/Kabul", "300,1": "Asia/Yekaterinburg", "300,0": "Asia/Karachi", "330,0": "Asia/Kolkata", "345,0": "Asia/Kathmandu", "360,0": "Asia/Dhaka", "360,1": "Asia/Omsk", "390,0": "Asia/Rangoon", "420,1": "Asia/Krasnoyarsk", "420,0": "Asia/Jakarta", "480,0": "Asia/Shanghai", "480,1": "Asia/Irkutsk", "525,0": "Australia/Eucla", "525,1,s": "Australia/Eucla", "540,1": "Asia/Yakutsk", "540,0": "Asia/Tokyo", "570,0": "Australia/Darwin", "570,1,s": "Australia/Adelaide", "600,0": "Australia/Brisbane", "600,1": "Asia/Vladivostok", "600,1,s": "Australia/Sydney", "630,1,s": "Australia/Lord_Howe", "660,1": "Asia/Kamchatka", "660,0": "Pacific/Noumea", "690,0": "Pacific/Norfolk", "720,1,s": "Pacific/Auckland", "720,0": "Pacific/Tarawa", "765,1,s": "Pacific/Chatham", "780,0": "Pacific/Tongatapu", "780,1,s": "Pacific/Apia", "840,0": "Pacific/Kiritimati" }, typeof exports != "undefined" ? exports.jstz = t : e.jstz = t })(this);

/*
* Change tracker
* Detects and keeps a count of all the changed that have happened to the form
* elements that match the passed in selector. Allows for a function to be run
* everytime a change is detected
*
* Usage:
* $('.container-of-elements-to-be-tracked').changeTracker(options)
*
* Options:
* selector = the selector string that determines what elements should be monitored for changes
* eventsToWatch = what events represent a change that should be tracked
* onChange = a function to be run every time a change is detected
*
* Depends:
*   jquery.ui.core.js
*   jquery.ui.widget.js
*/

(function ($) {
    
    

    $.widget("timely.changeTracker", {
        options: {
            selector: 'input, textarea, select',
            eventsToWatch: 'keydown change click',
            onChange: function (changedElement) {
            }
        },

        _create: function () {

            var self = this,
            options = self.options;
            self.container = self.element;
            self.changes = 0;
       
            self.container.on(options.eventsToWatch, options.selector, function () {
                self.changes++;
                options.onChange(this);
            });

        },
        
        hasChanged: function () {
            var self = this;
            return self.changes > 0;
        },

        destroy: function () {
            this._trigger("destroy", { type: "destroy" }, { options: this.options });
            $.Widget.prototype.destroy.call(this);
        },

        _setOption: function (key, value) {
            $.Widget.prototype._setOption.apply(this, arguments);
        }

    });

})(jQuery);

/*
 * 	Character Count Plugin - jQuery plugin
 * 	Dynamic character count for text areas and input fields
 *	written by Alen Grakalic	
 *	http://cssglobe.com/post/7161/jquery-plugin-simplest-twitterlike-dynamic-character-count-for-textareas
 *
 *	Copyright (c) 2009 Alen Grakalic (http://cssglobe.com)
 *	Dual licensed under the MIT (MIT-LICENSE.txt)
 *	and GPL (GPL-LICENSE.txt) licenses.
 *
 *	Built for jQuery library
 *	http://jquery.com
 *
 */
 
(function($) {

	$.fn.charCount = function(options){
	  
		// default configuration properties
		var defaults = {	
			allowed: 140,		
			warning: 25,
			css: 'counter',
			counterElement: 'span',
			cssWarning: 'warning',
			cssExceeded: 'exceeded',
			counterText: ''
		}; 
			
		var options = $.extend(defaults, options); 
		
		function calculate(obj){
		    var count = $(obj).val().replace(/\r(?!\n)|\n(?!\r)/g, "\r\n").length;
			var available = options.allowed - count;
			if(available <= options.warning && available >= 0){
				$(obj).next().addClass(options.cssWarning);
			} else {
				$(obj).next().removeClass(options.cssWarning);
			}
			if(available < 0){
				$(obj).next().addClass(options.cssExceeded);
			} else {
				$(obj).next().removeClass(options.cssExceeded);
			}
			$(obj).next().html(options.counterText + available);
		};
				
		this.each(function() {  			
		    $(this).after('<' + options.counterElement + ' style="font-size: 12px;" class="' + options.css + '">' + options.counterText + '</' + options.counterElement + '>');
			calculate(this);
			$(this).keyup(function(){calculate(this)});
			$(this).change(function(){calculate(this)});
		});
	  
	};

})(jQuery);

/*
* Handles expander elements
*/
(function ($) {
    $(document).on('click', '.expander__more', function(e) {
        e.preventDefault();
        var link = $(this);
        link.closest('.expander').addClass('expander--expanded');
    });
    $(document).on('click', '.expander__less', function (e) {
        e.preventDefault();
        var link = $(this);
        link.closest('.expander').removeClass('expander--expanded');
    });
})(jQuery);


            
