var cookie_namespace = 'android_developer';
var isMobile = false; // true if mobile, so we can adjust some layout
var mPagePath; // initialized in ready() function

var basePath = getBaseUri(location.pathname);
var SITE_ROOT = toRoot + basePath.substring(1, basePath.indexOf("/", 1));

// Ensure that all ajax getScript() requests allow caching
$.ajaxSetup({
  cache: true
});

/******  ON LOAD SET UP STUFF *********/

$(document).ready(function() {

  // prep nav expandos
  var pagePath = document.location.pathname;
  // account for intl docs by removing the intl/*/ path
  if (pagePath.indexOf("/intl/") == 0) {
    pagePath = pagePath.substr(pagePath.indexOf("/", 6)); // start after intl/ to get last /
  }

  if (pagePath.indexOf(SITE_ROOT) == 0) {
    if (pagePath == '' || pagePath.charAt(pagePath.length - 1) == '/') {
      pagePath += 'index.html';
    }
  }

  // Need a copy of the pagePath before it gets changed in the next block;
  // it's needed to perform proper tab highlighting in offline docs (see rootDir below)
  var pagePathOriginal = pagePath;
  if (SITE_ROOT.match(/\.\.\//) || SITE_ROOT == '') {
    // If running locally, SITE_ROOT will be a relative path, so account for that by
    // finding the relative URL to this page. This will allow us to find links on the page
    // leading back to this page.
    var pathParts = pagePath.split('/');
    var relativePagePathParts = [];
    var upDirs = (SITE_ROOT.match(/(\.\.\/)+/) || [''])[0].length / 3;
    for (var i = 0; i < upDirs; i++) {
      relativePagePathParts.push('..');
    }
    for (var i = 0; i < upDirs; i++) {
      relativePagePathParts.push(pathParts[pathParts.length - (upDirs - i) - 1]);
    }
    relativePagePathParts.push(pathParts[pathParts.length - 1]);
    pagePath = relativePagePathParts.join('/');
  } else {
    // Otherwise the page path is already an absolute URL
  }

  // set global variable so we can highlight the sidenav a bit later (such as for google reference)
  // and highlight the sidenav
  mPagePath = pagePath;
  highlightSidenav();

  // set up prev/next links if they exist
  var $selNavLink = $('#nav').find('a[href="' + pagePath + '"]');
  var $selListItem;
  if ($selNavLink.length) {
    $selListItem = $selNavLink.closest('li');

    // set up prev links
    var $prevLink = [];
    var $prevListItem = $selListItem.prev('li');

    var crossBoundaries = ($("body.design").length > 0) || ($("body.guide").length > 0) ? true :
false; // navigate across topic boundaries only in design docs
    if ($prevListItem.length) {
      if ($prevListItem.hasClass('nav-section') || crossBoundaries) {
        // jump to last topic of previous section
        $prevLink = $prevListItem.find('a:last');
      } else if (!$selListItem.hasClass('nav-section')) {
        // jump to previous topic in this section
        $prevLink = $prevListItem.find('a:eq(0)');
      }
    } else {
      // jump to this section's index page (if it exists)
      var $parentListItem = $selListItem.parents('li');
      $prevLink = $selListItem.parents('li').find('a');

      // except if cross boundaries aren't allowed, and we're at the top of a section already
      // (and there's another parent)
      if (!crossBoundaries && $parentListItem.hasClass('nav-section') &&
                           $selListItem.hasClass('nav-section')) {
        $prevLink = [];
      }
    }

    // set up next links
    var $nextLink = [];
    var startClass = false;
    var isCrossingBoundary = false;

    if ($selListItem.hasClass('nav-section') && $selListItem.children('div.empty').length == 0) {
      // we're on an index page, jump to the first topic
      $nextLink = $selListItem.find('ul:eq(0)').find('a:eq(0)');

      // if there aren't any children, go to the next section (required for About pages)
      if ($nextLink.length == 0) {
        $nextLink = $selListItem.next('li').find('a');
      } else if ($('.topic-start-link').length) {
        // as long as there's a child link and there is a "topic start link" (we're on a landing)
        // then set the landing page "start link" text to be the first doc title
        $('.topic-start-link').text($nextLink.text().toUpperCase());
      }

      // If the selected page has a description, then it's a class or article homepage
      if ($selListItem.find('a[description]').length) {
        // this means we're on a class landing page
        startClass = true;
      }
    } else {
      // jump to the next topic in this section (if it exists)
      $nextLink = $selListItem.next('li').find('a:eq(0)');
      if ($nextLink.length == 0) {
        isCrossingBoundary = true;
        // no more topics in this section, jump to the first topic in the next section
        $nextLink = $selListItem.parents('li:eq(0)').next('li').find('a:eq(0)');
        if (!$nextLink.length) {  // Go up another layer to look for next page (lesson > class > course)
          $nextLink = $selListItem.parents('li:eq(1)').next('li.nav-section').find('a:eq(0)');
          if ($nextLink.length == 0) {
            // if that doesn't work, we're at the end of the list, so disable NEXT link
            $('.next-page-link').attr('href', '').addClass("disabled")
                                .click(function() { return false; });
            // and completely hide the one in the footer
            $('.content-footer .next-page-link').hide();
          }
        }
      }
    }

    if (startClass) {
      $('.start-class-link').attr('href', $nextLink.attr('href')).removeClass("hide");

      // if there's no training bar (below the start button),
      // then we need to add a bottom border to button
      if (!$("#tb").length) {
        $('.start-class-link').css({'border-bottom':'1px solid #DADADA'});
      }
    } else if (isCrossingBoundary && !$('body.design').length) {  // Design always crosses boundaries
      $('.content-footer.next-class').show();
      $('.next-page-link').attr('href', '')
                          .removeClass("hide").addClass("disabled")
                          .click(function() { return false; });
      // and completely hide the one in the footer
      $('.content-footer .next-page-link').hide();
      $('.content-footer .prev-page-link').hide();

      if ($nextLink.length) {
        $('.next-class-link').attr('href', $nextLink.attr('href'))
                             .removeClass("hide");

        $('.content-footer .next-class-link').append($nextLink.html());

        $('.next-class-link').find('.new').empty();
      }
    } else {
      $('.next-page-link').attr('href', $nextLink.attr('href'))
                          .removeClass("hide");
      // for the footer link, also add the previous and next page titles
      $('.content-footer .prev-page-link').append($prevLink.html());
      $('.content-footer .next-page-link').append($nextLink.html());
    }

    if (!startClass && $prevLink.length) {
      var prevHref = $prevLink.attr('href');
      if (prevHref == SITE_ROOT + 'index.html') {
        // Don't show Previous when it leads to the homepage
      } else {
        $('.prev-page-link').attr('href', $prevLink.attr('href')).removeClass("hide");
      }
    }

  }

  // Set up the course landing pages for Training with class names and descriptions
  if ($('body.trainingcourse').length) {
    var $classLinks = $selListItem.find('ul li a').not('#nav .nav-section .nav-section ul a');

    // create an array for all the class descriptions
    var $classDescriptions = new Array($classLinks.length);
    var lang = getLangPref();
    $classLinks.each(function(index) {
      var langDescr = $(this).attr(lang + "-description");
      if (typeof langDescr !== 'undefined' && langDescr !== false) {
        // if there's a class description in the selected language, use that
        $classDescriptions[index] = langDescr;
      } else {
        // otherwise, use the default english description
        $classDescriptions[index] = $(this).attr("description");
      }
    });

    var $olClasses  = $('<ol class="class-list"></ol>');
    var $liClass;
    var $h2Title;
    var $pSummary;
    var $olLessons;
    var $liLesson;
    $classLinks.each(function(index) {
      $liClass  = $('<li class="clearfix"></li>');
      $h2Title  = $('<a class="title" href="' + $(this).attr('href') + '"><h2 class="norule">' + $(this).html() + '</h2><span></span></a>');
      $pSummary = $('<p class="description">' + $classDescriptions[index] + '</p>');

      $olLessons  = $('<ol class="lesson-list"></ol>');

      $lessons = $(this).closest('li').find('ul li a');

      if ($lessons.length) {
        $lessons.each(function(index) {
          $olLessons.append('<li><a href="' + $(this).attr('href') + '">' + $(this).html() + '</a></li>');
        });
      } else {
        $pSummary.addClass('article');
      }

      $liClass.append($h2Title).append($pSummary).append($olLessons);
      $olClasses.append($liClass);
    });
    $('#classes').append($olClasses);
  }

  // Set up expand/collapse behavior
  initExpandableNavItems("#nav");

  // Set up play-on-hover <video> tags.
  $('video.play-on-hover').bind('click', function() {
    $(this).get(0).load(); // in case the video isn't seekable
    $(this).get(0).play();
  });

  // Set up tooltips
  var TOOLTIP_MARGIN = 10;
  $('acronym,.tooltip-link').each(function() {
    var $target = $(this);
    var $tooltip = $('<div>')
        .addClass('tooltip-box')
        .append($target.attr('title'))
        .hide()
        .appendTo('body');
    $target.removeAttr('title');

    $target.hover(function() {
      // in
      var targetRect = $target.offset();
      targetRect.width = $target.width();
      targetRect.height = $target.height();

      $tooltip.css({
        left: targetRect.left,
        top: targetRect.top + targetRect.height + TOOLTIP_MARGIN
      });
      $tooltip.addClass('below');
      $tooltip.show();
    }, function() {
      // out
      $tooltip.hide();
    });
  });

  // Set up <h2> deeplinks
  $('h2').click(function() {
    var id = $(this).attr('id');
    if (id) {
      if (history && history.replaceState) {
        // Change url without scrolling.
        history.replaceState({}, '', '#' + id);
      } else {
        document.location.hash = id;
      }
    }
  });

  //Loads the +1 button
  //var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
  //po.src = 'https://apis.google.com/js/plusone.js';
  //var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
});
// END of the onload event

function initExpandableNavItems(rootTag) {
  $(rootTag + ' li.nav-section .nav-section-header').click(function() {
    var section = $(this).closest('li.nav-section');
    if (section.hasClass('expanded')) {
      /* hide me and descendants */
      section.find('ul').slideUp(250, function() {
        // remove 'expanded' class from my section and any children
        section.closest('li').removeClass('expanded');
        $('li.nav-section', section).removeClass('expanded');
      });
    } else {
      /* show me */
      // first hide all other siblings
      var $others = $('li.nav-section.expanded', $(this).closest('ul')).not('.sticky');
      $others.removeClass('expanded').children('ul').slideUp(250);

      // now expand me
      section.closest('li').addClass('expanded');
      section.children('ul').slideDown(250);
    }
  });

  // Stop expand/collapse behavior when clicking on nav section links
  // (since we're navigating away from the page)
  // This selector captures the first instance of <a>, but not those with "#" as the href.
  $('.nav-section-header').find('a:eq(0)').not('a[href="#"]').click(function(evt) {
    window.location.href = $(this).attr('href');
    return false;
  });
}

/** Highlight the current page in sidenav, expanding children as appropriate */
function highlightSidenav() {
  // if something is already highlighted, undo it. This is for dynamic navigation (Samples index)
  if ($("ul#nav li.selected").length) {
    unHighlightSidenav();
  }
  // look for URL in sidenav, including the hash
  var $selNavLink = $('#nav').find('a[href="' + mPagePath + location.hash + '"]');

  // If the selNavLink is still empty, look for it without the hash
  if ($selNavLink.length == 0) {
    $selNavLink = $('#nav').find('a[href="' + mPagePath + '"]');
  }

  var $selListItem;
  var breadcrumb = [];

  if ($selNavLink.length) {
    // Find this page's <li> in sidenav and set selected
    $selListItem = $selNavLink.closest('li');
    $selListItem.addClass('selected');

    // Traverse up the tree and expand all parent nav-sections
    $selNavLink.parents('li.nav-section').each(function() {
      $(this).addClass('expanded');
      $(this).children('ul').show();

      var link = $(this).find('a').first();

      if (!$(this).is($selListItem)) {
        breadcrumb.unshift(link)
      }
    });

    $('#nav').scrollIntoView($selNavLink);
  }

  breadcrumb.forEach(function(link) {
    link.dacCrumbs();
  });
}

function unHighlightSidenav() {
  $("ul#nav li.selected").removeClass("selected");
  $('ul#nav li.nav-section.expanded').removeClass('expanded').children('ul').hide();
}

var agent = navigator['userAgent'].toLowerCase();
// If a mobile phone, set flag and do mobile setup
if ((agent.indexOf("mobile") != -1) ||      // android, iphone, ipod
    (agent.indexOf("blackberry") != -1) ||
    (agent.indexOf("webos") != -1) ||
    (agent.indexOf("mini") != -1)) {        // opera mini browsers
  isMobile = true;
}

$(document).ready(function() {
  $("pre:not(.no-pretty-print)").addClass("prettyprint");
  prettyPrint();
});

/* Show popup dialogs */
function showDialog(id) {
  $dialog = $("#" + id);
  $dialog.prepend('<div class="box-border"><div class="top"> <div class="left"></div> <div class="right"></div></div><div class="bottom"> <div class="left"></div> <div class="right"></div> </div> </div>');
  $dialog.wrapInner('<div/>');
  $dialog.removeClass("hide");
}

/* #########    COOKIES!     ########## */

function readCookie(cookie) {
  var myCookie = cookie_namespace + "_" + cookie + "=";
  if (document.cookie) {
    var index = document.cookie.indexOf(myCookie);
    if (index != -1) {
      var valStart = index + myCookie.length;
      var valEnd = document.cookie.indexOf(";", valStart);
      if (valEnd == -1) {
        valEnd = document.cookie.length;
      }
      var val = document.cookie.substring(valStart, valEnd);
      return val;
    }
  }
  return 0;
}

function writeCookie(cookie, val, section) {
  if (val == undefined) return;
  section = section == null ? "_" : "_" + section + "_";
  var age = 2 * 365 * 24 * 60 * 60; // set max-age to 2 years
  var cookieValue = cookie_namespace + section + cookie + "=" + val +
                    "; max-age=" + age + "; path=/";
  document.cookie = cookieValue;
}

/* #########     END COOKIES!     ########## */

/*
 * Manages secion card states and nav resize to conclude loading
 */
(function() {
  $(document).ready(function() {

    // Stack hover states
    $('.section-card-menu').each(function(index, el) {
      var height = $(el).height();
      $(el).css({height:height + 'px', position:'relative'});
      var $cardInfo = $(el).find('.card-info');

      $cardInfo.css({position: 'absolute', bottom:'0px', left:'0px', right:'0px', overflow:'visible'});
    });

  });

})();

/*      MISC LIBRARY FUNCTIONS     */

function toggle(obj, slide) {
  var ul = $("ul:first", obj);
  var li = ul.parent();
  if (li.hasClass("closed")) {
    if (slide) {
      ul.slideDown("fast");
    } else {
      ul.show();
    }
    li.removeClass("closed");
    li.addClass("open");
    $(".toggle-img", li).attr("title", "hide pages");
  } else {
    ul.slideUp("fast");
    li.removeClass("open");
    li.addClass("closed");
    $(".toggle-img", li).attr("title", "show pages");
  }
}

function buildToggleLists() {
  $(".toggle-list").each(
    function(i) {
      $("div:first", this).append("<a class='toggle-img' href='#' title='show pages' onClick='toggle(this.parentNode.parentNode, true); return false;'></a>");
      $(this).addClass("closed");
    });
}

function hideNestedItems(list, toggle) {
  $list = $(list);
  // hide nested lists
  if ($list.hasClass('showing')) {
    $("li ol", $list).hide('fast');
    $list.removeClass('showing');
  // show nested lists
  } else {
    $("li ol", $list).show('fast');
    $list.addClass('showing');
  }
  $(".more,.less", $(toggle)).toggle();
}

/* Call this to add listeners to a <select> element for Studio/Eclipse/Other docs */
function setupIdeDocToggle() {
  $("select.ide").change(function() {
    var selected = $(this).find("option:selected").attr("value");
    $(".select-ide").hide();
    $(".select-ide." + selected).show();

    $("select.ide").val(selected);
  });
}

/* Used to hide and reveal supplemental content, such as long code samples.
   See the companion CSS in android-developer-docs.css */
function toggleContent(obj) {
  var div = $(obj).closest(".toggle-content");
  var toggleMe = $(".toggle-content-toggleme:eq(0)", div);
  if (div.hasClass("closed")) { // if it's closed, open it
    toggleMe.slideDown();
    $(".toggle-content-text:eq(0)", obj).toggle();
    div.removeClass("closed").addClass("open");
    $(".toggle-content-img:eq(0)", div).attr("title", "hide").attr("src", toRoot +
                  "assets/images/triangle-opened.png");
  } else { // if it's open, close it
    toggleMe.slideUp('fast', function() {  // Wait until the animation is done before closing arrow
      $(".toggle-content-text:eq(0)", obj).toggle();
      div.removeClass("open").addClass("closed");
      div.find(".toggle-content").removeClass("open").addClass("closed")
              .find(".toggle-content-toggleme").hide();
      $(".toggle-content-img", div).attr("title", "show").attr("src", toRoot +
                  "assets/images/triangle-closed.png");
    });
  }
  return false;
}

/* New version of expandable content */
function toggleExpandable(link, id) {
  if ($(id).is(':visible')) {
    $(id).slideUp();
    $(link).removeClass('expanded');
  } else {
    $(id).slideDown();
    $(link).addClass('expanded');
  }
}

function hideExpandable(ids) {
  $(ids).slideUp();
  $(ids).prev('h4').find('a.expandable').removeClass('expanded');
}

/*
 *  Slideshow 1.0
 *  Used on /index.html and /develop/index.html for carousel
 *
 *  Sample usage:
 *  HTML -
 *  <div class="slideshow-container">
 *   <a href="" class="slideshow-prev">Prev</a>
 *   <a href="" class="slideshow-next">Next</a>
 *   <ul>
 *       <li class="item"><img src="images/marquee1.jpg"></li>
 *       <li class="item"><img src="images/marquee2.jpg"></li>
 *       <li class="item"><img src="images/marquee3.jpg"></li>
 *       <li class="item"><img src="images/marquee4.jpg"></li>
 *   </ul>
 *  </div>
 *
 *   <script type="text/javascript">
 *   $('.slideshow-container').dacSlideshow({
 *       auto: true,
 *       btnPrev: '.slideshow-prev',
 *       btnNext: '.slideshow-next'
 *   });
 *   </script>
 *
 *  Options:
 *  btnPrev:    optional identifier for previous button
 *  btnNext:    optional identifier for next button
 *  btnPause:   optional identifier for pause button
 *  auto:       whether or not to auto-proceed
 *  speed:      animation speed
 *  autoTime:   time between auto-rotation
 *  easing:     easing function for transition
 *  start:      item to select by default
 *  scroll:     direction to scroll in
 *  pagination: whether or not to include dotted pagination
 *
 */

(function($) {
  $.fn.dacSlideshow = function(o) {

    //Options - see above
    o = $.extend({
      btnPrev:   null,
      btnNext:   null,
      btnPause:  null,
      auto:      true,
      speed:     500,
      autoTime:  12000,
      easing:    null,
      start:     0,
      scroll:    1,
      pagination: true

    }, o || {});

    //Set up a carousel for each
    return this.each(function() {

      var running = false;
      var animCss = o.vertical ? "top" : "left";
      var sizeCss = o.vertical ? "height" : "width";
      var div = $(this);
      var ul = $("ul", div);
      var tLi = $("li", ul);
      var tl = tLi.size();
      var timer = null;

      var li = $("li", ul);
      var itemLength = li.size();
      var curr = o.start;

      li.css({float: o.vertical ? "none" : "left"});
      ul.css({margin: "0", padding: "0", position: "relative", "list-style-type": "none", "z-index": "1"});
      div.css({position: "relative", "z-index": "2", left: "0px"});

      var liSize = o.vertical ? height(li) : width(li);
      var ulSize = liSize * itemLength;
      var divSize = liSize;

      li.css({width: li.width(), height: li.height()});
      ul.css(sizeCss, ulSize + "px").css(animCss, -(curr * liSize));

      div.css(sizeCss, divSize + "px");

      //Pagination
      if (o.pagination) {
        var pagination = $("<div class='pagination'></div>");
        var pag_ul = $("<ul></ul>");
        if (tl > 1) {
          for (var i = 0; i < tl; i++) {
            var li = $("<li>" + i + "</li>");
            pag_ul.append(li);
            if (i == o.start) li.addClass('active');
            li.click(function() {
              go(parseInt($(this).text()));
            })
          }
          pagination.append(pag_ul);
          div.append(pagination);
        }
      }

      //Previous button
      if (o.btnPrev)
             $(o.btnPrev).click(function(e) {
               e.preventDefault();
               return go(curr - o.scroll);
             });

      //Next button
      if (o.btnNext)
             $(o.btnNext).click(function(e) {
               e.preventDefault();
               return go(curr + o.scroll);
             });

      //Pause button
      if (o.btnPause)
             $(o.btnPause).click(function(e) {
               e.preventDefault();
               if ($(this).hasClass('paused')) {
                 startRotateTimer();
               } else {
                 pauseRotateTimer();
               }
             });

      //Auto rotation
      if (o.auto) startRotateTimer();

      function startRotateTimer() {
        clearInterval(timer);
        timer = setInterval(function() {
          if (curr == tl - 1) {
            go(0);
          } else {
            go(curr + o.scroll);
          }
        }, o.autoTime);
        $(o.btnPause).removeClass('paused');
      }

      function pauseRotateTimer() {
        clearInterval(timer);
        $(o.btnPause).addClass('paused');
      }

      //Go to an item
      function go(to) {
        if (!running) {

          if (to < 0) {
            to = itemLength - 1;
          } else if (to > itemLength - 1) {
            to = 0;
          }
          curr = to;

          running = true;

          ul.animate(
              animCss == "left" ? {left: -(curr * liSize)} : {top: -(curr * liSize)} , o.speed, o.easing,
                     function() {
                       running = false;
                     }
                 );

          $(o.btnPrev + "," + o.btnNext).removeClass("disabled");
          $((curr - o.scroll < 0 && o.btnPrev)              ||
             (curr + o.scroll > itemLength && o.btnNext)              ||
             []
           ).addClass("disabled");

          var nav_items = $('li', pagination);
          nav_items.removeClass('active');
          nav_items.eq(to).addClass('active');

        }
        if (o.auto) startRotateTimer();
        return false;
      };
    });
  };

  function css(el, prop) {
    return parseInt($.css(el[0], prop)) || 0;
  };
  function width(el) {
    return el[0].offsetWidth + css(el, 'marginLeft') + css(el, 'marginRight');
  };
  function height(el) {
    return el[0].offsetHeight + css(el, 'marginTop') + css(el, 'marginBottom');
  };

})(jQuery);

/*
 *  dacSlideshow 1.0
 *  Used on develop/index.html for side-sliding tabs
 *
 *  Sample usage:
 *  HTML -
 *  <div class="slideshow-container">
 *   <a href="" class="slideshow-prev">Prev</a>
 *   <a href="" class="slideshow-next">Next</a>
 *   <ul>
 *       <li class="item"><img src="images/marquee1.jpg"></li>
 *       <li class="item"><img src="images/marquee2.jpg"></li>
 *       <li class="item"><img src="images/marquee3.jpg"></li>
 *       <li class="item"><img src="images/marquee4.jpg"></li>
 *   </ul>
 *  </div>
 *
 *   <script type="text/javascript">
 *   $('.slideshow-container').dacSlideshow({
 *       auto: true,
 *       btnPrev: '.slideshow-prev',
 *       btnNext: '.slideshow-next'
 *   });
 *   </script>
 *
 *  Options:
 *  btnPrev:    optional identifier for previous button
 *  btnNext:    optional identifier for next button
 *  auto:       whether or not to auto-proceed
 *  speed:      animation speed
 *  autoTime:   time between auto-rotation
 *  easing:     easing function for transition
 *  start:      item to select by default
 *  scroll:     direction to scroll in
 *  pagination: whether or not to include dotted pagination
 *
 */
(function($) {
  $.fn.dacTabbedList = function(o) {

    //Options - see above
    o = $.extend({
      speed : 250,
      easing: null,
      nav_id: null,
      frame_id: null
    }, o || {});

    //Set up a carousel for each
    return this.each(function() {

      var curr = 0;
      var running = false;
      var animCss = "margin-left";
      var sizeCss = "width";
      var div = $(this);

      var nav = $(o.nav_id, div);
      var nav_li = $("li", nav);
      var nav_size = nav_li.size();
      var frame = div.find(o.frame_id);
      var content_width = $(frame).find('ul').width();
      //Buttons
      $(nav_li).click(function(e) {
           go($(nav_li).index($(this)));
         })

      //Go to an item
      function go(to) {
        if (!running) {
          curr = to;
          running = true;

          frame.animate({'margin-left' : -(curr * content_width)}, o.speed, o.easing,
                     function() {
                       running = false;
                     }
                 );

          nav_li.removeClass('active');
          nav_li.eq(to).addClass('active');

        }
        return false;
      };
    });
  };

  function css(el, prop) {
    return parseInt($.css(el[0], prop)) || 0;
  };
  function width(el) {
    return el[0].offsetWidth + css(el, 'marginLeft') + css(el, 'marginRight');
  };
  function height(el) {
    return el[0].offsetHeight + css(el, 'marginTop') + css(el, 'marginBottom');
  };

})(jQuery);

/* ######################################################## */
/* #################  JAVADOC REFERENCE ################### */
/* ######################################################## */

/* Initialize some droiddoc stuff, but only if we're in the reference */
if (location.pathname.indexOf("/reference") == 0) {
  if (!(location.pathname.indexOf("/reference-gms/packages.html") == 0) &&
    !(location.pathname.indexOf("/reference-gcm/packages.html") == 0) &&
    !(location.pathname.indexOf("/reference/com/google") == 0)) {
    $(document).ready(function() {
      // init available apis based on user pref
      changeApiLevel();
    });
  }
}

var API_LEVEL_COOKIE = "api_level";
var minLevel = 1;
var maxLevel = 1;

function buildApiLevelSelector() {
  maxLevel = SINCE_DATA.length;
  var userApiLevel = parseInt(readCookie(API_LEVEL_COOKIE));
  userApiLevel = userApiLevel == 0 ? maxLevel : userApiLevel; // If there's no cookie (zero), use the max by default

  minLevel = parseInt($("#doc-api-level").attr("class"));
  // Handle provisional api levels; the provisional level will always be the highest possible level
  // Provisional api levels will also have a length; other stuff that's just missing a level won't,
  // so leave those kinds of entities at the default level of 1 (for example, the R.styleable class)
  if (isNaN(minLevel) && minLevel.length) {
    minLevel = maxLevel;
  }
  var select = $("#apiLevelSelector").html("").change(changeApiLevel);
  for (var i = maxLevel - 1; i >= 0; i--) {
    var option = $("<option />").attr("value", "" + SINCE_DATA[i]).append("" + SINCE_DATA[i]);
    //  if (SINCE_DATA[i] < minLevel) option.addClass("absent"); // always false for strings (codenames)
    select.append(option);
  }

  // get the DOM element and use setAttribute cuz IE6 fails when using jquery .attr('selected',true)
  var selectedLevelItem = $("#apiLevelSelector option[value='" + userApiLevel + "']").get(0);
  selectedLevelItem.setAttribute('selected', true);
}

function changeApiLevel() {
  maxLevel = SINCE_DATA.length;
  var selectedLevel = maxLevel;

  selectedLevel = parseInt($("#apiLevelSelector option:selected").val());
  toggleVisisbleApis(selectedLevel, "body");

  writeCookie(API_LEVEL_COOKIE, selectedLevel, null);

  if (selectedLevel < minLevel) {
    $("#naMessage").show().html("<div><p><strong>This API" +
              " requires API level " + minLevel + " or higher.</strong></p>" +
              "<p>This document is hidden because your selected API level for the documentation is " +
              selectedLevel + ". You can change the documentation API level with the selector " +
              "above the left navigation.</p>" +
              "<p>For more information about specifying the API level your app requires, " +
              "read <a href='" + toRoot + "training/basics/supporting-devices/platforms.html'" +
              ">Supporting Different Platform Versions</a>.</p>" +
              "<input type='button' value='OK, make this page visible' " +
              "title='Change the API level to " + minLevel + "' " +
              "onclick='$(\"#apiLevelSelector\").val(\"" + minLevel + "\");changeApiLevel();' />" +
              "</div>");
  } else {
    $("#naMessage").hide();
  }
}

function toggleVisisbleApis(selectedLevel, context) {
  var apis = $(".api", context);
  apis.each(function(i) {
    var obj = $(this);
    var className = obj.attr("class");
    var apiLevelIndex = className.lastIndexOf("-") + 1;
    var apiLevelEndIndex = className.indexOf(" ", apiLevelIndex);
    apiLevelEndIndex = apiLevelEndIndex != -1 ? apiLevelEndIndex : className.length;
    var apiLevel = className.substring(apiLevelIndex, apiLevelEndIndex);
    if (apiLevel.length == 0) { // for odd cases when the since data is actually missing, just bail
      return;
    }
    apiLevel = parseInt(apiLevel);

    // Handle provisional api levels; if this item's level is the provisional one, set it to the max
    var selectedLevelNum = parseInt(selectedLevel)
    var apiLevelNum = parseInt(apiLevel);
    if (isNaN(apiLevelNum)) {
      apiLevelNum = maxLevel;
    }

    // Grey things out that aren't available and give a tooltip title
    if (apiLevelNum > selectedLevelNum) {
      obj.addClass("absent").attr("title", "Requires API Level \"" +
            apiLevel + "\" or higher. To reveal, change the target API level " +
              "above the left navigation.");
    } else obj.removeClass("absent").removeAttr("title");
  });
}

/* #################  SIDENAV TREE VIEW ################### */
/* TODO: eliminate redundancy with non-google functions */
function init_google_navtree(navtree_id, toroot, root_nodes) {
  var me = new Object();
  me.toroot = toroot;
  me.node = new Object();

  me.node.li = document.getElementById(navtree_id);
  if (!me.node.li) {
    return;
  }

  me.node.children_data = root_nodes;
  me.node.children = new Array();
  me.node.children_ul = document.createElement("ul");
  me.node.get_children_ul = function() { return me.node.children_ul; };
  //me.node.children_ul.className = "children_ul";
  me.node.li.appendChild(me.node.children_ul);
  me.node.depth = 0;

  get_google_node(me, me.node);
}

function new_google_node(me, mom, text, link, children_data, api_level) {
  var node = new Object();
  var child;
  node.children = Array();
  node.children_data = children_data;
  node.depth = mom.depth + 1;
  node.get_children_ul = function() {
      if (!node.children_ul) {
        node.children_ul = document.createElement("ul");
        node.children_ul.className = "tree-list-children";
        node.li.appendChild(node.children_ul);
      }
      return node.children_ul;
    };
  node.li = document.createElement("li");

  mom.get_children_ul().appendChild(node.li);

  if (link) {
    child = document.createElement("a");

  } else {
    child = document.createElement("span");
    child.className = "tree-list-subtitle";

  }
  if (children_data != null) {
    node.li.className = "nav-section";
    node.label_div = document.createElement("div");
    node.label_div.className = "nav-section-header-ref";
    node.li.appendChild(node.label_div);
    get_google_node(me, node);
    node.label_div.appendChild(child);
  } else {
    node.li.appendChild(child);
  }
  if (link) {
    child.href = me.toroot + link;
  }
  node.label = document.createTextNode(text);
  child.appendChild(node.label);

  node.children_ul = null;

  return node;
}

function get_google_node(me, mom) {
  mom.children_visited = true;
  var linkText;
  for (var i in mom.children_data) {
    var node_data = mom.children_data[i];
    linkText = node_data[0];

    if (linkText.match("^" + "com.google.android") == "com.google.android") {
      linkText = linkText.substr(19, linkText.length);
    }
    mom.children[i] = new_google_node(me, mom, linkText, node_data[1],
        node_data[2], node_data[3]);
  }
}

/****** NEW version of script to build google and sample navs dynamically ******/
// TODO: update Google reference docs to tolerate this new implementation

var NODE_NAME = 0;
var NODE_HREF = 1;
var NODE_GROUP = 2;
var NODE_TAGS = 3;
var NODE_CHILDREN = 4;

function init_google_navtree2(navtree_id, data) {
  var $containerUl = $("#" + navtree_id);
  for (var i in data) {
    var node_data = data[i];
    $containerUl.append(new_google_node2(node_data));
  }

  // Make all third-generation list items 'sticky' to prevent them from collapsing
  $containerUl.find('li li li.nav-section').addClass('sticky');

  initExpandableNavItems("#" + navtree_id);
}

function new_google_node2(node_data) {
  var linkText = node_data[NODE_NAME];
  if (linkText.match("^" + "com.google.android") == "com.google.android") {
    linkText = linkText.substr(19, linkText.length);
  }
  var $li = $('<li>');
  var $a;
  if (node_data[NODE_HREF] != null) {
    $a = $('<a href="' + toRoot + node_data[NODE_HREF] + '" title="' + linkText + '" >' +
        linkText + '</a>');
  } else {
    $a = $('<a href="#" onclick="return false;" title="' + linkText + '" >' +
        linkText + '/</a>');
  }
  var $childUl = $('<ul>');
  if (node_data[NODE_CHILDREN] != null) {
    $li.addClass("nav-section");
    $a = $('<div class="nav-section-header">').append($a);
    if (node_data[NODE_HREF] == null) $a.addClass('empty');

    for (var i in node_data[NODE_CHILDREN]) {
      var child_node_data = node_data[NODE_CHILDREN][i];
      $childUl.append(new_google_node2(child_node_data));
    }
    $li.append($childUl);
  }
  $li.prepend($a);

  return $li;
}

function showGoogleRefTree() {
  init_default_google_navtree(toRoot);
  init_default_gcm_navtree(toRoot);
}

function init_default_google_navtree(toroot) {
  // load json file for navtree data
  $.getScript(toRoot + 'gms_navtree_data.js', function(data, textStatus, jqxhr) {
    // when the file is loaded, initialize the tree
    if (jqxhr.status === 200) {
      init_google_navtree("gms-tree-list", toroot, GMS_NAVTREE_DATA);
      highlightSidenav();
    }
  });
}

function init_default_gcm_navtree(toroot) {
  // load json file for navtree data
  $.getScript(toRoot + 'gcm_navtree_data.js', function(data, textStatus, jqxhr) {
    // when the file is loaded, initialize the tree
    if (jqxhr.status === 200) {
      init_google_navtree("gcm-tree-list", toroot, GCM_NAVTREE_DATA);
      highlightSidenav();
    }
  });
}

/* TOGGLE INHERITED MEMBERS */

/* Toggle an inherited class (arrow toggle)
 * @param linkObj  The link that was clicked.
 * @param expand  'true' to ensure it's expanded. 'false' to ensure it's closed.
 *                'null' to simply toggle.
 */
function toggleInherited(linkObj, expand) {
  var base = linkObj.getAttribute("id");
  var list = document.getElementById(base + "-list");
  var summary = document.getElementById(base + "-summary");
  var trigger = document.getElementById(base + "-trigger");
  var a = $(linkObj);
  if ((expand == null && a.hasClass("closed")) || expand) {
    list.style.display = "none";
    summary.style.display = "block";
    trigger.src = toRoot + "assets/images/styles/disclosure_up.png";
    a.removeClass("closed");
    a.addClass("opened");
  } else if ((expand == null && a.hasClass("opened")) || (expand == false)) {
    list.style.display = "block";
    summary.style.display = "none";
    trigger.src = toRoot + "assets/images/styles/disclosure_down.png";
    a.removeClass("opened");
    a.addClass("closed");
  }
  return false;
}

/* Toggle all inherited classes in a single table (e.g. all inherited methods)
 * @param linkObj  The link that was clicked.
 * @param expand  'true' to ensure it's expanded. 'false' to ensure it's closed.
 *                'null' to simply toggle.
 */
function toggleAllInherited(linkObj, expand) {
  var a = $(linkObj);
  var table = $(a.parent().parent().parent()); // ugly way to get table/tbody
  var expandos = $(".jd-expando-trigger", table);
  if ((expand == null && a.text() == "[Expand]") || expand) {
    expandos.each(function(i) {
      toggleInherited(this, true);
    });
    a.text("[Collapse]");
  } else if ((expand == null && a.text() == "[Collapse]") || (expand == false)) {
    expandos.each(function(i) {
      toggleInherited(this, false);
    });
    a.text("[Expand]");
  }
  return false;
}

/* Toggle all inherited members in the class (link in the class title)
 */
function toggleAllClassInherited() {
  var a = $("#toggleAllClassInherited"); // get toggle link from class title
  var toggles = $(".toggle-all", $("#body-content"));
  if (a.text() == "[Expand All]") {
    toggles.each(function(i) {
      toggleAllInherited(this, true);
    });
    a.text("[Collapse All]");
  } else {
    toggles.each(function(i) {
      toggleAllInherited(this, false);
    });
    a.text("[Expand All]");
  }
  return false;
}

/* Expand all inherited members in the class. Used when initiating page search */
function ensureAllInheritedExpanded() {
  var toggles = $(".toggle-all", $("#body-content"));
  toggles.each(function(i) {
    toggleAllInherited(this, true);
  });
  $("#toggleAllClassInherited").text("[Collapse All]");
}

/* HANDLE KEY EVENTS
 * - Listen for Ctrl+F (Cmd on Mac) and expand all inherited members (to aid page search)
 */
var agent = navigator['userAgent'].toLowerCase();
var mac = agent.indexOf("macintosh") != -1;

$(document).keydown(function(e) {
  var control = mac ? e.metaKey && !e.ctrlKey : e.ctrlKey; // get ctrl key
  if (control && e.which == 70) {  // 70 is "F"
    ensureAllInheritedExpanded();
  }
});

/* On-demand functions */

/** Move sample code line numbers out of PRE block and into non-copyable column */
function initCodeLineNumbers() {
  var numbers = $("#codesample-block a.number");
  if (numbers.length) {
    $("#codesample-line-numbers").removeClass("hidden").append(numbers);
  }

  $(document).ready(function() {
    // select entire line when clicked
    $("span.code-line").click(function() {
      if (!shifted) {
        selectText(this);
      }
    });
    // invoke line link on double click
    $(".code-line").dblclick(function() {
      document.location.hash = $(this).attr('id');
    });
    // highlight the line when hovering on the number
    $("#codesample-line-numbers a.number").mouseover(function() {
      var id = $(this).attr('href');
      $(id).css('background', '#e7e7e7');
    });
    $("#codesample-line-numbers a.number").mouseout(function() {
      var id = $(this).attr('href');
      $(id).css('background', 'none');
    });
  });
}

// create SHIFT key binder to avoid the selectText method when selecting multiple lines
var shifted = false;
$(document).bind('keyup keydown', function(e) {
  shifted = e.shiftKey; return true;
});

// courtesy of jasonedelman.com
function selectText(element) {
  var doc = document      ,
        range, selection
  ;
  if (doc.body.createTextRange) { //ms
    range = doc.body.createTextRange();
    range.moveToElementText(element);
    range.select();
  } else if (window.getSelection) { //all others
    selection = window.getSelection();
    range = doc.createRange();
    range.selectNodeContents(element);
    selection.removeAllRanges();
    selection.addRange(range);
  }
}

/** Display links and other information about samples that match the
    group specified by the URL */
function showSamples() {
  var group = $("#samples").attr('class');
  $("#samples").html("<p>Here are some samples for <b>" + group + "</b> apps:</p>");

  var $ul = $("<ul>");
  $selectedLi = $("#nav li.selected");

  $selectedLi.children("ul").children("li").each(function() {
    var $li = $("<li>").append($(this).find("a").first().clone());
    $ul.append($li);
  });

  $("#samples").append($ul);

}

/* ########################################################## */
/* ###################  RESOURCE CARDS  ##################### */
/* ########################################################## */

/** Handle resource queries, collections, and grids (sections). Requires
    jd_tag_helpers.js and the *_unified_data.js to be loaded. */

(function() {
  $(document).ready(function() {
    // Need to initialize hero carousel before other sections for dedupe
    // to work correctly.
    $('[data-carousel-query]').dacCarouselQuery();

    // Iterate over all instances and initialize a resource widget.
    $('.resource-widget').resourceWidget();
  });

  $.fn.widgetOptions = function() {
    return {
      cardSizes: (this.data('cardsizes') || '').split(','),
      maxResults: parseInt(this.data('maxresults'), 10) || Infinity,
      initialResults: this.data('initialResults'),
      itemsPerPage: this.data('itemsPerPage'),
      sortOrder: this.data('sortorder'),
      query: this.data('query'),
      section: this.data('section'),
      /* Added by LFL 6/6/14 */
      resourceStyle: this.data('resourcestyle') || 'card',
      stackSort: this.data('stacksort') || 'true',
      // For filter based resources
      allowDuplicates: this.data('allow-duplicates') || 'false'
    };
  };

  $.fn.deprecateOldGridStyles = function() {
    var m = this.get(0).className.match(/\bcol-(\d+)\b/);
    if (m && !this.is('.cols > *')) {
      this.removeClass('col-' + m[1]);
    }
    return this;
  }

  /*
   * Three types of resource layouts:
   * Flow - Uses a fixed row-height flow using float left style.
   * Carousel - Single card slideshow all same dimension absolute.
   * Stack - Uses fixed columns and flexible element height.
   */
  function initResourceWidget(widget, resources, opts) {
    var $widget = $(widget).deprecateOldGridStyles();
    var isFlow = $widget.hasClass('resource-flow-layout');
    var isCarousel = $widget.hasClass('resource-carousel-layout');
    var isStack = $widget.hasClass('resource-stack-layout');

    opts = opts || $widget.widgetOptions();
    resources = resources || metadata.query(opts);

    if (opts.maxResults !== undefined) {
      resources = resources.slice(0, opts.maxResults);
    }

    if (isFlow) {
      drawResourcesFlowWidget($widget, opts, resources);
    } else if (isCarousel) {
      drawResourcesCarouselWidget($widget, opts, resources);
    } else if (isStack) {
      opts.numStacks = $widget.data('numstacks');
      drawResourcesStackWidget($widget, opts, resources);
    }
  }

  $.fn.resourceWidget = function(resources, options) {
    return this.each(function() {
      initResourceWidget(this, resources, options);
    });
  };

  /* Initializes a Resource Carousel Widget */
  function drawResourcesCarouselWidget($widget, opts, resources) {
    $widget.empty();
    var plusone = false; // stop showing plusone buttons on cards

    $widget.addClass('resource-card slideshow-container')
      .append($('<a>').addClass('slideshow-prev').text('Prev'))
      .append($('<a>').addClass('slideshow-next').text('Next'));

    var css = {'width': $widget.width() + 'px',
                'height': $widget.height() + 'px'};

    var $ul = $('<ul>');

    for (var i = 0; i < resources.length; ++i) {
      var $card = $('<a>')
        .attr('href', cleanUrl(resources[i].url))
        .decorateResourceCard(resources[i], plusone);

      $('<li>').css(css)
          .append($card)
          .appendTo($ul);
    }

    $('<div>').addClass('frame')
      .append($ul)
      .appendTo($widget);

    $widget.dacSlideshow({
      auto: true,
      btnPrev: '.slideshow-prev',
      btnNext: '.slideshow-next'
    });
  }

  /* Initializes a Resource Card Stack Widget (column-based layout)
     Modified by LFL 6/6/14
   */
  function drawResourcesStackWidget($widget, opts, resources, sections) {
    // Don't empty widget, grab all items inside since they will be the first
    // items stacked, followed by the resource query
    var plusone = false; // stop showing plusone buttons on cards
    var cards = $widget.find('.resource-card').detach().toArray();
    var numStacks = opts.numStacks || 1;
    var $stacks = [];

    for (var i = 0; i < numStacks; ++i) {
      $stacks[i] = $('<div>').addClass('resource-card-stack')
          .appendTo($widget);
    }

    var sectionResources = [];

    // Extract any subsections that are actually resource cards
    if (sections) {
      for (i = 0; i < sections.length; ++i) {
        if (!sections[i].sections || !sections[i].sections.length) {
          // Render it as a resource card
          sectionResources.push(
            $('<a>')
              .addClass('resource-card section-card')
              .attr('href', cleanUrl(sections[i].resource.url))
              .decorateResourceCard(sections[i].resource, plusone)[0]
          );

        } else {
          cards.push(
            $('<div>')
              .addClass('resource-card section-card-menu')
              .decorateResourceSection(sections[i], plusone)[0]
          );
        }
      }
    }

    cards = cards.concat(sectionResources);

    for (i = 0; i < resources.length; ++i) {
      var $card = createResourceElement(resources[i], opts);

      if (opts.resourceStyle.indexOf('related') > -1) {
        $card.addClass('related-card');
      }

      cards.push($card[0]);
    }

    if (opts.stackSort !== 'false') {
      for (i = 0; i < cards.length; ++i) {
        // Find the stack with the shortest height, but give preference to
        // left to right order.
        var minHeight = $stacks[0].height();
        var minIndex = 0;

        for (var j = 1; j < numStacks; ++j) {
          var height = $stacks[j].height();
          if (height < minHeight - 45) {
            minHeight = height;
            minIndex = j;
          }
        }

        $stacks[minIndex].append($(cards[i]));
      }
    }
  }

  /*
    Create a resource card using the given resource object and a list of html
     configured options. Returns a jquery object containing the element.
  */
  function createResourceElement(resource, opts, plusone) {
    var $el;

    // The difference here is that generic cards are not entirely clickable
    // so its a div instead of an a tag, also the generic one is not given
    // the resource-card class so it appears with a transparent background
    // and can be styled in whatever way the css setup.
    if (opts.resourceStyle === 'generic') {
      $el = $('<div>')
        .addClass('resource')
        .attr('href', cleanUrl(resource.url))
        .decorateResource(resource, opts);
    } else {
      var cls = 'resource resource-card';

      $el = $('<a>')
        .addClass(cls)
        .attr('href', cleanUrl(resource.url))
        .decorateResourceCard(resource, plusone);
    }

    return $el;
  }

  function createResponsiveFlowColumn(cardSize) {
    var cardWidth = parseInt(cardSize.match(/(\d+)/)[1], 10);
    var column = $('<div>').addClass('col-' + (cardWidth / 3) + 'of6');
    if (cardWidth < 9) {
      column.addClass('col-tablet-1of2');
    } else if (cardWidth > 9 && cardWidth < 18) {
      column.addClass('col-tablet-1of1');
    }
    if (cardWidth < 18) {
      column.addClass('col-mobile-1of1');
    }
    return column;
  }

  /* Initializes a flow widget, see distribute.scss for generating accompanying css */
  function drawResourcesFlowWidget($widget, opts, resources) {
    // We'll be doing our own modifications to opts.
    opts = $.extend({}, opts);

    $widget.empty().addClass('cols');
    if (opts.itemsPerPage) {
      $('<div class="col-1of1 dac-section-links dac-text-center">')
        .append(
          $('<div class="dac-section-link dac-show-less" data-toggle="show-less">Less<i class="dac-sprite dac-auto-unfold-less"></i></div>'),
          $('<div class="dac-section-link dac-show-more" data-toggle="show-more">More<i class="dac-sprite dac-auto-unfold-more"></i></div>')
        )
        .appendTo($widget);
    }

    $widget.data('options.resourceflow', opts);
    $widget.data('resources.resourceflow', resources);

    drawResourceFlowPage($widget, opts, resources);
  }

  function drawResourceFlowPage($widget, opts, resources) {
    var cardSizes = opts.cardSizes || ['6x6']; // 2015-08-09: dynamic card sizes are deprecated
    var i = opts.currentIndex || 0;
    var j = 0;
    var plusone = false; // stop showing plusone buttons on cards
    var firstPage = i === 0;
    var initialResults = opts.initialResults || opts.itemsPerPage || resources.length;
    var max = firstPage ? initialResults : i + opts.itemsPerPage;
    max = Math.min(resources.length, max);

    var page = $('<div class="resource-flow-page">');
    if (opts.itemsPerPage) {
      $widget.find('.dac-section-links').before(page);
    } else {
      $widget.append(page);
    }

    while (i < max) {
      var cardSize = cardSizes[j++ % cardSizes.length];
      cardSize = cardSize.replace(/^\s+|\s+$/, '');

      var column = createResponsiveFlowColumn(cardSize).appendTo(page);

      // A stack has a third dimension which is the number of stacked items
      var isStack = cardSize.match(/(\d+)x(\d+)x(\d+)/);
      var stackCount = 0;
      var $stackDiv = null;

      if (isStack) {
        // Create a stack container which should have the dimensions defined
        // by the product of the items inside.
        $stackDiv = $('<div>').addClass('resource-card-stack resource-card-' + isStack[1] +
          'x' + isStack[2] * isStack[3]) .appendTo(column);
      }

      // Build each stack item or just a single item
      do {
        var resource = resources[i];

        var $card = createResourceElement(resources[i], opts, plusone);

        $card.addClass('resource-card-' + cardSize +
          ' resource-card-' + resource.type.toLowerCase());

        if (isStack) {
          $card.addClass('resource-card-' + isStack[1] + 'x' + isStack[2]);
          if (++stackCount === parseInt(isStack[3])) {
            $card.addClass('resource-card-row-stack-last');
            stackCount = 0;
          }
        } else {
          stackCount = 0;
        }

        $card.appendTo($stackDiv || column);

      } while (++i < max && stackCount > 0);

      // Record number of pages viewed in analytics.
      if (!firstPage) {
        var clicks = Math.ceil((i - initialResults) / opts.itemsPerPage);
        ga('send', 'event', 'Cards', 'Click More', clicks);
      }
    }

    opts.currentIndex = i;
    $widget.toggleClass('dac-has-more', i < resources.length);
    $widget.toggleClass('dac-has-less', !firstPage);

    $widget.trigger('dac:domchange');
    if (opts.onRenderPage) {
      opts.onRenderPage(page);
    }
  }

  function drawResourceFlowReset($widget, opts, resources) {
    $widget.find('.resource-flow-page')
        .slice(1)
        .remove();
    $widget.toggleClass('dac-has-more', true);
    $widget.toggleClass('dac-has-less', false);

    opts.currentIndex = Math.min(opts.initialResults, resources.length);

    ga('send', 'event', 'Cards', 'Click Less');
  }

  /* A decorator for event functions which finds the surrounding widget and it's options */
  function wrapWithWidget(func) {
    return function(e) {
      if (e) e.preventDefault();

      var $widget = $(this).closest('.resource-flow-layout');
      var opts = $widget.data('options.resourceflow');
      var resources = $widget.data('resources.resourceflow');
      func($widget, opts, resources);
    };
  }

  /* Build a site map of resources using a section as a root. */
  function buildSectionList(opts) {
    if (opts.section && SECTION_BY_ID[opts.section]) {
      return SECTION_BY_ID[opts.section].sections || [];
    }
    return [];
  }

  function cleanUrl(url) {
    if (url && url.indexOf('//') === -1) {
      url = toRoot + url;
    }

    return url;
  }

  // Delegated events for resources.
  $(document).on('click', '.resource-flow-layout [data-toggle="show-more"]', wrapWithWidget(drawResourceFlowPage));
  $(document).on('click', '.resource-flow-layout [data-toggle="show-less"]', wrapWithWidget(drawResourceFlowReset));
})();

(function($) {
  // A mapping from category and type values to new values or human presentable strings.
  var SECTION_MAP = {
    googleplay: 'google play'
  };

  /*
    Utility method for creating dom for the description area of a card.
    Used in decorateResourceCard and decorateResource.
  */
  function buildResourceCardDescription(resource, plusone) {
    var $description = $('<div>').addClass('description ellipsis');

    $description.append($('<div>').addClass('text').html(resource.summary));

    if (resource.cta) {
      $description.append($('<a>').addClass('cta').html(resource.cta));
    }

    if (plusone) {
      var plusurl = resource.url.indexOf("//") > -1 ? resource.url :
        "//developer.android.com/" + resource.url;

      $description.append($('<div>').addClass('util')
        .append($('<div>').addClass('g-plusone')
          .attr('data-size', 'small')
          .attr('data-align', 'right')
          .attr('data-href', plusurl)));
    }

    return $description;
  }

  /* Simple jquery function to create dom for a standard resource card */
  $.fn.decorateResourceCard = function(resource, plusone) {
    var section = resource.category || resource.type;
    section = (SECTION_MAP[section] || section).toLowerCase();
    var imgUrl = resource.image ||
      'assets/images/resource-card-default-android.jpg';

    if (imgUrl.indexOf('//') === -1) {
      imgUrl = toRoot + imgUrl;
    }

    if (resource.type === 'youtube' || resource.type === 'video') {
      $('<div>').addClass('play-button')
        .append($('<i class="dac-sprite dac-play-white">'))
        .appendTo(this);
    }

    $('<div>').addClass('card-bg')
      .css('background-image', 'url(' + (imgUrl || toRoot +
        'assets/images/resource-card-default-android.jpg') + ')')
      .appendTo(this);

    $('<div>').addClass('card-info' + (!resource.summary ? ' empty-desc' : ''))
      .append($('<div>').addClass('section').text(section))
      .append($('<div>').addClass('title' + (resource.title_highlighted ? ' highlighted' : ''))
        .html(resource.title_highlighted || resource.title))
      .append(buildResourceCardDescription(resource, plusone))
      .appendTo(this);

    return this;
  };

  /* Simple jquery function to create dom for a resource section card (menu) */
  $.fn.decorateResourceSection = function(section, plusone) {
    var resource = section.resource;
    //keep url clean for matching and offline mode handling
    var urlPrefix = resource.image.indexOf("//") > -1 ? "" : toRoot;
    var $base = $('<a>')
        .addClass('card-bg')
        .attr('href', resource.url)
        .append($('<div>').addClass('card-section-icon')
          .append($('<div>').addClass('icon'))
          .append($('<div>').addClass('section').html(resource.title)))
      .appendTo(this);

    var $cardInfo = $('<div>').addClass('card-info').appendTo(this);

    if (section.sections && section.sections.length) {
      // Recurse the section sub-tree to find a resource image.
      var stack = [section];

      while (stack.length) {
        if (stack[0].resource.image) {
          $base.css('background-image', 'url(' + urlPrefix + stack[0].resource.image + ')');
          break;
        }

        if (stack[0].sections) {
          stack = stack.concat(stack[0].sections);
        }

        stack.shift();
      }

      var $ul = $('<ul>')
        .appendTo($cardInfo);

      var max = section.sections.length > 3 ? 3 : section.sections.length;

      for (var i = 0; i < max; ++i) {

        var subResource = section.sections[i];
        if (!plusone) {
          $('<li>')
            .append($('<a>').attr('href', subResource.url)
              .append($('<div>').addClass('title').html(subResource.title))
              .append($('<div>').addClass('description ellipsis')
                .append($('<div>').addClass('text').html(subResource.summary))
                .append($('<div>').addClass('util'))))
          .appendTo($ul);
        } else {
          $('<li>')
            .append($('<a>').attr('href', subResource.url)
              .append($('<div>').addClass('title').html(subResource.title))
              .append($('<div>').addClass('description ellipsis')
                .append($('<div>').addClass('text').html(subResource.summary))
                .append($('<div>').addClass('util')
                  .append($('<div>').addClass('g-plusone')
                    .attr('data-size', 'small')
                    .attr('data-align', 'right')
                    .attr('data-href', resource.url)))))
          .appendTo($ul);
        }
      }

      // Add a more row
      if (max < section.sections.length) {
        $('<li>')
          .append($('<a>').attr('href', resource.url)
            .append($('<div>')
              .addClass('title')
              .text('More')))
        .appendTo($ul);
      }
    } else {
      // No sub-resources, just render description?
    }

    return this;
  };

  /* Render other types of resource styles that are not cards. */
  $.fn.decorateResource = function(resource, opts) {
    var imgUrl = resource.image ||
      'assets/images/resource-card-default-android.jpg';
    var linkUrl = resource.url;

    if (imgUrl.indexOf('//') === -1) {
      imgUrl = toRoot + imgUrl;
    }

    if (linkUrl && linkUrl.indexOf('//') === -1) {
      linkUrl = toRoot + linkUrl;
    }

    $(this).append(
      $('<div>').addClass('image')
        .css('background-image', 'url(' + imgUrl + ')'),
      $('<div>').addClass('info').append(
        $('<h4>').addClass('title').html(resource.title_highlighted || resource.title),
        $('<p>').addClass('summary').html(resource.summary),
        $('<a>').attr('href', linkUrl).addClass('cta').html('Learn More')
      )
    );

    return this;
  };
})(jQuery);

/*
  Fullscreen Carousel

  The following allows for an area at the top of the page that takes over the
  entire browser height except for its top offset and an optional bottom
  padding specified as a data attribute.

  HTML:

  <div class="fullscreen-carousel">
    <div class="fullscreen-carousel-content">
      <!-- content here -->
    </div>
    <div class="fullscreen-carousel-content">
      <!-- content here -->
    </div>

    etc ...

  </div>

  Control over how the carousel takes over the screen can mostly be defined in
  a css file. Setting min-height on the .fullscreen-carousel-content elements
  will prevent them from shrinking to far vertically when the browser is very
  short, and setting max-height on the .fullscreen-carousel itself will prevent
  the area from becoming to long in the case that the browser is stretched very
  tall.

  There is limited functionality for having multiple sections since that request
  was removed, but it is possible to add .next-arrow and .prev-arrow elements to
  scroll between multiple content areas.
*/

(function() {
  $(document).ready(function() {
    $('.fullscreen-carousel').each(function() {
      initWidget(this);
    });
  });

  function initWidget(widget) {
    var $widget = $(widget);

    var topOffset = $widget.offset().top;
    var padBottom = parseInt($widget.data('paddingbottom')) || 0;
    var maxHeight = 0;
    var minHeight = 0;
    var $content = $widget.find('.fullscreen-carousel-content');
    var $nextArrow = $widget.find('.next-arrow');
    var $prevArrow = $widget.find('.prev-arrow');
    var $curSection = $($content[0]);

    if ($content.length <= 1) {
      $nextArrow.hide();
      $prevArrow.hide();
    } else {
      $nextArrow.click(function() {
        var index = ($content.index($curSection) + 1);
        $curSection.hide();
        $curSection = $($content[index >= $content.length ? 0 : index]);
        $curSection.show();
      });

      $prevArrow.click(function() {
        var index = ($content.index($curSection) - 1);
        $curSection.hide();
        $curSection = $($content[index < 0 ? $content.length - 1 : 0]);
        $curSection.show();
      });
    }

    // Just hide all content sections except first.
    $content.each(function(index) {
      if ($(this).height() > minHeight) minHeight = $(this).height();
      $(this).css({position: 'absolute',  display: index > 0 ? 'none' : ''});
    });

    // Register for changes to window size, and trigger.
    $(window).resize(resizeWidget);
    resizeWidget();

    function resizeWidget() {
      var height = $(window).height() - topOffset - padBottom;
      $widget.width($(window).width());
      $widget.height(height < minHeight ? minHeight :
        (maxHeight && height > maxHeight ? maxHeight : height));
    }
  }
})();

/*
  Tab Carousel

  The following allows tab widgets to be installed via the html below. Each
  tab content section should have a data-tab attribute matching one of the
  nav items'. Also each tab content section should have a width matching the
  tab carousel.

  HTML:

  <div class="tab-carousel">
    <ul class="tab-nav">
      <li><a href="#" data-tab="handsets">Handsets</a>
      <li><a href="#" data-tab="wearable">Wearable</a>
      <li><a href="#" data-tab="tv">TV</a>
    </ul>

    <div class="tab-carousel-content">
      <div data-tab="handsets">
        <!--Full width content here-->
      </div>

      <div data-tab="wearable">
        <!--Full width content here-->
      </div>

      <div data-tab="tv">
        <!--Full width content here-->
      </div>
    </div>
  </div>

*/
(function() {
  $(document).ready(function() {
    $('.tab-carousel').each(function() {
      initWidget(this);
    });
  });

  function initWidget(widget) {
    var $widget = $(widget);
    var $nav = $widget.find('.tab-nav');
    var $anchors = $nav.find('[data-tab]');
    var $li = $nav.find('li');
    var $contentContainer = $widget.find('.tab-carousel-content');
    var $tabs = $contentContainer.find('[data-tab]');
    var $curTab = $($tabs[0]); // Current tab is first tab.
    var width = $widget.width();

    // Setup nav interactivity.
    $anchors.click(function(evt) {
      evt.preventDefault();
      var query = '[data-tab=' + $(this).data('tab') + ']';
      transitionWidget($tabs.filter(query));
    });

    // Add highlight for navigation on first item.
    var $highlight = $('<div>').addClass('highlight')
      .css({left:$li.position().left + 'px', width:$li.outerWidth() + 'px'})
      .appendTo($nav);

    // Store height since we will change contents to absolute.
    $contentContainer.height($contentContainer.height());

    // Absolutely position tabs so they're ready for transition.
    $tabs.each(function(index) {
      $(this).css({position: 'absolute', left: index > 0 ? width + 'px' : '0'});
    });

    function transitionWidget($toTab) {
      if (!$curTab.is($toTab)) {
        var curIndex = $tabs.index($curTab[0]);
        var toIndex = $tabs.index($toTab[0]);
        var dir = toIndex > curIndex ? 1 : -1;

        // Animate content sections.
        $toTab.css({left:(width * dir) + 'px'});
        $curTab.animate({left:(width * -dir) + 'px'});
        $toTab.animate({left:'0'});

        // Animate navigation highlight.
        $highlight.animate({left:$($li[toIndex]).position().left + 'px',
          width:$($li[toIndex]).outerWidth() + 'px'})

        // Store new current section.
        $curTab = $toTab;
      }
    }
  }
})();

/**
 * Auto TOC
 *
 * Upgrades h2s on the page to have a rule and be toggle-able on mobile.
 */
(function($) {
  var upgraded = false;
  var h2Titles;

  function initWidget() {
    // add HRs below all H2s (except for a few other h2 variants)
    // Consider doing this with css instead.
    h2Titles = $('h2').not('#qv h2, #tb h2, .sidebox h2, #devdoc-nav h2, h2.norule');
    h2Titles.css({paddingBottom:0}).after('<hr/>');

    // Exit early if on older browser.
    if (!window.matchMedia) {
      return;
    }

    // Only run logic in mobile layout.
    var query = window.matchMedia('(max-width: 719px)');
    if (query.matches) {
      makeTogglable();
    } else {
      query.addListener(makeTogglable);
    }
  }

  function makeTogglable() {
    // Only run this logic once.
    if (upgraded) { return; }
    upgraded = true;

    // Only make content h2s togglable.
    var contentTitles = h2Titles.filter('#jd-content *');

    // If there are more than 1
    if (contentTitles.size() < 2) {
      return;
    }

    contentTitles.each(function() {
      // Find all the relevant nodes.
      var $title = $(this);
      var $hr = $title.next();
      var $contents = allNextUntil($hr[0], 'h2, .next-docs');
      var $section = $($title)
        .add($hr)
        .add($title.prev('a[name]'))
        .add($contents);
      var $anchor = $section.first().prev();
      var anchorMethod = 'after';
      if ($anchor.length === 0) {
        $anchor = $title.parent();
        anchorMethod = 'prepend';
      }

      // Some h2s are in their own container making it pretty hard to find the end, so skip.
      if ($contents.length === 0) {
        return;
      }

      // Remove from DOM before messing with it. DOM is slow!
      $section.detach();

      // Add mobile-only expand arrows.
      $title.prepend('<span class="dac-visible-mobile-inline-block">' +
          '<i class="dac-toggle-expand dac-sprite dac-expand-more-black"></i>' +
          '<i class="dac-toggle-collapse dac-sprite dac-expand-less-black"></i>' +
          '</span>')
        .attr('data-toggle', 'section');

      // Wrap in magic markup.
      $section = $section.wrapAll('<div class="dac-toggle dac-mobile">').parent();

      // extra div used for max-height calculation.
      $contents.wrapAll('<div class="dac-toggle-content dac-expand"><div>');

      // Pre-expand section if requested.
      if ($title.hasClass('is-expanded')) {
        $section.addClass('is-expanded');
      }

      // Pre-expand section if targetted by hash.
      if (location.hash && $section.find(location.hash).length) {
        $section.addClass('is-expanded');
      }

      // Add it back to the dom.
      $anchor[anchorMethod].call($anchor, $section);
    });
  }

  // Similar to $.fn.nextUntil() except we need all nodes, jQuery skips text nodes.
  function allNextUntil(elem, until) {
    var matched = [];

    while ((elem = elem.nextSibling) && elem.nodeType !== 9) {
      if (elem.nodeType === 1 && jQuery(elem).is(until)) {
        break;
      }
      matched.push(elem);
    }
    return $(matched);
  }

  $(function() {
    initWidget();
  });
})(jQuery);

(function($, window) {
  'use strict';

  // Blogger API info
  var apiUrl = 'https://www.googleapis.com/blogger/v3';
  var apiKey = 'AIzaSyCFhbGnjW06dYwvRCU8h_zjdpS4PYYbEe8';

  // Blog IDs can be found in the markup of the blog posts
  var blogs = {
    'android-developers': {
      id: '6755709643044947179',
      title: 'Android Developers Blog'
    }
  };
  var monthNames = ['January', 'February', 'March', 'April', 'May', 'June',
      'July', 'August', 'September', 'October', 'November', 'December'];

  var BlogReader = (function() {
    var reader;

    function BlogReader() {
      this.doneSetup = false;
    }

    /**
     * Initialize the blog reader and modal.
     */
    BlogReader.prototype.setup = function() {
      $('#jd-content').append(
          '<div id="blog-reader" data-modal="blog-reader" class="dac-modal dac-has-small-header">' +
            '<div class="dac-modal-container">' +
              '<div class="dac-modal-window">' +
                '<header class="dac-modal-header">' +
                  '<div class="dac-modal-header-actions">' +
                    '<a href="" class="dac-modal-header-open" target="_blank">' +
                      '<i class="dac-sprite dac-open-in-new"></i>' +
                    '</a>' +
                    '<button class="dac-modal-header-close" data-modal-toggle>' +
                    '</button>' +
                  '</div>' +
                  '<h2 class="norule dac-modal-header-title"></h2>' +
                '</header>' +
                '<div class="dac-modal-content dac-blog-reader">' +
                  '<time class="dac-blog-reader-date" pubDate></time>' +
                  '<h3 class="dac-blog-reader-title"></h3>' +
                  '<div class="dac-blog-reader-text clearfix"></div>' +
                '</div>' +
              '</div>' +
            '</div>' +
          '</div>');

      this.blogReader = $('#blog-reader').dacModal();

      this.doneSetup = true;
    };

    BlogReader.prototype.openModal_ = function(blog, post) {
      var published = new Date(post.published);
      var formattedDate = monthNames[published.getMonth()] + ' ' + published.getDay() + ' ' + published.getFullYear();
      this.blogReader.find('.dac-modal-header-open').attr('href', post.url);
      this.blogReader.find('.dac-modal-header-title').text(blog.title);
      this.blogReader.find('.dac-blog-reader-title').html(post.title);
      this.blogReader.find('.dac-blog-reader-date').html(formattedDate);
      this.blogReader.find('.dac-blog-reader-text').html(post.content);
      this.blogReader.trigger('modal-open');
    };

    /**
     * Show a blog post in a modal
     * @param  {string} blogName - The name of the Blogspot blog.
     * @param  {string} postPath - The path to the blog post.
     * @param  {bool} secondTry - Has it failed once?
     */
    BlogReader.prototype.showPost = function(blogName, postPath, secondTry) {
      var blog = blogs[blogName];
      var postUrl = 'https://' + blogName + '.blogspot.com' + postPath;

      var url = apiUrl + '/blogs/' + blog.id + '/posts/bypath?path=' + encodeURIComponent(postPath) + '&key=' + apiKey;
      $.ajax(url, {timeout: 650}).done(this.openModal_.bind(this, blog)).fail(function(error) {
        // Retry once if we get an error
        if (error.status === 500 && !secondTry) {
          this.showPost(blogName, postPath, true);
        } else {
          window.location.href = postUrl;
        }
      }.bind(this));
    };

    return {
      getReader: function() {
        if (!reader) {
          reader = new BlogReader();
        }
        return reader;
      }
    };
  })();

  var blogReader = BlogReader.getReader();

  function wrapLinkWithReader(e) {
    var el = $(e.currentTarget);
    if (el.hasClass('dac-modal-header-open')) {
      return;
    }

    // Only catch links on blogspot.com
    var matches = el.attr('href').match(/https?:\/\/([^\.]*).blogspot.com([^$]*)/);
    if (matches && matches.length === 3) {
      var blogName = matches[1];
      var postPath = matches[2];

      // Check if we have information about the blog
      if (!blogs[blogName]) {
        return;
      }

      // Setup the first time it's used
      if (!blogReader.doneSetup) {
        blogReader.setup();
      }

      e.preventDefault();
      blogReader.showPost(blogName, postPath);
    }
  }

  $(document).on('click.blog-reader', 'a[href*="blogspot.com/"]', wrapLinkWithReader);
})(jQuery, window);

(function($) {
  $.fn.debounce = function(func, wait, immediate) {
    var timeout;

    return function() {
      var context = this;
      var args = arguments;

      var later = function() {
        timeout = null;
        if (!immediate) {
          func.apply(context, args);
        }
      };

      var callNow = immediate && !timeout;
      clearTimeout(timeout);
      timeout = setTimeout(later, wait);

      if (callNow) {
        func.apply(context, args);
      }
    };
  };
})(jQuery);

/* Calculate the vertical area remaining */
(function($) {
  $.fn.ellipsisfade = function() {
    // Only fetch line-height of first element to avoid recalculate style.
    // Will be NaN if no elements match, which is ok.
    var lineHeight = parseInt(this.css('line-height'), 10);

    this.each(function() {
      // get element text
      var $this = $(this);
      var remainingHeight = $this.parent().parent().height();
      $this.parent().siblings().each(function() {
        var elHeight;
        if ($(this).is(':visible')) {
          elHeight = $(this).outerHeight(true);
          remainingHeight = remainingHeight - elHeight;
        }
      });

      var adjustedRemainingHeight = ((remainingHeight) / lineHeight >> 0) * lineHeight;
      $this.parent().css({height: adjustedRemainingHeight});
      $this.css({height: 'auto'});
    });

    return this;
  };

  /* Pass the line height to ellipsisfade() to adjust the height of the
   text container to show the max number of lines possible, without
   showing lines that are cut off. This works with the css ellipsis
   classes to fade last text line and apply an ellipsis char. */
  function updateEllipsis(context) {
    if (!(context instanceof jQuery)) {
      context = $('html');
    }

    context.find('.card-info .text').ellipsisfade();
  }

  $(window).on('resize', $.fn.debounce(updateEllipsis, 500));
  $(updateEllipsis);
  $('html').on('dac:domchange', function(e) { updateEllipsis($(e.target)); });
})(jQuery);

/* Filter */
(function($) {
  'use strict';

  /**
   * A single filter item content.
   * @type {string} - Element template.
   * @private
   */
  var ITEM_STR_ = '<input type="checkbox" value="{{value}}" class="dac-form-checkbox" id="{{id}}">' +
      '<label for="{{id}}" class="dac-form-checkbox-button"></label>' +
      '<label for="{{id}}" class="dac-form-label">{{name}}</label>';

  /**
   * Template for a chip element.
   * @type {*|HTMLElement}
   * @private
   */
  var CHIP_BASE_ = $('<li class="dac-filter-chip">' +
    '<button class="dac-filter-chip-close">' +
      '<i class="dac-sprite dac-close-black dac-filter-chip-close-icon"></i>' +
    '</button>' +
  '</li>');

  /**
   * Component to handle narrowing down resources.
   * @param {HTMLElement} el - The DOM element.
   * @param {Object} options
   * @constructor
   */
  function Filter(el, options) {
    this.el = $(el);
    this.options = $.extend({}, Filter.DEFAULTS_, options);
    this.init();
  }

  Filter.DEFAULTS_ = {
    activeClass: 'dac-active',
    chipsDataAttr: 'filter-chips',
    nameDataAttr: 'filter-name',
    countDataAttr: 'filter-count',
    tabViewDataAttr: 'tab-view',
    valueDataAttr: 'filter-value'
  };

  /**
   * Draw resource cards.
   * @param {Array} resources
   * @private
   */
  Filter.prototype.draw_ = function(resources) {
    var that = this;

    if (resources.length === 0) {
      this.containerEl_.html('<p class="dac-filter-message">Nothing matches selected filters.</p>');
      return;
    }

    // Draw resources.
    that.containerEl_.resourceWidget(resources, that.data_.options);
  };

  /**
   * Initialize a Filter component.
   */
  Filter.prototype.init = function() {
    this.containerEl_ = $(this.options.filter);

    // Setup data settings
    this.data_ = {};
    this.data_.chips = {};
    this.data_.options = this.containerEl_.widgetOptions();
    this.data_.all = window.metadata.query(this.data_.options);

    // Initialize filter UI
    this.initUi();
  };

  /**
   * Generate a chip for a given filter item.
   * @param {Object} item - A single filter option (checkbox container).
   * @returns {HTMLElement} A new Chip element.
   */
  Filter.prototype.chipForItem = function(item) {
    var chip = CHIP_BASE_.clone();
    chip.prepend(this.data_.chips[item.data('filter-value')]);
    chip.data('item.dac-filter', item);
    item.data('chip.dac-filter', chip);
    this.addToItemValue(item, 1);
    return chip[0];
  };

  /**
   * Update count of checked filter items.
   * @param {Object} item - A single filter option (checkbox container).
   * @param {Number} value - Either -1 or 1.
   */
  Filter.prototype.addToItemValue = function(item, value) {
    var tab = item.parent().data(this.options.tabViewDataAttr);
    var countEl = this.countEl_.filter('[data-' + this.options.countDataAttr + '="' + tab + '"]');
    var count = value + parseInt(countEl.text(), 10);
    countEl.text(count);
    countEl.toggleClass('dac-disabled', count === 0);
  };

  /**
   * Set event listeners.
   * @private
   */
  Filter.prototype.setEventListeners_ = function() {
    this.chipsEl_.on('click.dac-filter', '.dac-filter-chip-close', this.closeChipHandler_.bind(this));
    this.tabViewEl_.on('change.dac-filter', ':checkbox', this.toggleCheckboxHandler_.bind(this));
  };

  /**
   * Check filter items that are active by default.
   */
  Filter.prototype.activateInitialFilters_ = function() {
    var id = (new Date()).getTime();
    var initiallyCheckedValues = this.data_.options.query.replace(/,\s*/g, '+').split('+');
    var chips = document.createDocumentFragment();
    var that = this;

    this.items_.each(function(i) {
      var item = $(this);
      var opts = item.data();
      that.data_.chips[opts.filterValue] = opts.filterName;

      var checkbox = $(ITEM_STR_.replace(/\{\{name\}\}/g, opts.filterName)
        .replace(/\{\{value\}\}/g, opts.filterValue)
        .replace(/\{\{id\}\}/g, 'filter-' + id + '-' + (i + 1)));

      if (initiallyCheckedValues.indexOf(opts.filterValue) > -1) {
        checkbox[0].checked = true;
        chips.appendChild(that.chipForItem(item));
      }

      item.append(checkbox);
    });

    this.chipsEl_.append(chips);
  };

  /**
   * Initialize the Filter view
   */
  Filter.prototype.initUi = function() {
    // Cache DOM elements
    this.chipsEl_ = this.el.find('[data-' + this.options.chipsDataAttr + ']');
    this.countEl_ = this.el.find('[data-' + this.options.countDataAttr + ']');
    this.tabViewEl_ = this.el.find('[data-' + this.options.tabViewDataAttr + ']');
    this.items_ = this.el.find('[data-' + this.options.nameDataAttr + ']');

    // Setup UI
    this.draw_(this.data_.all);
    this.activateInitialFilters_();
    this.setEventListeners_();
  };

  /**
   * @returns {[types|Array, tags|Array, category|Array]}
   */
  Filter.prototype.getActiveClauses = function() {
    var tags = [];
    var types = [];
    var categories = [];

    this.items_.find(':checked').each(function(i, checkbox) {
      // Currently, there is implicit business logic here that `tag` is AND'ed together
      // while `type` is OR'ed. So , and + do the same thing here. It would be great to
      // reuse the same query engine for filters, but it would need more powerful syntax.
      // Probably parenthesis, to support "tag:dog + tag:cat + (type:video, type:blog)"
      var expression = $(checkbox).val();
      var regex = /(\w+):(\w+)/g;
      var match;

      while (match = regex.exec(expression)) {
        switch (match[1]) {
          case 'category':
            categories.push(match[2]);
            break;
          case 'tag':
            tags.push(match[2]);
            break;
          case 'type':
            types.push(match[2]);
            break;
        }
      }
    });

    return [types, tags, categories];
  };

  /**
   * Actual filtering logic.
   * @returns {Array}
   */
  Filter.prototype.filteredResources = function() {
    var data = this.getActiveClauses();
    var types = data[0];
    var tags = data[1];
    var categories = data[2];
    var resources = [];
    var resource = {};
    var tag = '';
    var shouldAddResource = true;

    for (var resourceIndex = 0; resourceIndex < this.data_.all.length; resourceIndex++) {
      resource = this.data_.all[resourceIndex];
      shouldAddResource = types.indexOf(resource.type) > -1;

      if (categories && categories.length > 0) {
        shouldAddResource = shouldAddResource && categories.indexOf(resource.category) > -1;
      }

      for (var tagIndex = 0; shouldAddResource && tagIndex < tags.length; tagIndex++) {
        tag = tags[tagIndex];
        shouldAddResource = resource.tags.indexOf(tag) > -1;
      }

      if (shouldAddResource) {
        resources.push(resource);
      }
    }

    return resources;
  };

  /**
   * Close Chip Handler
   * @param {Event} event - Click event
   * @private
   */
  Filter.prototype.closeChipHandler_ = function(event) {
    var chip = $(event.currentTarget).parent();
    var checkbox = chip.data('item.dac-filter').find(':first-child')[0];
    checkbox.checked = false;
    this.changeStateForCheckbox(checkbox);
  };

  /**
   * Handle filter item state change.
   * @param {Event} event - Change event
   * @private
   */
  Filter.prototype.toggleCheckboxHandler_ = function(event) {
    this.changeStateForCheckbox(event.currentTarget);
  };

  /**
   * Redraw resource view based on new state.
   * @param checkbox
   */
  Filter.prototype.changeStateForCheckbox = function(checkbox) {
    var item = $(checkbox).parent();

    if (checkbox.checked) {
      this.chipsEl_.append(this.chipForItem(item));
      ga('send', 'event', 'Filters', 'Check', $(checkbox).val());
    } else {
      item.data('chip.dac-filter').remove();
      this.addToItemValue(item, -1);
      ga('send', 'event', 'Filters', 'Uncheck', $(checkbox).val());
    }

    this.draw_(this.filteredResources());
  };

  /**
   * jQuery plugin
   */
  $.fn.dacFilter = function() {
    return this.each(function() {
      var el = $(this);
      new Filter(el, el.data());
    });
  };

  /**
   * Data Attribute API
   */
  $(function() {
    $('[data-filter]').dacFilter();
  });
})(jQuery);

(function($) {
  'use strict';

  /**
   * Toggle Floating Label state.
   * @param {HTMLElement} el - The DOM element.
   * @param options
   * @constructor
   */
  function FloatingLabel(el, options) {
    this.el = $(el);
    this.options = $.extend({}, FloatingLabel.DEFAULTS_, options);
    this.group = this.el.closest('.dac-form-input-group');
    this.input = this.group.find('.dac-form-input');

    this.checkValue_ = this.checkValue_.bind(this);
    this.checkValue_();

    this.input.on('focus', function() {
      this.group.addClass('dac-focused');
    }.bind(this));
    this.input.on('blur', function() {
      this.group.removeClass('dac-focused');
      this.checkValue_();
    }.bind(this));
    this.input.on('keyup', this.checkValue_);
  }

  /**
   * The label is moved out of the textbox when it has a value.
   */
  FloatingLabel.prototype.checkValue_ = function() {
    if (this.input.val().length) {
      this.group.addClass('dac-has-value');
    } else {
      this.group.removeClass('dac-has-value');
    }
  };

  /**
   * jQuery plugin
   * @param  {object} options - Override default options.
   */
  $.fn.dacFloatingLabel = function(options) {
    return this.each(function() {
      new FloatingLabel(this, options);
    });
  };

  $(document).on('ready.aranja', function() {
    $('.dac-form-floatlabel').each(function() {
      $(this).dacFloatingLabel($(this).data());
    });
  });
})(jQuery);

(function($) {
  'use strict';

  /**
   * @param {HTMLElement} el - The DOM element.
   * @param {Object} options
   * @constructor
   */
  function Crumbs(selected, options) {
    this.options = $.extend({}, Crumbs.DEFAULTS_, options);
    this.el = $(this.options.container);

    // Do not build breadcrumbs for landing site.
    if (!selected || location.pathname === '/index.html' || location.pathname === '/') {
      return;
    }

    // Cache navigation resources
    this.selected = $(selected);
    this.selectedParent = this.selected.closest('.dac-nav-secondary').siblings('a');

    // Build the breadcrumb list.
    this.init();
  }

  Crumbs.DEFAULTS_ = {
    container: '.dac-header-crumbs',
    crumbItem: $('<li class="dac-header-crumbs-item">'),
    linkClass: 'dac-header-crumbs-link'
  };

  Crumbs.prototype.init = function() {
    Crumbs.buildCrumbForLink(this.selected.clone()).appendTo(this.el);

    if (this.selectedParent.length) {
      Crumbs.buildCrumbForLink(this.selectedParent.clone()).prependTo(this.el);
    }

    // Reveal the breadcrumbs
    this.el.addClass('dac-has-content');
  };

  /**
   * Build a HTML structure for a breadcrumb.
   * @param {string} link
   * @return {jQuery}
   */
  Crumbs.buildCrumbForLink = function(link) {
    link.find('br').replaceWith(' ');

    var crumbLink = $('<a>')
      .attr('class', Crumbs.DEFAULTS_.linkClass)
      .attr('href', link.attr('href'))
      .text(link.text());

    return Crumbs.DEFAULTS_.crumbItem.clone().append(crumbLink);
  };

  /**
   * jQuery plugin
   */
  $.fn.dacCrumbs = function(options) {
    return this.each(function() {
      new Crumbs(this, options);
    });
  };
})(jQuery);

(function($) {
  'use strict';

  /**
   * @param {HTMLElement} el - The DOM element.
   * @param {Object} options
   * @constructor
   */
  function SearchInput(el, options) {
    this.el = $(el);
    this.options = $.extend({}, SearchInput.DEFAULTS_, options);
    this.body = $('body');
    this.input = this.el.find('input');
    this.close = this.el.find(this.options.closeButton);
    this.clear = this.el.find(this.options.clearButton);
    this.icon = this.el.find('.' + this.options.iconClass);
    this.init();
  }

  SearchInput.DEFAULTS_ = {
    activeClass: 'dac-active',
    activeIconClass: 'dac-search',
    closeButton: '[data-search-close]',
    clearButton: '[data-search-clear]',
    hiddenClass: 'dac-hidden',
    iconClass: 'dac-header-search-icon',
    searchModeClass: 'dac-search-mode',
    transitionDuration: 250
  };

  SearchInput.prototype.init = function() {
    this.input.on('focus.dac-search', this.setActiveState.bind(this))
              .on('input.dac-search', this.checkInputValue.bind(this));
    this.close.on('click.dac-search', this.unsetActiveStateHandler_.bind(this));
    this.clear.on('click.dac-search', this.clearInput.bind(this));
  };

  SearchInput.prototype.setActiveState = function() {
    var that = this;

    this.clear.addClass(this.options.hiddenClass);
    this.body.addClass(this.options.searchModeClass);
    this.checkInputValue();

    // Set icon to black after background has faded to white.
    setTimeout(function() {
      that.icon.addClass(that.options.activeIconClass);
    }, this.options.transitionDuration);
  };

  SearchInput.prototype.unsetActiveStateHandler_ = function(event) {
    event.preventDefault();
    this.unsetActiveState();
  };

  SearchInput.prototype.unsetActiveState = function() {
    this.icon.removeClass(this.options.activeIconClass);
    this.clear.addClass(this.options.hiddenClass);
    this.body.removeClass(this.options.searchModeClass);
  };

  SearchInput.prototype.clearInput = function(event) {
    event.preventDefault();
    this.input.val('');
    this.clear.addClass(this.options.hiddenClass);
  };

  SearchInput.prototype.checkInputValue = function() {
    if (this.input.val().length) {
      this.clear.removeClass(this.options.hiddenClass);
    } else {
      this.clear.addClass(this.options.hiddenClass);
    }
  };

  /**
   * jQuery plugin
   * @param {object} options - Override default options.
   */
  $.fn.dacSearchInput = function() {
    return this.each(function() {
      var el = $(this);
      el.data('search-input.dac', new SearchInput(el, el.data()));
    });
  };

  /**
   * Data Attribute API
   */
  $(function() {
    $('[data-search]').dacSearchInput();
  });
})(jQuery);

/* global METADATA */
(function($) {
  function DacCarouselQuery(el) {
    el = $(el);

    var opts = el.data();
    opts.maxResults = parseInt(opts.maxResults || '100', 10);
    opts.query = opts.carouselQuery;
    var resources = window.metadata.query(opts);

    el.empty();
    $(resources).each(function() {
      var resource = $.extend({}, this, METADATA.carousel[this.url]);
      el.dacHero(resource);
    });

    // Pagination element.
    el.append('<div class="dac-hero-carousel-pagination"><div class="wrap" data-carousel-pagination>');

    el.dacCarousel();
  }

  // jQuery plugin
  $.fn.dacCarouselQuery = function() {
    return this.each(function() {
      var el = $(this);
      var data = el.data('dac.carouselQuery');

      if (!data) { el.data('dac.carouselQuery', (data = new DacCarouselQuery(el))); }
    });
  };

  // Data API
  $(function() {
    $('[data-carousel-query]').dacCarouselQuery();
  });
})(jQuery);

(function($) {
  /**
   * A CSS based carousel, inspired by SequenceJS.
   * @param {jQuery} el
   * @param {object} options
   * @constructor
   */
  function DacCarousel(el, options) {
    this.el = $(el);
    this.options = options = $.extend({}, DacCarousel.OPTIONS, this.el.data(), options || {});
    this.frames = this.el.find(options.frameSelector);
    this.count = this.frames.size();
    this.current = options.start;

    this.initPagination();
    this.initEvents();
    this.initFrame();
  }

  DacCarousel.OPTIONS = {
    auto:      true,
    autoTime:  10000,
    autoMinTime: 5000,
    btnPrev:   '[data-carousel-prev]',
    btnNext:   '[data-carousel-next]',
    frameSelector: 'article',
    loop:      true,
    start:     0,
    swipeThreshold: 160,
    pagination: '[data-carousel-pagination]'
  };

  DacCarousel.prototype.initPagination = function() {
    this.pagination = $([]);
    if (!this.options.pagination) { return; }

    var pagination = $('<ul class="dac-pagination">');
    var parent = this.el;
    if (typeof this.options.pagination === 'string') { parent = this.el.find(this.options.pagination); }

    if (this.count > 1) {
      for (var i = 0; i < this.count; i++) {
        var li = $('<li class="dac-pagination-item">').text(i);
        if (i === this.options.start) { li.addClass('active'); }
        li.click(this.go.bind(this, i));

        pagination.append(li);
      }
      this.pagination = pagination.children();
      parent.append(pagination);
    }
  };

  DacCarousel.prototype.initEvents = function() {
    var that = this;

    this.touch = {
      start: {x: 0, y: 0},
      end:   {x: 0, y: 0}
    };

    this.el.on('touchstart', this.touchstart_.bind(this));
    this.el.on('touchend', this.touchend_.bind(this));
    this.el.on('touchmove', this.touchmove_.bind(this));

    this.el.hover(function() {
      that.pauseRotateTimer();
    }, function() {
      that.startRotateTimer();
    });

    $(this.options.btnPrev).click(function(e) {
      e.preventDefault();
      that.prev();
    });

    $(this.options.btnNext).click(function(e) {
      e.preventDefault();
      that.next();
    });
  };

  DacCarousel.prototype.touchstart_ = function(event) {
    var t = event.originalEvent.touches[0];
    this.touch.start = {x: t.screenX, y: t.screenY};
  };

  DacCarousel.prototype.touchend_ = function() {
    var deltaX = this.touch.end.x - this.touch.start.x;
    var deltaY = Math.abs(this.touch.end.y - this.touch.start.y);
    var shouldSwipe = (deltaY < Math.abs(deltaX)) && (Math.abs(deltaX) >= this.options.swipeThreshold);

    if (shouldSwipe) {
      if (deltaX > 0) {
        this.prev();
      } else {
        this.next();
      }
    }
  };

  DacCarousel.prototype.touchmove_ = function(event) {
    var t = event.originalEvent.touches[0];
    this.touch.end = {x: t.screenX, y: t.screenY};
  };

  DacCarousel.prototype.initFrame = function() {
    this.frames.removeClass('active').eq(this.options.start).addClass('active');
  };

  DacCarousel.prototype.startRotateTimer = function() {
    if (!this.options.auto || this.rotateTimer) { return; }
    this.rotateTimer = setTimeout(this.next.bind(this), this.options.autoTime);
  };

  DacCarousel.prototype.pauseRotateTimer = function() {
    clearTimeout(this.rotateTimer);
    this.rotateTimer = null;
  };

  DacCarousel.prototype.prev = function() {
    this.go(this.current - 1);
  };

  DacCarousel.prototype.next = function() {
    this.go(this.current + 1);
  };

  DacCarousel.prototype.go = function(next) {
    // Figure out what the next slide is.
    while (this.count > 0 && next >= this.count) { next -= this.count; }
    while (next < 0) { next += this.count; }

    // Cancel if we're already on that slide.
    if (next === this.current) { return; }

    // Prepare next slide.
    this.frames.eq(next).removeClass('out');

    // Recalculate styles before starting slide transition.
    this.el.resolveStyles();
    // Update pagination
    this.pagination.removeClass('active').eq(next).addClass('active');

    // Transition out current frame
    this.frames.eq(this.current).toggleClass('active out');

    // Transition in a new frame
    this.frames.eq(next).toggleClass('active');

    this.current = next;
  };

  // Helper which resolves new styles for an element, so it can start transitioning
  // from the new values.
  $.fn.resolveStyles = function() {
    /*jshint expr:true*/
    this[0] && this[0].offsetTop;
    return this;
  };

  // jQuery plugin
  $.fn.dacCarousel = function() {
    this.each(function() {
      var $el = $(this);
      $el.data('dac-carousel', new DacCarousel(this));
    });
    return this;
  };

  // Data API
  $(function() {
    $('[data-carousel]').dacCarousel();
  });
})(jQuery);

/* global toRoot */

(function($) {
  // Ordering matters
  var TAG_MAP = [
    {from: 'developerstory', to: 'Android Developer Story'},
    {from: 'googleplay', to: 'Google Play'}
  ];

  function DacHero(el, resource, isSearch) {
    var slide = $('<article>');
    slide.addClass(isSearch ? 'dac-search-hero' : 'dac-expand dac-hero');
    var image = cleanUrl(resource.heroImage || resource.image);
    var fullBleed = image && !resource.heroColor;

    if (!isSearch) {
      // Configure background
      slide.css({
        backgroundImage: fullBleed ? 'url(' + image + ')' : '',
        backgroundColor: resource.heroColor || ''
      });

      // Should copy be inverted
      slide.toggleClass('dac-invert', resource.heroInvert || fullBleed);
      slide.toggleClass('dac-darken', fullBleed);

      // Should be clickable
      slide.append($('<a class="dac-hero-carousel-action">').attr('href', cleanUrl(resource.url)));
    }

    var cols = $('<div class="cols dac-hero-content">');

    // inline image column
    var rightCol = $('<div class="col-1of2 col-push-1of2 dac-hero-figure">')
      .appendTo(cols);

    if ((!fullBleed || isSearch) && image) {
      rightCol.append($('<img>').attr('src', image));
    }

    // info column
    $('<div class="col-1of2 col-pull-1of2">')
      .append($('<div class="dac-hero-tag">').text(formatTag(resource)))
      .append($('<h1 class="dac-hero-title">').text(formatTitle(resource)))
      .append($('<p class="dac-hero-description">').text(resource.summary))
      .append($('<a class="dac-hero-cta">')
        .text(formatCTA(resource))
        .attr('href', cleanUrl(resource.url))
        .prepend($('<span class="dac-sprite dac-auto-chevron">'))
      )
      .appendTo(cols);

    slide.append(cols.wrap('<div class="wrap">').parent());
    el.append(slide);
  }

  function cleanUrl(url) {
    if (url && url.indexOf('//') === -1) {
      url = toRoot + url;
    }
    return url;
  }

  function formatTag(resource) {
    // Hmm, need a better more scalable solution for this.
    for (var i = 0, mapping; mapping = TAG_MAP[i]; i++) {
      if (resource.tags.indexOf(mapping.from) > -1) {
        return mapping.to;
      }
    }
    return resource.type;
  }

  function formatTitle(resource) {
    return resource.title.replace(/android developer story: /i, '');
  }

  function formatCTA(resource) {
    return resource.type === 'youtube' ? 'Watch the video' : 'Learn more';
  }

  // jQuery plugin
  $.fn.dacHero = function(resource, isSearch) {
    return this.each(function() {
      var el = $(this);
      return new DacHero(el, resource, isSearch);
    });
  };
})(jQuery);

(function($) {
  'use strict';

  function highlightString(label, query) {
    query = query || '';
    //query = query.replace('<wbr>', '').replace('.', '\\.');
    var queryRE = new RegExp('(' + query + ')', 'ig');
    return label.replace(queryRE, '<em>$1</em>');
  }

  $.fn.highlightMatches = function(query) {
    return this.each(function() {
      var el = $(this);
      var label = el.html();
      var highlighted = highlightString(label, query);
      el.html(highlighted);
      el.addClass('highlighted');
    });
  };
})(jQuery);

/**
 * History tracking.
 * Track visited urls in localStorage.
 */
(function($) {
  var PAGES_TO_STORE_ = 100;
  var MIN_NUMBER_OF_PAGES_TO_DISPLAY_ = 6;
  var CONTAINER_SELECTOR_ = '.dac-search-results-history-wrap';

  /**
   * Generate resource cards for visited pages.
   * @param {HTMLElement} el
   * @constructor
   */
  function HistoryQuery(el) {
    this.el = $(el);

    // Only show history component if enough pages have been visited.
    if (getVisitedPages().length < MIN_NUMBER_OF_PAGES_TO_DISPLAY_) {
      this.el.closest(CONTAINER_SELECTOR_).addClass('dac-hidden');
      return;
    }

    // Rename query
    this.el.data('query', this.el.data('history-query'));

    // jQuery method to populate cards.
    this.el.resourceWidget();
  }

  /**
   * Fetch from localStorage an array of visted pages
   * @returns {Array}
   */
  function getVisitedPages() {
    var visited = localStorage.getItem('visited-pages');
    return visited ? JSON.parse(visited) : [];
  }

  /**
   * Return a page corresponding to cuurent pathname. If none exists, create one.
   * @param {Array} pages
   * @param {String} path
   * @returns {Object} Page
   */
  function getPageForPath(pages, path) {
    var page;

    // Backwards lookup for current page, last pages most likely to be visited again.
    for (var i = pages.length - 1; i >= 0; i--) {
      if (pages[i].path === path) {
        page = pages[i];

        // Remove page object from pages list to ensure correct ordering.
        pages.splice(i, 1);

        return page;
      }
    }

    // If storage limit is exceeded, remove last visited path.
    if (pages.length >= PAGES_TO_STORE_) {
      pages.shift();
    }

    return {path: path};
  }

  /**
   * Add current page to back of visited array, increase hit count by 1.
   */
  function addCurrectPage() {
    var path = location.pathname;

    // Do not track frontpage visits.
    if (path === '/' || path === '/index.html') {return;}

    var pages = getVisitedPages();
    var page = getPageForPath(pages, path);

    // New page visits have no hit count.
    page.hit = ~~page.hit + 1;

    // Most recently visted pages are located at the end of the visited array.
    pages.push(page);

    localStorage.setItem('visited-pages', JSON.stringify(pages));
  }

  /**
   * Hit count compare function.
   * @param {Object} a - page
   * @param {Object} b - page
   * @returns {number}
   */
  function byHit(a, b) {
    if (a.hit > b.hit) {
      return -1;
    } else if (a.hit < b.hit) {
      return 1;
    }

    return 0;
  }

  /**
   * Return a list of visited urls in a given order.
   * @param {String} order - (recent|most-visited)
   * @returns {Array}
   */
  $.dacGetVisitedUrls = function(order) {
    var pages = getVisitedPages();

    if (order === 'recent') {
      pages.reverse();
    } else {
      pages.sort(byHit);
    }

    return pages.map(function(page) {
      return page.path.replace(/^\//, '');
    });
  };

  // jQuery plugin
  $.fn.dacHistoryQuery = function() {
    return this.each(function() {
      var el = $(this);
      var data = el.data('dac.recentlyVisited');

      if (!data) {
        el.data('dac.recentlyVisited', (data = new HistoryQuery(el)));
      }
    });
  };

  $(function() {
    $('[data-history-query]').dacHistoryQuery();
    // Do not block page rendering.
    setTimeout(addCurrectPage, 0);
  });
})(jQuery);

/* ############################################ */
/* ##########     LOCALIZATION     ############ */
/* ############################################ */
/**
 * Global helpers.
 */
function getBaseUri(uri) {
  var intlUrl = (uri.substring(0, 6) === '/intl/');
  if (intlUrl) {
    var base = uri.substring(uri.indexOf('intl/') + 5, uri.length);
    base = base.substring(base.indexOf('/') + 1, base.length);
    return '/' + base;
  } else {
    return uri;
  }
}

function changeLangPref(targetLang, submit) {
  window.writeCookie('pref_lang', targetLang, null);
//DD
  $('#language').find('option[value="' + targetLang + '"]').attr('selected', true);
  //  #######  TODO:  Remove this condition once we're stable on devsite #######
  //  This condition is only needed if we still need to support legacy GAE server
  if (window.devsite) {
    // Switch language when on Devsite server
    if (submit) {
      $('#setlang').submit();
    }
  } else {
    // Switch language when on legacy GAE server
    if (submit) {
      window.location = getBaseUri(location.pathname);
    }
  }
}
// Redundant usage to appease jshint.
window.changeLangPref = changeLangPref;

(function() {
  /**
   * Whitelisted locales. Should match choices in language dropdown. Repeated here
   * as a lot of i18n logic happens before page load and dropdown is ready.
   */
  var LANGUAGES = [
    'en',
    'es',
    'in',
    'ja',
    'ko',
    'pt-br',
    'ru',
    'vi',
    'zh-cn',
    'zh-tw'
  ];

  /**
   * Master list of translated strings for template files.
   */
  var PHRASES = {
    'newsletter': {
      'title': 'Get the latest Android developer news and tips that will help you find success on Google Play.',
      'requiredHint': '* Required Fields',
      'name': 'Full name',
      'email': 'Email address',
      'company': 'Company / developer name',
      'appUrl': 'One of your Play Store app URLs',
      'business': {
        'label': 'Which best describes your business:',
        'apps': 'Apps',
        'games': 'Games',
        'both': 'Apps & Games'
      },
      'confirmMailingList': 'Add me to the mailing list for the monthly newsletter and occasional emails about ' +
                            'development and Google Play opportunities.',
      'privacyPolicy': 'I acknowledge that the information provided in this form will be subject to Google\'s ' +
                       '<a href="https://www.google.com/policies/privacy/" target="_blank">privacy policy</a>.',
      'languageVal': 'English',
      'successTitle': 'Hooray!',
      'successDetails': 'You have successfully signed up for the latest Android developer news and tips.',
      'languageValTarget': {
        'en': 'English',
        'ar': 'Arabic (العربيّة)',
        'in': 'Indonesian (Bahasa)',
        'fr': 'French (français)',
        'de': 'German (Deutsch)',
        'ja': 'Japanese (日本語)',
        'ko': 'Korean (한국어)',
        'ru': 'Russian (Русский)',
        'es': 'Spanish (español)',
        'th': 'Thai (ภาษาไทย)',
        'tr': 'Turkish (Türkçe)',
        'vi': 'Vietnamese (tiếng Việt)',
        'pt-br': 'Brazilian Portuguese (Português Brasileiro)',
        'zh-cn': 'Simplified Chinese (简体中文)',
        'zh-tw': 'Traditional Chinese (繁體中文)',
      },
      'resetLangTitle': "Browse this site in %{targetLang}?",
      'resetLangTextIntro': 'You requested a page in %{targetLang}, but your language preference for this site is %{lang}.',
      'resetLangTextCta': 'Would you like to change your language preference and browse this site in %{targetLang}? ' +
                          'If you want to change your language preference later, use the language menu at the bottom of each page.',
      'resetLangButtonYes': 'Change Language',
      'resetLangButtonNo': 'Not Now'
    }
  };

  /**
   * Current locale.
   */
  var locale = (function() {
    var lang = window.devsite ? window.devsiteLang : window.readCookie('pref_lang');
    if (lang === 0 || LANGUAGES.indexOf(lang) === -1) {
      lang = 'en';
    }
    return lang;
  })();
  var localeTarget = (function() {
    var localeTarget = locale;
    if (location.pathname.substring(0,6) == "/intl/") {
      var target = location.pathname.split('/')[2];
      if (!(target === 0) || (LANGUAGES.indexOf(target) === -1)) {
        localeTarget = target;
      }
    }
    return localeTarget;
  })();

  /**
   * Global function shims for backwards compatibility
   */
  window.changeNavLang = function() {
    // Already done.
  };

  window.loadLangPref = function() {
    // Languages pref already loaded.
  };

  window.getLangPref = function() {
    return locale;
  };

  window.getLangTarget = function() {
    return localeTarget;
  };

  // Expose polyglot instance for advanced localization.
  var polyglot = window.polyglot = new window.Polyglot({
    locale: locale,
    phrases: PHRASES
  });

  // When DOM is ready.
  $(function() {
    // Mark current locale in language picker.
    $('#language').find('option[value="' + locale + '"]').attr('selected', true);

    $('html').dacTranslate().on('dac:domchange', function(e) {
      $(e.target).dacTranslate();
    });
  });

  $.fn.dacTranslate = function() {
    // Translate strings in template markup:

    // OLD
    // Having all translations in HTML does not scale well and bloats every page.
    // Need to migrate this to data-l JS translations below.
    if (locale !== 'en') {
      var $links = this.find('a[' + locale + '-lang]');
      $links.each(function() { // for each link with a translation
        var $link = $(this);
        // put the desired language from the attribute as the text
        $link.text($link.attr(locale + '-lang'));
      });
    }

    // NEW
    // A simple declarative api for JS translations. Feel free to extend as appropriate.

    // Miscellaneous string compilations
    // Build full strings from localized substrings:
    var myLocaleTarget = window.getLangTarget();
    var myTargetLang = window.polyglot.t("newsletter.languageValTarget." + myLocaleTarget);
    var myLang = window.polyglot.t("newsletter.languageVal");
    var myTargetLangTitleString = window.polyglot.t("newsletter.resetLangTitle", {targetLang: myTargetLang});
    var myResetLangTextIntro = window.polyglot.t("newsletter.resetLangTextIntro", {targetLang: myTargetLang, lang: myLang});
    var myResetLangTextCta = window.polyglot.t("newsletter.resetLangTextCta", {targetLang: myTargetLang});
    //var myResetLangButtonYes = window.polyglot.t("newsletter.resetLangButtonYes", {targetLang: myTargetLang});

    // Inject strings as text values in dialog components:
    $("#langform .dac-modal-header-title").text(myTargetLangTitleString);
    $("#langform #resetLangText").text(myResetLangTextIntro);
    $("#langform #resetLangCta").text(myResetLangTextCta);
    //$("#resetLangButtonYes").attr("data-t", window.polyglot.t(myResetLangButtonYes));

    // Text: <div data-t="nav.home"></div>
    // HTML: <div data-t="privacy" data-t-html></html>
    this.find('[data-t]').each(function() {
      var el = $(this);
      var data = el.data();
      if (data.t) {
        el[data.tHtml === '' ? 'html' : 'text'](polyglot.t(data.t));
      }
    });

    return this;
  };
})();
/* ##########     END LOCALIZATION     ############ */

// Translations. These should eventually be moved into language-specific files and loaded on demand.
// jshint nonbsp:false
switch (window.getLangPref()) {
  case 'ar':
    window.polyglot.extend({
      'newsletter': {
        'title': 'Google Play. يمكنك الحصول على آخر الأخبار والنصائح من مطوّري تطبيقات Android، مما يساعدك ' +
          'على تحقيق النجاح على',
        'requiredHint': '* حقول مطلوبة',
        'name': '. الاسم بالكامل ',
        'email': '. عنوان البريد الإلكتروني ',
        'company': '. اسم الشركة / اسم مطوّر البرامج',
        'appUrl': '. أحد عناوين URL لتطبيقاتك في متجر Play',
        'business': {
          'label': '. ما العنصر الذي يوضح طبيعة نشاطك التجاري بدقة؟ ',
          'apps': 'التطبيقات',
          'games': 'الألعاب',
          'both': 'التطبيقات والألعاب'
        },
        'confirmMailingList': 'إضافتي إلى القائمة البريدية للنشرة الإخبارية الشهرية والرسائل الإلكترونية التي يتم' +
          ' إرسالها من حين لآخر بشأن التطوير وفرص Google Play.',
        'privacyPolicy': 'أقر بأن المعلومات المقدَّمة في هذا النموذج تخضع لسياسة خصوصية ' +
          '<a href="https://www.google.com/intl/ar/policies/privacy/" target="_blank">Google</a>.',
        'languageVal': 'Arabic (العربيّة)',
        'successTitle': 'رائع!',
        'successDetails': 'لقد اشتركت بنجاح للحصول على آخر الأخبار والنصائح من مطوّري برامج Android.'
      }
    });
    break;
  case 'zh-cn':
    window.polyglot.extend({
      'newsletter': {
        'title': '获取最新的 Android 开发者资讯和提示，助您在 Google Play 上取得成功。',
        'requiredHint': '* 必填字段',
        'name': '全名',
        'email': '电子邮件地址',
        'company': '公司/开发者名称',
        'appUrl': '您的某个 Play 商店应用网址',
        'business': {
          'label': '哪一项能够最准确地描述您的业务？',
          'apps': '应用',
          'games': '游戏',
          'both': '应用和游戏'
        },
        'confirmMailingList': '将我添加到邮寄名单，以便接收每月简报以及不定期发送的关于开发和 Google Play 商机的电子邮件。',
        'privacyPolicy': '我确认自己了解在此表单中提供的信息受 <a href="https://www.google.com/intl/zh-CN/' +
        'policies/privacy/" target="_blank">Google</a> 隐私权政策的约束。',
        'languageVal': 'Simplified Chinese (简体中文)',
        'successTitle': '太棒了！',
        'successDetails': '您已成功订阅最新的 Android 开发者资讯和提示。'
      }
    });
    break;
  case 'zh-tw':
    window.polyglot.extend({
      'newsletter': {
        'title': '獲得 Android 開發人員的最新消息和各項秘訣，讓您在 Google Play 上輕鬆邁向成功之路。',
        'requiredHint': '* 必要欄位',
        'name': '全名',
        'email': '電子郵件地址',
        'company': '公司/開發人員名稱',
        'appUrl': '您其中一個 Play 商店應用程式的網址',
        'business': {
          'label': '為您的商家選取最合適的產品類別。',
          'apps': '應用程式',
          'games': '遊戲',
          'both': '應用程式和遊戲'
        },
        'confirmMailingList': '我想加入 Google Play 的郵寄清單，以便接收每月電子報和 Google Play 不定期寄送的電子郵件，' +
          '瞭解關於開發和 Google Play 商機的資訊。',
        'privacyPolicy': '我瞭解，我在這張表單中提供的資訊將受到 <a href="' +
        'https://www.google.com/intl/zh-TW/policies/privacy/" target="_blank">Google</a> 隱私權政策.',
        'languageVal': 'Traditional Chinese (繁體中文)',
        'successTitle': '太棒了！',
        'successDetails': '您已經成功訂閱 Android 開發人員的最新消息和各項秘訣。'
      }
    });
    break;
  case 'fr':
    window.polyglot.extend({
      'newsletter': {
        'title': 'Recevez les dernières actualités destinées aux développeurs Android, ainsi que des conseils qui ' +
          'vous mèneront vers le succès sur Google Play.',
        'requiredHint': '* Champs obligatoires',
        'name': 'Nom complet',
        'email': 'Adresse e-mail',
        'company': 'Nom de la société ou du développeur',
        'appUrl': 'Une de vos URL Play Store',
        'business': {
          'label': 'Quelle option décrit le mieux votre activité ?',
          'apps': 'Applications',
          'games': 'Jeux',
          'both': 'Applications et jeux'
        },
        'confirmMailingList': 'Ajoutez-moi à la liste de diffusion de la newsletter mensuelle et tenez-moi informé ' +
          'par des e-mails occasionnels de l\'évolution et des opportunités de Google Play.',
        'privacyPolicy': 'Je comprends que les renseignements fournis dans ce formulaire seront soumis aux <a href="' +
        'https://www.google.com/intl/fr/policies/privacy/" target="_blank">règles de confidentialité</a> de Google.',
        'languageVal': 'French (français)',
        'successTitle': 'Super !',
        'successDetails': 'Vous êtes bien inscrit pour recevoir les actualités et les conseils destinés aux ' +
          'développeurs Android.'
      }
    });
    break;
  case 'de':
    window.polyglot.extend({
      'newsletter': {
        'title': 'Abonniere aktuelle Informationen und Tipps für Android-Entwickler und werde noch erfolgreicher ' +
          'bei Google Play.',
        'requiredHint': '* Pflichtfelder',
        'name': 'Vollständiger Name',
        'email': 'E-Mail-Adresse',
        'company': 'Unternehmens-/Entwicklername',
        'appUrl': 'Eine der URLs deiner Play Store App',
        'business': {
          'label': 'Welche der folgenden Kategorien beschreibt dein Unternehmen am besten?',
          'apps': 'Apps',
          'games': 'Spiele',
          'both': 'Apps und Spiele'
        },
        'confirmMailingList': 'Meine E-Mail-Adresse soll zur Mailingliste hinzugefügt werden, damit ich den ' +
          'monatlichen Newsletter sowie gelegentlich E-Mails zu Entwicklungen und Optionen bei Google Play erhalte.',
        'privacyPolicy': 'Ich bestätige, dass die in diesem Formular bereitgestellten Informationen gemäß der ' +
          '<a href="https://www.google.com/intl/de/policies/privacy/" target="_blank">Datenschutzerklärung</a> von ' +
          'Google verwendet werden dürfen.',
        'languageVal': 'German (Deutsch)',
        'successTitle': 'Super!',
        'successDetails': 'Du hast dich erfolgreich angemeldet und erhältst jetzt aktuelle Informationen und Tipps ' +
          'für Android-Entwickler.'
      }
    });
    break;
  case 'in':
    window.polyglot.extend({
      'newsletter': {
        'title': 'Receba as dicas e as notícias mais recentes para os desenvolvedores Android e seja bem-sucedido ' +
        'no Google Play.',
        'requiredHint': '* Bidang Wajib Diisi',
        'name': 'Nama lengkap',
        'email': 'Alamat email',
        'company': 'Nama pengembang / perusahaan',
        'appUrl': 'Salah satu URL aplikasi Play Store Anda',
        'business': {
          'label': 'Dari berikut ini, mana yang paling cocok dengan bisnis Anda?',
          'apps': 'Aplikasi',
          'games': 'Game',
          'both': 'Aplikasi dan Game'
        },
        'confirmMailingList': 'Tambahkan saya ke milis untuk mendapatkan buletin bulanan dan email sesekali mengenai ' +
          'perkembangan dan kesempatan yang ada di Google Play.',
        'privacyPolicy': 'Saya memahami bahwa informasi yang diberikan dalam formulir ini tunduk pada <a href="' +
        'https://www.google.com/intl/in/policies/privacy/" target="_blank">kebijakan privasi</a> Google.',
        'languageVal': 'Indonesian (Bahasa)',
        'successTitle': 'Hore!',
        'successDetails': 'Anda berhasil mendaftar untuk kiat dan berita pengembang Android terbaru.'
      }
    });
    break;
  case 'it':
    //window.polyglot.extend({
    //  'newsletter': {
    //    'title': 'Receba as dicas e as notícias mais recentes para os desenvolvedores Android e seja bem-sucedido ' +
    //    'no Google Play.',
    //    'requiredHint': '* Campos obrigatórios',
    //    'name': 'Nome completo',
    //    'email': 'Endereço de Email',
    //    'company': 'Nome da empresa / do desenvolvedor',
    //    'appUrl': 'URL de um dos seus apps da Play Store',
    //    'business': {
    //      'label': 'Qual das seguintes opções melhor descreve sua empresa?',
    //      'apps': 'Apps',
    //      'games': 'Jogos',
    //      'both': 'Apps e Jogos'
    //    },
    //    'confirmMailingList': 'Inscreva-me na lista de e-mails para que eu receba o boletim informativo mensal, ' +
    //    'bem como e-mails ocasionais sobre o desenvolvimento e as oportunidades do Google Play.',
    //    'privacyPolicy': 'Reconheço que as informações fornecidas neste formulário estão sujeitas à <a href="' +
    //    'https://www.google.com.br/policies/privacy/" target="_blank">Política de Privacidade</a> do Google.',
    //    'languageVal': 'Italian (italiano)',
    //    'successTitle': 'Uhu!',
    //    'successDetails': 'Você se inscreveu para receber as notícias e as dicas mais recentes para os ' +
    //    'desenvolvedores Android.',
    //  }
    //});
    break;
  case 'ja':
    window.polyglot.extend({
      'newsletter': {
        'title': 'Google Play での成功に役立つ Android デベロッパー向けの最新ニュースやおすすめの情報をお届けします。',
        'requiredHint': '* 必須',
        'name': '氏名',
        'email': 'メールアドレス',
        'company': '会社名 / デベロッパー名',
        'appUrl': 'Play ストア アプリの URL（いずれか 1 つ）',
        'business': {
          'label': 'お客様のビジネスに最もよく当てはまるものをお選びください。',
          'apps': 'アプリ',
          'games': 'ゲーム',
          'both': 'アプリとゲーム'
        },
        'confirmMailingList': '開発や Google Play の最新情報に関する毎月発行のニュースレターや不定期発行のメールを受け取る',
        'privacyPolicy': 'このフォームに入力した情報に <a href="https://www.google.com/intl/ja/policies/privacy/" ' +
          'target="_blank">Google</a> のプライバシー ポリシーが適用',
        'languageVal': 'Japanese (日本語)',
        'successTitle': '完了です！',
        'successDetails': 'Android デベロッパー向けの最新ニュースやおすすめの情報の配信登録が完了しました。'
      }
    });
    break;
  case 'ko':
    window.polyglot.extend({
      'newsletter': {
        'title': 'Google Play에서 성공을 거두는 데 도움이 되는 최신 Android 개발자 소식 및 도움말을 받아 보세요.',
        'requiredHint': '* 필수 입력란',
        'name': '이름',
        'email': '이메일 주소',
        'company': '회사/개발자 이름',
        'appUrl': 'Play 스토어 앱 URL 중 1개',
        'business': {
          'label': '다음 중 내 비즈니스를 가장 잘 설명하는 단어는 무엇인가요?',
          'apps': '앱',
          'games': '게임',
          'both': '앱 및 게임'
        },
        'confirmMailingList': '개발 및 Google Play 관련 소식에 관한 월별 뉴스레터 및 비정기 이메일을 받아보겠습니다.',
        'privacyPolicy': '이 양식에 제공한 정보는 <a href="https://www.google.com/intl/ko/policies/privacy/" ' +
          'target="_blank">Google의</a> 개인정보취급방침에 따라 사용됨을',
        'languageVal':'Korean (한국어)',
        'successTitle': '축하합니다!',
        'successDetails': '최신 Android 개발자 뉴스 및 도움말을 받아볼 수 있도록 가입을 완료했습니다.'
      }
    });
    break;
  case 'pt-br':
    window.polyglot.extend({
      'newsletter': {
        'title': 'Receba as dicas e as notícias mais recentes para os desenvolvedores Android e seja bem-sucedido ' +
        'no Google Play.',
        'requiredHint': '* Campos obrigatórios',
        'name': 'Nome completo',
        'email': 'Endereço de Email',
        'company': 'Nome da empresa / do desenvolvedor',
        'appUrl': 'URL de um dos seus apps da Play Store',
        'business': {
          'label': 'Qual das seguintes opções melhor descreve sua empresa?',
          'apps': 'Apps',
          'games': 'Jogos',
          'both': 'Apps e Jogos'
        },
        'confirmMailingList': 'Inscreva-me na lista de e-mails para que eu receba o boletim informativo mensal, ' +
        'bem como e-mails ocasionais sobre o desenvolvimento e as oportunidades do Google Play.',
        'privacyPolicy': 'Reconheço que as informações fornecidas neste formulário estão sujeitas à <a href="' +
        'https://www.google.com.br/policies/privacy/" target="_blank">Política de Privacidade</a> do Google.',
        'languageVal': 'Brazilian Portuguese (Português Brasileiro)',
        'successTitle': 'Uhu!',
        'successDetails': 'Você se inscreveu para receber as notícias e as dicas mais recentes para os ' +
        'desenvolvedores Android.'
      }
    });
    break;
  case 'ru':
    window.polyglot.extend({
      'newsletter': {
        'title': 'Хотите получать последние новости и советы для разработчиков Google Play? Заполните эту форму.',
        'requiredHint': '* Обязательные поля',
        'name': 'Полное имя',
        'email': 'Адрес электронной почты',
        'company': 'Название компании или имя разработчика',
        'appUrl': 'Ссылка на любое ваше приложение в Google Play',
        'business': {
          'label': 'Что вы создаете?',
          'apps': 'Приложения',
          'games': 'Игры',
          'both': 'Игры и приложения'
        },
        'confirmMailingList': 'Я хочу получать ежемесячную рассылку для разработчиков и другие полезные новости ' +
          'Google Play.',
        'privacyPolicy': 'Я предоставляю эти данные в соответствии с <a href="' +
          'https://www.google.com/intl/ru/policies/privacy/" target="_blank">Политикой конфиденциальности</a> Google.',
        'languageVal': 'Russian (Русский)',
        'successTitle': 'Поздравляем!',
        'successDetails': 'Теперь вы подписаны на последние новости и советы для разработчиков Android.'
      }
    });
    break;
  case 'es':
    window.polyglot.extend({
      'newsletter': {
        'title': 'Recibe las últimas noticias y sugerencias para programadores de Android y logra tener éxito en ' +
          'Google Play.',
        'requiredHint': '* Campos obligatorios',
        'name': 'Dirección de correo electrónico',
        'email': 'Endereço de Email',
        'company': 'Nombre de la empresa o del programador',
        'appUrl': 'URL de una de tus aplicaciones de Play Store',
        'business': {
          'label': '¿Qué describe mejor a tu empresa?',
          'apps': 'Aplicaciones',
          'games': 'Juegos',
          'both': 'Juegos y aplicaciones'
        },
        'confirmMailingList': 'Deseo unirme a la lista de distribución para recibir el boletín informativo mensual ' +
          'y correos electrónicos ocasionales sobre desarrollo y oportunidades de Google Play.',
        'privacyPolicy': 'Acepto que la información que proporcioné en este formulario cumple con la <a href="' +
        'https://www.google.com/intl/es/policies/privacy/" target="_blank">política de privacidad</a> de Google.',
        'languageVal': 'Spanish (español)',
        'successTitle': '¡Felicitaciones!',
        'successDetails': 'El registro para recibir las últimas noticias y sugerencias para programadores de Android ' +
          'se realizó correctamente.'
      }
    });
    break;
  case 'th':
    window.polyglot.extend({
      'newsletter': {
        'title': 'รับข่าวสารล่าสุดสำหรับนักพัฒนาซอฟต์แวร์ Android ตลอดจนเคล็ดลับที่จะช่วยให้คุณประสบความสำเร็จบน ' +
          'Google Play',
        'requiredHint': '* ช่องที่ต้องกรอก',
        'name': 'ชื่อและนามสกุล',
        'email': 'ที่อยู่อีเมล',
        'company': 'ชื่อบริษัท/นักพัฒนาซอฟต์แวร์',
        'appUrl': 'URL แอปใดแอปหนึ่งของคุณใน Play สโตร์',
        'business': {
          'label': 'ข้อใดตรงกับธุรกิจของคุณมากที่สุด',
          'apps': 'แอป',
          'games': 'เกม',
          'both': 'แอปและเกม'
        },
        'confirmMailingList': 'เพิ่มฉันลงในรายชื่ออีเมลเพื่อรับจดหมายข่าวรายเดือนและอีเมลเป็นครั้งคราวเกี่ยวกับก' +
          'ารพัฒนาซอฟต์แวร์และโอกาสใน Google Play',
        'privacyPolicy': 'ฉันรับทราบว่าข้อมูลที่ให้ไว้ในแบบฟอร์มนี้จะเป็นไปตามนโยบายส่วนบุคคลของ ' +
          '<a href="https://www.google.com/intl/th/policies/privacy/" target="_blank">Google</a>',
        'languageVal': 'Thai (ภาษาไทย)',
        'successTitle': 'ไชโย!',
        'successDetails': 'คุณลงชื่อสมัครรับข่าวสารและเคล็ดลับล่าสุดสำหรับนักพัฒนาซอฟต์แวร์ Android เสร็จเรียบร้อยแล้ว'
      }
    });
    break;
  case 'tr':
    window.polyglot.extend({
      'newsletter': {
        'title': 'Google Play\'de başarılı olmanıza yardımcı olacak en son Android geliştirici haberleri ve ipuçları.',
        'requiredHint': '* Zorunlu Alanlar',
        'name': 'Tam ad',
        'email': 'E-posta adresi',
        'company': 'Şirket / geliştirici adı',
        'appUrl': 'Play Store uygulama URL\'lerinizden biri',
        'business': {
          'label': 'İşletmenizi en iyi hangisi tanımlar?',
          'apps': 'Uygulamalar',
          'games': 'Oyunlar',
          'both': 'Uygulamalar ve Oyunlar'
        },
        'confirmMailingList': 'Beni, geliştirme ve Google Play fırsatlarıyla ilgili ara sıra gönderilen e-posta ' +
          'iletilerine ilişkin posta listesine ve aylık haber bültenine ekle.',
        'privacyPolicy': 'Bu formda sağlanan bilgilerin Google\'ın ' +
          '<a href="https://www.google.com/intl/tr/policies/privacy/" target="_blank">Gizlilik Politikası\'na</a> ' +
          'tabi olacağını kabul ediyorum.',
        'languageVal': 'Turkish (Türkçe)',
        'successTitle': 'Yaşasın!',
        'successDetails': 'En son Android geliştirici haberleri ve ipuçlarına başarıyla kaydoldunuz.'
      }
    });
    break;
  case 'vi':
    window.polyglot.extend({
      'newsletter': {
        'title': 'Nhận tin tức và mẹo mới nhất dành cho nhà phát triển Android sẽ giúp bạn tìm thấy thành công trên ' +
          'Google Play.',
        'requiredHint': '* Các trường bắt buộc',
        'name': 'Tên đầy đủ',
        'email': 'Địa chỉ email',
        'company': 'Tên công ty/nhà phát triển',
        'appUrl': 'Một trong số các URL ứng dụng trên cửa hàng Play của bạn',
        'business': {
          'label': 'Lựa chọn nào sau đây mô tả chính xác nhất doanh nghiệp của bạn?',
          'apps': 'Ứng dụng',
          'games': 'Trò chơi',
          'both': 'Ứng dụng và trò chơi'
        },
        'confirmMailingList': 'Thêm tôi vào danh sách gửi thư cho bản tin hàng tháng và email định kỳ về việc phát ' +
          'triển và cơ hội của Google Play.',
        'privacyPolicy': 'Tôi xác nhận rằng thông tin được cung cấp trong biểu mẫu này tuân thủ chính sách bảo mật ' +
          'của <a href="https://www.google.com/intl/vi/policies/privacy/" target="_blank">Google</a>.',
        'languageVal': 'Vietnamese (tiếng Việt)',
        'successTitle': 'Thật tuyệt!',
        'successDetails': 'Bạn đã đăng ký thành công nhận tin tức và mẹo mới nhất dành cho nhà phát triển của Android.'
      }
    });
    break;
}

(function($) {
  'use strict';

  function Modal(el, options) {
    this.el = $(el);
    this.options = $.extend({}, options);
    this.isOpen = false;

    this.el.on('click', function(event) {
      if (!$.contains(this.el.find('.dac-modal-window')[0], event.target)) {
        return this.el.trigger('modal-close');
      }
    }.bind(this));

    this.el.on('modal-open', this.open_.bind(this));
    this.el.on('modal-close', this.close_.bind(this));
    this.el.on('modal-toggle', this.toggle_.bind(this));
  }

  Modal.prototype.toggle_ = function() {
    this.el.trigger('modal-' + (this.isOpen ? 'close' : 'open'));
  };

  Modal.prototype.close_ = function() {
    this.el.removeClass('dac-active');
    $('body').removeClass('dac-modal-open');
    this.isOpen = false;
  };

  Modal.prototype.open_ = function() {
    this.el.addClass('dac-active');
    $('body').addClass('dac-modal-open');
    this.isOpen = true;
  };

  function onClickToggleModal(event) {
    event.preventDefault();
    var toggle = $(event.currentTarget);
    var options = toggle.data();
    var modal = options.modalToggle ? $('[data-modal="' + options.modalToggle + '"]') :
      toggle.closest('[data-modal]');
    modal.trigger('modal-toggle');
  }

  /**
   * jQuery plugin
   * @param  {object} options - Override default options.
   */
  $.fn.dacModal = function(options) {
    return this.each(function() {
      new Modal(this, options);
    });
  };

  $.fn.dacToggleModal = function(options) {
    return this.each(function() {
      new ToggleModal(this, options);
    });
  };

  /**
   * Data Attribute API
   */
  $(document).on('ready.aranja', function() {
    $('[data-modal]').each(function() {
      $(this).dacModal($(this).data());
    });

    $('html').on('click.modal', '[data-modal-toggle]', onClickToggleModal);

    // Check if url anchor is targetting a toggle to open the modal.
    if (location.hash) {
      $(location.hash + '[data-modal-toggle]').trigger('click');
    }

    if (window.getLangTarget() !== window.getLangPref()) {
          $('#langform').trigger('modal-open');
          $("#langform button.yes").attr("onclick","window.changeLangPref('" + window.getLangTarget() + "', true);  return false;");
          $("#langform button.no").attr("onclick","window.changeLangPref('" + window.getLangPref() + "', true); return false;");
    }
  });
})(jQuery);

/* Fullscreen - Toggle fullscreen mode for reference pages */
(function($) {
  'use strict';

  /**
   * @param {HTMLElement} el - The DOM element.
   * @constructor
   */
  function Fullscreen(el) {
    this.el = $(el);
    this.html = $('html');
    this.icon = this.el.find('.dac-sprite');
    this.isFullscreen = window.readCookie(Fullscreen.COOKIE_) === 'true';
    this.activate_();
    this.el.on('click.dac-fullscreen', this.toggleHandler_.bind(this));
  }

  /**
   * Cookie name for storing the state
   * @type {string}
   * @private
   */
  Fullscreen.COOKIE_ = 'fullscreen';

  /**
   * Classes to modify the DOM
   * @type {{mode: string, fullscreen: string, fullscreenExit: string}}
   * @private
   */
  Fullscreen.CLASSES_ = {
    mode: 'dac-fullscreen-mode',
    fullscreen: 'dac-fullscreen',
    fullscreenExit: 'dac-fullscreen-exit'
  };

  /**
   * Event listener for toggling fullscreen mode
   * @param {MouseEvent} event
   * @private
   */
  Fullscreen.prototype.toggleHandler_ = function(event) {
    event.stopPropagation();
    this.toggle(!this.isFullscreen, true);
  };

  /**
   * Change the DOM based on current state.
   * @private
   */
  Fullscreen.prototype.activate_ = function() {
    this.icon.toggleClass(Fullscreen.CLASSES_.fullscreen, !this.isFullscreen);
    this.icon.toggleClass(Fullscreen.CLASSES_.fullscreenExit, this.isFullscreen);
    this.html.toggleClass(Fullscreen.CLASSES_.mode, this.isFullscreen);
  };

  /**
   * Toggle fullscreen mode and store the state in a cookie.
   */
  Fullscreen.prototype.toggle = function() {
    this.isFullscreen = !this.isFullscreen;
    window.writeCookie(Fullscreen.COOKIE_, this.isFullscreen, null);
    this.activate_();
  };

  /**
   * jQuery plugin
   */
  $.fn.dacFullscreen = function() {
    return this.each(function() {
      new Fullscreen($(this));
    });
  };
})(jQuery);

(function($) {
  'use strict';

  /**
   * @param {HTMLElement} selected - The link that is selected in the nav.
   * @constructor
   */
  function HeaderTabs(selected) {

    // Don't highlight any tabs on the index page
    if (location.pathname === '/index.html' || location.pathname === '/') {
      //return;
    }

    this.selected = $(selected);
    this.selectedParent = this.selected.closest('.dac-nav-secondary').siblings('a');
    this.links = $('.dac-header-tabs a');

    this.selectActiveTab();
  }

  HeaderTabs.prototype.selectActiveTab = function() {
    var section = null;

    if (this.selectedParent.length) {
      section = this.selectedParent.text();
    } else {
      section = this.selected.text();
    }

    if (section) {
      this.links.removeClass('selected');

      this.links.filter(function() {
        return $(this).text() === $.trim(section);
      }).addClass('selected');
    }
  };

  /**
   * jQuery plugin
   */
  $.fn.dacHeaderTabs = function() {
    return this.each(function() {
      new HeaderTabs(this);
    });
  };
})(jQuery);

(function($) {
  'use strict';
  var icon = $('<i/>').addClass('dac-sprite dac-nav-forward');
  var config = JSON.parse(window.localStorage.getItem('global-navigation') || '{}');
  var forwardLink = $('<span/>')
    .addClass('dac-nav-link-forward')
    .html(icon)
    .on('click', swap_);

  /**
   * @constructor
   */
  function Nav(navigation) {
    $('.dac-nav-list').dacCurrentPage().dacHeaderTabs().dacSidebarToggle($('body'));

    navigation.find('[data-reference-tree]').dacReferenceNav();

    setupViews_(navigation.children().eq(0).children());

    initCollapsedNavs(navigation.find('.dac-nav-sub-slider'));

    $('#dac-main-navigation').scrollIntoView('.selected')
  }

  function updateStore(icon) {
    var navClass = getCurrentLandingPage_(icon);
    var isExpanded = icon.hasClass('dac-expand-less-black');
    var expandedNavs = config.expanded || [];
    if (isExpanded) {
      expandedNavs.push(navClass);
    } else {
      expandedNavs = expandedNavs.filter(function(item) {
        return item !== navClass;
      });
    }
    config.expanded = expandedNavs;
    window.localStorage.setItem('global-navigation', JSON.stringify(config));
  }

  function toggleSubNav_(icon) {
    var isExpanded = icon.hasClass('dac-expand-less-black');
    icon.toggleClass('dac-expand-less-black', !isExpanded);
    icon.toggleClass('dac-expand-more-black', isExpanded);
    icon.data('sub-navigation.dac').slideToggle(200);

    updateStore(icon);
  }

  function handleSubNavToggle_(event) {
    event.preventDefault();
    var icon = $(event.target);
    toggleSubNav_(icon);
  }

  function getCurrentLandingPage_(icon) {
    return icon.closest('li')[0].className.replace('dac-nav-item ', '');
  }

  // Setup sub navigation collapse/expand
  function initCollapsedNavs(toggleIcons) {
    toggleIcons.each(setInitiallyActive_($('body')));
    toggleIcons.on('click', handleSubNavToggle_);

  }

  function setInitiallyActive_(body) {
    var expandedNavs = config.expanded || [];
    return function(i, icon) {
      icon = $(icon);
      var subNav = icon.next();

      if (!subNav.length) {
        return;
      }

      var landingPageClass = getCurrentLandingPage_(icon);
      var expanded = expandedNavs.indexOf(landingPageClass) >= 0;
      landingPageClass = landingPageClass === 'home' ? 'about' : landingPageClass;

      // TODO: Should read from localStorage
      var visible = body.hasClass(landingPageClass) || expanded;

      icon.data('sub-navigation.dac', subNav);
      icon.toggleClass('dac-expand-less-black', visible);
      icon.toggleClass('dac-expand-more-black', !visible);
      subNav.toggle(visible);
    };
  }

  function setupViews_(views) {
    if (views.length === 1) {
      // Active tier 1 nav.
      views.addClass('dac-active');
    } else {
      // Activate back button and tier 2 nav.
      views.slice(0, 2).addClass('dac-active');
      var selectedNav = views.eq(2).find('.selected').after(forwardLink);
      var langAttr = selectedNav.attr(window.getLangPref() + '-lang');
      //form the label from locale attr if possible, else set to selectedNav text value
      if ((typeof langAttr !== typeof undefined &&  langAttr !== false) && (langAttr !== '')) {
        $('.dac-nav-back-title').text(langAttr);
      } else {
        $('.dac-nav-back-title').text(selectedNav.text());
      }
    }

    // Navigation should animate.
    setTimeout(function() {
      views.removeClass('dac-no-anim');
    }, 10);
  }

  function swap_(event) {
    event.preventDefault();
    $(event.currentTarget).trigger('swap-content');
  }

  /**
   * jQuery plugin
   */
  $.fn.dacNav = function() {
    return this.each(function() {
      new Nav($(this));
    });
  };
})(jQuery);

/* global NAVTREE_DATA */
(function($) {
  /**
   * Build the reference navigation with namespace dropdowns.
   * @param {jQuery} el - The DOM element.
   */
  function buildReferenceNav(el) {
    var namespaceList = el.find('[data-reference-namespaces]');
    var resources = el.find('[data-reference-resources]');
    var selected = namespaceList.find('.selected');

    // Links should be toggleable.
    namespaceList.find('a').addClass('dac-reference-nav-toggle dac-closed');

    // Load in all resources
    $.getScript('/navtree_data.js', function(data, textStatus, xhr) {
      if (xhr.status === 200) {
        namespaceList.on('click', 'a.dac-reference-nav-toggle', toggleResourcesHandler);
      }
    });

    // No setup required if no resources are present
    if (!resources.length) {
      return;
    }

    // The resources should be a part of selected namespace.
    var overview = addResourcesToView(resources, selected);

    // Currently viewing Overview
    if (location.pathname === overview.attr('href')) {
      overview.parent().addClass('selected');
    }

    // Open currently selected resource
    var listsToOpen = selected.children().eq(1);
    listsToOpen = listsToOpen.add(listsToOpen.find('.selected').parent()).show();

    // Mark dropdowns as open
    listsToOpen.prev().removeClass('dac-closed');

    // Scroll into view
    namespaceList.scrollIntoView(selected);
  }

  /**
   * Handles the toggling of resources.
   * @param {Event} event
   */
  function toggleResourcesHandler(event) {
    event.preventDefault();
    var el = $(this);

    // If resources for given namespace is not present, fetch correct data.
    if (this.tagName === 'A' && !this.hasResources) {
      addResourcesToView(buildResourcesViewForData(getDataForNamespace(el.text())), el.parent());
    }

    el.toggleClass('dac-closed').next().slideToggle(200);
  }

  /**
   * @param {String} namespace
   * @returns {Array} namespace data
   */
  function getDataForNamespace(namespace) {
    var namespaceData = NAVTREE_DATA.filter(function(data) {
      return data[0] === namespace;
    });

    return namespaceData.length ? namespaceData[0][2] : [];
  }

  /**
   * Build a list item for a resource
   * @param {Array} resource
   * @returns {String}
   */
  function buildResourceItem(resource) {
    return '<li class="api apilevel-' + resource[3] + '"><a href="/' + resource[1] + '">' + resource[0] + '</a></li>';
  }

  /**
   * Build resources list items.
   * @param {Array} resources
   * @returns {String}
   */
  function buildResourceList(resources) {
    return '<li><h2>' + resources[0] + '</h2><ul>' + resources[2].map(buildResourceItem).join('') + '</ul>';
  }

  /**
   * Build a resources view
   * @param {Array} data
   * @returns {jQuery} resources in an unordered list.
   */
  function buildResourcesViewForData(data) {
    return $('<ul>' + data.map(buildResourceList).join('') + '</ul>');
  }

  /**
   * Add resources to a containing view.
   * @param {jQuery} resources
   * @param {jQuery} view
   * @returns {jQuery} the overview link.
   */
  function addResourcesToView(resources, view) {
    var namespace = view.children().eq(0);
    var overview = $('<a href="' + namespace.attr('href') + '">Overview</a>');

    // Mark namespace with content;
    namespace[0].hasResources = true;

    // Add correct classes / event listeners to resources.
    resources.prepend($('<li>').html(overview))
      .find('a')
        .addClass('dac-reference-nav-resource')
      .end()
        .find('h2')
        .addClass('dac-reference-nav-toggle dac-closed')
        .on('click', toggleResourcesHandler)
      .end()
        .add(resources.find('ul'))
        .addClass('dac-reference-nav-resources')
      .end()
        .appendTo(view);

    return overview;
  }

  /**
   * jQuery plugin
   */
  $.fn.dacReferenceNav = function() {
    return this.each(function() {
      buildReferenceNav($(this));
    });
  };
})(jQuery);

/** Scroll a container to make a target element visible
 This is called when the page finished loading. */
$.fn.scrollIntoView = function(target) {
  if ('string' === typeof target) {
    target = this.find(target);
  }
  if (this.is(':visible')) {
    if (target.length == 0) {
      // If no selected item found, exit
      return;
    }

    // get the target element's offset from its container nav by measuring the element's offset
    // relative to the document then subtract the container nav's offset relative to the document
    var targetOffset = target.offset().top - this.offset().top;
    var containerHeight = this.height();
    if (targetOffset > containerHeight * .8) { // multiply nav height by .8 so we move up the item
      // if it's more than 80% down the nav
      // scroll the item up by an amount equal to 80% the container height
      this.scrollTop(targetOffset - (containerHeight * .8));
    }
  }
};

(function($) {
  $.fn.dacCurrentPage = function() {
    // Highlight the header tabs...
    // highlight Design tab
    var baseurl = getBaseUri(window.location.pathname);
    var urlSegments = baseurl.split('/');
    var navEl = this;
    var body = $('body');
    var subNavEl = navEl.find('.dac-nav-secondary');
    var parentNavEl;
    var selected;
    // In NDK docs, highlight appropriate sub-nav
    if (body.hasClass('ndk')) {
      if (body.hasClass('guide')) {
        selected = navEl.find('> li.guides > a').addClass('selected');
      } else if (body.hasClass('reference')) {
        selected = navEl.find('> li.reference > a').addClass('selected');
      } else if (body.hasClass('samples')) {
        selected = navEl.find('> li.samples > a').addClass('selected');
      } else if (body.hasClass('downloads')) {
        selected = navEl.find('> li.downloads > a').addClass('selected');
      }
    } else if (body.hasClass('design')) {
      selected = navEl.find('> li.design > a').addClass('selected');
      // highlight Home nav
    } else if (body.hasClass('about')) {
      parentNavEl = navEl.find('> li.home > a');
      parentNavEl.addClass('has-subnav');
      // In Home docs, also highlight appropriate sub-nav
      if (urlSegments[1] === 'wear' || urlSegments[1] === 'tv' ||
        urlSegments[1] === 'auto') {
        selected = subNavEl.find('li.' + urlSegments[1] + ' > a').addClass('selected');
      } else if (urlSegments[1] === 'about') {
        selected = subNavEl.find('li.versions > a').addClass('selected');
      } else {
        selected = parentNavEl.removeClass('has-subnav').addClass('selected');
      }
      // highlight Develop nav
    } else if (body.hasClass('develop') || body.hasClass('google')) {
      parentNavEl = navEl.find('> li.develop > a');
      parentNavEl.addClass('has-subnav');
      // In Develop docs, also highlight appropriate sub-nav
      if (urlSegments[1] === 'training') {
        selected = subNavEl.find('li.training > a').addClass('selected');
      } else if (urlSegments[1] === 'guide') {
        selected = subNavEl.find('li.guide > a').addClass('selected');
      } else if (urlSegments[1] === 'reference') {
        // If the root is reference, but page is also part of Google Services, select Google
        if (body.hasClass('google')) {
          selected = subNavEl.find('li.google > a').addClass('selected');
        } else {
          selected = subNavEl.find('li.reference > a').addClass('selected');
        }
      } else if ((urlSegments[1] === 'tools') || (urlSegments[1] === 'sdk')) {
        selected = subNavEl.find('li.tools > a').addClass('selected');
      } else if (body.hasClass('google')) {
        selected = subNavEl.find('li.google > a').addClass('selected');
      } else if (body.hasClass('samples')) {
        selected = subNavEl.find('li.samples > a').addClass('selected');
      } else {
        selected = parentNavEl.removeClass('has-subnav').addClass('selected');
      }
      // highlight Distribute nav
    } else if (body.hasClass('distribute')) {
      parentNavEl = navEl.find('> li.distribute > a');
      parentNavEl.addClass('has-subnav');
      // In Distribute docs, also highlight appropriate sub-nav
      if (urlSegments[2] === 'users') {
        selected = subNavEl.find('li.users > a').addClass('selected');
      } else if (urlSegments[2] === 'engage') {
        selected = subNavEl.find('li.engage > a').addClass('selected');
      } else if (urlSegments[2] === 'monetize') {
        selected = subNavEl.find('li.monetize > a').addClass('selected');
      } else if (urlSegments[2] === 'analyze') {
        selected = subNavEl.find('li.analyze > a').addClass('selected');
      } else if (urlSegments[2] === 'tools') {
        selected = subNavEl.find('li.disttools > a').addClass('selected');
      } else if (urlSegments[2] === 'stories') {
        selected = subNavEl.find('li.stories > a').addClass('selected');
      } else if (urlSegments[2] === 'essentials') {
        selected = subNavEl.find('li.essentials > a').addClass('selected');
      } else if (urlSegments[2] === 'googleplay') {
        selected = subNavEl.find('li.googleplay > a').addClass('selected');
      } else {
        selected = parentNavEl.removeClass('has-subnav').addClass('selected');
      }
    } else if (body.hasClass('preview')) {
      selected = navEl.find('> li.preview > a').addClass('selected');
    }
    return $(selected);
  };
})(jQuery);

(function($) {
  'use strict';

  /**
   * Toggle the visabilty of the mobile navigation.
   * @param {HTMLElement} el - The DOM element.
   * @param {Object} options
   * @constructor
   */
  function ToggleNav(el, options) {
    this.el = $(el);
    this.options = $.extend({}, ToggleNav.DEFAULTS_, options);
    this.body = $(document.body);
    this.navigation_ = this.body.find(this.options.navigation);
    this.el.on('click', this.clickHandler_.bind(this));
  }

  ToggleNav.BREAKPOINT_ = 980;

  /**
   * Open on correct sizes
   */
  function toggleSidebarVisibility(body) {
    var wasClosed = ('' + localStorage.getItem('navigation-open')) === 'false';

    if (wasClosed) {
      body.removeClass(ToggleNav.DEFAULTS_.activeClass);
    } else if (window.innerWidth >= ToggleNav.BREAKPOINT_) {
      body.addClass(ToggleNav.DEFAULTS_.activeClass);
    } else {
      body.removeClass(ToggleNav.DEFAULTS_.activeClass);
    }
  }

  /**
   * ToggleNav Default Settings
   * @type {{body: boolean, dimmer: string, navigation: string, activeClass: string}}
   * @private
   */
  ToggleNav.DEFAULTS_ = {
    body: true,
    dimmer: '.dac-nav-dimmer',
    animatingClass: 'dac-nav-animating',
    navigation: '[data-dac-nav]',
    activeClass: 'dac-nav-open'
  };

  /**
   * The actual toggle logic.
   * @param {Event} event
   * @private
   */
  ToggleNav.prototype.clickHandler_ = function(event) {
    event.preventDefault();
    var animatingClass = this.options.animatingClass;
    var body = this.body;

    body.addClass(animatingClass);
    body.toggleClass(this.options.activeClass);

    setTimeout(function() {
      body.removeClass(animatingClass);
    }, this.navigation_.transitionDuration());

    if (window.innerWidth >= ToggleNav.BREAKPOINT_) {
      localStorage.setItem('navigation-open', body.hasClass(this.options.activeClass));
    }
  };

  /**
   * jQuery plugin
   * @param  {object} options - Override default options.
   */
  $.fn.dacToggleMobileNav = function() {
    return this.each(function() {
      var el = $(this);
      new ToggleNav(el, el.data());
    });
  };

  $.fn.dacSidebarToggle = function(body) {
    toggleSidebarVisibility(body);
    $(window).on('resize', toggleSidebarVisibility.bind(null, body));
  };

  /**
   * Data Attribute API
   */
  $(function() {
    $('[data-dac-toggle-nav]').dacToggleMobileNav();
  });
})(jQuery);

(function($) {
  'use strict';

  /**
   * Submit the newsletter form to a Google Form.
   * @param {HTMLElement} el - The Form DOM element.
   * @constructor
   */
  function NewsletterForm(el) {
    this.el = $(el);
    this.form = this.el.find('form');
    $('<iframe/>').hide()
      .attr('name', 'dac-newsletter-iframe')
      .attr('src', '')
      .insertBefore(this.form);
    this.el.find('[data-newsletter-language]').val(window.polyglot.t('newsletter.languageVal'));
    this.form.on('submit', this.submitHandler_.bind(this));
  }

  /**
   * Milliseconds until modal has vanished after modal-close is triggered.
   * @type {number}
   * @private
   */
  NewsletterForm.CLOSE_DELAY_ = 300;

  /**
   * Switch view to display form after close.
   * @private
   */
  NewsletterForm.prototype.closeHandler_ = function() {
    setTimeout(function() {
      this.el.trigger('swap-reset');
    }.bind(this), NewsletterForm.CLOSE_DELAY_);
  };

  /**
   * Reset the modal to initial state.
   * @private
   */
  NewsletterForm.prototype.reset_ = function() {
    this.form.trigger('reset');
    this.el.one('modal-close', this.closeHandler_.bind(this));
  };

  /**
   * Display a success view on submit.
   * @private
   */
  NewsletterForm.prototype.submitHandler_ = function() {
    this.el.one('swap-complete', this.reset_.bind(this));
    this.el.trigger('swap-content');
  };

  /**
   * jQuery plugin
   * @param  {object} options - Override default options.
   */
  $.fn.dacNewsletterForm = function(options) {
    return this.each(function() {
      new NewsletterForm(this, options);
    });
  };

  /**
   * Data Attribute API
   */
  $(document).on('ready.aranja', function() {
    $('[data-newsletter]').each(function() {
      $(this).dacNewsletterForm();
    });
  });
})(jQuery);

/* globals METADATA, YOUTUBE_RESOURCES, BLOGGER_RESOURCES */
window.metadata = {};

/**
 * Prepare metadata and indices for querying.
 */
window.metadata.prepare = (function() {
  // Helper functions.
  function mergeArrays() {
    return Array.prototype.concat.apply([], arguments);
  }

  /**
   * Creates lookup maps for a resource index.
   * I.e. where MAP['some tag'][resource.id] === true when that resource has 'some tag'.
   * @param resourceDict
   * @returns {{}}
   */
  function buildResourceLookupMap(resourceDict) {
    var map = {};
    for (var key in resourceDict) {
      var dictForKey = {};
      var srcArr = resourceDict[key];
      for (var i = 0; i < srcArr.length; i++) {
        dictForKey[srcArr[i].index] = true;
      }
      map[key] = dictForKey;
    }
    return map;
  }

  /**
   * Merges metadata maps for english and the current language into the global store.
   */
  function mergeMetadataMap(name, locale) {
    if (locale && locale !== 'en' && METADATA[locale]) {
      METADATA[name] = $.extend(METADATA.en[name], METADATA[locale][name]);
    } else {
      METADATA[name] = METADATA.en[name];
    }
  }

  /**
   * Index all resources by type, url, tag and category.
   * @param resources
   */
  function createIndices(resources) {
    // URL, type, tag and category lookups
    var byType = METADATA.byType = {};
    var byUrl = METADATA.byUrl = {};
    var byTag = METADATA.byTag = {};
    var byCategory = METADATA.byCategory = {};

    for (var i = 0; i < resources.length; i++) {
      var res = resources[i];

      // Store index.
      res.index = i;

      // Index by type.
      var type = res.type;
      if (type) {
        byType[type] = byType[type] || [];
        byType[type].push(res);
      }

      // Index by tag.
      var tags = res.tags || [];
      for (var j = 0; j < tags.length; j++) {
        var tag = tags[j];
        if (tag) {
          byTag[tag] = byTag[tag] || [];
          byTag[tag].push(res);
        }
      }

      // Index by category.
      var category = res.category;
      if (category) {
        byCategory[category] = byCategory[category] || [];
        byCategory[category].push(res);
      }

      // Index by url.
      var url = res.url;
      if (url) {
        res.baseUrl = url.replace(/^intl\/\w+[\/]/, '');
        byUrl[res.baseUrl] = res;
      }
    }
    METADATA.hasType = buildResourceLookupMap(byType);
    METADATA.hasTag = buildResourceLookupMap(byTag);
    METADATA.hasCategory = buildResourceLookupMap(byCategory);
  }

  return function() {
    // Only once.
    if (METADATA.all) { return; }

    // Get current language.
    var locale = getLangPref();

    // Merge english resources.
    METADATA.all = mergeArrays(
      METADATA.en.about,
      METADATA.en.design,
      METADATA.en.distribute,
      METADATA.en.develop,
      YOUTUBE_RESOURCES,
      BLOGGER_RESOURCES,
      METADATA.en.extras
    );

    // Merge local language resources.
    if (locale !== 'en' && METADATA[locale]) {
      METADATA.all = mergeArrays(
        METADATA.all,
        METADATA[locale].about,
        METADATA[locale].design,
        METADATA[locale].distribute,
        METADATA[locale].develop,
        METADATA[locale].extras
      );
    }

    mergeMetadataMap('collections', locale);
    mergeMetadataMap('searchHeroCollections', locale);
    mergeMetadataMap('carousel', locale);

    // Create query indicies for resources.
    createIndices(METADATA.all, locale);

    // Reference metadata.
    METADATA.androidReference = window.DATA;
    METADATA.googleReference = mergeArrays(window.GMS_DATA, window.GCM_DATA);
  };
})();

/* global METADATA, util */
window.metadata.query = (function($) {
  var pageMap = {};

  function buildResourceList(opts) {
    window.metadata.prepare();
    var expressions = parseResourceQuery(opts.query || '');
    var instanceMap = {};
    var results = [];

    for (var i = 0; i < expressions.length; i++) {
      var clauses = expressions[i];

      // Get all resources for first clause
      var resources = getResourcesForClause(clauses.shift());

      // Concat to final results list
      results = results.concat(resources.map(filterResources(clauses, i > 0, instanceMap)).filter(filterEmpty));
    }

    // Set correct order
    if (opts.sortOrder && results.length) {
      results = opts.sortOrder === 'random' ? util.shuffle(results) : results.sort(sortResultsByKey(opts.sortOrder));
    }

    // Slice max results.
    if (opts.maxResults !== Infinity) {
      results = results.slice(0, opts.maxResults);
    }

    // Remove page level duplicates
    if (opts.allowDuplicates === undefined || opts.allowDuplicates === 'false') {
      results = results.filter(removePageLevelDuplicates);

      for (var index = 0; index < results.length; ++index) {
        pageMap[results[index].index] = 1;
      }
    }

    return results;
  }

  function filterResources(clauses, removeDuplicates, map) {
    return function(resource) {
      var resourceIsAllowed = true;

      // References must be defined.
      if (resource === undefined) {
        return;
      }

      // Get canonical (localized) version of resource if possible.
      resource = METADATA.byUrl[resource.baseUrl] || METADATA.byUrl[resource.url] || resource;

      // Filter out resources already used
      if (removeDuplicates) {
        resourceIsAllowed = !map[resource.index];
      }

      // Must fulfill all criteria
      if (clauses.length > 0) {
        resourceIsAllowed = resourceIsAllowed && doesResourceMatchClauses(resource, clauses);
      }

      // Mark resource as used.
      if (resourceIsAllowed) {
        map[resource.index] = 1;
      }

      return resourceIsAllowed && resource;
    };
  }

  function filterEmpty(resource) {
    return resource;
  }

  function sortResultsByKey(key) {
    var desc = key.charAt(0) === '-';

    if (desc) {
      key = key.substring(1);
    }

    return function(x, y) {
      return (desc ? -1 : 1) * (parseInt(x[key], 10) - parseInt(y[key], 10));
    };
  }

  function getResourcesForClause(clause) {
    switch (clause.attr) {
      case 'type':
        return METADATA.byType[clause.value];
      case 'tag':
        return METADATA.byTag[clause.value];
      case 'collection':
        var resources = METADATA.collections[clause.value] || {};
        return getResourcesByUrlCollection(resources.resources);
      case 'history':
        return getResourcesByUrlCollection($.dacGetVisitedUrls(clause.value));
      case 'section':
        return getResourcesByUrlCollection([clause.value].sections);
      default:
        return [];
    }
  }

  function getResourcesByUrlCollection(resources) {
    return (resources || []).map(function(url) {
      return METADATA.byUrl[url];
    });
  }

  function removePageLevelDuplicates(resource) {
    return resource && !pageMap[resource.index];
  }

  function doesResourceMatchClauses(resource, clauses) {
    for (var i = 0; i < clauses.length; i++) {
      var map;
      switch (clauses[i].attr) {
        case 'type':
          map = METADATA.hasType[clauses[i].value];
          break;
        case 'tag':
          map = METADATA.hasTag[clauses[i].value];
          break;
      }

      if (!map || (!!clauses[i].negative ? map[resource.index] : !map[resource.index])) {
        return clauses[i].negative;
      }
    }

    return true;
  }

  function parseResourceQuery(query) {
    // Parse query into array of expressions (expression e.g. 'tag:foo + type:video')
    var expressions = [];
    var expressionStrs = query.split(',') || [];
    for (var i = 0; i < expressionStrs.length; i++) {
      var expr = expressionStrs[i] || '';

      // Break expression into clauses (clause e.g. 'tag:foo')
      var clauses = [];
      var clauseStrs = expr.split(/(?=[\+\-])/);
      for (var j = 0; j < clauseStrs.length; j++) {
        var clauseStr = clauseStrs[j] || '';

        // Get attribute and value from clause (e.g. attribute='tag', value='foo')
        var parts = clauseStr.split(':');
        var clause = {};

        clause.attr = parts[0].replace(/^\s+|\s+$/g, '');
        if (clause.attr) {
          if (clause.attr.charAt(0) === '+') {
            clause.attr = clause.attr.substring(1);
          } else if (clause.attr.charAt(0) === '-') {
            clause.negative = true;
            clause.attr = clause.attr.substring(1);
          }
        }

        if (parts.length > 1) {
          clause.value = parts[1].replace(/^\s+|\s+$/g, '');
        }

        clauses.push(clause);
      }

      if (!clauses.length) {
        continue;
      }

      expressions.push(clauses);
    }

    return expressions;
  }

  return buildResourceList;
})(jQuery);

/* global METADATA, getLangPref */

window.metadata.search = (function() {
  'use strict';

  var currentLang = getLangPref();

  function search(query) {
    window.metadata.prepare();
    return {
      android: findDocsMatches(query, METADATA.androidReference),
      docs: findDocsMatches(query, METADATA.googleReference),
      resources: findResourceMatches(query)
    };
  }

  function findDocsMatches(query, data) {
    var results = [];

    for (var i = 0; i < data.length; i++) {
      var s = data[i];
      if (query.length !== 0 && s.label.toLowerCase().indexOf(query.toLowerCase()) !== -1) {
        results.push(s);
      }
    }

    rankAutocompleteApiResults(query, results);

    return results;
  }

  function findResourceMatches(query) {
    var results = [];

    // Search for matching JD docs
    if (query.length >= 2) {
      /* In some langs, spaces may be optional between certain non-Ascii word-glyphs. For
       * those langs, only match query at word boundaries if query includes Ascii chars only.
       */
      var NO_BOUNDARY_LANGUAGES = ['ja','ko','vi','zh-cn','zh-tw'];
      var isAsciiOnly = /^[\u0000-\u007f]*$/.test(query);
      var noBoundaries = (NO_BOUNDARY_LANGUAGES.indexOf(window.getLangPref()) !== -1);
      var exprBoundary = (!isAsciiOnly && noBoundaries) ? '' : '(?:^|\\s)';
      var queryRegex = new RegExp(exprBoundary + query.toLowerCase(), 'g');

      var all = METADATA.all;
      for (var i = 0; i < all.length; i++) {
        // current search comparison, with counters for tag and title,
        // used later to improve ranking
        var s = all[i];
        s.matched_tag = 0;
        s.matched_title = 0;
        var matched = false;

        // Check if query matches any tags; work backwards toward 1 to assist ranking
        if (s.keywords) {
          for (var j = s.keywords.length - 1; j >= 0; j--) {
            // it matches a tag
            if (s.keywords[j].toLowerCase().match(queryRegex)) {
              matched = true;
              s.matched_tag = j + 1; // add 1 to index position
            }
          }
        }

        // Check if query matches doc title
        if (s.title.toLowerCase().match(queryRegex)) {
          matched = true;
          s.matched_title = 1;
        }

        // Remember the doc if it matches either
        if (matched) {
          results.push(s);
        }
      }

      // Improve the current results
      results = lookupBetterResult(results);

      // Rank/sort all the matched pages
      rankAutocompleteDocResults(results);

      return results;
    }
  }

  // Replaces a match with another resource by url, if it exists.
  function lookupReplacementByUrl(match, url) {
    var replacement = METADATA.byUrl[url];

    // Replacement resource does not exists.
    if (!replacement) { return; }

    replacement.matched_title = Math.max(replacement.matched_title, match.matched_title);
    replacement.matched_tag = Math.max(replacement.matched_tag, match.matched_tag);

    return replacement;
  }

  // Find the localized version of a page if it exists.
  function lookupLocalizedVersion(match) {
    return METADATA.byUrl[match.baseUrl] || METADATA.byUrl[match.url];
  }

  // Find the main page for a tutorial when matching a subpage.
  function lookupTutorialIndex(match) {
    // Guard for non index tutorial pages.
    if (match.type !== 'training' || match.url.indexOf('index.html') >= 0) { return; }

    var indexUrl = match.url.replace(/[^\/]+$/, 'index.html');
    return lookupReplacementByUrl(match, indexUrl);
  }

  // Find related results which are a better match for the user.
  function lookupBetterResult(matches) {
    var newMatches = [];

    matches = matches.filter(function(match) {
      var newMatch = match;
      newMatch = lookupTutorialIndex(newMatch) || newMatch;
      newMatch = lookupLocalizedVersion(newMatch) || newMatch;

      if (newMatch !== match) {
        newMatches.push(newMatch);
      }

      return newMatch === match;
    });

    return toUnique(newMatches.concat(matches));
  }

  /* Order the jd doc result list based on match quality */
  function rankAutocompleteDocResults(matches) {
    if (!matches || !matches.length) {
      return;
    }

    var _resultScoreFn = function(match) {
      var score = 1.0;

      // if the query matched a tag
      if (match.matched_tag > 0) {
        // multiply score by factor relative to position in tags list (max of 3)
        score *= 3 / match.matched_tag;

        // if it also matched the title
        if (match.matched_title > 0) {
          score *= 2;
        }
      } else if (match.matched_title > 0) {
        score *= 3;
      }

      if (match.lang === currentLang) {
        score *= 5;
      }

      return score;
    };

    for (var i = 0; i < matches.length; i++) {
      matches[i].__resultScore = _resultScoreFn(matches[i]);
    }

    matches.sort(function(a, b) {
      var n = b.__resultScore - a.__resultScore;

      if (n === 0) {
        // lexicographical sort if scores are the same
        n = (a.title < b.title) ? -1 : 1;
      }

      return n;
    });
  }

  /* Order the result list based on match quality */
  function rankAutocompleteApiResults(query, matches) {
    query = query || '';
    if (!matches || !matches.length) {
      return;
    }

    // helper function that gets the last occurence index of the given regex
    // in the given string, or -1 if not found
    var _lastSearch = function(s, re) {
      if (s === '') {
        return -1;
      }
      var l = -1;
      var tmp;
      while ((tmp = s.search(re)) >= 0) {
        if (l < 0) {
          l = 0;
        }
        l += tmp;
        s = s.substr(tmp + 1);
      }
      return l;
    };

    // helper function that counts the occurrences of a given character in
    // a given string
    var _countChar = function(s, c) {
      var n = 0;
      for (var i = 0; i < s.length; i++) {
        if (s.charAt(i) === c) {
          ++n;
        }
      }
      return n;
    };

    var queryLower = query.toLowerCase();
    var queryAlnum = (queryLower.match(/\w+/) || [''])[0];
    var partPrefixAlnumRE = new RegExp('\\b' + queryAlnum);
    var partExactAlnumRE = new RegExp('\\b' + queryAlnum + '\\b');

    var _resultScoreFn = function(result) {
      // scores are calculated based on exact and prefix matches,
      // and then number of path separators (dots) from the last
      // match (i.e. favoring classes and deep package names)
      var score = 1.0;
      var labelLower = result.label.toLowerCase();
      var t;
      var partsAfter;
      t = _lastSearch(labelLower, partExactAlnumRE);
      if (t >= 0) {
        // exact part match
        partsAfter = _countChar(labelLower.substr(t + 1), '.');
        score *= 200 / (partsAfter + 1);
      } else {
        t = _lastSearch(labelLower, partPrefixAlnumRE);
        if (t >= 0) {
          // part prefix match
          partsAfter = _countChar(labelLower.substr(t + 1), '.');
          score *= 20 / (partsAfter + 1);
        }
      }

      return score;
    };

    for (var i = 0; i < matches.length; i++) {
      // if the API is deprecated, default score is 0; otherwise, perform scoring
      if (matches[i].deprecated === 'true') {
        matches[i].__resultScore = 0;
      } else {
        matches[i].__resultScore = _resultScoreFn(matches[i]);
      }
    }

    matches.sort(function(a, b) {
      var n = b.__resultScore - a.__resultScore;

      if (n === 0) {
        // lexicographical sort if scores are the same
        n = (a.label < b.label) ? -1 : 1;
      }

      return n;
    });
  }

  // Destructive but fast toUnique.
  // http://stackoverflow.com/a/25082874
  function toUnique(array) {
    var c;
    var b = array.length || 1;

    while (c = --b) {
      while (c--) {
        if (array[b] === array[c]) {
          array.splice(c, 1);
        }
      }
    }
    return array;
  }

  return search;
})();

(function($) {
  'use strict';

  /**
   * Smoothly scroll to location on current page.
   * @param el
   * @param options
   * @constructor
   */
  function ScrollButton(el, options) {
    this.el = $(el);
    this.target = $(this.el.attr('href'));
    this.options = $.extend({}, ScrollButton.DEFAULTS_, options);

    if (typeof this.options.offset === 'string') {
      this.options.offset = $(this.options.offset).height();
    }

    this.el.on('click', this.clickHandler_.bind(this));
  }

  /**
   * Default options
   * @type {{duration: number, easing: string, offset: number, scrollContainer: string}}
   * @private
   */
  ScrollButton.DEFAULTS_ = {
    duration: 300,
    easing: 'swing',
    offset: '.dac-header',
    scrollContainer: 'html, body'
  };

  /**
   * Scroll logic
   * @param event
   * @private
   */
  ScrollButton.prototype.clickHandler_ = function(event) {
    if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {
      return;
    }

    event.preventDefault();

    var position = this.getTargetPosition();
    $(this.options.scrollContainer).animate({
      scrollTop: position - this.options.offset
    }, this.options);
  };

  ScrollButton.prototype.getTargetPosition = function() {
    if (this.options.scrollContainer === ScrollButton.DEFAULTS_.scrollContainer) {
      return this.target.offset().top;
    }
    var scrollContainer = $(this.options.scrollContainer)[0];
    var currentEl = this.target[0];
    var pos = 0;
    while (currentEl !== scrollContainer && currentEl !== null) {
      pos += currentEl.offsetTop;
      currentEl = currentEl.offsetParent;
    }
    return pos;
  };

  /**
   * jQuery plugin
   * @param  {object} options - Override default options.
   */
  $.fn.dacScrollButton = function(options) {
    return this.each(function() {
      new ScrollButton(this, options);
    });
  };

  /**
   * Data Attribute API
   */
  $(document).on('ready.aranja', function() {
    $('[data-scroll-button]').each(function() {
      $(this).dacScrollButton($(this).data());
    });
  });
})(jQuery);

/* global getLangPref */
(function($) {
  var LANG;

  function getSearchLang() {
    if (!LANG) {
      LANG = getLangPref();

      // Fix zh-cn to be zh-CN.
      LANG = LANG.replace(/-\w+/, function(m) { return m.toUpperCase(); });
    }
    return LANG;
  }

  function customSearch(query, start) {
    var searchParams = {
      // current cse instance:
      //cx: '001482626316274216503:zu90b7s047u',
      // new cse instance:
      cx: '000521750095050289010:zpcpi1ea4s8',
      key: 'AIzaSyCFhbGnjW06dYwvRCU8h_zjdpS4PYYbEe8',
      q: query,
      start: start || 1,
      num: 6,
      hl: getSearchLang(),
      fields: 'queries,items(pagemap,link,title,htmlSnippet,formattedUrl)'
    };

    return $.get('https://content.googleapis.com/customsearch/v1?' +  $.param(searchParams));
  }

  function renderResults(el, results) {
    if (!results.items) {
      el.append($('<div>').text('No results'));
      return;
    }

    for (var i = 0; i < results.items.length; i++) {
      var item = results.items[i];
      var hasImage = item.pagemap && item.pagemap.cse_thumbnail;
      var sectionMatch = item.link.match(/developer\.android\.com\/(\w*)/);
      var section = (sectionMatch && sectionMatch[1]) || 'blog';

      var entry = $('<div>').addClass('dac-custom-search-entry cols');

      if (hasImage) {
        var image = item.pagemap.cse_thumbnail[0];
        entry.append($('<div>').addClass('col-1of6')
          .append($('<div>').addClass('dac-custom-search-image').css('background-image', 'url(' + image.src + ')')));
      }

      entry.append($('<div>').addClass(hasImage ? 'col-5of6' : 'col-6of6')
        .append($('<p>').addClass('dac-custom-search-section').text(section))
        .append(
          $('<a>').text(item.title).attr('href', item.link).wrap('<h2>').parent().addClass('dac-custom-search-title')
        )
        .append($('<p>').addClass('dac-custom-search-snippet').html(item.htmlSnippet.replace(/<br>/g, '')))
        .append($('<a>').addClass('dac-custom-search-link').text(item.formattedUrl).attr('href', item.link)));

      el.append(entry);
    }

    if (results.queries.nextPage) {
      var loadMoreButton = $('<button id="dac-custom-search-load-more">')
        .addClass('dac-custom-search-load-more')
        .text('Load more')
        .click(function() {
          loadMoreResults(el, results);
        });

      el.append(loadMoreButton);
    }
  }

  function loadMoreResults(el, results) {
    var query = results.queries.request.searchTerms;
    var start = results.queries.nextPage.startIndex;
    var loadMoreButton = el.find('#dac-custom-search-load-more');

    loadMoreButton.text('Loading more...');

    customSearch(query, start).then(function(results) {
      loadMoreButton.remove();
      renderResults(el, results);
    });
  }

  $.fn.customSearch = function(query) {
    var el = $(this);

    customSearch(query).then(function(results) {
      el.empty();
      renderResults(el, results);
    });
  };
})(jQuery);

/* global METADATA */

(function($) {
  $.fn.dacSearchRenderHero = function(resources, query) {
    var el = $(this);
    el.empty();

    var resource = METADATA.searchHeroCollections[query];

    if (resource) {
      el.dacHero(resource, true);
      el.show();

      return true;
    } else {
      el.hide();
    }
  };
})(jQuery);

(function($) {
  $.fn.dacSearchRenderReferences = function(results, query) {
    var referenceCard = $('.suggest-card.reference');
    referenceCard.data('searchreferences.dac', {results: results, query: query});
    renderResults(referenceCard, results, query, false);
  };

  var ROW_COUNT_COLLAPSED = 7;
  var ROW_COUNT_EXPANDED = 33;
  var ROW_COUNT_GOOGLE_COLLAPSED = 1;
  var ROW_COUNT_GOOGLE_EXPANDED = 8;

  function onSuggestionClick(e) {
    var normalClick = e.which === 1 && !e.ctrlKey && !e.shiftKey && !e.metaKey;
    if (normalClick) {
      e.preventDefault();
    }

    // When user clicks a suggested document, track it
    var url = $(e.currentTarget).attr('href');
    ga('send', 'event', 'Suggestion Click', 'clicked: ' + url,
        'query: ' + $('#search_autocomplete').val().toLowerCase(),
        {hitCallback: function() {
          if (normalClick) {
            document.location = url;
          }
        }});
  }

  function buildLink(match) {
    var link = $('<a>').attr('href', window.toRoot + match.link);

    var label = match.label;
    var classNameStart = label.match(/[A-Z]/) ? label.search(/[A-Z]/) : label.lastIndexOf('.') + 1;

    var newLink = '<span class="namespace">' +
      label.substr(0, classNameStart) +
      '</span><br />' +
      label.substr(classNameStart, label.length);

    link.html(newLink);
    return link;
  }

  function buildSuggestion(match, query) {
    var li = $('<li>').addClass('dac-search-results-reference-entry');

    var link = buildLink(match);
    link.highlightMatches(query);
    li.append(link);
    return li[0];
  }

  function buildResults(results, query) {
    return results.map(function(match) {
      return buildSuggestion(match, query);
    });
  }

  function renderAndroidResults(list, gMatches, query) {
    list.empty();

    var header = $('<li class="dac-search-results-reference-header">Reference</li>');
    list.append(header);

    if (gMatches.length > 0) {
      list.removeClass('no-results');

      var resources = buildResults(gMatches, query);
      list.append(resources);

      return true;
    } else {
      list.append('<li class="dac-search-results-reference-entry-empty">No results</li>');
    }
  }

  function renderGoogleDocsResults(list, gGoogleMatches, query) {
    list = $('.suggest-card.reference ul');

    if (gGoogleMatches.length > 0) {
      list.append('<li class="dac-search-results-reference-header">in Google Services</li>');

      var resources = buildResults(gGoogleMatches, query);
      list.append(resources);

      return true;
    }
  }

  function renderResults(referenceCard, results, query, expanded) {
    var list = referenceCard.find('ul');
    list.toggleClass('is-expanded', !!expanded);

    // Figure out how many results we can show in our fixed size box.
    var total = expanded ? ROW_COUNT_EXPANDED : ROW_COUNT_COLLAPSED;
    var googleCount = expanded ? ROW_COUNT_GOOGLE_EXPANDED : ROW_COUNT_GOOGLE_COLLAPSED;
    googleCount = Math.max(googleCount, total - results.android.length);
    googleCount = Math.min(googleCount, results.docs.length);

    if (googleCount > 0) {
      // If there are google results, reserve space for its header.
      googleCount++;
    }

    var androidCount = Math.max(0, total - googleCount);
    if (androidCount === 0) {
      // Reserve space for "No reference results"
      googleCount--;
    }

    renderAndroidResults(list, results.android.slice(0, androidCount), query);
    renderGoogleDocsResults(list, results.docs.slice(0, googleCount - 1), query);

    var totalResults = results.android.length + results.docs.length;
    if (totalResults === 0) {
      list.addClass('no-results');
    }

    // Tweak see more logic to account for references.
    var hasMore = totalResults > ROW_COUNT_COLLAPSED && !util.matchesMedia('mobile');
    var searchEl = $('#search-resources');
    searchEl.toggleClass('dac-has-more', searchEl.hasClass('dac-has-more') || (hasMore && !expanded));
    searchEl.toggleClass('dac-has-less', searchEl.hasClass('dac-has-less') || (hasMore && expanded));
  }

  function onToggleMore(e) {
    var link = $(e.currentTarget);
    var referenceCard = $('.suggest-card.reference');
    var data = referenceCard.data('searchreferences.dac');

    if (util.matchesMedia('mobile')) { return; }

    renderResults(referenceCard, data.results, data.query, link.data('toggle') === 'show-more');
  }

  $(document).on('click', '.dac-search-results-resources [data-toggle="show-more"]', onToggleMore);
  $(document).on('click', '.dac-search-results-resources [data-toggle="show-less"]', onToggleMore);
  $(document).on('click', '.suggest-card.reference a', onSuggestionClick);
})(jQuery);

(function($) {
  function highlightPage(query, page) {
    page.find('.title').highlightMatches(query);
  }

  $.fn.dacSearchRenderResources = function(gDocsMatches, query) {
    this.resourceWidget(gDocsMatches, {
      itemsPerPage: 18,
      initialResults: 6,
      cardSizes: ['6x2'],
      onRenderPage: highlightPage.bind(null, query)
    });

    return this;
  };
})(jQuery);

/*global metadata */

(function($, metadata) {
  'use strict';

  function Search() {
    this.body = $('body');
    this.lastQuery = null;
    this.searchResults = $('#search-results');
    this.searchClose = $('[data-search-close]');
    this.searchClear = $('[data-search-clear]');
    this.searchInput = $('#search_autocomplete');
    this.searchResultsContent = $('#dac-search-results-content');
    this.searchResultsFor = $('#search-results-for');
    this.searchResultsHistory = $('#dac-search-results-history');
    this.searchResultsResources = $('#search-resources');
    this.searchResultsHero = $('#dac-search-results-hero');
    this.searchResultsReference = $('#dac-search-results-reference');
    this.searchHeader = $('[data-search]').data('search-input.dac');
  }

  Search.prototype.init = function() {
    if (this.checkRedirectToIndex()) { return; }

    this.searchHistory = window.dacStore('search-history');

    this.searchInput.focus(this.onSearchChanged.bind(this));
    this.searchInput.keydown(this.handleKeyboardShortcut.bind(this));
    this.searchInput.on('input', this.onSearchChanged.bind(this));
    this.searchClear.click(this.clear.bind(this));
    this.searchClose.click(this.close.bind(this));

    this.customSearch = $.fn.debounce(function(query) {
      $('#dac-custom-search-results').customSearch(query);
    }, 1000);

    // Start search shortcut (/)
    $('body').keyup(function(event) {
      if (event.which === 191 && $(event.target).is(':not(:input)')) {
        this.searchInput.focus();
      }
    }.bind(this));

    $(window).on('popstate', this.onPopState.bind(this));
    $(window).hashchange(this.onHashChange.bind(this));
    this.onHashChange();
  };

  Search.prototype.checkRedirectToIndex = function() {
    var query = this.getUrlQuery();
    var target = window.getLangTarget();
    var prefix = (target !== 'en') ? '/intl/' + target : '';
    var pathname = location.pathname.slice(prefix.length);
    if (query != null && pathname !== '/index.html') {
      location.href = prefix + '/index.html' + location.hash;
      return true;
    }
  };

  Search.prototype.handleKeyboardShortcut = function(event) {
    // Close (esc)
    if (event.which === 27) {
      this.searchClose.trigger('click');
      event.preventDefault();
    }

    // Previous result (up arrow)
    if (event.which === 38) {
      this.previousResult();
      event.preventDefault();
    }

    // Next result (down arrow)
    if (event.which === 40) {
      this.nextResult();
      event.preventDefault();
    }

    // Navigate to result (enter)
    if (event.which === 13) {
      this.navigateToResult();
      event.preventDefault();
    }
  };

  Search.prototype.goToResult = function(relativeIndex) {
    var links = this.searchResults.find('a').filter(':visible');
    var selectedLink = this.searchResults.find('.dac-selected');

    if (selectedLink.length) {
      var found = $.inArray(selectedLink[0], links);

      selectedLink.removeClass('dac-selected');
      links.eq(found + relativeIndex).addClass('dac-selected');
      return true;
    } else {
      if (relativeIndex > 0) {
        links.first().addClass('dac-selected');
      }
    }
  };

  Search.prototype.previousResult = function() {
    this.goToResult(-1);
  };

  Search.prototype.nextResult = function() {
    this.goToResult(1);
  };

  Search.prototype.navigateToResult = function() {
    var query = this.getQuery();
    var selectedLink = this.searchResults.find('.dac-selected');

    if (selectedLink.length) {
      selectedLink[0].click();
    } else {
      this.searchHistory.push(query);
      this.addQueryToUrl(query);

      var isMobileOrTablet = typeof window.orientation !== 'undefined';

      if (isMobileOrTablet) {
        this.searchInput.blur();
      }
    }
  };

  Search.prototype.onHashChange = function() {
    var query = this.getUrlQuery();
    if (query != null && query !== this.getQuery()) {
      this.searchInput.val(query);
      this.onSearchChanged();
    }
  };

  Search.prototype.clear = function() {
    this.searchInput.val('');
    window.location.hash = '';
    this.onSearchChanged();
    this.searchInput.focus();
  };

  Search.prototype.close = function() {
    this.removeQueryFromUrl();
    this.searchInput.blur();
    this.hideOverlay();
  };

  Search.prototype.getUrlQuery = function() {
    var queryMatch = location.hash.match(/q=(.*)&?/);
    return queryMatch && queryMatch[1] && decodeURI(queryMatch[1]);
  };

  Search.prototype.getQuery = function() {
    return this.searchInput.val().replace(/(^ +)|( +$)/g, '');
  };

  Search.prototype.onSearchChanged = function() {
    var query = this.getQuery();

    this.showOverlay();
    this.render(query);
  };

  Search.prototype.render = function(query) {
    if (this.lastQuery === query) { return; }

    if (query.length < 2) {
      query = '';
    }

    this.lastQuery = query;
    this.searchResultsFor.text(query);
    this.customSearch(query);
    var metadataResults = metadata.search(query);
    this.searchResultsResources.dacSearchRenderResources(metadataResults.resources, query);
    this.searchResultsReference.dacSearchRenderReferences(metadataResults, query);
    var hasHero = this.searchResultsHero.dacSearchRenderHero(metadataResults.resources, query);
    var hasQuery = !!query;

    this.searchResultsReference.toggle(!hasHero);
    this.searchResultsContent.toggle(hasQuery);
    this.searchResultsHistory.toggle(!hasQuery);
    this.addQueryToUrl(query);
    this.pushState();
  };

  Search.prototype.addQueryToUrl = function(query) {
    var hash = 'q=' + encodeURI(query);

    if (query) {
      if (window.history.replaceState) {
        window.history.replaceState(null, '', '#' + hash);
      } else {
        window.location.hash = hash;
      }
    }
  };

  Search.prototype.onPopState = function() {
    if (!this.getUrlQuery()) {
      this.hideOverlay();
      this.searchHeader.unsetActiveState();
    }
  };

  Search.prototype.removeQueryFromUrl = function() {
    window.location.hash = '';
  };

  Search.prototype.pushState = function() {
    if (window.history.pushState && !this.lastQuery.length) {
      window.history.pushState(null, '');
    }
  };

  Search.prototype.showOverlay = function() {
    this.body.addClass('dac-modal-open dac-search-open');
  };

  Search.prototype.hideOverlay = function() {
    this.body.removeClass('dac-modal-open dac-search-open');
  };

  $(document).on('ready.aranja', function() {
    var search = new Search();
    search.init();
  });
})(jQuery, metadata);

window.dacStore = (function(window) {
  /**
   * Creates a new persistent store.
   * If localStorage is unavailable, the items are stored in memory.
   *
   * @constructor
   * @param {string} name    The name of the store
   * @param {number} maxSize The maximum number of items the store can hold.
   */
  var Store = function(name, maxSize) {
    var content = [];

    var hasLocalStorage = !!window.localStorage;

    if (hasLocalStorage) {
      try {
        content = JSON.parse(window.localStorage.getItem(name) || []);
      } catch (e) {
        // Store contains invalid data
        window.localStorage.removeItem(name);
      }
    }

    function push(item) {
      if (content[0] === item) {
        return;
      }

      content.unshift(item);

      if (maxSize) {
        content.splice(maxSize, content.length);
      }

      if (hasLocalStorage) {
        window.localStorage.setItem(name, JSON.stringify(content));
      }
    }

    function all() {
      // Return a copy
      return content.slice();
    }

    return {
      push: push,
      all: all
    };
  };

  var stores = {
    'search-history': new Store('search-history', 3)
  };

  /**
   * Get a named persistent store.
   * @param  {string} name
   * @return {Store}
   */
  return function getStore(name) {
    return stores[name];
  };
})(window);

(function($) {
  'use strict';

  /**
   * A component that swaps two dynamic height views with an animation.
   * Listens for the following events:
   * * swap-content: triggers SwapContent.swap_()
   * * swap-reset: triggers SwapContent.reset()
   * @param el
   * @param options
   * @constructor
   */
  function SwapContent(el, options) {
    this.el = $(el);
    this.options = $.extend({}, SwapContent.DEFAULTS_, options);
    this.options.dynamic = this.options.dynamic === 'true';
    this.containers = this.el.find(this.options.container);
    this.initiallyActive = this.containers.children('.' + this.options.activeClass).eq(0);
    this.el.on('swap-content', this.swap.bind(this));
    this.el.on('swap-reset', this.reset.bind(this));
    this.el.find(this.options.swapButton).on('click', this.swap.bind(this));
  }

  /**
   * SwapContent's default settings.
   * @type {{activeClass: string, container: string, transitionSpeed: number}}
   * @private
   */
  SwapContent.DEFAULTS_ = {
    activeClass: 'dac-active',
    container: '[data-swap-container]',
    dynamic: 'true',
    swapButton: '[data-swap-button]',
    transitionSpeed: 500
  };

  /**
   * Returns container's visible height.
   * @param container
   * @returns {number}
   */
  SwapContent.prototype.currentHeight = function(container) {
    return container.children('.' + this.options.activeClass).outerHeight();
  };

  /**
   * Reset to show initial content
   */
  SwapContent.prototype.reset = function() {
    if (!this.initiallyActive.hasClass(this.initiallyActive)) {
      this.containers.children().toggleClass(this.options.activeClass);
    }
  };

  /**
   * Complete the swap.
   */
  SwapContent.prototype.complete = function() {
    this.containers.height('auto');
    this.containers.trigger('swap-complete');
  };

  /**
   * Perform the swap of content.
   */
  SwapContent.prototype.swap = function() {
    this.containers.each(function(index, container) {
      container = $(container);

      if (!this.options.dynamic) {
        container.children().toggleClass(this.options.activeClass);
        this.complete.bind(this);
        return;
      }

      container.height(this.currentHeight(container)).children().toggleClass(this.options.activeClass);
      container.animate({height: this.currentHeight(container)}, this.options.transitionSpeed,
        this.complete.bind(this));
    }.bind(this));
  };

  /**
   * jQuery plugin
   * @param  {object} options - Override default options.
   */
  $.fn.dacSwapContent = function(options) {
    return this.each(function() {
      new SwapContent(this, options);
    });
  };

  /**
   * Data Attribute API
   */
  $(document).on('ready.aranja', function() {
    $('[data-swap]').each(function() {
      $(this).dacSwapContent($(this).data());
    });
  });
})(jQuery);

/* Tabs */
(function($) {
  'use strict';

  /**
   * @param {HTMLElement} el - The DOM element.
   * @param {Object} options
   * @constructor
   */
  function Tabs(el, options) {
    this.el = $(el);
    this.options = $.extend({}, Tabs.DEFAULTS_, options);
    this.init();
  }

  Tabs.DEFAULTS_ = {
    activeClass: 'dac-active',
    viewDataAttr: 'tab-view',
    itemDataAttr: 'tab-item'
  };

  Tabs.prototype.init = function() {
    var itemDataAttribute = '[data-' + this.options.itemDataAttr + ']';
    this.tabEl_ = this.el.find(itemDataAttribute);
    this.tabViewEl_ = this.el.find('[data-' + this.options.viewDataAttr + ']');
    this.el.on('click.dac-tabs', itemDataAttribute, this.changeTabs.bind(this));
  };

  Tabs.prototype.changeTabs = function(event) {
    var current = $(event.currentTarget);
    var index = current.index();

    if (current.hasClass(this.options.activeClass)) {
      current.add(this.tabViewEl_.eq(index)).removeClass(this.options.activeClass);
    } else {
      this.tabEl_.add(this.tabViewEl_).removeClass(this.options.activeClass);
      current.add(this.tabViewEl_.eq(index)).addClass(this.options.activeClass);
    }
  };

  /**
   * jQuery plugin
   */
  $.fn.dacTabs = function() {
    return this.each(function() {
      var el = $(this);
      new Tabs(el, el.data());
    });
  };

  /**
   * Data Attribute API
   */
  $(function() {
    $('[data-tabs]').dacTabs();
  });
})(jQuery);

/* Toast Component */
(function($) {
  'use strict';
  /**
   * @constant
   * @type {String}
   */
  var LOCAL_STORAGE_KEY = 'toast-closed-index';

  /**
   * Dictionary from local storage.
   */
  var toastDictionary = localStorage.getItem(LOCAL_STORAGE_KEY);
  toastDictionary = toastDictionary ? JSON.parse(toastDictionary) : {};

  /**
   * Variable used for caching the body.
   */
  var bodyCached;

  /**
   * @param {HTMLElement} el - The DOM element.
   * @param {Object} options
   * @constructor
   */
  function Toast(el, options) {
    this.el = $(el);
    this.options = $.extend({}, Toast.DEFAULTS_, options);
    this.init();
  }

  Toast.DEFAULTS_ = {
    closeBtnClass: 'dac-toast-close-btn',
    closeDuration: 200,
    visibleClass: 'dac-visible',
    wrapClass: 'dac-toast-wrap'
  };

  /**
   * Generate a close button.
   * @returns {*|HTMLElement}
   */
  Toast.prototype.closeBtn = function() {
    this.closeBtnEl = this.closeBtnEl || $('<button class="' + this.options.closeBtnClass + '">' +
      '<i class="dac-sprite dac-close-black"></i>' +
    '</button>');
    return this.closeBtnEl;
  };

  /**
   * Initialize a new toast element
   */
  Toast.prototype.init = function() {
    this.hash = this.el.text().replace(/[\s\n\t]/g, '').split('').slice(0, 128).join('');

    if (toastDictionary[this.hash]) {
      return;
    }

    this.closeBtn().on('click', this.onClickHandler.bind(this));
    this.el.find('.' + this.options.wrapClass).append(this.closeBtn());
    this.el.addClass(this.options.visibleClass);
    this.dynamicPadding(this.el.outerHeight());
  };

  /**
   * Add padding to make sure all page is visible.
   */
  Toast.prototype.dynamicPadding = function(val) {
    var currentPadding = parseInt(bodyCached.css('padding-bottom') || 0);
    bodyCached.css('padding-bottom', val + currentPadding);
  };

  /**
   * Remove a toast from the DOM
   */
  Toast.prototype.remove = function() {
    this.dynamicPadding(-this.el.outerHeight());
    this.el.remove();
  };

  /**
   * Handle removal of the toast.
   */
  Toast.prototype.onClickHandler = function() {
    // Only fadeout toasts from top of stack. Others are removed immediately.
    var duration = this.el.index() === 0 ? this.options.closeDuration : 0;
    this.el.fadeOut(duration, this.remove.bind(this));

    // Save closed state.
    toastDictionary[this.hash] = 1;
    localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(toastDictionary));
  };

  /**
   * jQuery plugin
   * @param  {object} options - Override default options.
   */
  $.fn.dacToast = function() {
    return this.each(function() {
      var el = $(this);
      new Toast(el, el.data());
    });
  };

  /**
   * Data Attribute API
   */
  $(function() {
    bodyCached = $('#body-content');
    $('[data-toast]').dacToast();
  });
})(jQuery);

(function($) {
  function Toggle(el) {
    $(el).on('click.dac.togglesection', this.toggle);
  }

  Toggle.prototype.toggle = function() {
    var $this = $(this);

    var $parent = getParent($this);
    var isExpanded = $parent.hasClass('is-expanded');

    transitionMaxHeight($parent.find('.dac-toggle-content'), !isExpanded);
    $parent.toggleClass('is-expanded');

    return false;
  };

  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]*$)/, '');
    }

    var $parent = selector && $(selector);

    $parent = $parent && $parent.length ? $parent : $this.closest('.dac-toggle');

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

  /**
   * Runs a transition of max-height along with responsive styles which hide or expand the element.
   * @param $el
   * @param visible
   */
  function transitionMaxHeight($el, visible) {
    var contentHeight = $el.prop('scrollHeight');
    var targetHeight = visible ? contentHeight : 0;
    var duration = $el.transitionDuration();

    // If we're hiding, first set the maxHeight we're transitioning from.
    if (!visible) {
      $el.css({
          transitionDuration: '0s',
          maxHeight: contentHeight + 'px'
        })
        .resolveStyles()
        .css('transitionDuration', '');
    }

    // Transition to new state
    $el.css('maxHeight', targetHeight);

    // Reset maxHeight to css value after transition.
    setTimeout(function() {
      $el.css({
          transitionDuration: '0s',
          maxHeight: ''
        })
        .resolveStyles()
        .css('transitionDuration', '');
    }, duration);
  }

  // Utility to get the transition duration for the element.
  $.fn.transitionDuration = function() {
    var d = $(this).css('transitionDuration') || '0s';

    return +(parseFloat(d) * (/ms/.test(d) ? 1 : 1000)).toFixed(0);
  };

  // jQuery plugin
  $.fn.toggleSection = function(option) {
    return this.each(function() {
      var $this = $(this);
      var data = $this.data('dac.togglesection');
      if (!data) {$this.data('dac.togglesection', (data = new Toggle(this)));}
      if (typeof option === 'string') {data[option].call($this);}
    });
  };

  // Data api
  $(document)
    .on('click.toggle', '[data-toggle="section"]', Toggle.prototype.toggle);
})(jQuery);

