text: /*
  *
  * jQuery listnav plugin
  * Original Version Copyright iHwy, Jack Killpatrick
  *
  * Dual licensed under the MIT and GPL licenses:
  *   http://www.opensource.org/licenses/mit-license.php
  *   http://www.gnu.org/licenses/gpl.html
  *
  *
  * Version 2.3 (01/04/13)
  * Author: Eric Steinborn
  * Compatibility:
  * jQuery 1.3.x through 1.9.1
  * This is confirmed compatible with IE6+, FF, Chrome & Safari
  * CSS is a little wonky in IE6, just set your listnav class to be 100% width and it works fine.
  *
  * ListNav will create an alphabetical navigation above your list that you can click on to filter
  * your list items and will hide the other letters.
  *
  */
  (function ($) {
  
      $.fn.listnav = function (options) {
  
          var opts = $.extend({}, $.fn.listnav.defaults, options),
              letters = ['_', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '-'],
              firstClick = false;
  
          opts.prefixes = $.map(opts.prefixes, function (n) {
  
              return n.toLowerCase();
  
          });
  
          return this.each(function () {
  
              var $wrapper, $letters, $letterCount,
                  id = this.id,
                  $list = $(this),
                  counts = {},
                  allCount = 0,
                  isAll = true,
                  prevLetter = '';
  
              if ( !$('#' + id + '-nav').length ) {
  
                  $('<div id="' + id + '-nav" class="listNav"/>').insertBefore($list);
                  // Insert the nav if its not been inserted already (preferred method)
                  // Legacy method was to add the nav yourself in HTML, I didn't like that requirement
  
              }
  
              $wrapper = $('#' + id + '-nav');
              // <ul id="myList"> for list and <div id="myList-nav"> for nav wrapper
  
              function init() {
  
                  $wrapper.append(createLettersHtml());
  
                  $letters = $('.ln-letters', $wrapper).slice(0, 1);
  
                  if ( opts.showCounts ) {
  
                      $letterCount = $('.ln-letter-count', $wrapper).slice(0, 1);
  
                  }
  
                  addClasses();
  
                  addNoMatchLI();
  
                  bindHandlers();
  
                  if (opts.flagDisabled) {
  
                      addDisabledClass();
  
                  }
  
                  // remove nav items we don't need
  
                  if ( !opts.includeAll ) {
  
                      $('.all', $letters).remove();
  
                  }
                  if ( !opts.includeNums ) {
  
                      $('._', $letters).remove();
  
                  }
                  if ( !opts.includeOther ) {
  
                      $('.-', $letters).remove();
  
                  }
                  if ( opts.removeDisabled ) {
  
                      $('.ln-disabled', $letters).remove();
  
                  }
  
                  $(':last', $letters).addClass('ln-last');
  
                  if ( $.cookie && (opts.cookieName !== null) ) {
  
                      var cookieLetter = $.cookie(opts.cookieName);
  
                      if ( cookieLetter !== null ) {
  
                          opts.initLetter = cookieLetter;
  
                      }
  
                  }
  
                  // decide what to show first
  
                  // Is there an initLetter set, if so, show that letter first
                  if ( opts.initLetter !== '' ) {
  
                      firstClick = true;
  
                      // click the initLetter if there was one
                      $('.' + opts.initLetter.toLowerCase(), $letters).slice(0, 1).click();
  
                  } else {
  
                      // If no init letter is set, and you included All, then show it
                      if ( opts.includeAll ) {
  
                          // make the All link look clicked, but don't actually click it
                          $('.all', $letters).addClass('ln-selected');
  
                      } else {
  
                          // All was not included, lets find the first letter with a count and show it
                          for ( var i = ((opts.includeNums) ? 0 : 1); i < letters.length; i++) {
  
                              if ( counts[letters[i]] > 0 ) {
  
                                  firstClick = true;
  
                                  $('.' + letters[i], $letters).slice(0, 1).click();
  
                                  break;
  
                              }
                          }
                      }
                  }
              }
  
              // position the letter count above the letter links
              function setLetterCountTop() {
  
                  // we're going to need to subtract this from the top value of the wrapper to accomodate changes in font-size in CSS.
                  var letterCountHeight = $letterCount.outerHeight();
  
                  $letterCount.css({
                      top: $('a:first', $wrapper).slice(0, 1).position().top - letterCountHeight
                      // we're going to grab the first anchor in the list
                      // We can no longer guarantee that a specific letter will be present
                      // since adding the "removeDisabled" option
  
                  });
  
              }
  
              // adds a class to each LI that has text content inside of it (ie, inside an <a>, a <div>, nested DOM nodes, etc)
              function addClasses() {
  
                  var str, spl, $this,
                      firstChar = '',
                      hasPrefixes = (opts.prefixes.length > 0),
                      hasFilterSelector = (opts.filterSelector.length > 0);
  
                  // Iterate over the list and set a class on each one and use that to filter by
                  $($list).children().each(function () {
  
                      $this = $(this);
  
                      // I'm assuming you didn't choose a filterSelector, hopefully saving some cycles
                      if ( !hasFilterSelector ) {
  
                          //Grab the first text content of the LI, we'll use this to filter by
                          str = $.trim($this.text()).toLowerCase();
  
                      } else {
  
                          // You set a filterSelector so lets find it and use that to search by instead
                          str = $.trim($this.find(opts.filterSelector).text()).toLowerCase();
  
                      }
  
                      // This will run only if there is something to filter by, skipping over images and non-filterable content.
                      if (str !== '') {
  
                          // Apply the non-prefix class to LIs that have prefixed content in them
                          if (hasPrefixes) {
                                                          var prefixes = $.map(opts.prefixes, function(value) {
                                                                  return value.indexOf(' ') <= 0 ? value + ' ' : value;
                                                          });
                                                          var matches = $.grep(prefixes, function(value) {
                                                                  return str.indexOf(value) === 0;
                                                          });
                                                          if (matches.length > 0) {
                                                                  var afterMatch = str.toLowerCase().split(matches[0])[1];
                                                                  if(afterMatch != null) {
                                                                          firstChar = $.trim(afterMatch).charAt(0);
                                                                  } else {
                                                                          firstChar = str.charAt(0);
                                                                  }
                                                                  addLetterClass(firstChar, $this, true);
                                                                  return;
                              }
                                                  }
                                                  // Find the first letter in the LI, including prefixes
                                                  firstChar = str.charAt(0);
  
                                                  // Doesn't send true to function, which will ++ the All count on prefixed items
                                                  addLetterClass(firstChar, $this);
                      }
                  });
              }
  
              // Add the appropriate letter class to the current element
              function addLetterClass(firstChar, $el, isPrefix) {
  
                  if ( /\W/.test(firstChar) ) {
  
                      firstChar = '-'; // not A-Z, a-z or 0-9, so considered "other"
  
                  }
  
                  if ( !isNaN(firstChar) ) {
  
                      firstChar = '_'; // use '_' if the first char is a number
  
                  }
  
                  $el.addClass('ln-' + firstChar);
  
                  if ( counts[firstChar] === undefined ) {
  
                      counts[firstChar] = 0;
  
                  }
  
                  counts[firstChar]++;
  
                  if (!isPrefix) {
  
                      allCount++;
  
                  }
  
              }
  
              function addDisabledClass() {
  
                  for ( var i = 0; i < letters.length; i++ ) {
  
                      if ( counts[letters[i]] === undefined ) {
  
                          $('.' + letters[i], $letters).addClass('ln-disabled');
  
                      }
                  }
              }
  
              function addNoMatchLI() {
                  $list.append('<li class="ln-no-match listNavHide">' + opts.noMatchText + '</li>');
              }
  
              function getLetterCount(el) {
                  if ($(el).hasClass('all')) {
                      return allCount;
                  } else {
                      var count = counts[$(el).attr('class').split(' ')[0]];
                      return (count !== undefined) ? count : 0; // some letters may not have a count in the hash
                  }
              }
  
              function bindHandlers() {
  
                  if (opts.showCounts) {
                      // sets the top position of the count div in case something above it on the page has resized
                      $wrapper.mouseover(function () {
                          setLetterCountTop();
                      });
  
                      //shows the count above the letter
                      //
                      $('.ln-letters a', $wrapper).mouseover(function () {
                          var left = $(this).position().left,
                              width = ($(this).outerWidth()) + 'px',
                              count = getLetterCount(this);
  
                          $letterCount.css({
                              left: left,
                              width: width
                          }).text(count).addClass("letterCountShow").removeClass("listNavHide"); // set left position and width of letter count, set count text and show it
                      }).mouseout(function () { // mouseout for each letter: hide the count
                          $letterCount.addClass("listNavHide").removeClass("letterCountShow");
                      });
                  }
  
                  // click handler for letters: shows/hides relevant LI's
                  //
                  var clickEventType=((document.ontouchstart!==null)?'click':'touchstart'); //detect if you are on a touch device easily.
                  $('a', $letters).bind(clickEventType, function (e) {
                      e.preventDefault();
                      var $this = $(this),
                          letter = $this.attr('class').split(' ')[0],
                          noMatches = $list.children('.ln-no-match');
  
                      if ( prevLetter !== letter ) {
                      // Only to run this once for each click, won't double up if they clicked the same letter
                      // Won't hinder firstRun
  
                          $('a.ln-selected', $letters).removeClass('ln-selected');
  
                          if ( letter === 'all' ) {
                              // If ALL button is clicked:
  
                              $list.children().addClass("listNavShow").removeClass("listNavHide"); // Show ALL
  
                              noMatches.addClass("listNavHide").removeClass("listNavShow"); // Hide the list item for no matches
  
                              isAll = true; // set this to quickly check later
  
                          } else {
                              // If you didn't click ALL
  
                              if ( isAll ) {
                                  // since you clicked ALL last time:
  
                                  $list.children().addClass("listNavHide").removeClass("listNavShow");
  
                                  isAll = false;
  
                              } else if (prevLetter !== '') {
  
                                  $list.children('.ln-' + prevLetter).addClass("listNavHide").removeClass("listNavShow");
  
                              }
  
                              var count = getLetterCount(this);
  
                              if (count > 0) {
                                  $list.children('.ln-' + letter).addClass("listNavShow").removeClass("listNavHide");
                                  noMatches.addClass("listNavHide").removeClass("listNavShow"); // in case it's showing
                              } else {
                                  noMatches.addClass("listNavShow").removeClass("listNavHide");
                              }
  
  
                          }
  
                          prevLetter = letter;
  
                          if ($.cookie && (opts.cookieName !== null)) {
                              $.cookie(opts.cookieName, letter, {
                                  expires: 999
                              });
                          }
  
                          $this.addClass('ln-selected');
  
                          $this.blur();
  
                          if (!firstClick && (opts.onClick !== null)) {
  
                              opts.onClick(letter);
  
                          } else {
  
                              firstClick = false; //return false;
  
                          }
  
                      } // end if prevLetter !== letter
  
                  }); // end click()
  
              } // end BindHandlers()
  
              // creates the HTML for the letter links
              //
              function createLettersHtml() {
                  var html = [];
                  for (var i = 1; i < letters.length; i++) {
                      if (html.length === 0) {
                          html.push('<a class="all" href="#">ALL</a><a class="_" href="#">0-9</a>');
                      }
                      html.push('<a class="' + letters[i] + '" href="#">' + ((letters[i] === '-') ? '...' : letters[i].toUpperCase()) + '</a>');
                  }
                  return '<div class="ln-letters">' + html.join('') + '</div>' + ((opts.showCounts) ? '<div class="ln-letter-count listNavHide">0</div>' : '');
                  // Remove inline styles, replace with css class
                  // Element will be repositioned when made visible
              }
              init();
          });
      };
  
      $.fn.listnav.defaults = {
          initLetter: '',
          includeAll: true,
          incudeOther: false,
          includeNums: true,
          flagDisabled: true,
          removeDisabled: false,
          noMatchText: 'No matching entries',
          showCounts: true,
          cookieName: null,
          onClick: null,
          prefixes: [],
          filterSelector: ''
      };
  })(jQuery);