diff --git a/readthedocs/api/base.py b/readthedocs/api/base.py
index 0ff3e82e2be..d7c99f13f8f 100644
--- a/readthedocs/api/base.py
+++ b/readthedocs/api/base.py
@@ -18,8 +18,7 @@
from builds.models import Build, Version
from core.utils import trigger_build
from projects.models import Project, ImportedFile
-from projects.version_handling import highest_version
-from projects.version_handling import parse_version_failsafe
+from restapi.views.footer_views import get_version_compare_data
from .utils import SearchMixin, PostAuthentication
@@ -144,34 +143,16 @@ def get_object_list(self, request):
self._meta.queryset = Version.objects.api(user=request.user, only_active=False)
return super(VersionResource, self).get_object_list(request)
- def version_compare(self, request, **kwargs):
- project = get_object_or_404(Project, slug=kwargs['project_slug'])
- highest_version_obj, highest_version_comparable = highest_version(
- project.versions.filter(active=True))
- base = kwargs.get('base', None)
- ret_val = {
- 'project': highest_version_obj,
- 'version': highest_version_comparable,
- 'is_highest': True,
- }
- if highest_version_obj:
- ret_val['url'] = highest_version_obj.get_absolute_url()
- ret_val['slug'] = highest_version_obj.slug,
+ def version_compare(self, request, project_slug, base=None, **kwargs):
+ project = get_object_or_404(Project, slug=project_slug)
if base and base != LATEST:
try:
- base_version_obj = project.versions.get(slug=base)
- base_version_comparable = parse_version_failsafe(
- base_version_obj.verbose_name)
- if base_version_comparable:
- # This is only place where is_highest can get set. All
- # error cases will be set to True, for non- standard
- # versions.
- ret_val['is_highest'] = (
- base_version_comparable >= highest_version_comparable)
- else:
- ret_val['is_highest'] = True
+ base_version = project.versions.get(slug=base)
except (Version.DoesNotExist, TypeError):
- ret_val['is_highest'] = True
+ base_version = None
+ else:
+ base_version = None
+ ret_val = get_version_compare_data(project, base_version)
return self.create_response(request, ret_val)
def build_version(self, request, **kwargs):
diff --git a/readthedocs/core/static-src/core/js/doc-embed/footer.js b/readthedocs/core/static-src/core/js/doc-embed/footer.js
new file mode 100644
index 00000000000..adaa0ba7da5
--- /dev/null
+++ b/readthedocs/core/static-src/core/js/doc-embed/footer.js
@@ -0,0 +1,97 @@
+var rtd = require('./rtd-data');
+var versionCompare = require('./version-compare');
+
+
+function init(build) {
+ var get_data = {
+ project: rtd['project'],
+ version: rtd['version'],
+ page: rtd['page'],
+ theme: rtd['theme'],
+ format: "jsonp",
+ };
+
+ // Crappy heuristic, but people change the theme name on us.
+ // So we have to do some duck typing.
+ if ("docroot" in rtd) {
+ get_data['docroot'] = rtd['docroot'];
+ }
+
+ if ("source_suffix" in rtd) {
+ get_data['source_suffix'] = rtd['source_suffix'];
+ }
+
+ if (window.location.pathname.indexOf('/projects/') === 0) {
+ get_data['subproject'] = true;
+ }
+
+ // Get footer HTML from API and inject it into the page.
+ $.ajax({
+ url: rtd.api_host + "/api/v2/footer_html/",
+ crossDomain: true,
+ xhrFields: {
+ withCredentials: true,
+ },
+ dataType: "jsonp",
+ data: get_data,
+ success: function (data) {
+ versionCompare.init(data.version_compare);
+ injectFooter(data);
+ setupBookmarkCSRFToken();
+ },
+ error: function () {
+ console.error('Error loading Read the Docs footer');
+ }
+ });
+}
+
+
+function injectFooter(data) {
+ // If the theme looks like ours, update the existing badge
+ // otherwise throw a a full one into the page.
+ if (build.is_rtd_theme()) {
+ $("div.rst-other-versions").html(data['html']);
+ } else {
+ $("body").append(data['html']);
+ }
+
+ if (!data['version_active']) {
+ $('.rst-current-version').addClass('rst-out-of-date');
+ } else if (!data['version_supported']) {
+ //$('.rst-current-version').addClass('rst-active-old-version')
+ }
+
+ // Show promo selectively
+ if (data.promo && build.show_promo()) {
+ var promo = new sponsorship.Promo(
+ data.promo_data.id,
+ data.promo_data.text,
+ data.promo_data.link,
+ data.promo_data.image
+ )
+ if (promo) {
+ promo.display();
+ }
+ }
+}
+
+
+function setupBookmarkCSRFToken() {
+ function csrfSafeMethod(method) {
+ // these HTTP methods do not require CSRF protection
+ return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
+ }
+
+ $.ajaxSetup({
+ beforeSend: function(xhr, settings) {
+ if (!csrfSafeMethod(settings.type)) {
+ xhr.setRequestHeader("X-CSRFToken", $('a.bookmark[token]').attr('token'));
+ }
+ }
+ });
+}
+
+
+module.exports = {
+ init: init
+};
diff --git a/readthedocs/core/static-src/core/js/doc-embed/grokthedocs-client.js b/readthedocs/core/static-src/core/js/doc-embed/grokthedocs-client.js
new file mode 100644
index 00000000000..5792252b276
--- /dev/null
+++ b/readthedocs/core/static-src/core/js/doc-embed/grokthedocs-client.js
@@ -0,0 +1,13 @@
+function init() {
+ // Add Grok the Docs Client
+ $.ajax({
+ url: "https://api.grokthedocs.com/static/javascript/bundle-client.js",
+ crossDomain: true,
+ dataType: "script",
+ });
+}
+
+
+module.exports = {
+ init: init
+};
diff --git a/readthedocs/core/static-src/core/js/doc-embed/mkdocs.js b/readthedocs/core/static-src/core/js/doc-embed/mkdocs.js
new file mode 100644
index 00000000000..c311b5b9a5e
--- /dev/null
+++ b/readthedocs/core/static-src/core/js/doc-embed/mkdocs.js
@@ -0,0 +1,51 @@
+/*
+ * Mkdocs specific JS code.
+ */
+
+
+var rtd = require('./rtd-data');
+
+
+function init() {
+
+ // Override MkDocs styles
+ if ("builder" in rtd && rtd["builder"] == "mkdocs") {
+ $('').attr({
+ type: 'hidden',
+ name: 'project',
+ value: rtd["project"]
+ }).appendTo('#rtd-search-form');
+ $('').attr({
+ type: 'hidden',
+ name: 'version',
+ value: rtd["version"]
+ }).appendTo('#rtd-search-form');
+ $('').attr({
+ type: 'hidden',
+ name: 'type',
+ value: 'file'
+ }).appendTo('#rtd-search-form');
+
+ $("#rtd-search-form").prop("action", rtd.api_host + "/elasticsearch/");
+
+ // Apply stickynav to mkdocs builds
+ var nav_bar = $('nav.wy-nav-side:first'),
+ win = $(window),
+ sticky_nav_class = 'stickynav',
+ apply_stickynav = function () {
+ if (nav_bar.height() <= win.height()) {
+ nav_bar.addClass(sticky_nav_class);
+ } else {
+ nav_bar.removeClass(sticky_nav_class);
+ }
+ };
+ win.on('resize', apply_stickynav);
+ apply_stickynav();
+ }
+
+}
+
+
+module.exports = {
+ init: init
+};
diff --git a/readthedocs/core/static-src/core/js/doc-embed/rtd-data.js b/readthedocs/core/static-src/core/js/doc-embed/rtd-data.js
new file mode 100644
index 00000000000..ba5642bf884
--- /dev/null
+++ b/readthedocs/core/static-src/core/js/doc-embed/rtd-data.js
@@ -0,0 +1,16 @@
+/*
+ * This exposes data injected during the RTD build into the template. It's
+ * provided via the global READTHEDOCS_DATA variable and is exposed here as a
+ * module for cleaner usage.
+ */
+
+
+var data = READTHEDOCS_DATA;
+
+
+if (data.api_host === undefined) {
+ data.api_host = 'https://readthedocs.org';
+}
+
+
+module.exports = data;
diff --git a/readthedocs/core/static-src/core/js/doc-embed/sphinx.js b/readthedocs/core/static-src/core/js/doc-embed/sphinx.js
new file mode 100644
index 00000000000..6a13c57cf0f
--- /dev/null
+++ b/readthedocs/core/static-src/core/js/doc-embed/sphinx.js
@@ -0,0 +1,131 @@
+/*
+ * Sphinx builder specific JS code.
+ */
+
+
+var rtd = require('./rtd-data');
+
+
+function init() {
+
+ /// Read the Docs Sphinx theme code
+ if (!("builder" in rtd) || "builder" in rtd && rtd["builder"] != "mkdocs") {
+ function toggleCurrent (elem) {
+ var parent_li = elem.closest('li');
+ parent_li.siblings('li.current').removeClass('current');
+ parent_li.siblings().find('li.current').removeClass('current');
+ parent_li.find('> ul li.current').removeClass('current');
+ parent_li.toggleClass('current');
+ }
+
+ // Shift nav in mobile when clicking the menu.
+ $(document).on('click', "[data-toggle='wy-nav-top']", function() {
+ $("[data-toggle='wy-nav-shift']").toggleClass("shift");
+ $("[data-toggle='rst-versions']").toggleClass("shift");
+ });
+ // Nav menu link click operations
+ $(document).on('click', ".wy-menu-vertical .current ul li a", function() {
+ var target = $(this);
+ // Close menu when you click a link.
+ $("[data-toggle='wy-nav-shift']").removeClass("shift");
+ $("[data-toggle='rst-versions']").toggleClass("shift");
+ // Handle dynamic display of l3 and l4 nav lists
+ toggleCurrent(target);
+ if (typeof(window.SphinxRtdTheme) != 'undefined') {
+ window.SphinxRtdTheme.StickyNav.hashChange();
+ }
+ });
+ $(document).on('click', "[data-toggle='rst-current-version']", function() {
+ $("[data-toggle='rst-versions']").toggleClass("shift-up");
+ });
+ // Make tables responsive
+ $("table.docutils:not(.field-list)").wrap("
");
+
+ // Add expand links to all parents of nested ul
+ $('.wy-menu-vertical ul').siblings('a').each(function () {
+ var link = $(this);
+ expand = $('');
+ expand.on('click', function (ev) {
+ toggleCurrent(link);
+ ev.stopPropagation();
+ return false;
+ });
+ link.prepend(expand);
+ });
+
+ // Sphinx theme state
+ window.SphinxRtdTheme = (function (jquery) {
+ var stickyNav = (function () {
+ var navBar,
+ win,
+ winScroll = false,
+ linkScroll = false,
+ winPosition = 0,
+ enable = function () {
+ init();
+ reset();
+ win.on('hashchange', reset);
+
+ // Set scrolling
+ win.on('scroll', function () {
+ if (!linkScroll) {
+ winScroll = true;
+ }
+ });
+ setInterval(function () {
+ if (winScroll) {
+ winScroll = false;
+ var newWinPosition = win.scrollTop(),
+ navPosition = navBar.scrollTop(),
+ newNavPosition = navPosition + (newWinPosition - winPosition);
+ navBar.scrollTop(newNavPosition);
+ winPosition = newWinPosition;
+ }
+ }, 25);
+ },
+ init = function () {
+ navBar = jquery('nav.wy-nav-side:first');
+ win = jquery(window);
+ },
+ reset = function () {
+ // Get anchor from URL and open up nested nav
+ var anchor = encodeURI(window.location.hash);
+ if (anchor) {
+ try {
+ var link = $('.wy-menu-vertical')
+ .find('[href="' + anchor + '"]');
+ $('.wy-menu-vertical li.toctree-l1 li.current')
+ .removeClass('current');
+ link.closest('li.toctree-l2').addClass('current');
+ link.closest('li.toctree-l3').addClass('current');
+ link.closest('li.toctree-l4').addClass('current');
+ }
+ catch (err) {
+ console.log("Error expanding nav for anchor", err);
+ }
+ }
+ },
+ hashChange = function () {
+ linkScroll = true;
+ win.one('hashchange', function () {
+ linkScroll = false;
+ });
+ };
+ jquery(init);
+ return {
+ enable: enable,
+ hashChange: hashChange
+ };
+ }());
+ return {
+ StickyNav: stickyNav
+ };
+ }($));
+ }
+
+}
+
+
+module.exports = {
+ init: init
+};
diff --git a/readthedocs/core/static-src/core/js/doc-embed/version-compare.js b/readthedocs/core/static-src/core/js/doc-embed/version-compare.js
new file mode 100644
index 00000000000..d8d3c0c0339
--- /dev/null
+++ b/readthedocs/core/static-src/core/js/doc-embed/version-compare.js
@@ -0,0 +1,36 @@
+var rtd = require('./rtd-data');
+
+
+function init(data) {
+ /// Out of date message
+
+ if (data.is_highest) {
+ return;
+ }
+
+ var currentURL = window.location.pathname.replace(rtd['version'], data.slug);
+ var warning = $(
+ ' ' +
+ '
Note
' +
+ '
' +
+ 'You are not using the most up to date version of the library. ' +
+ ' is the newest version.' +
+ '
' +
+ '
');
+
+ warning
+ .find('a')
+ .attr('href', currentURL)
+ .text(data.version);
+
+ var body = $("div.body");
+ if (!body.length) {
+ body = $("div.document");
+ }
+ body.prepend(warning);
+}
+
+
+module.exports = {
+ init: init
+};
diff --git a/readthedocs/core/static-src/core/js/readthedocs-doc-embed.js b/readthedocs/core/static-src/core/js/readthedocs-doc-embed.js
index 953da77069a..1811fab55f9 100644
--- a/readthedocs/core/static-src/core/js/readthedocs-doc-embed.js
+++ b/readthedocs/core/static-src/core/js/readthedocs-doc-embed.js
@@ -1,298 +1,16 @@
var sponsorship = require('./sponsorship'),
- doc = require('./doc');
+ doc = require('./doc'),
+ footer = require('./doc-embed/footer.js'),
+ grokthedocs = require('./doc-embed/grokthedocs-client'),
+ mkdocs = require('./doc-embed/mkdocs'),
+ rtd = require('./doc-embed/rtd-data'),
+ sphinx = require('./doc-embed/sphinx');
$(document).ready(function () {
+ var build = new doc.Build(rtd);
- var build = new doc.Build(READTHEDOCS_DATA);
-
- get_data = {
- project: READTHEDOCS_DATA['project'],
- version: READTHEDOCS_DATA['version'],
- page: READTHEDOCS_DATA['page'],
- theme: READTHEDOCS_DATA['theme'],
- format: "jsonp",
- };
-
-
- // Crappy heuristic, but people change the theme name on us.
- // So we have to do some duck typing.
- if ("docroot" in READTHEDOCS_DATA) {
- get_data['docroot'] = READTHEDOCS_DATA['docroot'];
- }
-
- if ("source_suffix" in READTHEDOCS_DATA) {
- get_data['source_suffix'] = READTHEDOCS_DATA['source_suffix'];
- }
-
- var API_HOST = READTHEDOCS_DATA['api_host'];
- if (API_HOST === undefined) {
- API_HOST = 'https://readthedocs.org';
- }
-
- if (window.location.pathname.indexOf('/projects/') === 0) {
- get_data['subproject'] = true;
- }
-
- // Theme popout code
- $.ajax({
- url: API_HOST + "/api/v2/footer_html/",
- crossDomain: true,
- xhrFields: {
- withCredentials: true,
- },
- dataType: "jsonp",
- data: get_data,
- success: function (data) {
- // If the theme looks like ours, update the existing badge
- // otherwise throw a a full one into the page.
- if (build.is_rtd_theme()) {
- $("div.rst-other-versions").html(data['html']);
- } else {
- $("body").append(data['html']);
- }
-
- if (!data['version_active']) {
- $('.rst-current-version').addClass('rst-out-of-date');
- } else if (!data['version_supported']) {
- //$('.rst-current-version').addClass('rst-active-old-version')
- }
-
- // Show promo selectively
- if (data.promo && build.show_promo()) {
- var promo = new sponsorship.Promo(
- data.promo_data.id,
- data.promo_data.text,
- data.promo_data.link,
- data.promo_data.image
- )
- if (promo) {
- promo.display();
- }
- }
-
- // using jQuery
- function getCookie(name) {
- var cookieValue = null;
- if (document.cookie && document.cookie !== '') {
- var cookies = document.cookie.split(';');
- for (var i = 0; i < cookies.length; i++) {
- var cookie = jQuery.trim(cookies[i]);
- // Does this cookie string begin with the name we want?
- if (cookie.substring(0, name.length + 1) == (name + '=')) {
- cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
- break;
- }
- }
- }
- return cookieValue;
- }
-
- function csrfSafeMethod(method) {
- // these HTTP methods do not require CSRF protection
- return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
- }
- $.ajaxSetup({
- beforeSend: function(xhr, settings) {
- if (!csrfSafeMethod(settings.type)) {
- xhr.setRequestHeader("X-CSRFToken", $('a.bookmark[token]').attr('token'));
- }
- }
- });
- },
- error: function () {
- console.log('Error loading Read the Docs footer');
- }
- });
-
-
- /// Read the Docs Sphinx theme code
- if (!("builder" in READTHEDOCS_DATA) || "builder" in READTHEDOCS_DATA && READTHEDOCS_DATA["builder"] != "mkdocs") {
- function toggleCurrent (elem) {
- var parent_li = elem.closest('li');
- parent_li.siblings('li.current').removeClass('current');
- parent_li.siblings().find('li.current').removeClass('current');
- parent_li.find('> ul li.current').removeClass('current');
- parent_li.toggleClass('current');
- }
-
- // Shift nav in mobile when clicking the menu.
- $(document).on('click', "[data-toggle='wy-nav-top']", function() {
- $("[data-toggle='wy-nav-shift']").toggleClass("shift");
- $("[data-toggle='rst-versions']").toggleClass("shift");
- });
- // Nav menu link click operations
- $(document).on('click', ".wy-menu-vertical .current ul li a", function() {
- var target = $(this);
- // Close menu when you click a link.
- $("[data-toggle='wy-nav-shift']").removeClass("shift");
- $("[data-toggle='rst-versions']").toggleClass("shift");
- // Handle dynamic display of l3 and l4 nav lists
- toggleCurrent(target);
- if (typeof(window.SphinxRtdTheme) != 'undefined') {
- window.SphinxRtdTheme.StickyNav.hashChange();
- }
- });
- $(document).on('click', "[data-toggle='rst-current-version']", function() {
- $("[data-toggle='rst-versions']").toggleClass("shift-up");
- });
- // Make tables responsive
- $("table.docutils:not(.field-list)").wrap("");
-
- // Add expand links to all parents of nested ul
- $('.wy-menu-vertical ul').siblings('a').each(function () {
- var link = $(this);
- expand = $('');
- expand.on('click', function (ev) {
- toggleCurrent(link);
- ev.stopPropagation();
- return false;
- });
- link.prepend(expand);
- });
-
- // Sphinx theme state
- window.SphinxRtdTheme = (function (jquery) {
- var stickyNav = (function () {
- var navBar,
- win,
- winScroll = false,
- linkScroll = false,
- winPosition = 0,
- enable = function () {
- init();
- reset();
- win.on('hashchange', reset);
-
- // Set scrolling
- win.on('scroll', function () {
- if (!linkScroll) {
- winScroll = true;
- }
- });
- setInterval(function () {
- if (winScroll) {
- winScroll = false;
- var newWinPosition = win.scrollTop(),
- navPosition = navBar.scrollTop(),
- newNavPosition = navPosition + (newWinPosition - winPosition);
- navBar.scrollTop(newNavPosition);
- winPosition = newWinPosition;
- }
- }, 25);
- },
- init = function () {
- navBar = jquery('nav.wy-nav-side:first');
- win = jquery(window);
- },
- reset = function () {
- // Get anchor from URL and open up nested nav
- var anchor = encodeURI(window.location.hash);
- if (anchor) {
- try {
- var link = $('.wy-menu-vertical')
- .find('[href="' + anchor + '"]');
- $('.wy-menu-vertical li.toctree-l1 li.current')
- .removeClass('current');
- link.closest('li.toctree-l2').addClass('current');
- link.closest('li.toctree-l3').addClass('current');
- link.closest('li.toctree-l4').addClass('current');
- }
- catch (err) {
- console.log("Error expanding nav for anchor", err);
- }
- }
- },
- hashChange = function () {
- linkScroll = true;
- win.one('hashchange', function () {
- linkScroll = false;
- });
- };
- jquery(init);
- return {
- enable: enable,
- hashChange: hashChange
- };
- }());
- return {
- StickyNav: stickyNav
- };
- }($));
- }
-
- // Add Grok the Docs Client
- $.ajax({
- url: "https://api.grokthedocs.com/static/javascript/bundle-client.js",
- crossDomain: true,
- dataType: "script",
- });
-
-
- /// Out of date message
-
- var versionURL = [API_HOST + "/api/v1/version/", READTHEDOCS_DATA['project'],
- "/highest/", READTHEDOCS_DATA['version'], "/?callback=?"].join("");
-
- $.getJSON(versionURL, onData);
-
- function onData (data) {
- if (data.is_highest) {
- return;
- }
-
- var currentURL = window.location.pathname.replace(READTHEDOCS_DATA['version'], data.slug),
- warning = $(' Note
\
- You are not using the most up to date version \
- of the library. is the newest version.
\
-
');
-
- warning
- .find('a')
- .attr('href', currentURL)
- .text(data.version);
-
- body = $("div.body");
- if (!body.length) {
- body = $("div.document");
- }
- body.prepend(warning);
- }
-
-
- // Override MkDocs styles
- if ("builder" in READTHEDOCS_DATA && READTHEDOCS_DATA["builder"] == "mkdocs") {
- $('').attr({
- type: 'hidden',
- name: 'project',
- value: READTHEDOCS_DATA["project"]
- }).appendTo('#rtd-search-form');
- $('').attr({
- type: 'hidden',
- name: 'version',
- value: READTHEDOCS_DATA["version"]
- }).appendTo('#rtd-search-form');
- $('').attr({
- type: 'hidden',
- name: 'type',
- value: 'file'
- }).appendTo('#rtd-search-form');
-
- $("#rtd-search-form").prop("action", API_HOST + "/elasticsearch/");
-
- // Apply stickynav to mkdocs builds
- var nav_bar = $('nav.wy-nav-side:first'),
- win = $(window),
- sticky_nav_class = 'stickynav',
- apply_stickynav = function () {
- if (nav_bar.height() <= win.height()) {
- nav_bar.addClass(sticky_nav_class);
- } else {
- nav_bar.removeClass(sticky_nav_class);
- }
- };
- win.on('resize', apply_stickynav);
- apply_stickynav();
- }
-
+ footer.init(build);
+ sphinx.init();
+ grokthedocs.init();
+ mkdocs.init();
});
diff --git a/readthedocs/core/static/core/js/readthedocs-doc-embed.js b/readthedocs/core/static/core/js/readthedocs-doc-embed.js
index 0252a32196a..8e79024a544 100644
--- a/readthedocs/core/static/core/js/readthedocs-doc-embed.js
+++ b/readthedocs/core/static/core/js/readthedocs-doc-embed.js
@@ -1 +1 @@
-!function t(e,o,r){function n(a,s){if(!o[a]){if(!e[a]){var c="function"==typeof require&&require;if(!s&&c)return c(a,!0);if(i)return i(a,!0);var d=new Error("Cannot find module '"+a+"'");throw d.code="MODULE_NOT_FOUND",d}var p=o[a]={exports:{}};e[a][0].call(p.exports,function(t){var o=e[a][1][t];return n(o?o:t)},p,p.exports,t,e,o,r)}return o[a].exports}for(var i="function"==typeof require&&require,a=0;a ul li.current").removeClass("current"),e.toggleClass("current")}function e(t){if(!t.is_highest){var e=window.location.pathname.replace(READTHEDOCS_DATA.version,t.slug),o=$(' Note
You are not using the most up to date version of the library. is the newest version.
');o.find("a").attr("href",e).text(t.version),body=$("div.body"),body.length||(body=$("div.document")),body.prepend(o)}}var o=new n.Build(READTHEDOCS_DATA);get_data={project:READTHEDOCS_DATA.project,version:READTHEDOCS_DATA.version,page:READTHEDOCS_DATA.page,theme:READTHEDOCS_DATA.theme,format:"jsonp"},"docroot"in READTHEDOCS_DATA&&(get_data.docroot=READTHEDOCS_DATA.docroot),"source_suffix"in READTHEDOCS_DATA&&(get_data.source_suffix=READTHEDOCS_DATA.source_suffix);var i=READTHEDOCS_DATA.api_host;void 0===i&&(i="https://readthedocs.org"),0===window.location.pathname.indexOf("/projects/")&&(get_data.subproject=!0),$.ajax({url:i+"/api/v2/footer_html/",crossDomain:!0,xhrFields:{withCredentials:!0},dataType:"jsonp",data:get_data,success:function(t){function e(t){return/^(GET|HEAD|OPTIONS|TRACE)$/.test(t)}if(o.is_rtd_theme()?$("div.rst-other-versions").html(t.html):$("body").append(t.html),t.version_active?!t.version_supported:$(".rst-current-version").addClass("rst-out-of-date"),t.promo&&o.show_promo()){var n=new r.Promo(t.promo_data.id,t.promo_data.text,t.promo_data.link,t.promo_data.image);n&&n.display()}$.ajaxSetup({beforeSend:function(t,o){e(o.type)||t.setRequestHeader("X-CSRFToken",$("a.bookmark[token]").attr("token"))}})},error:function(){console.log("Error loading Read the Docs footer")}}),(!("builder"in READTHEDOCS_DATA)||"builder"in READTHEDOCS_DATA&&"mkdocs"!=READTHEDOCS_DATA.builder)&&($(document).on("click","[data-toggle='wy-nav-top']",function(){$("[data-toggle='wy-nav-shift']").toggleClass("shift"),$("[data-toggle='rst-versions']").toggleClass("shift")}),$(document).on("click",".wy-menu-vertical .current ul li a",function(){var e=$(this);$("[data-toggle='wy-nav-shift']").removeClass("shift"),$("[data-toggle='rst-versions']").toggleClass("shift"),t(e),"undefined"!=typeof window.SphinxRtdTheme&&window.SphinxRtdTheme.StickyNav.hashChange()}),$(document).on("click","[data-toggle='rst-current-version']",function(){$("[data-toggle='rst-versions']").toggleClass("shift-up")}),$("table.docutils:not(.field-list)").wrap(""),$(".wy-menu-vertical ul").siblings("a").each(function(){var e=$(this);expand=$(''),expand.on("click",function(o){return t(e),o.stopPropagation(),!1}),e.prepend(expand)}),window.SphinxRtdTheme=function(t){var e=function(){var e,o,r=!1,n=!1,i=0,a=function(){s(),c(),o.on("hashchange",c),o.on("scroll",function(){n||(r=!0)}),setInterval(function(){if(r){r=!1;var t=o.scrollTop(),n=e.scrollTop(),a=n+(t-i);e.scrollTop(a),i=t}},25)},s=function(){e=t("nav.wy-nav-side:first"),o=t(window)},c=function(){var t=encodeURI(window.location.hash);if(t)try{var e=$(".wy-menu-vertical").find('[href="'+t+'"]');$(".wy-menu-vertical li.toctree-l1 li.current").removeClass("current"),e.closest("li.toctree-l2").addClass("current"),e.closest("li.toctree-l3").addClass("current"),e.closest("li.toctree-l4").addClass("current")}catch(o){console.log("Error expanding nav for anchor",o)}},d=function(){n=!0,o.one("hashchange",function(){n=!1})};return t(s),{enable:a,hashChange:d}}();return{StickyNav:e}}($)),$.ajax({url:"https://api.grokthedocs.com/static/javascript/bundle-client.js",crossDomain:!0,dataType:"script"});var a=[i+"/api/v1/version/",READTHEDOCS_DATA.project,"/highest/",READTHEDOCS_DATA.version,"/?callback=?"].join("");if($.getJSON(a,e),"builder"in READTHEDOCS_DATA&&"mkdocs"==READTHEDOCS_DATA.builder){$("").attr({type:"hidden",name:"project",value:READTHEDOCS_DATA.project}).appendTo("#rtd-search-form"),$("").attr({type:"hidden",name:"version",value:READTHEDOCS_DATA.version}).appendTo("#rtd-search-form"),$("").attr({type:"hidden",name:"type",value:"file"}).appendTo("#rtd-search-form"),$("#rtd-search-form").prop("action",i+"/elasticsearch/");var s=$("nav.wy-nav-side:first"),c=$(window),d="stickynav",p=function(){s.height()<=c.height()?s.addClass(d):s.removeClass(d)};c.on("resize",p),p()}})},{"./doc":1,"./sponsorship":3}],3:[function(t,e,o){function r(t,e,o,r){this.id=t,this.text=e,this.link=o,this.image=r,this.promo=null}var n=window.$;e.exports={Promo:r},r.prototype.create=function(){var t=this,e=n("nav.wy-nav-side");if(e.length){promo=n("").attr("class","wy-menu rst-pro");{var o=n("").attr("class","rst-pro-about"),r=n("").attr("href","http://docs.readthedocs.org/en/latest/sponsors.html#sponsorship-information").appendTo(o);n("").attr("class","fa fa-info-circle").appendTo(r)}if(o.appendTo(promo),t.image){{var i=n("").attr("class","rst-pro-image-wrapper").attr("href",t.link);n("
").attr("class","rst-pro-image").attr("src",t.image).appendTo(i)}promo.append(i)}var a=n("").html(t.text);return n(a).find("a").each(function(){n(this).attr("class","rst-pro-link").attr("href",t.link).attr("target","_blank").on("click",function(e){_gaq&&_gaq.push(["rtfd._setAccount","UA-17997319-1"],["rtfd._trackEvent","Promo","Click",t.id])})}),promo.append(a),promo.appendTo(e),promo.wrapper=n("").attr("class","rst-pro-wrapper").appendTo(e),promo}},r.prototype.display=function(){var t=this.promo;t||(t=this.promo=this.create()),t.show()},r.prototype.disable=function(){},r.from_variants=function(t){if(0==t.length)return null;var e=Math.floor(Math.random()*t.length),o=t[e],n=o.text,i=o.link,a=o.image,s=o.id;return new r(s,n,i,a)}},{}]},{},[2]);
\ No newline at end of file
+!function t(o,e,r){function n(a,s){if(!e[a]){if(!o[a]){var c="function"==typeof require&&require;if(!s&&c)return c(a,!0);if(i)return i(a,!0);var d=new Error("Cannot find module '"+a+"'");throw d.code="MODULE_NOT_FOUND",d}var p=e[a]={exports:{}};o[a][0].call(p.exports,function(t){var e=o[a][1][t];return n(e?e:t)},p,p.exports,t,o,e,r)}return e[a].exports}for(var i="function"==typeof require&&require,a=0;a").attr({type:"hidden",name:"project",value:n.project}).appendTo("#rtd-search-form"),$("").attr({type:"hidden",name:"version",value:n.version}).appendTo("#rtd-search-form"),$("").attr({type:"hidden",name:"type",value:"file"}).appendTo("#rtd-search-form"),$("#rtd-search-form").prop("action",n.api_host+"/elasticsearch/");var t=$("nav.wy-nav-side:first"),o=$(window),e="stickynav",r=function(){t.height()<=o.height()?t.addClass(e):t.removeClass(e)};o.on("resize",r),r()}}var n=t("./rtd-data");o.exports={init:r}},{"./rtd-data":4}],4:[function(t,o,e){var r=READTHEDOCS_DATA;void 0===r.api_host&&(r.api_host="https://readthedocs.org"),o.exports=r},{}],5:[function(t,o,e){function r(){function t(t){var o=t.closest("li");o.siblings("li.current").removeClass("current"),o.siblings().find("li.current").removeClass("current"),o.find("> ul li.current").removeClass("current"),o.toggleClass("current")}(!("builder"in n)||"builder"in n&&"mkdocs"!=n.builder)&&($(document).on("click","[data-toggle='wy-nav-top']",function(){$("[data-toggle='wy-nav-shift']").toggleClass("shift"),$("[data-toggle='rst-versions']").toggleClass("shift")}),$(document).on("click",".wy-menu-vertical .current ul li a",function(){var o=$(this);$("[data-toggle='wy-nav-shift']").removeClass("shift"),$("[data-toggle='rst-versions']").toggleClass("shift"),t(o),"undefined"!=typeof window.SphinxRtdTheme&&window.SphinxRtdTheme.StickyNav.hashChange()}),$(document).on("click","[data-toggle='rst-current-version']",function(){$("[data-toggle='rst-versions']").toggleClass("shift-up")}),$("table.docutils:not(.field-list)").wrap(""),$(".wy-menu-vertical ul").siblings("a").each(function(){var o=$(this);expand=$(''),expand.on("click",function(e){return t(o),e.stopPropagation(),!1}),o.prepend(expand)}),window.SphinxRtdTheme=function(t){var o=function(){var o,e,r=!1,n=!1,i=0,a=function(){s(),c(),e.on("hashchange",c),e.on("scroll",function(){n||(r=!0)}),setInterval(function(){if(r){r=!1;var t=e.scrollTop(),n=o.scrollTop(),a=n+(t-i);o.scrollTop(a),i=t}},25)},s=function(){o=t("nav.wy-nav-side:first"),e=t(window)},c=function(){var t=encodeURI(window.location.hash);if(t)try{var o=$(".wy-menu-vertical").find('[href="'+t+'"]');$(".wy-menu-vertical li.toctree-l1 li.current").removeClass("current"),o.closest("li.toctree-l2").addClass("current"),o.closest("li.toctree-l3").addClass("current"),o.closest("li.toctree-l4").addClass("current")}catch(e){console.log("Error expanding nav for anchor",e)}},d=function(){n=!0,e.one("hashchange",function(){n=!1})};return t(s),{enable:a,hashChange:d}}();return{StickyNav:o}}($))}var n=t("./rtd-data");o.exports={init:r}},{"./rtd-data":4}],6:[function(t,o,e){function r(t){if(!t.is_highest){var o=window.location.pathname.replace(n.version,t.slug),e=$(' Note
You are not using the most up to date version of the library. is the newest version.
');e.find("a").attr("href",o).text(t.version);var r=$("div.body");r.length||(r=$("div.document")),r.prepend(e)}}var n=t("./rtd-data");o.exports={init:r}},{"./rtd-data":4}],7:[function(t,o,e){function r(t){this.config=t,"sphinx_rtd_theme"!=this.config.theme&&1==$("div.rst-other-versions").length&&(this.config.theme="sphinx_rtd_theme"),void 0==this.config.api_host&&(this.config.api_host="https://readthedocs.org")}o.exports={Build:r},r.prototype.is_rtd_theme=function(){return"sphinx_rtd_theme"==this.config.theme},r.prototype.is_sphinx_builder=function(){return!("builder"in this.config)||"mkdocs"!=this.config.builder},r.prototype.show_promo=function(){return"https://readthedocs.com"!=this.config.api_host&&this.is_sphinx_builder()&&this.is_rtd_theme()}},{}],8:[function(t,o,e){var r=(t("./sponsorship"),t("./doc")),n=t("./doc-embed/footer.js"),i=t("./doc-embed/grokthedocs-client"),a=t("./doc-embed/mkdocs"),s=t("./doc-embed/rtd-data"),c=t("./doc-embed/sphinx");$(document).ready(function(){var t=new r.Build(s);n.init(t),c.init(),i.init(),a.init()})},{"./doc":7,"./doc-embed/footer.js":1,"./doc-embed/grokthedocs-client":2,"./doc-embed/mkdocs":3,"./doc-embed/rtd-data":4,"./doc-embed/sphinx":5,"./sponsorship":9}],9:[function(t,o,e){function r(t,o,e,r){this.id=t,this.text=o,this.link=e,this.image=r,this.promo=null}var n=window.$;o.exports={Promo:r},r.prototype.create=function(){var t=this,o=n("nav.wy-nav-side");if(o.length){promo=n("").attr("class","wy-menu rst-pro");{var e=n("").attr("class","rst-pro-about"),r=n("").attr("href","http://docs.readthedocs.org/en/latest/sponsors.html#sponsorship-information").appendTo(e);n("").attr("class","fa fa-info-circle").appendTo(r)}if(e.appendTo(promo),t.image){{var i=n("").attr("class","rst-pro-image-wrapper").attr("href",t.link);n("
").attr("class","rst-pro-image").attr("src",t.image).appendTo(i)}promo.append(i)}var a=n("").html(t.text);return n(a).find("a").each(function(){n(this).attr("class","rst-pro-link").attr("href",t.link).attr("target","_blank").on("click",function(o){_gaq&&_gaq.push(["rtfd._setAccount","UA-17997319-1"],["rtfd._trackEvent","Promo","Click",t.id])})}),promo.append(a),promo.appendTo(o),promo.wrapper=n("").attr("class","rst-pro-wrapper").appendTo(o),promo}},r.prototype.display=function(){var t=this.promo;t||(t=this.promo=this.create()),t.show()},r.prototype.disable=function(){},r.from_variants=function(t){if(0==t.length)return null;var o=Math.floor(Math.random()*t.length),e=t[o],n=e.text,i=e.link,a=e.image,s=e.id;return new r(s,n,i,a)}},{}]},{},[8]);
\ No newline at end of file
diff --git a/readthedocs/donate/static/donate/js/donate.js b/readthedocs/donate/static/donate/js/donate.js
index 956fa1a9887..69c52c4f450 100644
--- a/readthedocs/donate/static/donate/js/donate.js
+++ b/readthedocs/donate/static/donate/js/donate.js
@@ -1 +1 @@
-!function e(t,n,r){function o(i,u){if(!n[i]){if(!t[i]){var l="function"==typeof require&&require;if(!u&&l)return l(i,!0);if(a)return a(i,!0);var c=new Error("Cannot find module '"+i+"'");throw c.code="MODULE_NOT_FOUND",c}var s=n[i]={exports:{}};t[i][0].call(s.exports,function(e){var n=t[i][1][e];return o(n?n:e)},s,s.exports,e,t,n,r)}return n[i].exports}for(var a="function"==typeof require&&require,i=0;it;t++)if(t in this&&this[t]===e)return t;return-1};$.payment={},$.payment.fn={},$.fn.payment=function(){var e,t;return t=arguments[0],e=2<=arguments.length?b.call(arguments,1):[],$.payment.fn[t].apply(this,e)},r=/(\d{1,4})/g,$.payment.cards=n=[{type:"visaelectron",pattern:/^4(026|17500|405|508|844|91[37])/,format:r,length:[16],cvcLength:[3],luhn:!0},{type:"maestro",pattern:/^(5(018|0[23]|[68])|6(39|7))/,format:r,length:[12,13,14,15,16,17,18,19],cvcLength:[3],luhn:!0},{type:"forbrugsforeningen",pattern:/^600/,format:r,length:[16],cvcLength:[3],luhn:!0},{type:"dankort",pattern:/^5019/,format:r,length:[16],cvcLength:[3],luhn:!0},{type:"visa",pattern:/^4/,format:r,length:[13,16],cvcLength:[3],luhn:!0},{type:"mastercard",pattern:/^5[0-5]/,format:r,length:[16],cvcLength:[3],luhn:!0},{type:"amex",pattern:/^3[47]/,format:/(\d{1,4})(\d{1,6})?(\d{1,5})?/,length:[15],cvcLength:[3,4],luhn:!0},{type:"dinersclub",pattern:/^3[0689]/,format:/(\d{1,4})(\d{1,6})?(\d{1,4})?/,length:[14],cvcLength:[3],luhn:!0},{type:"discover",pattern:/^6([045]|22)/,format:r,length:[16],cvcLength:[3],luhn:!0},{type:"unionpay",pattern:/^(62|88)/,format:r,length:[16,17,18,19],cvcLength:[3],luhn:!1},{type:"jcb",pattern:/^35/,format:r,length:[16],cvcLength:[3],luhn:!0}],e=function(e){var t,r,o;for(e=(e+"").replace(/\D/g,""),r=0,o=n.length;o>r;r++)if(t=n[r],t.pattern.test(e))return t},t=function(e){var t,r,o;for(r=0,o=n.length;o>r;r++)if(t=n[r],t.type===e)return t},p=function(e){var t,n,r,o,a,i;for(r=!0,o=0,n=(e+"").split("").reverse(),a=0,i=n.length;i>a;a++)t=n[a],t=parseInt(t,10),(r=!r)&&(t*=2),t>9&&(t-=9),o+=t;return o%10===0},s=function(e){var t;return null!=e.prop("selectionStart")&&e.prop("selectionStart")!==e.prop("selectionEnd")?!0:null!=("undefined"!=typeof document&&null!==document&&null!=(t=document.selection)?t.createRange:void 0)&&document.selection.createRange().text?!0:!1},v=function(e){return setTimeout(function(){var t,n;return t=$(e.currentTarget),n=t.val(),n=n.replace(/\D/g,""),t.val(n)})},h=function(e){return setTimeout(function(){var t,n;return t=$(e.currentTarget),n=t.val(),n=$.payment.formatCardNumber(n),t.val(n)})},i=function(t){var n,r,o,a,i,u,l;return o=String.fromCharCode(t.which),!/^\d+$/.test(o)||(n=$(t.currentTarget),l=n.val(),r=e(l+o),a=(l.replace(/\D/g,"")+o).length,u=16,r&&(u=r.length[r.length.length-1]),a>=u||null!=n.prop("selectionStart")&&n.prop("selectionStart")!==l.length)?void 0:(i=r&&"amex"===r.type?/^(\d{4}|\d{4}\s\d{6})$/:/(?:^|\s)(\d{4})$/,i.test(l)?(t.preventDefault(),setTimeout(function(){return n.val(l+" "+o)})):i.test(l+o)?(t.preventDefault(),setTimeout(function(){return n.val(l+o+" ")})):void 0)},o=function(e){var t,n;return t=$(e.currentTarget),n=t.val(),8!==e.which||null!=t.prop("selectionStart")&&t.prop("selectionStart")!==n.length?void 0:/\d\s$/.test(n)?(e.preventDefault(),setTimeout(function(){return t.val(n.replace(/\d\s$/,""))})):/\s\d?$/.test(n)?(e.preventDefault(),setTimeout(function(){return t.val(n.replace(/\d$/,""))})):void 0},f=function(e){return setTimeout(function(){var t,n;return t=$(e.currentTarget),n=t.val(),n=$.payment.formatExpiry(n),t.val(n)})},u=function(e){var t,n,r;return n=String.fromCharCode(e.which),/^\d+$/.test(n)?(t=$(e.currentTarget),r=t.val()+n,/^\d$/.test(r)&&"0"!==r&&"1"!==r?(e.preventDefault(),setTimeout(function(){return t.val("0"+r+" / ")})):/^\d\d$/.test(r)?(e.preventDefault(),setTimeout(function(){return t.val(""+r+" / ")})):void 0):void 0},l=function(e){var t,n,r;return n=String.fromCharCode(e.which),/^\d+$/.test(n)?(t=$(e.currentTarget),r=t.val(),/^\d\d$/.test(r)?t.val(""+r+" / "):void 0):void 0},c=function(e){var t,n,r;return r=String.fromCharCode(e.which),"/"===r||" "===r?(t=$(e.currentTarget),n=t.val(),/^\d$/.test(n)&&"0"!==n?t.val("0"+n+" / "):void 0):void 0},a=function(e){var t,n;return t=$(e.currentTarget),n=t.val(),8!==e.which||null!=t.prop("selectionStart")&&t.prop("selectionStart")!==n.length?void 0:/\d\s\/\s$/.test(n)?(e.preventDefault(),setTimeout(function(){return t.val(n.replace(/\d\s\/\s$/,""))})):void 0},d=function(e){return setTimeout(function(){var t,n;return t=$(e.currentTarget),n=t.val(),n=n.replace(/\D/g,"").slice(0,4),t.val(n)})},w=function(e){var t;return e.metaKey||e.ctrlKey?!0:32===e.which?!1:0===e.which?!0:e.which<33?!0:(t=String.fromCharCode(e.which),!!/[\d\s]/.test(t))},g=function(t){var n,r,o,a;return n=$(t.currentTarget),o=String.fromCharCode(t.which),/^\d+$/.test(o)&&!s(n)?(a=(n.val()+o).replace(/\D/g,""),r=e(a),r?a.length<=r.length[r.length.length-1]:a.length<=16):void 0},y=function(e){var t,n,r;return t=$(e.currentTarget),n=String.fromCharCode(e.which),/^\d+$/.test(n)&&!s(t)?(r=t.val()+n,r=r.replace(/\D/g,""),r.length>6?!1:void 0):void 0},m=function(e){var t,n,r;return t=$(e.currentTarget),n=String.fromCharCode(e.which),/^\d+$/.test(n)&&!s(t)?(r=t.val()+n,r.length<=4):void 0},_=function(e){var t,r,o,a,i;return t=$(e.currentTarget),i=t.val(),a=$.payment.cardType(i)||"unknown",t.hasClass(a)?void 0:(r=function(){var e,t,r;for(r=[],e=0,t=n.length;t>e;e++)o=n[e],r.push(o.type);return r}(),t.removeClass("unknown"),t.removeClass(r.join(" ")),t.addClass(a),t.toggleClass("identified","unknown"!==a),t.trigger("payment.cardType",a))},$.payment.fn.formatCardCVC=function(){return this.on("keypress",w),this.on("keypress",m),this.on("paste",d),this.on("change",d),this.on("input",d),this},$.payment.fn.formatCardExpiry=function(){return this.on("keypress",w),this.on("keypress",y),this.on("keypress",u),this.on("keypress",c),this.on("keypress",l),this.on("keydown",a),this.on("change",f),this.on("input",f),this},$.payment.fn.formatCardNumber=function(){return this.on("keypress",w),this.on("keypress",g),this.on("keypress",i),this.on("keydown",o),this.on("keyup",_),this.on("paste",h),this.on("change",h),this.on("input",h),this.on("input",_),this},$.payment.fn.restrictNumeric=function(){return this.on("keypress",w),this.on("paste",v),this.on("change",v),this.on("input",v),this},$.payment.fn.cardExpiryVal=function(){return $.payment.cardExpiryVal($(this).val())},$.payment.cardExpiryVal=function(e){var t,n,r,o;return e=e.replace(/\s/g,""),o=e.split("/",2),t=o[0],r=o[1],2===(null!=r?r.length:void 0)&&/^\d+$/.test(r)&&(n=(new Date).getFullYear(),n=n.toString().slice(0,2),r=n+r),t=parseInt(t,10),r=parseInt(r,10),{month:t,year:r}},$.payment.validateCardNumber=function(t){var n,r;return t=(t+"").replace(/\s+|-/g,""),/^\d+$/.test(t)?(n=e(t),n?(r=t.length,C.call(n.length,r)>=0&&(n.luhn===!1||p(t))):!1):!1},$.payment.validateCardExpiry=function(e,t){var n,r,o;return"object"==typeof e&&"month"in e&&(o=e,e=o.month,t=o.year),e&&t?(e=$.trim(e),t=$.trim(t),/^\d+$/.test(e)&&/^\d+$/.test(t)&&e>=1&&12>=e?(2===t.length&&(t=70>t?"20"+t:"19"+t),4!==t.length?!1:(r=new Date(t,e),n=new Date,r.setMonth(r.getMonth()-1),r.setMonth(r.getMonth()+1,1),r>n)):!1):!1},$.payment.validateCardCVC=function(e,n){var r,o;return e=$.trim(e),/^\d+$/.test(e)?(r=t(n),null!=r?(o=e.length,C.call(r.cvcLength,o)>=0):e.length>=3&&e.length<=4):!1},$.payment.cardType=function(t){var n;return t?(null!=(n=e(t))?n.type:void 0)||null:null},$.payment.formatCardNumber=function(t){var n,r,o,a;return t=t.replace(/\D/g,""),(n=e(t))?(o=n.length[n.length.length-1],t=t.slice(0,o),n.format.global?null!=(a=t.match(n.format))?a.join(" "):void 0:(r=n.format.exec(t),null!=r?(r.shift(),r=$.grep(r,function(e){return e}),r.join(" ")):void 0)):t},$.payment.formatExpiry=function(e){var t,n,r,o;return(n=e.match(/^\D*(\d{1,2})(\D+)?(\d{1,4})?/))?(t=n[1]||"",r=n[2]||"",o=n[3]||"",o.length>0?r=" / ":" /"===r?(t=t.substring(0,1),r=""):2===t.length||r.length>0?r=" / ":1===t.length&&"0"!==t&&"1"!==t&&(t="0"+t,r=" / "),t+r+o):""}}).call(this)},{}],2:[function(e,t,n){function r(e){var t=this,e=e||{};i.publishableKey=t.stripe_key=e.key,t.form=e.form,t.cc_number=o.observable(null),t.cc_expiry=o.observable(null),t.cc_cvv=o.observable(null),t.cc_error_number=o.observable(null),t.cc_error_expiry=o.observable(null),t.cc_error_cvv=o.observable(null),t.initialize_form(),t.error=o.observable(null),t.process_form=function(){var e=a.payment.cardExpiryVal(t.cc_expiry()),n={number:t.cc_number(),exp_month:e.month,exp_year:e.year,cvc:t.cc_cvv()};return t.error(null),t.cc_error_number(null),t.cc_error_expiry(null),t.cc_error_cvv(null),a.payment.validateCardNumber(n.number)?a.payment.validateCardExpiry(n.exp_month,n.exp_year)?a.payment.validateCardCVC(n.cvc)?void i.createToken(n,function(e,n){if(200===e){var r=t.form.find("#id_last_4_digits"),o=t.form.find("#id_stripe_id,#id_stripe_token");r.val(n.card.last4),o.val(n.id),t.form.submit()}else t.error(n.error.message)}):(t.cc_error_cvv("Invalid security code"),!1):(t.cc_error_expiry("Invalid expiration date"),!1):(t.cc_error_number("Invalid card number"),console.log(n),!1)}}var o=e("knockout"),a=(e("./../../../../../bower_components/jquery.payment/lib/jquery.payment.js"),null),i=null;a="undefined"==typeof window?e("jquery"):window.$,"undefined"!=typeof window&&"undefined"!=typeof window.Stripe&&(i=window.Stripe||{}),r.prototype.initialize_form=function(){var e=a("input#cc-number"),t=a("input#cc-cvv"),n=a("input#cc-expiry");e.payment("formatCardNumber"),n.payment("formatCardExpiry"),t.payment("formatCardCVC")},r.init=function(e,t){var n=new GoldView(e),t=t||a("#payment-form")[0];return o.applyBindings(n,t),n},t.exports.PaymentView=r,"undefined"!=typeof window&&(window.payment=t.exports)},{"./../../../../../bower_components/jquery.payment/lib/jquery.payment.js":1,jquery:"jquery",knockout:"knockout"}],3:[function(e,t,n){function r(e){var t=this,e=e||{};a.utils.extend(t,new o.PaymentView(e)),t.dollars=a.observable(),t.logo_url=a.observable(),t.site_url=a.observable(),a.computed(function(){var e=window.$("input#id_logo_url").closest("p"),n=window.$("input#id_site_url").closest("p");t.dollars()<400?(t.logo_url(null),t.site_url(null),e.hide(),n.hide()):(e.show(),n.show())}),t.urls_enabled=a.computed(function(){return t.dollars()>=400})}var o=e("../../../../core/static-src/core/js/payment"),a=e("knockout");r.init=function(e,t){var n=new r(e),t=t||$("#donate-payment")[0];return a.applyBindings(n,t),n},t.exports.DonateView=r,"undefined"!=typeof window&&(window.donate=t.exports)},{"../../../../core/static-src/core/js/payment":2,knockout:"knockout"}]},{},[3]);
\ No newline at end of file
+!function e(t,n,r){function o(i,u){if(!n[i]){if(!t[i]){var l="function"==typeof require&&require;if(!u&&l)return l(i,!0);if(a)return a(i,!0);var c=new Error("Cannot find module '"+i+"'");throw c.code="MODULE_NOT_FOUND",c}var s=n[i]={exports:{}};t[i][0].call(s.exports,function(e){var n=t[i][1][e];return o(n?n:e)},s,s.exports,e,t,n,r)}return n[i].exports}for(var a="function"==typeof require&&require,i=0;it;t++)if(t in this&&this[t]===e)return t;return-1};$.payment={},$.payment.fn={},$.fn.payment=function(){var e,t;return t=arguments[0],e=2<=arguments.length?b.call(arguments,1):[],$.payment.fn[t].apply(this,e)},r=/(\d{1,4})/g,$.payment.cards=n=[{type:"visaelectron",pattern:/^4(026|17500|405|508|844|91[37])/,format:r,length:[16],cvcLength:[3],luhn:!0},{type:"maestro",pattern:/^(5(018|0[23]|[68])|6(39|7))/,format:r,length:[12,13,14,15,16,17,18,19],cvcLength:[3],luhn:!0},{type:"forbrugsforeningen",pattern:/^600/,format:r,length:[16],cvcLength:[3],luhn:!0},{type:"dankort",pattern:/^5019/,format:r,length:[16],cvcLength:[3],luhn:!0},{type:"visa",pattern:/^4/,format:r,length:[13,16],cvcLength:[3],luhn:!0},{type:"mastercard",pattern:/^(5[0-5]|2[2-7])/,format:r,length:[16],cvcLength:[3],luhn:!0},{type:"amex",pattern:/^3[47]/,format:/(\d{1,4})(\d{1,6})?(\d{1,5})?/,length:[15],cvcLength:[3,4],luhn:!0},{type:"dinersclub",pattern:/^3[0689]/,format:/(\d{1,4})(\d{1,6})?(\d{1,4})?/,length:[14],cvcLength:[3],luhn:!0},{type:"discover",pattern:/^6([045]|22)/,format:r,length:[16],cvcLength:[3],luhn:!0},{type:"unionpay",pattern:/^(62|88)/,format:r,length:[16,17,18,19],cvcLength:[3],luhn:!1},{type:"jcb",pattern:/^35/,format:r,length:[16],cvcLength:[3],luhn:!0}],e=function(e){var t,r,o;for(e=(e+"").replace(/\D/g,""),r=0,o=n.length;o>r;r++)if(t=n[r],t.pattern.test(e))return t},t=function(e){var t,r,o;for(r=0,o=n.length;o>r;r++)if(t=n[r],t.type===e)return t},p=function(e){var t,n,r,o,a,i;for(r=!0,o=0,n=(e+"").split("").reverse(),a=0,i=n.length;i>a;a++)t=n[a],t=parseInt(t,10),(r=!r)&&(t*=2),t>9&&(t-=9),o+=t;return o%10===0},s=function(e){var t;return null!=e.prop("selectionStart")&&e.prop("selectionStart")!==e.prop("selectionEnd")?!0:null!=("undefined"!=typeof document&&null!==document&&null!=(t=document.selection)?t.createRange:void 0)&&document.selection.createRange().text?!0:!1},v=function(e){return setTimeout(function(){var t,n;return t=$(e.currentTarget),n=t.val(),n=n.replace(/\D/g,""),t.val(n)})},h=function(e){return setTimeout(function(){var t,n;return t=$(e.currentTarget),n=t.val(),n=$.payment.formatCardNumber(n),t.val(n)})},i=function(t){var n,r,o,a,i,u,l;return o=String.fromCharCode(t.which),!/^\d+$/.test(o)||(n=$(t.currentTarget),l=n.val(),r=e(l+o),a=(l.replace(/\D/g,"")+o).length,u=16,r&&(u=r.length[r.length.length-1]),a>=u||null!=n.prop("selectionStart")&&n.prop("selectionStart")!==l.length)?void 0:(i=r&&"amex"===r.type?/^(\d{4}|\d{4}\s\d{6})$/:/(?:^|\s)(\d{4})$/,i.test(l)?(t.preventDefault(),setTimeout(function(){return n.val(l+" "+o)})):i.test(l+o)?(t.preventDefault(),setTimeout(function(){return n.val(l+o+" ")})):void 0)},o=function(e){var t,n;return t=$(e.currentTarget),n=t.val(),8!==e.which||null!=t.prop("selectionStart")&&t.prop("selectionStart")!==n.length?void 0:/\d\s$/.test(n)?(e.preventDefault(),setTimeout(function(){return t.val(n.replace(/\d\s$/,""))})):/\s\d?$/.test(n)?(e.preventDefault(),setTimeout(function(){return t.val(n.replace(/\d$/,""))})):void 0},f=function(e){return setTimeout(function(){var t,n;return t=$(e.currentTarget),n=t.val(),n=$.payment.formatExpiry(n),t.val(n)})},u=function(e){var t,n,r;return n=String.fromCharCode(e.which),/^\d+$/.test(n)?(t=$(e.currentTarget),r=t.val()+n,/^\d$/.test(r)&&"0"!==r&&"1"!==r?(e.preventDefault(),setTimeout(function(){return t.val("0"+r+" / ")})):/^\d\d$/.test(r)?(e.preventDefault(),setTimeout(function(){return t.val(""+r+" / ")})):void 0):void 0},l=function(e){var t,n,r;return n=String.fromCharCode(e.which),/^\d+$/.test(n)?(t=$(e.currentTarget),r=t.val(),/^\d\d$/.test(r)?t.val(""+r+" / "):void 0):void 0},c=function(e){var t,n,r;return r=String.fromCharCode(e.which),"/"===r||" "===r?(t=$(e.currentTarget),n=t.val(),/^\d$/.test(n)&&"0"!==n?t.val("0"+n+" / "):void 0):void 0},a=function(e){var t,n;return t=$(e.currentTarget),n=t.val(),8!==e.which||null!=t.prop("selectionStart")&&t.prop("selectionStart")!==n.length?void 0:/\d\s\/\s$/.test(n)?(e.preventDefault(),setTimeout(function(){return t.val(n.replace(/\d\s\/\s$/,""))})):void 0},d=function(e){return setTimeout(function(){var t,n;return t=$(e.currentTarget),n=t.val(),n=n.replace(/\D/g,"").slice(0,4),t.val(n)})},w=function(e){var t;return e.metaKey||e.ctrlKey?!0:32===e.which?!1:0===e.which?!0:e.which<33?!0:(t=String.fromCharCode(e.which),!!/[\d\s]/.test(t))},g=function(t){var n,r,o,a;return n=$(t.currentTarget),o=String.fromCharCode(t.which),/^\d+$/.test(o)&&!s(n)?(a=(n.val()+o).replace(/\D/g,""),r=e(a),r?a.length<=r.length[r.length.length-1]:a.length<=16):void 0},y=function(e){var t,n,r;return t=$(e.currentTarget),n=String.fromCharCode(e.which),/^\d+$/.test(n)&&!s(t)?(r=t.val()+n,r=r.replace(/\D/g,""),r.length>6?!1:void 0):void 0},m=function(e){var t,n,r;return t=$(e.currentTarget),n=String.fromCharCode(e.which),/^\d+$/.test(n)&&!s(t)?(r=t.val()+n,r.length<=4):void 0},_=function(e){var t,r,o,a,i;return t=$(e.currentTarget),i=t.val(),a=$.payment.cardType(i)||"unknown",t.hasClass(a)?void 0:(r=function(){var e,t,r;for(r=[],e=0,t=n.length;t>e;e++)o=n[e],r.push(o.type);return r}(),t.removeClass("unknown"),t.removeClass(r.join(" ")),t.addClass(a),t.toggleClass("identified","unknown"!==a),t.trigger("payment.cardType",a))},$.payment.fn.formatCardCVC=function(){return this.on("keypress",w),this.on("keypress",m),this.on("paste",d),this.on("change",d),this.on("input",d),this},$.payment.fn.formatCardExpiry=function(){return this.on("keypress",w),this.on("keypress",y),this.on("keypress",u),this.on("keypress",c),this.on("keypress",l),this.on("keydown",a),this.on("change",f),this.on("input",f),this},$.payment.fn.formatCardNumber=function(){return this.on("keypress",w),this.on("keypress",g),this.on("keypress",i),this.on("keydown",o),this.on("keyup",_),this.on("paste",h),this.on("change",h),this.on("input",h),this.on("input",_),this},$.payment.fn.restrictNumeric=function(){return this.on("keypress",w),this.on("paste",v),this.on("change",v),this.on("input",v),this},$.payment.fn.cardExpiryVal=function(){return $.payment.cardExpiryVal($(this).val())},$.payment.cardExpiryVal=function(e){var t,n,r,o;return e=e.replace(/\s/g,""),o=e.split("/",2),t=o[0],r=o[1],2===(null!=r?r.length:void 0)&&/^\d+$/.test(r)&&(n=(new Date).getFullYear(),n=n.toString().slice(0,2),r=n+r),t=parseInt(t,10),r=parseInt(r,10),{month:t,year:r}},$.payment.validateCardNumber=function(t){var n,r;return t=(t+"").replace(/\s+|-/g,""),/^\d+$/.test(t)?(n=e(t),n?(r=t.length,C.call(n.length,r)>=0&&(n.luhn===!1||p(t))):!1):!1},$.payment.validateCardExpiry=function(e,t){var n,r,o;return"object"==typeof e&&"month"in e&&(o=e,e=o.month,t=o.year),e&&t?(e=$.trim(e),t=$.trim(t),/^\d+$/.test(e)&&/^\d+$/.test(t)&&e>=1&&12>=e?(2===t.length&&(t=70>t?"20"+t:"19"+t),4!==t.length?!1:(r=new Date(t,e),n=new Date,r.setMonth(r.getMonth()-1),r.setMonth(r.getMonth()+1,1),r>n)):!1):!1},$.payment.validateCardCVC=function(e,n){var r,o;return e=$.trim(e),/^\d+$/.test(e)?(r=t(n),null!=r?(o=e.length,C.call(r.cvcLength,o)>=0):e.length>=3&&e.length<=4):!1},$.payment.cardType=function(t){var n;return t?(null!=(n=e(t))?n.type:void 0)||null:null},$.payment.formatCardNumber=function(t){var n,r,o,a;return t=t.replace(/\D/g,""),(n=e(t))?(o=n.length[n.length.length-1],t=t.slice(0,o),n.format.global?null!=(a=t.match(n.format))?a.join(" "):void 0:(r=n.format.exec(t),null!=r?(r.shift(),r=$.grep(r,function(e){return e}),r.join(" ")):void 0)):t},$.payment.formatExpiry=function(e){var t,n,r,o;return(n=e.match(/^\D*(\d{1,2})(\D+)?(\d{1,4})?/))?(t=n[1]||"",r=n[2]||"",o=n[3]||"",o.length>0?r=" / ":" /"===r?(t=t.substring(0,1),r=""):2===t.length||r.length>0?r=" / ":1===t.length&&"0"!==t&&"1"!==t&&(t="0"+t,r=" / "),t+r+o):""}}).call(this)},{}],2:[function(e,t,n){function r(e){var t=this,e=e||{};i.publishableKey=t.stripe_key=e.key,t.form=e.form,t.cc_number=o.observable(null),t.cc_expiry=o.observable(null),t.cc_cvv=o.observable(null),t.cc_error_number=o.observable(null),t.cc_error_expiry=o.observable(null),t.cc_error_cvv=o.observable(null),t.initialize_form(),t.error=o.observable(null),t.process_form=function(){var e=a.payment.cardExpiryVal(t.cc_expiry()),n={number:t.cc_number(),exp_month:e.month,exp_year:e.year,cvc:t.cc_cvv()};return t.error(null),t.cc_error_number(null),t.cc_error_expiry(null),t.cc_error_cvv(null),a.payment.validateCardNumber(n.number)?a.payment.validateCardExpiry(n.exp_month,n.exp_year)?a.payment.validateCardCVC(n.cvc)?void i.createToken(n,function(e,n){if(200===e){var r=t.form.find("#id_last_4_digits"),o=t.form.find("#id_stripe_id,#id_stripe_token");r.val(n.card.last4),o.val(n.id),t.form.submit()}else t.error(n.error.message)}):(t.cc_error_cvv("Invalid security code"),!1):(t.cc_error_expiry("Invalid expiration date"),!1):(t.cc_error_number("Invalid card number"),console.log(n),!1)}}var o=e("knockout"),a=(e("./../../../../../bower_components/jquery.payment/lib/jquery.payment.js"),null),i=null;a="undefined"==typeof window?e("jquery"):window.$,"undefined"!=typeof window&&"undefined"!=typeof window.Stripe&&(i=window.Stripe||{}),r.prototype.initialize_form=function(){var e=a("input#cc-number"),t=a("input#cc-cvv"),n=a("input#cc-expiry");e.payment("formatCardNumber"),n.payment("formatCardExpiry"),t.payment("formatCardCVC")},r.init=function(e,t){var n=new GoldView(e),t=t||a("#payment-form")[0];return o.applyBindings(n,t),n},t.exports.PaymentView=r,"undefined"!=typeof window&&(window.payment=t.exports)},{"./../../../../../bower_components/jquery.payment/lib/jquery.payment.js":1,jquery:"jquery",knockout:"knockout"}],3:[function(e,t,n){function r(e){var t=this,e=e||{};a.utils.extend(t,new o.PaymentView(e)),t.dollars=a.observable(),t.logo_url=a.observable(),t.site_url=a.observable(),a.computed(function(){var e=window.$("input#id_logo_url").closest("p"),n=window.$("input#id_site_url").closest("p");t.dollars()<400?(t.logo_url(null),t.site_url(null),e.hide(),n.hide()):(e.show(),n.show())}),t.urls_enabled=a.computed(function(){return t.dollars()>=400})}var o=e("../../../../core/static-src/core/js/payment"),a=e("knockout");r.init=function(e,t){var n=new r(e),t=t||$("#donate-payment")[0];return a.applyBindings(n,t),n},t.exports.DonateView=r,"undefined"!=typeof window&&(window.donate=t.exports)},{"../../../../core/static-src/core/js/payment":2,knockout:"knockout"}]},{},[3]);
\ No newline at end of file
diff --git a/readthedocs/gold/static/gold/js/gold.js b/readthedocs/gold/static/gold/js/gold.js
index 5d048739b13..e25d4d7e881 100644
--- a/readthedocs/gold/static/gold/js/gold.js
+++ b/readthedocs/gold/static/gold/js/gold.js
@@ -1 +1 @@
-!function t(e,n,r){function o(i,u){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!u&&c)return c(i,!0);if(a)return a(i,!0);var l=new Error("Cannot find module '"+i+"'");throw l.code="MODULE_NOT_FOUND",l}var s=n[i]={exports:{}};e[i][0].call(s.exports,function(t){var n=e[i][1][t];return o(n?n:t)},s,s.exports,t,e,n,r)}return n[i].exports}for(var a="function"==typeof require&&require,i=0;ie;e++)if(e in this&&this[e]===t)return e;return-1};$.payment={},$.payment.fn={},$.fn.payment=function(){var t,e;return e=arguments[0],t=2<=arguments.length?_.call(arguments,1):[],$.payment.fn[e].apply(this,t)},r=/(\d{1,4})/g,$.payment.cards=n=[{type:"visaelectron",pattern:/^4(026|17500|405|508|844|91[37])/,format:r,length:[16],cvcLength:[3],luhn:!0},{type:"maestro",pattern:/^(5(018|0[23]|[68])|6(39|7))/,format:r,length:[12,13,14,15,16,17,18,19],cvcLength:[3],luhn:!0},{type:"forbrugsforeningen",pattern:/^600/,format:r,length:[16],cvcLength:[3],luhn:!0},{type:"dankort",pattern:/^5019/,format:r,length:[16],cvcLength:[3],luhn:!0},{type:"visa",pattern:/^4/,format:r,length:[13,16],cvcLength:[3],luhn:!0},{type:"mastercard",pattern:/^5[0-5]/,format:r,length:[16],cvcLength:[3],luhn:!0},{type:"amex",pattern:/^3[47]/,format:/(\d{1,4})(\d{1,6})?(\d{1,5})?/,length:[15],cvcLength:[3,4],luhn:!0},{type:"dinersclub",pattern:/^3[0689]/,format:/(\d{1,4})(\d{1,6})?(\d{1,4})?/,length:[14],cvcLength:[3],luhn:!0},{type:"discover",pattern:/^6([045]|22)/,format:r,length:[16],cvcLength:[3],luhn:!0},{type:"unionpay",pattern:/^(62|88)/,format:r,length:[16,17,18,19],cvcLength:[3],luhn:!1},{type:"jcb",pattern:/^35/,format:r,length:[16],cvcLength:[3],luhn:!0}],t=function(t){var e,r,o;for(t=(t+"").replace(/\D/g,""),r=0,o=n.length;o>r;r++)if(e=n[r],e.pattern.test(t))return e},e=function(t){var e,r,o;for(r=0,o=n.length;o>r;r++)if(e=n[r],e.type===t)return e},p=function(t){var e,n,r,o,a,i;for(r=!0,o=0,n=(t+"").split("").reverse(),a=0,i=n.length;i>a;a++)e=n[a],e=parseInt(e,10),(r=!r)&&(e*=2),e>9&&(e-=9),o+=e;return o%10===0},s=function(t){var e;return null!=t.prop("selectionStart")&&t.prop("selectionStart")!==t.prop("selectionEnd")?!0:null!=("undefined"!=typeof document&&null!==document&&null!=(e=document.selection)?e.createRange:void 0)&&document.selection.createRange().text?!0:!1},v=function(t){return setTimeout(function(){var e,n;return e=$(t.currentTarget),n=e.val(),n=n.replace(/\D/g,""),e.val(n)})},d=function(t){return setTimeout(function(){var e,n;return e=$(t.currentTarget),n=e.val(),n=$.payment.formatCardNumber(n),e.val(n)})},i=function(e){var n,r,o,a,i,u,c;return o=String.fromCharCode(e.which),!/^\d+$/.test(o)||(n=$(e.currentTarget),c=n.val(),r=t(c+o),a=(c.replace(/\D/g,"")+o).length,u=16,r&&(u=r.length[r.length.length-1]),a>=u||null!=n.prop("selectionStart")&&n.prop("selectionStart")!==c.length)?void 0:(i=r&&"amex"===r.type?/^(\d{4}|\d{4}\s\d{6})$/:/(?:^|\s)(\d{4})$/,i.test(c)?(e.preventDefault(),setTimeout(function(){return n.val(c+" "+o)})):i.test(c+o)?(e.preventDefault(),setTimeout(function(){return n.val(c+o+" ")})):void 0)},o=function(t){var e,n;return e=$(t.currentTarget),n=e.val(),8!==t.which||null!=e.prop("selectionStart")&&e.prop("selectionStart")!==n.length?void 0:/\d\s$/.test(n)?(t.preventDefault(),setTimeout(function(){return e.val(n.replace(/\d\s$/,""))})):/\s\d?$/.test(n)?(t.preventDefault(),setTimeout(function(){return e.val(n.replace(/\d$/,""))})):void 0},f=function(t){return setTimeout(function(){var e,n;return e=$(t.currentTarget),n=e.val(),n=$.payment.formatExpiry(n),e.val(n)})},u=function(t){var e,n,r;return n=String.fromCharCode(t.which),/^\d+$/.test(n)?(e=$(t.currentTarget),r=e.val()+n,/^\d$/.test(r)&&"0"!==r&&"1"!==r?(t.preventDefault(),setTimeout(function(){return e.val("0"+r+" / ")})):/^\d\d$/.test(r)?(t.preventDefault(),setTimeout(function(){return e.val(""+r+" / ")})):void 0):void 0},c=function(t){var e,n,r;return n=String.fromCharCode(t.which),/^\d+$/.test(n)?(e=$(t.currentTarget),r=e.val(),/^\d\d$/.test(r)?e.val(""+r+" / "):void 0):void 0},l=function(t){var e,n,r;return r=String.fromCharCode(t.which),"/"===r||" "===r?(e=$(t.currentTarget),n=e.val(),/^\d$/.test(n)&&"0"!==n?e.val("0"+n+" / "):void 0):void 0},a=function(t){var e,n;return e=$(t.currentTarget),n=e.val(),8!==t.which||null!=e.prop("selectionStart")&&e.prop("selectionStart")!==n.length?void 0:/\d\s\/\s$/.test(n)?(t.preventDefault(),setTimeout(function(){return e.val(n.replace(/\d\s\/\s$/,""))})):void 0},h=function(t){return setTimeout(function(){var e,n;return e=$(t.currentTarget),n=e.val(),n=n.replace(/\D/g,"").slice(0,4),e.val(n)})},w=function(t){var e;return t.metaKey||t.ctrlKey?!0:32===t.which?!1:0===t.which?!0:t.which<33?!0:(e=String.fromCharCode(t.which),!!/[\d\s]/.test(e))},y=function(e){var n,r,o,a;return n=$(e.currentTarget),o=String.fromCharCode(e.which),/^\d+$/.test(o)&&!s(n)?(a=(n.val()+o).replace(/\D/g,""),r=t(a),r?a.length<=r.length[r.length.length-1]:a.length<=16):void 0},g=function(t){var e,n,r;return e=$(t.currentTarget),n=String.fromCharCode(t.which),/^\d+$/.test(n)&&!s(e)?(r=e.val()+n,r=r.replace(/\D/g,""),r.length>6?!1:void 0):void 0},m=function(t){var e,n,r;return e=$(t.currentTarget),n=String.fromCharCode(t.which),/^\d+$/.test(n)&&!s(e)?(r=e.val()+n,r.length<=4):void 0},C=function(t){var e,r,o,a,i;return e=$(t.currentTarget),i=e.val(),a=$.payment.cardType(i)||"unknown",e.hasClass(a)?void 0:(r=function(){var t,e,r;for(r=[],t=0,e=n.length;e>t;t++)o=n[t],r.push(o.type);return r}(),e.removeClass("unknown"),e.removeClass(r.join(" ")),e.addClass(a),e.toggleClass("identified","unknown"!==a),e.trigger("payment.cardType",a))},$.payment.fn.formatCardCVC=function(){return this.on("keypress",w),this.on("keypress",m),this.on("paste",h),this.on("change",h),this.on("input",h),this},$.payment.fn.formatCardExpiry=function(){return this.on("keypress",w),this.on("keypress",g),this.on("keypress",u),this.on("keypress",l),this.on("keypress",c),this.on("keydown",a),this.on("change",f),this.on("input",f),this},$.payment.fn.formatCardNumber=function(){return this.on("keypress",w),this.on("keypress",y),this.on("keypress",i),this.on("keydown",o),this.on("keyup",C),this.on("paste",d),this.on("change",d),this.on("input",d),this.on("input",C),this},$.payment.fn.restrictNumeric=function(){return this.on("keypress",w),this.on("paste",v),this.on("change",v),this.on("input",v),this},$.payment.fn.cardExpiryVal=function(){return $.payment.cardExpiryVal($(this).val())},$.payment.cardExpiryVal=function(t){var e,n,r,o;return t=t.replace(/\s/g,""),o=t.split("/",2),e=o[0],r=o[1],2===(null!=r?r.length:void 0)&&/^\d+$/.test(r)&&(n=(new Date).getFullYear(),n=n.toString().slice(0,2),r=n+r),e=parseInt(e,10),r=parseInt(r,10),{month:e,year:r}},$.payment.validateCardNumber=function(e){var n,r;return e=(e+"").replace(/\s+|-/g,""),/^\d+$/.test(e)?(n=t(e),n?(r=e.length,b.call(n.length,r)>=0&&(n.luhn===!1||p(e))):!1):!1},$.payment.validateCardExpiry=function(t,e){var n,r,o;return"object"==typeof t&&"month"in t&&(o=t,t=o.month,e=o.year),t&&e?(t=$.trim(t),e=$.trim(e),/^\d+$/.test(t)&&/^\d+$/.test(e)&&t>=1&&12>=t?(2===e.length&&(e=70>e?"20"+e:"19"+e),4!==e.length?!1:(r=new Date(e,t),n=new Date,r.setMonth(r.getMonth()-1),r.setMonth(r.getMonth()+1,1),r>n)):!1):!1},$.payment.validateCardCVC=function(t,n){var r,o;return t=$.trim(t),/^\d+$/.test(t)?(r=e(n),null!=r?(o=t.length,b.call(r.cvcLength,o)>=0):t.length>=3&&t.length<=4):!1},$.payment.cardType=function(e){var n;return e?(null!=(n=t(e))?n.type:void 0)||null:null},$.payment.formatCardNumber=function(e){var n,r,o,a;return e=e.replace(/\D/g,""),(n=t(e))?(o=n.length[n.length.length-1],e=e.slice(0,o),n.format.global?null!=(a=e.match(n.format))?a.join(" "):void 0:(r=n.format.exec(e),null!=r?(r.shift(),r=$.grep(r,function(t){return t}),r.join(" ")):void 0)):e},$.payment.formatExpiry=function(t){var e,n,r,o;return(n=t.match(/^\D*(\d{1,2})(\D+)?(\d{1,4})?/))?(e=n[1]||"",r=n[2]||"",o=n[3]||"",o.length>0?r=" / ":" /"===r?(e=e.substring(0,1),r=""):2===e.length||r.length>0?r=" / ":1===e.length&&"0"!==e&&"1"!==e&&(e="0"+e,r=" / "),e+r+o):""}}).call(this)},{}],2:[function(t,e,n){function r(t){var e=this,t=t||{};i.publishableKey=e.stripe_key=t.key,e.form=t.form,e.cc_number=o.observable(null),e.cc_expiry=o.observable(null),e.cc_cvv=o.observable(null),e.cc_error_number=o.observable(null),e.cc_error_expiry=o.observable(null),e.cc_error_cvv=o.observable(null),e.initialize_form(),e.error=o.observable(null),e.process_form=function(){var t=a.payment.cardExpiryVal(e.cc_expiry()),n={number:e.cc_number(),exp_month:t.month,exp_year:t.year,cvc:e.cc_cvv()};return e.error(null),e.cc_error_number(null),e.cc_error_expiry(null),e.cc_error_cvv(null),a.payment.validateCardNumber(n.number)?a.payment.validateCardExpiry(n.exp_month,n.exp_year)?a.payment.validateCardCVC(n.cvc)?void i.createToken(n,function(t,n){if(200===t){var r=e.form.find("#id_last_4_digits"),o=e.form.find("#id_stripe_id,#id_stripe_token");r.val(n.card.last4),o.val(n.id),e.form.submit()}else e.error(n.error.message)}):(e.cc_error_cvv("Invalid security code"),!1):(e.cc_error_expiry("Invalid expiration date"),!1):(e.cc_error_number("Invalid card number"),console.log(n),!1)}}var o=t("knockout"),a=(t("./../../../../../bower_components/jquery.payment/lib/jquery.payment.js"),null),i=null;a="undefined"==typeof window?t("jquery"):window.$,"undefined"!=typeof window&&"undefined"!=typeof window.Stripe&&(i=window.Stripe||{}),r.prototype.initialize_form=function(){var t=a("input#cc-number"),e=a("input#cc-cvv"),n=a("input#cc-expiry");t.payment("formatCardNumber"),n.payment("formatCardExpiry"),e.payment("formatCardCVC")},r.init=function(t,e){var n=new GoldView(t),e=e||a("#payment-form")[0];return o.applyBindings(n,e),n},e.exports.PaymentView=r,"undefined"!=typeof window&&(window.payment=e.exports)},{"./../../../../../bower_components/jquery.payment/lib/jquery.payment.js":1,jquery:"jquery",knockout:"knockout"}],3:[function(t,e,n){function r(t){var e=this,t=t||{};a.utils.extend(e,new o.PaymentView(t))}var o=t("../../../../core/static-src/core/js/payment"),a=t("knockout");r.init=function(t,e){var n=new r(t),e=e||$("#payment-form")[0];return a.applyBindings(n,e),n},e.exports.GoldView=r,"undefined"!=typeof window&&(window.payment=e.exports)},{"../../../../core/static-src/core/js/payment":2,knockout:"knockout"}]},{},[3]);
\ No newline at end of file
+!function t(e,n,r){function o(i,u){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!u&&c)return c(i,!0);if(a)return a(i,!0);var l=new Error("Cannot find module '"+i+"'");throw l.code="MODULE_NOT_FOUND",l}var s=n[i]={exports:{}};e[i][0].call(s.exports,function(t){var n=e[i][1][t];return o(n?n:t)},s,s.exports,t,e,n,r)}return n[i].exports}for(var a="function"==typeof require&&require,i=0;ie;e++)if(e in this&&this[e]===t)return e;return-1};$.payment={},$.payment.fn={},$.fn.payment=function(){var t,e;return e=arguments[0],t=2<=arguments.length?_.call(arguments,1):[],$.payment.fn[e].apply(this,t)},r=/(\d{1,4})/g,$.payment.cards=n=[{type:"visaelectron",pattern:/^4(026|17500|405|508|844|91[37])/,format:r,length:[16],cvcLength:[3],luhn:!0},{type:"maestro",pattern:/^(5(018|0[23]|[68])|6(39|7))/,format:r,length:[12,13,14,15,16,17,18,19],cvcLength:[3],luhn:!0},{type:"forbrugsforeningen",pattern:/^600/,format:r,length:[16],cvcLength:[3],luhn:!0},{type:"dankort",pattern:/^5019/,format:r,length:[16],cvcLength:[3],luhn:!0},{type:"visa",pattern:/^4/,format:r,length:[13,16],cvcLength:[3],luhn:!0},{type:"mastercard",pattern:/^(5[0-5]|2[2-7])/,format:r,length:[16],cvcLength:[3],luhn:!0},{type:"amex",pattern:/^3[47]/,format:/(\d{1,4})(\d{1,6})?(\d{1,5})?/,length:[15],cvcLength:[3,4],luhn:!0},{type:"dinersclub",pattern:/^3[0689]/,format:/(\d{1,4})(\d{1,6})?(\d{1,4})?/,length:[14],cvcLength:[3],luhn:!0},{type:"discover",pattern:/^6([045]|22)/,format:r,length:[16],cvcLength:[3],luhn:!0},{type:"unionpay",pattern:/^(62|88)/,format:r,length:[16,17,18,19],cvcLength:[3],luhn:!1},{type:"jcb",pattern:/^35/,format:r,length:[16],cvcLength:[3],luhn:!0}],t=function(t){var e,r,o;for(t=(t+"").replace(/\D/g,""),r=0,o=n.length;o>r;r++)if(e=n[r],e.pattern.test(t))return e},e=function(t){var e,r,o;for(r=0,o=n.length;o>r;r++)if(e=n[r],e.type===t)return e},p=function(t){var e,n,r,o,a,i;for(r=!0,o=0,n=(t+"").split("").reverse(),a=0,i=n.length;i>a;a++)e=n[a],e=parseInt(e,10),(r=!r)&&(e*=2),e>9&&(e-=9),o+=e;return o%10===0},s=function(t){var e;return null!=t.prop("selectionStart")&&t.prop("selectionStart")!==t.prop("selectionEnd")?!0:null!=("undefined"!=typeof document&&null!==document&&null!=(e=document.selection)?e.createRange:void 0)&&document.selection.createRange().text?!0:!1},v=function(t){return setTimeout(function(){var e,n;return e=$(t.currentTarget),n=e.val(),n=n.replace(/\D/g,""),e.val(n)})},d=function(t){return setTimeout(function(){var e,n;return e=$(t.currentTarget),n=e.val(),n=$.payment.formatCardNumber(n),e.val(n)})},i=function(e){var n,r,o,a,i,u,c;return o=String.fromCharCode(e.which),!/^\d+$/.test(o)||(n=$(e.currentTarget),c=n.val(),r=t(c+o),a=(c.replace(/\D/g,"")+o).length,u=16,r&&(u=r.length[r.length.length-1]),a>=u||null!=n.prop("selectionStart")&&n.prop("selectionStart")!==c.length)?void 0:(i=r&&"amex"===r.type?/^(\d{4}|\d{4}\s\d{6})$/:/(?:^|\s)(\d{4})$/,i.test(c)?(e.preventDefault(),setTimeout(function(){return n.val(c+" "+o)})):i.test(c+o)?(e.preventDefault(),setTimeout(function(){return n.val(c+o+" ")})):void 0)},o=function(t){var e,n;return e=$(t.currentTarget),n=e.val(),8!==t.which||null!=e.prop("selectionStart")&&e.prop("selectionStart")!==n.length?void 0:/\d\s$/.test(n)?(t.preventDefault(),setTimeout(function(){return e.val(n.replace(/\d\s$/,""))})):/\s\d?$/.test(n)?(t.preventDefault(),setTimeout(function(){return e.val(n.replace(/\d$/,""))})):void 0},f=function(t){return setTimeout(function(){var e,n;return e=$(t.currentTarget),n=e.val(),n=$.payment.formatExpiry(n),e.val(n)})},u=function(t){var e,n,r;return n=String.fromCharCode(t.which),/^\d+$/.test(n)?(e=$(t.currentTarget),r=e.val()+n,/^\d$/.test(r)&&"0"!==r&&"1"!==r?(t.preventDefault(),setTimeout(function(){return e.val("0"+r+" / ")})):/^\d\d$/.test(r)?(t.preventDefault(),setTimeout(function(){return e.val(""+r+" / ")})):void 0):void 0},c=function(t){var e,n,r;return n=String.fromCharCode(t.which),/^\d+$/.test(n)?(e=$(t.currentTarget),r=e.val(),/^\d\d$/.test(r)?e.val(""+r+" / "):void 0):void 0},l=function(t){var e,n,r;return r=String.fromCharCode(t.which),"/"===r||" "===r?(e=$(t.currentTarget),n=e.val(),/^\d$/.test(n)&&"0"!==n?e.val("0"+n+" / "):void 0):void 0},a=function(t){var e,n;return e=$(t.currentTarget),n=e.val(),8!==t.which||null!=e.prop("selectionStart")&&e.prop("selectionStart")!==n.length?void 0:/\d\s\/\s$/.test(n)?(t.preventDefault(),setTimeout(function(){return e.val(n.replace(/\d\s\/\s$/,""))})):void 0},h=function(t){return setTimeout(function(){var e,n;return e=$(t.currentTarget),n=e.val(),n=n.replace(/\D/g,"").slice(0,4),e.val(n)})},w=function(t){var e;return t.metaKey||t.ctrlKey?!0:32===t.which?!1:0===t.which?!0:t.which<33?!0:(e=String.fromCharCode(t.which),!!/[\d\s]/.test(e))},y=function(e){var n,r,o,a;return n=$(e.currentTarget),o=String.fromCharCode(e.which),/^\d+$/.test(o)&&!s(n)?(a=(n.val()+o).replace(/\D/g,""),r=t(a),r?a.length<=r.length[r.length.length-1]:a.length<=16):void 0},g=function(t){var e,n,r;return e=$(t.currentTarget),n=String.fromCharCode(t.which),/^\d+$/.test(n)&&!s(e)?(r=e.val()+n,r=r.replace(/\D/g,""),r.length>6?!1:void 0):void 0},m=function(t){var e,n,r;return e=$(t.currentTarget),n=String.fromCharCode(t.which),/^\d+$/.test(n)&&!s(e)?(r=e.val()+n,r.length<=4):void 0},C=function(t){var e,r,o,a,i;return e=$(t.currentTarget),i=e.val(),a=$.payment.cardType(i)||"unknown",e.hasClass(a)?void 0:(r=function(){var t,e,r;for(r=[],t=0,e=n.length;e>t;t++)o=n[t],r.push(o.type);return r}(),e.removeClass("unknown"),e.removeClass(r.join(" ")),e.addClass(a),e.toggleClass("identified","unknown"!==a),e.trigger("payment.cardType",a))},$.payment.fn.formatCardCVC=function(){return this.on("keypress",w),this.on("keypress",m),this.on("paste",h),this.on("change",h),this.on("input",h),this},$.payment.fn.formatCardExpiry=function(){return this.on("keypress",w),this.on("keypress",g),this.on("keypress",u),this.on("keypress",l),this.on("keypress",c),this.on("keydown",a),this.on("change",f),this.on("input",f),this},$.payment.fn.formatCardNumber=function(){return this.on("keypress",w),this.on("keypress",y),this.on("keypress",i),this.on("keydown",o),this.on("keyup",C),this.on("paste",d),this.on("change",d),this.on("input",d),this.on("input",C),this},$.payment.fn.restrictNumeric=function(){return this.on("keypress",w),this.on("paste",v),this.on("change",v),this.on("input",v),this},$.payment.fn.cardExpiryVal=function(){return $.payment.cardExpiryVal($(this).val())},$.payment.cardExpiryVal=function(t){var e,n,r,o;return t=t.replace(/\s/g,""),o=t.split("/",2),e=o[0],r=o[1],2===(null!=r?r.length:void 0)&&/^\d+$/.test(r)&&(n=(new Date).getFullYear(),n=n.toString().slice(0,2),r=n+r),e=parseInt(e,10),r=parseInt(r,10),{month:e,year:r}},$.payment.validateCardNumber=function(e){var n,r;return e=(e+"").replace(/\s+|-/g,""),/^\d+$/.test(e)?(n=t(e),n?(r=e.length,b.call(n.length,r)>=0&&(n.luhn===!1||p(e))):!1):!1},$.payment.validateCardExpiry=function(t,e){var n,r,o;return"object"==typeof t&&"month"in t&&(o=t,t=o.month,e=o.year),t&&e?(t=$.trim(t),e=$.trim(e),/^\d+$/.test(t)&&/^\d+$/.test(e)&&t>=1&&12>=t?(2===e.length&&(e=70>e?"20"+e:"19"+e),4!==e.length?!1:(r=new Date(e,t),n=new Date,r.setMonth(r.getMonth()-1),r.setMonth(r.getMonth()+1,1),r>n)):!1):!1},$.payment.validateCardCVC=function(t,n){var r,o;return t=$.trim(t),/^\d+$/.test(t)?(r=e(n),null!=r?(o=t.length,b.call(r.cvcLength,o)>=0):t.length>=3&&t.length<=4):!1},$.payment.cardType=function(e){var n;return e?(null!=(n=t(e))?n.type:void 0)||null:null},$.payment.formatCardNumber=function(e){var n,r,o,a;return e=e.replace(/\D/g,""),(n=t(e))?(o=n.length[n.length.length-1],e=e.slice(0,o),n.format.global?null!=(a=e.match(n.format))?a.join(" "):void 0:(r=n.format.exec(e),null!=r?(r.shift(),r=$.grep(r,function(t){return t}),r.join(" ")):void 0)):e},$.payment.formatExpiry=function(t){var e,n,r,o;return(n=t.match(/^\D*(\d{1,2})(\D+)?(\d{1,4})?/))?(e=n[1]||"",r=n[2]||"",o=n[3]||"",o.length>0?r=" / ":" /"===r?(e=e.substring(0,1),r=""):2===e.length||r.length>0?r=" / ":1===e.length&&"0"!==e&&"1"!==e&&(e="0"+e,r=" / "),e+r+o):""}}).call(this)},{}],2:[function(t,e,n){function r(t){var e=this,t=t||{};i.publishableKey=e.stripe_key=t.key,e.form=t.form,e.cc_number=o.observable(null),e.cc_expiry=o.observable(null),e.cc_cvv=o.observable(null),e.cc_error_number=o.observable(null),e.cc_error_expiry=o.observable(null),e.cc_error_cvv=o.observable(null),e.initialize_form(),e.error=o.observable(null),e.process_form=function(){var t=a.payment.cardExpiryVal(e.cc_expiry()),n={number:e.cc_number(),exp_month:t.month,exp_year:t.year,cvc:e.cc_cvv()};return e.error(null),e.cc_error_number(null),e.cc_error_expiry(null),e.cc_error_cvv(null),a.payment.validateCardNumber(n.number)?a.payment.validateCardExpiry(n.exp_month,n.exp_year)?a.payment.validateCardCVC(n.cvc)?void i.createToken(n,function(t,n){if(200===t){var r=e.form.find("#id_last_4_digits"),o=e.form.find("#id_stripe_id,#id_stripe_token");r.val(n.card.last4),o.val(n.id),e.form.submit()}else e.error(n.error.message)}):(e.cc_error_cvv("Invalid security code"),!1):(e.cc_error_expiry("Invalid expiration date"),!1):(e.cc_error_number("Invalid card number"),console.log(n),!1)}}var o=t("knockout"),a=(t("./../../../../../bower_components/jquery.payment/lib/jquery.payment.js"),null),i=null;a="undefined"==typeof window?t("jquery"):window.$,"undefined"!=typeof window&&"undefined"!=typeof window.Stripe&&(i=window.Stripe||{}),r.prototype.initialize_form=function(){var t=a("input#cc-number"),e=a("input#cc-cvv"),n=a("input#cc-expiry");t.payment("formatCardNumber"),n.payment("formatCardExpiry"),e.payment("formatCardCVC")},r.init=function(t,e){var n=new GoldView(t),e=e||a("#payment-form")[0];return o.applyBindings(n,e),n},e.exports.PaymentView=r,"undefined"!=typeof window&&(window.payment=e.exports)},{"./../../../../../bower_components/jquery.payment/lib/jquery.payment.js":1,jquery:"jquery",knockout:"knockout"}],3:[function(t,e,n){function r(t){var e=this,t=t||{};a.utils.extend(e,new o.PaymentView(t))}var o=t("../../../../core/static-src/core/js/payment"),a=t("knockout");r.init=function(t,e){var n=new r(t),e=e||$("#payment-form")[0];return a.applyBindings(n,e),n},e.exports.GoldView=r,"undefined"!=typeof window&&(window.payment=e.exports)},{"../../../../core/static-src/core/js/payment":2,knockout:"knockout"}]},{},[3]);
\ No newline at end of file
diff --git a/readthedocs/restapi/views/footer_views.py b/readthedocs/restapi/views/footer_views.py
index 9a8afcdf31e..7ac22b28018 100644
--- a/readthedocs/restapi/views/footer_views.py
+++ b/readthedocs/restapi/views/footer_views.py
@@ -7,9 +7,39 @@
from rest_framework.renderers import JSONPRenderer, JSONRenderer, BrowsableAPIRenderer
from rest_framework.response import Response
+from builds.constants import LATEST
from builds.models import Version
-from projects.models import Project
from donate.models import SupporterPromo
+from projects.models import Project
+from projects.version_handling import highest_version
+from projects.version_handling import parse_version_failsafe
+
+
+def get_version_compare_data(project, base_version=None):
+ highest_version_obj, highest_version_comparable = highest_version(
+ project.versions.filter(active=True))
+ ret_val = {
+ 'project': unicode(highest_version_obj),
+ 'version': unicode(highest_version_comparable),
+ 'is_highest': True,
+ }
+ if highest_version_obj:
+ ret_val['url'] = highest_version_obj.get_absolute_url()
+ ret_val['slug'] = highest_version_obj.slug,
+ if base_version and base_version.slug != LATEST:
+ try:
+ base_version_comparable = parse_version_failsafe(
+ base_version.verbose_name)
+ if base_version_comparable:
+ # This is only place where is_highest can get set. All error
+ # cases will be set to True, for non- standard versions.
+ ret_val['is_highest'] = (
+ base_version_comparable >= highest_version_comparable)
+ else:
+ ret_val['is_highest'] = True
+ except (Version.DoesNotExist, TypeError):
+ ret_val['is_highest'] = True
+ return ret_val
@decorators.api_view(['GET'])
@@ -64,6 +94,8 @@ def footer_html(request):
if not promo_obj:
show_promo = False
+ version_compare_data = get_version_compare_data(project, version)
+
context = Context({
'project': project,
'path': path,
@@ -88,6 +120,7 @@ def footer_html(request):
resp_data = {
'html': html,
'version_active': version.active,
+ 'version_compare': version_compare_data,
'version_supported': version.supported,
'promo': show_promo,
}
diff --git a/readthedocs/rtd_tests/tests/test_api_version_compare.py b/readthedocs/rtd_tests/tests/test_api_version_compare.py
new file mode 100644
index 00000000000..13a5bc776f5
--- /dev/null
+++ b/readthedocs/rtd_tests/tests/test_api_version_compare.py
@@ -0,0 +1,33 @@
+from django.test import TestCase
+
+from builds.constants import LATEST
+from projects.models import Project
+from restapi.views.footer_views import get_version_compare_data
+
+
+class VersionCompareTests(TestCase):
+ fixtures = ['eric.json', 'test_data.json']
+
+ def test_not_highest(self):
+ project = Project.objects.get(slug='read-the-docs')
+ version = project.versions.get(slug='0.2.1')
+
+ data = get_version_compare_data(project, version)
+ self.assertEqual(data['is_highest'], False)
+
+ def test_latest_version_highest(self):
+ project = Project.objects.get(slug='read-the-docs')
+
+ data = get_version_compare_data(project)
+ self.assertEqual(data['is_highest'], True)
+
+ version = project.versions.get(slug=LATEST)
+ data = get_version_compare_data(project, version)
+ self.assertEqual(data['is_highest'], True)
+
+ def test_real_highest(self):
+ project = Project.objects.get(slug='read-the-docs')
+ version = project.versions.get(slug='0.2.2')
+
+ data = get_version_compare_data(project, version)
+ self.assertEqual(data['is_highest'], True)
diff --git a/readthedocs/rtd_tests/tests/test_footer.py b/readthedocs/rtd_tests/tests/test_footer.py
index 5be4614ca32..530180329e1 100644
--- a/readthedocs/rtd_tests/tests/test_footer.py
+++ b/readthedocs/rtd_tests/tests/test_footer.py
@@ -1,4 +1,5 @@
import json
+import mock
from django.test import TestCase
@@ -18,6 +19,7 @@ def test_footer(self):
r = self.client.get('/api/v2/footer_html/?project=pip&version=latest&page=index', {})
resp = json.loads(r.content)
self.assertEqual(resp['version_active'], True)
+ self.assertEqual(resp['version_compare']['is_highest'], True)
self.assertEqual(resp['version_supported'], True)
self.assertEqual(r.context['main_project'], self.pip)
self.assertEqual(r.status_code, 200)
@@ -29,6 +31,19 @@ def test_footer(self):
self.assertEqual(resp['version_active'], False)
self.assertEqual(r.status_code, 200)
+ def test_footer_uses_version_compare(self):
+ version_compare = 'restapi.views.footer_views.get_version_compare_data'
+ with mock.patch(version_compare) as get_version_compare_data:
+ get_version_compare_data.return_value = {
+ 'MOCKED': True
+ }
+
+ r = self.client.get('/api/v2/footer_html/?project=pip&version=latest&page=index', {})
+ self.assertEqual(r.status_code, 200)
+
+ resp = json.loads(r.content)
+ self.assertEqual(resp['version_compare'], {'MOCKED': True})
+
def test_pdf_build_mentioned_in_footer(self):
with fake_paths_by_regex('\.pdf$'):
response = self.client.get(