(function(window) {
  /**
   * Media query breakpoints. Should match CSS.
   */
  var BREAKPOINTS = {
    mobile: [0, 719],
    tablet: [720, 959],
    desktop: [960, 9999]
  };

  /**
   * Fisher-Yates Shuffle (Knuth shuffle).
   * @param {Array} input
   * @returns {Array} shuffled array.
   */
  function shuffle(input) {
    for (var i = input.length; i >= 0; i--) {
      var randomIndex = Math.floor(Math.random() * (i + 1));
      var randomItem = input[randomIndex];
      input[randomIndex] = input[i];
      input[i] = randomItem;
    }

    return input;
  }

  /**
   * Matches media breakpoints like in CSS.
   * @param {string} form of either mobile, tablet or desktop.
   */
  function matchesMedia(form) {
    var breakpoint = BREAKPOINTS[form];
    return window.innerWidth >= breakpoint[0] && window.innerWidth <= breakpoint[1];
  }

  window.util = {
    shuffle: shuffle,
    matchesMedia: matchesMedia
  };
})(window);

(function($, window) {
  'use strict';

  var YouTubePlayer = (function() {
    var player;

    function VideoPlayer() {
      this.mPlayerPaused = false;
      this.doneSetup = false;
    }

    VideoPlayer.prototype.setup = function() {
      // loads the IFrame Player API code asynchronously.
      $.getScript('https://www.youtube.com/iframe_api');

      // Add the shadowbox HTML to the body
      $('body').prepend(
'<div id="video-player" class="Video">' +
  '<div id="video-overlay" class="Video-overlay" />' +
  '<div class="Video-container">' +
    '<div class="Video-frame">' +
      '<span class="Video-loading">Loading&hellip;</span>' +
      '<div id="youTubePlayer"></div>' +
    '</div>' +
    '<div class="Video-controls">' +
      '<button id="picture-in-picture" class="Video-button Video-button--picture-in-picture">' +
      '<button id="close-video" class="Video-button Video-button--close" />' +
    '</div>' +
  '</div>' +
'</div>');

      this.videoPlayer = $('#video-player');

      var pictureInPictureButton = this.videoPlayer.find('#picture-in-picture');
      pictureInPictureButton.on('click.aranja', this.toggleMinimizeVideo.bind(this));

      var videoOverlay = this.videoPlayer.find('#video-overlay');
      var closeButton = this.videoPlayer.find('#close-video');
      var closeVideo = this.closeVideo.bind(this);
      videoOverlay.on('click.aranja', closeVideo);
      closeButton.on('click.aranja', closeVideo);

      this.doneSetup = true;
    };

    VideoPlayer.prototype.startYouTubePlayer = function(videoId) {
      this.videoPlayer.show();

      if (!this.isLoaded) {
        this.queueVideo = videoId;
        return;
      }

      this.mPlayerPaused = false;
      // check if we've already created this player
      if (!this.youTubePlayer) {
        // check if there's a start time specified
        var idAndHash = videoId.split('#');
        var startTime = 0;
        if (idAndHash.length > 1) {
          startTime = idAndHash[1].split('t=')[1] !== undefined ? idAndHash[1].split('t=')[1] : 0;
        }
        // enable localized player
        var lang = getLangPref();
        var captionsOn = lang === 'en' ? 0 : 1;

        this.youTubePlayer = new YT.Player('youTubePlayer', {
          height: 720,
          width: 1280,
          videoId: idAndHash[0],
          // jscs:disable requireCamelCaseOrUpperCaseIdentifiers
          playerVars: {start: startTime, hl: lang, cc_load_policy: captionsOn},
          // jscs:enable
          events: {
            'onReady': this.onPlayerReady.bind(this),
            'onStateChange': this.onPlayerStateChange.bind(this)
          }
        });
      } else {
        // if a video different from the one already playing was requested, cue it up
        if (videoId !== this.getVideoId()) {
          this.youTubePlayer.cueVideoById(videoId);
        }
        this.youTubePlayer.playVideo();
      }
    };

    VideoPlayer.prototype.onPlayerReady = function(event) {
      if (!isMobile) {
        event.target.playVideo();
        this.mPlayerPaused = false;
      }
    };

    VideoPlayer.prototype.toggleMinimizeVideo = function(event) {
      event.stopPropagation();
      this.videoPlayer.toggleClass('Video--picture-in-picture');
    };

    VideoPlayer.prototype.closeVideo = function() {
      try {
        this.youTubePlayer.pauseVideo();
      } catch (e) {
      }
      this.videoPlayer.fadeOut(200, function() {
        this.videoPlayer.removeClass('Video--picture-in-picture');
      }.bind(this));
    };

    VideoPlayer.prototype.getVideoId = function() {
      // jscs:disable requireCamelCaseOrUpperCaseIdentifiers
      return this.youTubePlayer && this.youTubePlayer.getVideoData().video_id;
      // jscs:enable
    };

    /* Track youtube playback for analytics */
    VideoPlayer.prototype.onPlayerStateChange = function(event) {
      var videoId = this.getVideoId();
      var currentTime = this.youTubePlayer && this.youTubePlayer.getCurrentTime();

      // Video starts, send the video ID
      if (event.data === YT.PlayerState.PLAYING) {
        if (this.mPlayerPaused) {
          ga('send', 'event', 'Videos', 'Resume', videoId);
        } else {
          // track the start playing event so we know from which page the video was selected
          ga('send', 'event', 'Videos', 'Start: ' + videoId, 'on: ' + document.location.href);
        }
        this.mPlayerPaused = false;
      }

      // Video paused, send video ID and video elapsed time
      if (event.data === YT.PlayerState.PAUSED) {
        ga('send', 'event', 'Videos', 'Paused', videoId, currentTime);
        this.mPlayerPaused = true;
      }

      // Video finished, send video ID and video elapsed time
      if (event.data === YT.PlayerState.ENDED) {
        ga('send', 'event', 'Videos', 'Finished', videoId, currentTime);
        this.mPlayerPaused = true;
      }
    };

    return {
      getPlayer: function() {
        if (!player) {
          player = new VideoPlayer();
        }

        return player;
      }
    };
  })();

  var videoPlayer = YouTubePlayer.getPlayer();

  window.onYouTubeIframeAPIReady = function() {
    videoPlayer.isLoaded = true;

    if (videoPlayer.queueVideo) {
      videoPlayer.startYouTubePlayer(videoPlayer.queueVideo);
    }
  };

  function wrapLinkInPlayer(e) {
    e.preventDefault();

    if (!videoPlayer.doneSetup) {
      videoPlayer.setup();
    }

    var videoIdMatches = $(e.currentTarget).attr('href').match(/(?:youtu.be\/|v=)([^&]*)/);
    var videoId = videoIdMatches && videoIdMatches[1];

    if (videoId) {
      videoPlayer.startYouTubePlayer(videoId);
    }
  }

  $(document).on('click.video', 'a[href*="youtube.com/watch"], a[href*="youtu.be"]', wrapLinkInPlayer);
})(jQuery, window);

/**
 * Wide table
 *
 * Wraps tables in a scrollable area so you can read them on mobile.
 */
(function($) {
  function initWideTable() {
    $('table.jd-sumtable').each(function(i, table) {
      $(table).wrap('<div class="dac-expand wide-table">');
    });
  }

  $(function() {
    initWideTable();
  });
})(jQuery);
