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) {
    var thing = ($("#jd-header").html().indexOf("package") != -1) ? "package" : "class";
    $("#naMessage").show().html("<div><p><strong>This " + thing +
              " 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/triangle-opened.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/triangle-closed.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.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.
      var langAttr = window.getLangPref();
      console.log("langAttr is " + langAttr);
      views.slice(0, 2).addClass('dac-active');
      var selectedNav = views.eq(2).find('.selected').after(forwardLink);
      //select the localized text if available else the selectedNav value
      if (langAttr!='en') {
        $('.dac-nav-back-title').text(selectedNav.attr(langAttr + '-lang'));
      } 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');
      }
    }
    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);
