From c7ffd3361ac931fc3ea93b6498cff52f99074c73 Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 27 Apr 2018 11:42:39 -0400 Subject: [PATCH 001/703] removed patterns from imports --- api/urls.py | 2 +- bisac/urls.py | 2 +- frontend/urls.py | 2 +- libraryauth/urls.py | 2 +- marc/urls.py | 2 +- payment/urls.py | 2 +- urls.py | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/api/urls.py b/api/urls.py index ec34a6a96..a5223895a 100644 --- a/api/urls.py +++ b/api/urls.py @@ -1,6 +1,6 @@ from tastypie.api import Api -from django.conf.urls import patterns, url, include +from django.conf.urls import url, include from django.views.generic.base import TemplateView from regluit.api import resources diff --git a/bisac/urls.py b/bisac/urls.py index cf368f861..813decf89 100644 --- a/bisac/urls.py +++ b/bisac/urls.py @@ -1,4 +1,4 @@ -from django.conf.urls import patterns, url, include +from django.conf.urls import url, include from .views import tree urlpatterns = [ diff --git a/frontend/urls.py b/frontend/urls.py index 131937a4d..fe8e3b692 100644 --- a/frontend/urls.py +++ b/frontend/urls.py @@ -1,5 +1,5 @@ from django.conf import settings -from django.conf.urls import patterns, url, include +from django.conf.urls import url, include from django.contrib.admin.views.decorators import staff_member_required from django.contrib.auth.decorators import login_required from django.contrib.sites.models import Site diff --git a/libraryauth/urls.py b/libraryauth/urls.py index a14b3cd35..138793397 100644 --- a/libraryauth/urls.py +++ b/libraryauth/urls.py @@ -1,4 +1,4 @@ -from django.conf.urls import patterns, url, include +from django.conf.urls import url, include from django.core.urlresolvers import reverse_lazy from django.views.generic.base import TemplateView from django.contrib.auth.decorators import login_required diff --git a/marc/urls.py b/marc/urls.py index 5b8db2303..8ef66c01c 100644 --- a/marc/urls.py +++ b/marc/urls.py @@ -1,4 +1,4 @@ -from django.conf.urls import patterns, url, include +from django.conf.urls import url, include from django.contrib.auth.decorators import login_required from . import views diff --git a/payment/urls.py b/payment/urls.py index 076295ccd..8606e2d03 100644 --- a/payment/urls.py +++ b/payment/urls.py @@ -1,5 +1,5 @@ from django.conf import settings -from django.conf.urls import patterns, url, include +from django.conf.urls import url, include from regluit.payment import views diff --git a/urls.py b/urls.py index bb802b52b..7ce6dbfbc 100755 --- a/urls.py +++ b/urls.py @@ -1,4 +1,4 @@ -from django.conf.urls import patterns, url, include +from django.conf.urls import url, include from django.contrib.auth.decorators import login_required from django.contrib.sitemaps.views import index, sitemap from django.views.decorators.cache import never_cache From 486e3a5200e911cfb5d2e42b5c3454529a3b254f Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 27 Apr 2018 18:03:22 -0400 Subject: [PATCH 002/703] remove duplicate truncatechars --- frontend/templates/base.html | 2 +- frontend/templates/explore.html | 1 - frontend/templates/home.html | 1 - frontend/templates/libraryauth/library.html | 1 - .../notification/notice_settings.html | 1 - .../notice.html | 1 - frontend/templates/supporter.html | 1 - frontend/templatetags/truncatechars.py | 186 ------------------ 8 files changed, 1 insertion(+), 193 deletions(-) delete mode 100644 frontend/templatetags/truncatechars.py diff --git a/frontend/templates/base.html b/frontend/templates/base.html index 3b9be42aa..0adcfaeb7 100644 --- a/frontend/templates/base.html +++ b/frontend/templates/base.html @@ -1,5 +1,5 @@ -{% load truncatechars %}{% load sass_tags %} +{% load sass_tags %} diff --git a/frontend/templates/explore.html b/frontend/templates/explore.html index 857280cd6..1c8b1f072 100644 --- a/frontend/templates/explore.html +++ b/frontend/templates/explore.html @@ -1,4 +1,3 @@ -{% load truncatechars %} {% load lang_utils %} {% load explore %}{% explore %}
diff --git a/frontend/templates/home.html b/frontend/templates/home.html index d5b9b4287..53334642a 100755 --- a/frontend/templates/home.html +++ b/frontend/templates/home.html @@ -1,6 +1,5 @@ {% extends "base.html" %} -{% load truncatechars %} {% load sass_tags %} {% block title %}— Support Free eBooks{% endblock %} diff --git a/frontend/templates/libraryauth/library.html b/frontend/templates/libraryauth/library.html index d13e5d9e0..62287860c 100644 --- a/frontend/templates/libraryauth/library.html +++ b/frontend/templates/libraryauth/library.html @@ -2,7 +2,6 @@ {% load el_pagination_tags %} {% load sass_tags %} -{% load truncatechars %} {% block title %} — {{ library }}{% endblock %} {% block extra_css %} diff --git a/frontend/templates/notification/notice_settings.html b/frontend/templates/notification/notice_settings.html index 2b4c79e30..d2c887f1d 100644 --- a/frontend/templates/notification/notice_settings.html +++ b/frontend/templates/notification/notice_settings.html @@ -2,7 +2,6 @@ {% load i18n %} {% load sass_tags %} -{% load truncatechars %} {% block title %}{% trans "Notification Settings" %}{% endblock %} diff --git a/frontend/templates/notification/wishlist_unglued_book_released/notice.html b/frontend/templates/notification/wishlist_unglued_book_released/notice.html index 0cf667f08..f3e8b46d9 100644 --- a/frontend/templates/notification/wishlist_unglued_book_released/notice.html +++ b/frontend/templates/notification/wishlist_unglued_book_released/notice.html @@ -1,6 +1,5 @@ {% extends 'notification/notice_template.html' %} -{% load truncatechars %} {% block comments_book %} cover image for {{ work.title }} diff --git a/frontend/templates/supporter.html b/frontend/templates/supporter.html index 8c06deb50..53b441b79 100644 --- a/frontend/templates/supporter.html +++ b/frontend/templates/supporter.html @@ -1,7 +1,6 @@ {% extends 'base.html' %} {% load el_pagination_tags %} -{% load truncatechars %} {% load sass_tags %} {% block title %} — {{ supporter.username }}{% endblock %} diff --git a/frontend/templatetags/truncatechars.py b/frontend/templatetags/truncatechars.py deleted file mode 100644 index 2754ebf75..000000000 --- a/frontend/templatetags/truncatechars.py +++ /dev/null @@ -1,186 +0,0 @@ -""" -The truncatechars filter is part of Django dev, but we're on 1.3.1 -The following is the filter and its dependencies -To use this filter, put "{% load truncatechars %}" at the beginning of your template, -then {{ myvariable|truncatechars:num }} -""" -import unicodedata - -from django import template -from django.template import Library -from django.template.defaultfilters import stringfilter -from django.utils.encoding import force_unicode -from django.utils.functional import allow_lazy, SimpleLazyObject -from django.utils.translation import pgettext - -register = Library() - -class Truncator(SimpleLazyObject): - """ - An object used to truncate text, either by characters or words. - """ - def __init__(self, text): - super(Truncator, self).__init__(lambda: force_unicode(text)) - - def add_truncation_text(self, text, truncate=None): - if truncate is None: - truncate = pgettext( - 'String to return when truncating text', - u'%(truncated_text)s...') - truncate = force_unicode(truncate) - if '%(truncated_text)s' in truncate: - return truncate % {'truncated_text': text} - # The truncation text didn't contain the %(truncated_text)s string - # replacement argument so just append it to the text. - if text.endswith(truncate): - # But don't append the truncation text if the current text already - # ends in this. - return text - return '%s%s' % (text, truncate) - - def chars(self, num, truncate=None): - """ - Returns the text truncated to be no longer than the specified number - of characters. - - Takes an optional argument of what should be used to notify that the - string has been truncated, defaulting to a translatable string of an - ellipsis (...). - """ - length = int(num) - uniself = unicode(self._wrapped) - text = unicodedata.normalize('NFC', uniself) - - # Calculate the length to truncate to (max length - end_text length) - truncate_len = length - for char in self.add_truncation_text('', truncate): - if not unicodedata.combining(char): - truncate_len -= 1 - if truncate_len == 0: - break - - s_len = 0 - end_index = None - for i, char in enumerate(text): - if unicodedata.combining(char): - # Don't consider combining characters - # as adding to the string length - continue - s_len += 1 - if end_index is None and s_len > truncate_len: - end_index = i - if s_len > length: - # Return the truncated string - return self.add_truncation_text(text[:end_index or 0], - truncate) - - # Return the original string since no truncation was necessary - return text - chars = allow_lazy(chars) - - def words(self, num, truncate=None, html=False): - """ - Truncates a string after a certain number of words. Takes an optional - argument of what should be used to notify that the string has been - truncated, defaulting to ellipsis (...). - """ - length = int(num) - if html: - return self._html_words(length, truncate) - return self._text_words(length, truncate) - words = allow_lazy(words) - - def _text_words(self, length, truncate): - """ - Truncates a string after a certain number of words. - - Newlines in the string will be stripped. - """ - words = self._wrapped.split() - if len(words) > length: - words = words[:length] - return self.add_truncation_text(u' '.join(words), truncate) - return u' '.join(words) - - def _html_words(self, length, truncate): - """ - Truncates HTML to a certain number of words (not counting tags and - comments). Closes opened tags if they were correctly closed in the - given HTML. - - Newlines in the HTML are preserved. - """ - if length <= 0: - return u'' - html4_singlets = ( - 'br', 'col', 'link', 'base', 'img', - 'param', 'area', 'hr', 'input' - ) - # Count non-HTML words and keep note of open tags - pos = 0 - end_text_pos = 0 - words = 0 - open_tags = [] - while words <= length: - m = re_words.search(self._wrapped, pos) - if not m: - # Checked through whole string - break - pos = m.end(0) - if m.group(1): - # It's an actual non-HTML word - words += 1 - if words == length: - end_text_pos = pos - continue - # Check for tag - tag = re_tag.match(m.group(0)) - if not tag or end_text_pos: - # Don't worry about non tags or tags after our truncate point - continue - closing_tag, tagname, self_closing = tag.groups() - # Element names are always case-insensitive - tagname = tagname.lower() - if self_closing or tagname in html4_singlets: - pass - elif closing_tag: - # Check for match in open tags list - try: - i = open_tags.index(tagname) - except ValueError: - pass - else: - # SGML: An end tag closes, back to the matching start tag, - # all unclosed intervening start tags with omitted end tags - open_tags = open_tags[i + 1:] - else: - # Add it to the start of the open tags list - open_tags.insert(0, tagname) - if words <= length: - # Don't try to close tags if we don't need to truncate - return self._wrapped - out = self._wrapped[:end_text_pos] - truncate_text = self.add_truncation_text('', truncate) - if truncate_text: - out += truncate_text - # Close any tags still open - for tag in open_tags: - out += '' % tag - # Return string - return out - -# django dev uses filter(is_safe=True) syntax here, but that's not yet available in 1.3.1 -@register.filter() -@stringfilter -def truncatechars(value, arg): - """ - Truncates a string after a certain number of characters. - - Argument: Number of characters to truncate after. - """ - try: - length = int(arg) - except ValueError: # Invalid literal for int(). - return value # Fail silently. - return Truncator(value).chars(length) -truncatechars.is_safe = True \ No newline at end of file From b7df794017a637079009c3eea153cd74e6730781 Mon Sep 17 00:00:00 2001 From: eric Date: Wed, 2 May 2018 11:11:16 -0400 Subject: [PATCH 003/703] deprecated template syntax --- frontend/templates/faceted_list.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/templates/faceted_list.html b/frontend/templates/faceted_list.html index b1697c2fd..043fe7f35 100644 --- a/frontend/templates/faceted_list.html +++ b/frontend/templates/faceted_list.html @@ -64,9 +64,9 @@
From f80b7a8d31f174f84cddad7bfa3470531d24281e Mon Sep 17 00:00:00 2001 From: eric Date: Wed, 2 May 2018 11:13:38 -0400 Subject: [PATCH 004/703] context_instance deprecated in django 1.10 --- payment/views.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/payment/views.py b/payment/views.py index d7c01fe02..3a486610c 100644 --- a/payment/views.py +++ b/payment/views.py @@ -21,8 +21,7 @@ HttpResponseRedirect, HttpResponseBadRequest ) -from django.shortcuts import render_to_response -from django.template import RequestContext +from django.shortcuts import render from django.test.utils import setup_test_environment from django.utils.timezone import now from django.views.decorators.csrf import csrf_exempt @@ -278,7 +277,7 @@ def checkStatus(request): # https://raw.github.com/agiliq/merchant/master/example/app/views.py def _render(request, template, template_vars={}): - return render_to_response(template, template_vars, RequestContext(request)) + return render(request, template, template_vars) class StripeView(FormView): template_name="stripe.html" From 2f532b97f9ecc399048cddf876c7046e180b5c4e Mon Sep 17 00:00:00 2001 From: eric Date: Mon, 9 Jul 2018 15:46:36 -0400 Subject: [PATCH 005/703] scrape multiple books from one url --- core/loaders/doab_utils.py | 3 + core/loaders/multiscrape.py | 94 ++++++++++++++++++++++++++++ core/loaders/scrape.py | 29 +++++---- core/management/commands/load_edp.py | 10 +++ 4 files changed, 123 insertions(+), 13 deletions(-) create mode 100644 core/loaders/multiscrape.py create mode 100644 core/management/commands/load_edp.py diff --git a/core/loaders/doab_utils.py b/core/loaders/doab_utils.py index ceef8bb70..4db1c42bf 100644 --- a/core/loaders/doab_utils.py +++ b/core/loaders/doab_utils.py @@ -124,6 +124,9 @@ def online_to_download(url): booknum = FRONTIERSIN.search(url).group(1) urls.append(u'https://www.frontiersin.org/GetFile.aspx?ebook={}&fileformat=EPUB'.format(booknum)) urls.append(u'https://www.frontiersin.org/GetFile.aspx?ebook={}&fileformat=PDF'.format(booknum)) + elif url.find(u'edp-open.org/books-in-') >= 0: + # pages needing multi-scrape + return urls else: urls.append(url) return urls diff --git a/core/loaders/multiscrape.py b/core/loaders/multiscrape.py new file mode 100644 index 000000000..ba98ad814 --- /dev/null +++ b/core/loaders/multiscrape.py @@ -0,0 +1,94 @@ +import logging +import re +from urlparse import urljoin + +from bs4 import BeautifulSoup +import requests + +from django.conf import settings + +from regluit.core.bookloader import add_from_bookdatas +from regluit.core.loaders.scrape import BaseScraper +from regluit.core.validation import identifier_cleaner + +logger = logging.getLogger(__name__) +''' +use for web pages with multiple books +returns an iterator of scrapers +''' + +class BaseMultiScraper(BaseScraper): + def __init__(self, url, doc): + self.metadata = {} + self.identifiers = {'http': url} + self.doc = doc + self.base = url + self.get_all() + if not self.metadata.get('title', None): + self.set('title', '!!! missing title !!!') + if not self.metadata.get('language', None): + self.set('language', 'en') + self.metadata['identifiers'] = self.identifiers + +def multiscrape(url, divider, scraper_class=BaseMultiScraper): + try: + response = requests.get(url, headers={"User-Agent": settings.USER_AGENT}) + if response.status_code == 200: + doc = BeautifulSoup(response.content, 'lxml') + sections = divider(doc) + for section in sections: + yield scraper_class(url, section) + except requests.exceptions.RequestException as e: + logger.error(e) + self.metadata = None + + +# following is code specific to edp-open.org; refactor when we add another + +def divider(doc): + return doc.select('article.Bk') + +ISBNMATCH = re.compile(r'([\d\-]+)') +class EDPMultiScraper(BaseMultiScraper): + def get_isbns(self): + '''return a dict of edition keys and ISBNs''' + isbns = {} + isbn_cleaner = identifier_cleaner('isbn', quiet=True) + labels = ['epub', 'pdf', 'paper'] + info = self.doc.select_one('p.nfo').text + isbntexts = re.split('ISBN', info) + for isbntext in isbntexts[1:]: + isbnmatch = ISBNMATCH.search(isbntext) + if isbnmatch: + isbn = isbn_cleaner(isbnmatch.group(0)) + isbns[labels.pop()] = isbn + return isbns + + def get_downloads(self): + dl = self.doc.select_one('nav.dl') + links = dl.select('a.fulldl') + for link in links: + href = urljoin(self.base, link['href']) + if href.endswith('.pdf'): + self.set('download_url_pdf', href) + elif href.endswith('.epub'): + self.set('download_url_epub', href) + + def get_language(self): + self.set('language', 'fr') + + def get_title(self): + value = self.doc.select_one('h2').text + book_id = self.doc.select_one('h2')['id'] + self.identifiers['http'] = u'{}#{}'.format(self.base, book_id) + self.set('title', value) + +def edp_scrape(): + edp_urls = [ + 'https://www.edp-open.org/books-in-french', + 'https://www.edp-open.org/books-in-english', + ] + for url in edp_urls: + scrapers = multiscrape(url, divider, scraper_class=EDPMultiScraper) + add_from_bookdatas(scrapers) + diff --git a/core/loaders/scrape.py b/core/loaders/scrape.py index 04a40e708..521748fd6 100644 --- a/core/loaders/scrape.py +++ b/core/loaders/scrape.py @@ -51,19 +51,7 @@ def __init__(self, url): self.doc = BeautifulSoup(response.content, 'lxml') for review in self.doc.find_all(itemtype="http://schema.org/Review"): review.clear() - self.setup() - self.get_genre() - self.get_title() - self.get_language() - self.get_description() - self.get_identifiers() - self.get_keywords() - self.get_publisher() - self.get_pubdate() - self.get_authors() - self.get_cover() - self.get_downloads() - self.get_license() + self.get_all() if not self.metadata.get('title', None): self.set('title', '!!! missing title !!!') if not self.metadata.get('language', None): @@ -140,6 +128,21 @@ def get_itemprop(self, name, **attrs): elif el.has_key('content'): value_list.append(el['content']) return value_list + + def get_all(self): + self.setup() + self.get_genre() + self.get_title() + self.get_language() + self.get_description() + self.get_identifiers() + self.get_keywords() + self.get_publisher() + self.get_pubdate() + self.get_authors() + self.get_cover() + self.get_downloads() + self.get_license() def setup(self): # use this method to get auxiliary resources based on doc diff --git a/core/management/commands/load_edp.py b/core/management/commands/load_edp.py new file mode 100644 index 000000000..55961052c --- /dev/null +++ b/core/management/commands/load_edp.py @@ -0,0 +1,10 @@ +from django.core.management.base import BaseCommand + +from regluit.core.loaders.multiscrape import edp_scrape + + +class Command(BaseCommand): + help = "load books from edp-open" + + def handle(self, **options): + edp_scrape() From ec3d26118e3325363c21097e4ca163acf649f177 Mon Sep 17 00:00:00 2001 From: eric Date: Tue, 10 Jul 2018 13:58:06 -0400 Subject: [PATCH 006/703] fr/en --- core/loaders/multiscrape.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/loaders/multiscrape.py b/core/loaders/multiscrape.py index ba98ad814..21e2140ea 100644 --- a/core/loaders/multiscrape.py +++ b/core/loaders/multiscrape.py @@ -75,6 +75,8 @@ def get_downloads(self): self.set('download_url_epub', href) def get_language(self): + if 'english' in self.base: + self.set('language', 'en') self.set('language', 'fr') def get_title(self): From 40794ee3f9de897fa51689fe96b18b6eda1318de Mon Sep 17 00:00:00 2001 From: eric Date: Tue, 10 Jul 2018 13:58:38 -0400 Subject: [PATCH 007/703] use rights info to set rights --- core/bookloader.py | 2 +- core/loaders/doab.py | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/core/bookloader.py b/core/bookloader.py index a9fed0c2f..688a0edff 100755 --- a/core/bookloader.py +++ b/core/bookloader.py @@ -986,6 +986,7 @@ def load_from_pandata(self, metadata, work=None): def load_ebooks(self, metadata, edition, test_mode=False, user=None): default_edition = edition + license = cc.license_from_cc_url(metadata.rights_url) for key in ['epub', 'pdf', 'mobi']: url = metadata.metadata.get('download_url_{}'.format(key), None) if url: @@ -995,7 +996,6 @@ def load_ebooks(self, metadata, edition, test_mode=False, user=None): if contentfile: contentfile_name = '/loaded/ebook_{}.{}'.format(edition.id, key) path = default_storage.save(contentfile_name, contentfile) - license = cc.license_from_cc_url(metadata.rights_url) ebf = models.EbookFile.objects.create( format=key, edition=edition, diff --git a/core/loaders/doab.py b/core/loaders/doab.py index 6d3643286..c45b02c68 100644 --- a/core/loaders/doab.py +++ b/core/loaders/doab.py @@ -65,7 +65,12 @@ def store_doab_cover(doab_id, redo=False): else: r = requests.get(url) cover_file = ContentFile(r.content) - cover_file.content_type = r.headers.get('content-type', '') + content_type = r.headers.get('content-type', '') + if u'text/html' in content_type: + logger.warning('Cover return html for doab_id={}: {}'.format(doab_id, e)) + return (None, False) + cover_file.content_type = content_type + default_storage.save(cover_file_name, cover_file) return (default_storage.url(cover_file_name), True) @@ -287,6 +292,12 @@ def load_doab_edition(title, doab_id, url, format, rights, publisher_name=unlist(kwargs.get('publisher')), authors=kwargs.get('creator'), ) + if rights: + for ebook in edition.ebooks.all(): + if not ebook.rights: + ebook.rights = rights + ebook.save() + return edition # From 1b4beb0b0b600a9f975c4f277093a5863bd4c8d6 Mon Sep 17 00:00:00 2001 From: eric Date: Tue, 10 Jul 2018 13:59:05 -0400 Subject: [PATCH 008/703] fix thumbnail fails --- core/models/bibmodels.py | 48 +++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/core/models/bibmodels.py b/core/models/bibmodels.py index 4347c6f5b..d804eba70 100644 --- a/core/models/bibmodels.py +++ b/core/models/bibmodels.py @@ -866,39 +866,47 @@ def __unicode__(self): def cover_image_large(self): #550 pixel high image if self.cover_image: - im = get_thumbnail(self.cover_image, 'x550', crop='noop', quality=95) - if im.exists(): - return im.url + try: + im = get_thumbnail(self.cover_image, 'x550', crop='noop', quality=95) + if im.exists(): + return im.url + except IOError: + pass elif self.googlebooks_id: url = "https://encrypted.google.com/books?id=%s&printsec=frontcover&img=1&zoom=0" % self.googlebooks_id - im = get_thumbnail(url, 'x550', crop='noop', quality=95) - if not im.exists() or im.storage.size(im.name) == 16392: # check for "image not available" image - url = "https://encrypted.google.com/books?id=%s&printsec=frontcover&img=1&zoom=1" % self.googlebooks_id + try: im = get_thumbnail(url, 'x550', crop='noop', quality=95) - if im.exists(): - return im.url - else: - return '' - else: - return '' + if not im.exists() or im.storage.size(im.name) == 16392: # check for "image not available" image + url = "https://encrypted.google.com/books?id=%s&printsec=frontcover&img=1&zoom=1" % self.googlebooks_id + im = get_thumbnail(url, 'x550', crop='noop', quality=95) + if im.exists(): + return im.url + except IOError: + pass + return '' def cover_image_small(self): #80 pixel high image if self.cover_image: - im = get_thumbnail(self.cover_image, 'x80', crop='noop', quality=95) - if im.exists(): - return im.url + try: + im = get_thumbnail(self.cover_image, 'x80', crop='noop', quality=95) + if im.exists(): + return im.url + except IOError: + pass if self.googlebooks_id: return "https://encrypted.google.com/books?id=%s&printsec=frontcover&img=1&zoom=5" % self.googlebooks_id - else: - return '' + return '' def cover_image_thumbnail(self): #128 pixel wide image if self.cover_image: - im = get_thumbnail(self.cover_image, '128', crop='noop', quality=95) - if im.exists(): - return im.url + try: + im = get_thumbnail(self.cover_image, '128', crop='noop', quality=95) + if im.exists(): + return im.url + except IOError: + pass if self.googlebooks_id: return "https://encrypted.google.com/books?id=%s&printsec=frontcover&img=1&zoom=1" % self.googlebooks_id else: From da601a77f6379ccb920150941ec101dbe19ddb9e Mon Sep 17 00:00:00 2001 From: eric Date: Wed, 11 Jul 2018 13:41:52 -0400 Subject: [PATCH 009/703] final fixes --- core/loaders/multiscrape.py | 5 ++--- requirements_versioned.pip | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/core/loaders/multiscrape.py b/core/loaders/multiscrape.py index 21e2140ea..1a42a24b7 100644 --- a/core/loaders/multiscrape.py +++ b/core/loaders/multiscrape.py @@ -26,8 +26,6 @@ def __init__(self, url, doc): self.get_all() if not self.metadata.get('title', None): self.set('title', '!!! missing title !!!') - if not self.metadata.get('language', None): - self.set('language', 'en') self.metadata['identifiers'] = self.identifiers def multiscrape(url, divider, scraper_class=BaseMultiScraper): @@ -77,7 +75,8 @@ def get_downloads(self): def get_language(self): if 'english' in self.base: self.set('language', 'en') - self.set('language', 'fr') + else: + self.set('language', 'fr') def get_title(self): value = self.doc.select_one('h2').text diff --git a/requirements_versioned.pip b/requirements_versioned.pip index f1e0f02db..38481e0e9 100644 --- a/requirements_versioned.pip +++ b/requirements_versioned.pip @@ -41,7 +41,7 @@ django-tastypie==0.13.3 git+git://github.com/resulto/django-transmeta.git@ad4d7278ba330dcf8c8446f8ae9b2c769ae8684e fef-questionnaire==4.0.1 #gitenberg.metadata==0.1.6 -git+https://github.com/gitenberg-dev/gitberg-build +git+git://github.com/gitenberg-dev/gitberg-build.git@61a5fb0011e1a547b1eac14dd845ce37dbb5f85a #git+ssh://git@github.com/gitenberg-dev/metadata.git@0.1.11 github3.py==0.9.5 html5lib==1.0.1 From ee03d2d434440096f4adae9d42444be135df3650 Mon Sep 17 00:00:00 2001 From: eric Date: Thu, 12 Jul 2018 12:56:09 -0400 Subject: [PATCH 010/703] add hosts --- bookdata/sitemaps.txt | 10 +++++++++- core/loaders/ubiquity.py | 4 +++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/bookdata/sitemaps.txt b/bookdata/sitemaps.txt index b91f2814e..8f31f2a0c 100644 --- a/bookdata/sitemaps.txt +++ b/bookdata/sitemaps.txt @@ -6,4 +6,12 @@ https://oa.psupress.org/sitemap.xml https://www.larcommons.net/sitemap.xml https://www.uwestminsterpress.co.uk/sitemap.xml https://www.stockholmuniversitypress.se/sitemap.xml -https://www.luminosoa.org/sitemap.xml \ No newline at end of file +https://www.luminosoa.org/sitemap.xml +https://iitikship.iiti.ac.in/sitemap.xml +https://aperio.press/sitemap.xml +https://press.lse.ac.uk/sitemap.xml +https://press.sjms.nu/sitemap.xml +https://trystingtree.library.oregonstate.edu/sitemap.xml +https://publishing.vt.edu/sitemap.xml +https://universitypress.whiterose.ac.uk/sitemap.xml +https://www.winchesteruniversitypress.org/sitemap.xml \ No newline at end of file diff --git a/core/loaders/ubiquity.py b/core/loaders/ubiquity.py index c346cec44..05334b886 100644 --- a/core/loaders/ubiquity.py +++ b/core/loaders/ubiquity.py @@ -8,7 +8,9 @@ HAS_EDS = re.compile(r'\(eds?\.\)') UBIQUITY_HOSTS = ["ubiquitypress.com", "kriterium.se", "oa.finlit.fi", "humanities-map.net", "oa.psupress.org", "larcommons.net", "uwestminsterpress.co.uk", "stockholmuniversitypress.se", - "luminosoa.org", + "luminosoa.org", "iitikship.iiti.ac.in", "aperio.press", "press.lse.ac.uk", "press.sjms.nu", + "trystingtree.library.oregonstate.edu", "publishing.vt.edu", "universitypress.whiterose.ac.uk", + "www.winchesteruniversitypress.org", ] class UbiquityScraper(BaseScraper): From 311d6fa0be5dd29c6a4652c311528dc078ba45ca Mon Sep 17 00:00:00 2001 From: eric Date: Thu, 12 Jul 2018 12:56:57 -0400 Subject: [PATCH 011/703] fix rare merge issue --- core/bookloader.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/bookloader.py b/core/bookloader.py index 688a0edff..ea88aafb3 100755 --- a/core/bookloader.py +++ b/core/bookloader.py @@ -909,10 +909,9 @@ def load_from_pandata(self, metadata, work=None): if work and id.work and id.work_id is not work.id: # dangerous! merge newer into older if work.id < id.work_id: - merge_works(work, id.work) + work = merge_works(work, id.work) else: - merge_works(id.work, work) - work = id.work + work = merge_works(id.work, work) else: work = id.work if id.edition and not edition: From 9f98ddddfe4eb02e50ad69227d3ac9597e393fbb Mon Sep 17 00:00:00 2001 From: eric Date: Thu, 19 Jul 2018 17:38:36 -0400 Subject: [PATCH 012/703] update to factored social_auth addresses facebook's limits on passing state in redirect; (also addresses dj111 compatibility) updated httplib2 fixes goodreads issue --- libraryauth/auth.py | 10 +++++----- libraryauth/urls.py | 2 +- requirements_versioned.pip | 7 ++++--- settings/common.py | 30 +++++++++++++++--------------- settings/dummy/host.py | 1 + 5 files changed, 26 insertions(+), 24 deletions(-) diff --git a/libraryauth/auth.py b/libraryauth/auth.py index 3876fd49d..4c3266010 100644 --- a/libraryauth/auth.py +++ b/libraryauth/auth.py @@ -4,11 +4,11 @@ from django.shortcuts import redirect from django.utils.http import urlquote -from social.pipeline.social_auth import associate_by_email -from social.apps.django_app.default.models import UserSocialAuth -from social.apps.django_app.middleware import SocialAuthExceptionMiddleware -from social.exceptions import (AuthAlreadyAssociated,SocialAuthBaseException) -from social.utils import social_logger +from social_core.pipeline.social_auth import associate_by_email +from social_django.models import UserSocialAuth +from social_django.middleware import SocialAuthExceptionMiddleware +from social_core.exceptions import (AuthAlreadyAssociated, SocialAuthBaseException) +from social_core.utils import social_logger ANONYMOUS_AVATAR = '/static/images/header/avatar.png' (NO_AVATAR, GRAVATAR, TWITTER, FACEBOOK, PRIVATETAR) = (0, 1, 2, 3, 4) diff --git a/libraryauth/urls.py b/libraryauth/urls.py index a14b3cd35..6b1e889ce 100644 --- a/libraryauth/urls.py +++ b/libraryauth/urls.py @@ -65,7 +65,7 @@ def get_context_data(self, **kwargs): 'password_reset_form': forms.SocialAwarePasswordResetForm}, name='libraryauth_password_reset'), - url(r'^socialauth/', include('social.apps.django_app.urls', namespace='social')), + url(r'^socialauth/', include('social_django.urls', namespace='social')), url('accounts/', include('email_change.urls')), url(r'^accounts/', include('registration.backends.model_activation.urls')), url(r'^accounts/', include('django.contrib.auth.urls')), diff --git a/requirements_versioned.pip b/requirements_versioned.pip index 38481e0e9..e0916ca3e 100644 --- a/requirements_versioned.pip +++ b/requirements_versioned.pip @@ -45,7 +45,7 @@ git+git://github.com/gitenberg-dev/gitberg-build.git@61a5fb0011e1a547b1eac14dd84 #git+ssh://git@github.com/gitenberg-dev/metadata.git@0.1.11 github3.py==0.9.5 html5lib==1.0.1 -httplib2==0.7.5 +httplib2==0.11.3 isodate==0.5.1 kombu==3.0.35 lxml==4.2.1 @@ -54,7 +54,7 @@ mechanize==0.2.5 mimeparse==0.1.3 nose==1.1.2 numpy==1.11.2 -oauth2==1.5.211 +oauth2==1.9.0.post1 oauthlib==1.1.2 pandas==0.19.1 paramiko==1.14.1 @@ -66,7 +66,8 @@ pyparsing==2.0.3 python-dateutil==2.5.3 python-mimeparse==0.1.4 python-openid==2.2.5 -python-social-auth==0.2.21 +social-auth-core==1.7.0 +social-auth-app-django==2.1.0 pytz==2016.6.1 rdflib==4.2.0 rdflib-jsonld==0.3 diff --git a/settings/common.py b/settings/common.py index e9d2016b4..8dc750be0 100644 --- a/settings/common.py +++ b/settings/common.py @@ -157,7 +157,7 @@ 'regluit.payment', 'regluit.utils', 'registration', - 'social.apps.django_app.default', + 'social_django', 'tastypie', 'djcelery', 'el_pagination', @@ -243,11 +243,11 @@ # django-socialauth AUTHENTICATION_BACKENDS = ( - 'social.backends.google.GoogleOAuth2', - 'social.backends.twitter.TwitterOAuth', - 'social.backends.yahoo.YahooOpenId', - 'social.backends.facebook.FacebookOAuth2', - 'social.backends.open_id.OpenIdAuth', + 'social_core.backends.google.GoogleOAuth2', + 'social_core.backends.twitter.TwitterOAuth', + 'social_core.backends.yahoo.YahooOpenId', + 'social_core.backends.facebook.FacebookOAuth2', + 'social_core.backends.open_id.OpenIdAuth', 'django.contrib.auth.backends.ModelBackend', ) @@ -265,50 +265,50 @@ # format to create the user instance later. On some cases the details are # already part of the auth response from the provider, but sometimes this # could hit a provider API. - 'social.pipeline.social_auth.social_details', + 'social_core.pipeline.social_auth.social_details', # Get the social uid from whichever service we're authing thru. The uid is # the unique identifier of the given user in the provider. - 'social.pipeline.social_auth.social_uid', + 'social_core.pipeline.social_auth.social_uid', # Verifies that the current auth process is valid within the current # project, this is were emails and domains whitelists are applied (if # defined). - 'social.pipeline.social_auth.auth_allowed', + 'social_core.pipeline.social_auth.auth_allowed', # Checks if the current social-account is already associated in the site. 'regluit.libraryauth.auth.selective_social_user', # Make up a username for this person, appends a random string at the end if # there's any collision. - 'social.pipeline.user.get_username', + 'social_core.pipeline.user.get_username', # make username < 222 in length 'regluit.libraryauth.auth.chop_username', # Send a validation email to the user to verify its email address. # Disabled by default. - # 'social.pipeline.mail.mail_validation', + # 'social_core.pipeline.mail.mail_validation', # Associates the current social details with another user account with # a similar email address. don't use twitter or facebook to log in 'regluit.libraryauth.auth.selectively_associate_by_email', # Create a user account if we haven't found one yet. - 'social.pipeline.user.create_user', + 'social_core.pipeline.user.create_user', # Create the record that associated the social account with this user. - 'social.pipeline.social_auth.associate_user', + 'social_core.pipeline.social_auth.associate_user', # Populate the extra_data field in the social record with the values # specified by settings (and the default ones like access_token, etc). - 'social.pipeline.social_auth.load_extra_data', + 'social_core.pipeline.social_auth.load_extra_data', # add extra data to user profile 'regluit.libraryauth.auth.deliver_extra_data', # Update the user record with any changed info from the auth service. - 'social.pipeline.user.user_details' + 'social_core.pipeline.user.user_details' ) SOCIAL_AUTH_TWITTER_EXTRA_DATA = [('profile_image_url_https', 'profile_image_url_https'),('screen_name','screen_name')] diff --git a/settings/dummy/host.py b/settings/dummy/host.py index 9819dc7f9..39d19c6f0 100644 --- a/settings/dummy/host.py +++ b/settings/dummy/host.py @@ -22,6 +22,7 @@ # twitter auth # you'll need to create a new Twitter application to fill in these blanks # https://dev.twitter.com/apps/new +# the field for redirect url must be filled in with https://unglue.it/socialauth/complete/twitter/? SOCIAL_AUTH_TWITTER_KEY = os.environ.get("SOCIAL_AUTH_TWITTER_KEY", '0123456789012345678901234') SOCIAL_AUTH_TWITTER_SECRET = os.environ.get("SOCIAL_AUTH_TWITTER_SECRET", '01234567890123456789012345678901234567890123456789') From f453555bf32c5c4ca8b2745b8040d65f53742e2e Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 20 Jul 2018 07:54:14 -0400 Subject: [PATCH 013/703] redirects should send user back to supporter page --- frontend/templates/supporter.html | 8 ++++---- frontend/views/__init__.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/templates/supporter.html b/frontend/templates/supporter.html index 8c06deb50..a533e3ca4 100644 --- a/frontend/templates/supporter.html +++ b/frontend/templates/supporter.html @@ -186,16 +186,16 @@

Your Links

{% if supporter.profile.twitter_id %} - Update your Twitter connection
or disconnect Twitter: {{ profile_form.clear_twitter }} + Update your Twitter connection
or disconnect Twitter: {{ profile_form.clear_twitter }} {% else %} - Connect your Twitter account to Unglue.it + Connect your Twitter account to Unglue.it {% endif %}
{% if supporter.profile.facebook_id %} - Update your Facebook connection
or disconnect Facebook: {{ profile_form.clear_facebook }} + Update your Facebook connection
or disconnect Facebook: {{ profile_form.clear_facebook }} {% else %} - Connect your Facebook account to Unglue.it + Connect your Facebook account to Unglue.it {% endif %}
diff --git a/frontend/views/__init__.py b/frontend/views/__init__.py index 84e764bc1..8f583d991 100755 --- a/frontend/views/__init__.py +++ b/frontend/views/__init__.py @@ -2236,7 +2236,7 @@ def goodreads_cb(request): profile.save() # is this needed? # redirect to the Goodreads display page -- should observe some next later - return HttpResponseRedirect(reverse('home')) + return HttpResponseRedirect(reverse('supporter', args=[request.user])) @require_POST @login_required From 26d65e8793b7ff05a75fdb66cd76c1ec1171db68 Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 20 Jul 2018 13:03:51 -0400 Subject: [PATCH 014/703] facebook id not useful; get pic instead --- core/models/__init__.py | 7 ++----- libraryauth/auth.py | 20 +++++++++----------- settings/common.py | 4 +++- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/core/models/__init__.py b/core/models/__init__.py index 662ddca34..1641b61a4 100755 --- a/core/models/__init__.py +++ b/core/models/__init__.py @@ -1314,7 +1314,7 @@ def unglueitar(self): @property def avatar_url(self): - if self.avatar_source is None or self.avatar_source is TWITTER: + if self.avatar_source is None or self.avatar_source in (TWITTER, FACEBOOK): if self.pic_url: return self.pic_url else: @@ -1323,10 +1323,7 @@ def avatar_url(self): return self.unglueitar() elif self.avatar_source == GRAVATAR: return self.gravatar() - elif self.avatar_source == FACEBOOK and self.facebook_id != None: - return 'https://graph.facebook.com/v2.3/' + str(self.facebook_id) + '/picture?redirect=true' - else: - return ANONYMOUS_AVATAR + return ANONYMOUS_AVATAR @property def social_auths(self): diff --git a/libraryauth/auth.py b/libraryauth/auth.py index 4c3266010..bd337f1f3 100644 --- a/libraryauth/auth.py +++ b/libraryauth/auth.py @@ -8,7 +8,6 @@ from social_django.models import UserSocialAuth from social_django.middleware import SocialAuthExceptionMiddleware from social_core.exceptions import (AuthAlreadyAssociated, SocialAuthBaseException) -from social_core.utils import social_logger ANONYMOUS_AVATAR = '/static/images/header/avatar.png' (NO_AVATAR, GRAVATAR, TWITTER, FACEBOOK, PRIVATETAR) = (0, 1, 2, 3, 4) @@ -30,19 +29,18 @@ def selectively_associate_by_email(backend, details, user=None, *args, **kwargs) return None return associate_by_email(backend, details, user=None, *args, **kwargs) -def facebook_extra_values( user, extra_data): +def facebook_extra_values(user, extra_data): try: - facebook_id = extra_data.get('id') - user.profile.facebook_id = facebook_id + user.profile.pic_url = extra_data['picture']['data']['url'] if user.profile.avatar_source is None or user.profile.avatar_source is PRIVATETAR: user.profile.avatar_source = FACEBOOK user.profile.save() return True - except Exception,e: - logger.error(e) - return False + except Exception, e: + logger.exception(e) + return -def twitter_extra_values( user, extra_data): +def twitter_extra_values(user, extra_data): try: twitter_id = extra_data.get('screen_name') profile_image_url = extra_data.get('profile_image_url_https') @@ -57,11 +55,11 @@ def twitter_extra_values( user, extra_data): logger.error(e) return False -def deliver_extra_data(backend, user, social, *args, **kwargs): +def deliver_extra_data(backend, user, social, response, *args, **kwargs): if backend.name is 'twitter': twitter_extra_values( user, social.extra_data) if backend.name is 'facebook': - facebook_extra_values( user, social.extra_data) + facebook_extra_values( user, response) # following is needed because of length limitations in a unique constrain for MySQL def chop_username(username, *args, **kwargs): @@ -98,7 +96,7 @@ def process_exception(self, request, exception): backend_name = getattr(backend, 'name', 'unknown-backend') message = self.get_message(request, exception) - social_logger.error(message) + logger.warning(message) url = self.get_redirect_uri(request, exception) url += ('?' in url and '&' or '?') + \ diff --git a/settings/common.py b/settings/common.py index 8dc750be0..aef82e98d 100644 --- a/settings/common.py +++ b/settings/common.py @@ -254,11 +254,13 @@ SOCIAL_AUTH_ENABLED_BACKENDS = ['google', 'facebook', 'twitter'] #SOCIAL_AUTH_ASSOCIATE_BY_MAIL = True SOCIAL_AUTH_NEW_USER_REDIRECT_URL = '/' -FACEBOOK_SOCIAL_AUTH_BACKEND_ERROR_URL = '/' SOCIAL_AUTH_SLUGIFY_USERNAMES = True SOCIAL_AUTH_NONCE_SERVER_URL_LENGTH = 200 SOCIAL_AUTH_ASSOCIATION_SERVER_URL_LENGTH = 135 SOCIAL_AUTH_ASSOCIATION_HANDLE_LENGTH = 125 +SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS = {'fields': 'picture'} +SOCIAL_AUTH_FACEBOOK_LOGIN_ERROR_URL = '/' +SOCIAL_AUTH_TWITTER_LOGIN_ERROR_URL = '/' SOCIAL_AUTH_PIPELINE = ( # Get the information we can about the user and return it in a simple From 5455c21d269abedcf65c6b1b91ad80589d458009 Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 20 Jul 2018 15:10:38 -0400 Subject: [PATCH 015/703] cleanup after the facebook changes --- core/management/commands/fix_avatars.py | 22 +++++++++++++++ .../commands/fix_twitter_avatars.py | 16 ----------- core/migrations/0015_auto_20180720_1413.py | 25 +++++++++++++++++ core/models/__init__.py | 5 ++-- frontend/forms/__init__.py | 14 ++-------- frontend/templates/supporter.html | 2 ++ libraryauth/auth.py | 27 +++++++++++++++++-- 7 files changed, 78 insertions(+), 33 deletions(-) create mode 100644 core/management/commands/fix_avatars.py delete mode 100644 core/management/commands/fix_twitter_avatars.py create mode 100644 core/migrations/0015_auto_20180720_1413.py diff --git a/core/management/commands/fix_avatars.py b/core/management/commands/fix_avatars.py new file mode 100644 index 000000000..f7d69f8d4 --- /dev/null +++ b/core/management/commands/fix_avatars.py @@ -0,0 +1,22 @@ +import string +from django.core.management.base import BaseCommand +from regluit.core.models import FACEBOOK, UNGLUEITAR +from regluit.libraryauth.auth import pic_storage_url + +from regluit.core import models + +class Command(BaseCommand): + help = "fix avatar urls and settings" + + def handle(self, **options): + for profile in models.UserProfile.objects.exclude(pic_url=''): + print "updating user %s" % profile.user + if not profile.pic_url.startswith('https://unglueit'): + profile.pic_url = pic_storage_url(profile.user, 'twitter', profile.pic_url) + profile.save() + for profile in models.UserProfile.objects.filter(avatar_source=FACEBOOK): + print "updating user %s" % profile.user + profile.facebook_id = '' + if not profile.pic_url: + profile.avatar_source = UNGLUEITAR + profile.save() diff --git a/core/management/commands/fix_twitter_avatars.py b/core/management/commands/fix_twitter_avatars.py deleted file mode 100644 index 520513093..000000000 --- a/core/management/commands/fix_twitter_avatars.py +++ /dev/null @@ -1,16 +0,0 @@ -import string -from django.core.management.base import BaseCommand -from regluit.core.models import TWITTER - -from regluit.core import models - -class Command(BaseCommand): - help = "fix old twitter avatar urls" - - def handle(self, **options): - print "Number of users affected with : %s" % models.UserProfile.objects.filter( pic_url__contains='//si0.twimg.com').count() - - for profile in models.UserProfile.objects.filter(pic_url__contains='//si0.twimg.com'): - print "updating user %s" % profile.user - profile.pic_url = string.replace( profile.pic_url, '//si0.twimg.com','//pbs.twimg.com') - profile.save() diff --git a/core/migrations/0015_auto_20180720_1413.py b/core/migrations/0015_auto_20180720_1413.py new file mode 100644 index 000000000..e9bf39bfc --- /dev/null +++ b/core/migrations/0015_auto_20180720_1413.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0014_auto_20180618_1646'), + ] + + operations = [ + migrations.AlterField( + model_name='userprofile', + name='avatar_source', + field=models.PositiveSmallIntegerField(default=4, null=True, choices=[(0, b'No Avatar, Please'), (1, b'Gravatar'), (2, b'Twitter/Facebook'), (4, b'Unglueitar')]), + ), + migrations.AlterField( + model_name='userprofile', + name='facebook_id', + field=models.CharField(default='', max_length=31, blank=True), + preserve_default=False, + ), + ] diff --git a/core/models/__init__.py b/core/models/__init__.py index 1641b61a4..76de86dcd 100755 --- a/core/models/__init__.py +++ b/core/models/__init__.py @@ -1163,7 +1163,7 @@ class UserProfile(models.Model): pic_url = models.URLField(blank=True) home_url = models.URLField(blank=True) twitter_id = models.CharField(max_length=15, blank=True) - facebook_id = models.BigIntegerField(null=True, blank=True) + facebook_id = models.CharField(max_length=31, blank=True) librarything_id = models.CharField(max_length=31, blank=True) badges = models.ManyToManyField('Badge', related_name='holders', blank=True) kindle_email = models.EmailField(max_length=254, blank=True) @@ -1183,8 +1183,7 @@ class UserProfile(models.Model): choices=( (NO_AVATAR, 'No Avatar, Please'), (GRAVATAR, 'Gravatar'), - (TWITTER, 'Twitter'), - (FACEBOOK, 'Facebook'), + (TWITTER, 'Twitter/Facebook'), (UNGLUEITAR, 'Unglueitar'), ) ) diff --git a/frontend/forms/__init__.py b/frontend/forms/__init__.py index 64233dea3..050bb9e0a 100644 --- a/frontend/forms/__init__.py +++ b/frontend/forms/__init__.py @@ -188,7 +188,7 @@ class ProfileForm(forms.ModelForm): class Meta: model = UserProfile - fields = 'tagline', 'librarything_id', 'home_url', 'clear_facebook', 'clear_twitter', 'clear_goodreads', 'avatar_source' + fields = 'tagline', 'librarything_id', 'facebook_id', 'home_url', 'clear_facebook', 'clear_twitter', 'clear_goodreads', 'avatar_source' widgets = { 'tagline': forms.Textarea(attrs={'rows': 5, 'onKeyUp': "counter(this, 140)", 'onBlur': "counter(this, 140)"}), } @@ -198,22 +198,12 @@ def __init__(self, *args, **kwargs): super(ProfileForm, self).__init__(*args, **kwargs) choices = [] for choice in self.fields['avatar_source'].choices : - if choice[0] == FACEBOOK and not profile.facebook_id: - pass - elif choice[0] == TWITTER and not profile.twitter_id: + if choice[0] == TWITTER and not profile.pic_url: pass else: choices.append(choice) self.fields['avatar_source'].choices = choices - def clean(self): - # check that if a social net is cleared, we're not using it a avatar source - if self.cleaned_data.get("clear_facebook", False) and self.cleaned_data.get("avatar_source", None) == FACEBOOK: - self.cleaned_data["avatar_source"] == UNGLUEITAR - if self.cleaned_data.get("clear_twitter", False) and self.cleaned_data.get("avatar_source", None) == TWITTER: - self.cleaned_data["avatar_source"] == UNGLUEITAR - return self.cleaned_data - def getTransferCreditForm(maximum, data=None, *args, **kwargs ): class TransferCreditForm(forms.Form): recipient = AutoCompleteSelectField( diff --git a/frontend/templates/supporter.html b/frontend/templates/supporter.html index a533e3ca4..674c8c518 100644 --- a/frontend/templates/supporter.html +++ b/frontend/templates/supporter.html @@ -197,6 +197,8 @@

Your Links

{% else %} Connect your Facebook account to Unglue.it {% endif %} + + {{ profile_form.facebook_id }}{{ profile_form.facebook_id.errors }}
{% if user.profile.goodreads_user_id %} diff --git a/libraryauth/auth.py b/libraryauth/auth.py index bd337f1f3..9ee036c31 100644 --- a/libraryauth/auth.py +++ b/libraryauth/auth.py @@ -1,9 +1,12 @@ import logging +import requests from django.http import HttpResponse from django.shortcuts import redirect from django.utils.http import urlquote +from django.core.files.base import ContentFile +from django.core.files.storage import default_storage from social_core.pipeline.social_auth import associate_by_email from social_django.models import UserSocialAuth from social_django.middleware import SocialAuthExceptionMiddleware @@ -12,8 +15,27 @@ ANONYMOUS_AVATAR = '/static/images/header/avatar.png' (NO_AVATAR, GRAVATAR, TWITTER, FACEBOOK, PRIVATETAR) = (0, 1, 2, 3, 4) AVATARS = (NO_AVATAR, GRAVATAR, TWITTER, FACEBOOK, PRIVATETAR) + logger = logging.getLogger(__name__) +def pic_storage_url(user, backend, url): + pic_file_name = '/pic/{}/{}'.format(backend, user) + # download cover image to cover_file + try: + r = requests.get(url) + pic_file = ContentFile(r.content) + content_type = r.headers.get('content-type', '') + if u'text' in content_type: + logger.warning('Cover return text for pic_url={}'.format(pic_url)) + return None + pic_file.content_type = content_type + default_storage.save(pic_file_name, pic_file) + return default_storage.url(pic_file_name) + except Exception, e: + # if there is a problem, return None for cover URL + logger.warning('Failed to store cover for username={}'.format(user)) + return None + def selectively_associate_by_email(backend, details, user=None, *args, **kwargs): """ @@ -31,7 +53,8 @@ def selectively_associate_by_email(backend, details, user=None, *args, **kwargs) def facebook_extra_values(user, extra_data): try: - user.profile.pic_url = extra_data['picture']['data']['url'] + profile_image_url = extra_data['picture']['data']['url'] + user.profile.pic_url = pic_storage_url(user, 'facebook', profile_image_url) if user.profile.avatar_source is None or user.profile.avatar_source is PRIVATETAR: user.profile.avatar_source = FACEBOOK user.profile.save() @@ -46,7 +69,7 @@ def twitter_extra_values(user, extra_data): profile_image_url = extra_data.get('profile_image_url_https') user.profile.twitter_id = twitter_id if user.profile.avatar_source is None or user.profile.avatar_source in (TWITTER, PRIVATETAR): - user.profile.pic_url = profile_image_url + user.profile.pic_url = pic_storage_url(user, 'twitter', profile_image_url) if user.profile.avatar_source is None or user.profile.avatar_source is PRIVATETAR: user.profile.avatar_source = TWITTER user.profile.save() From 456a341885e014ce72f03215b0823479ad147f88 Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 20 Jul 2018 15:23:14 -0400 Subject: [PATCH 016/703] fix test fixture --- core/fixtures/basic_campaign_test.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/fixtures/basic_campaign_test.json b/core/fixtures/basic_campaign_test.json index cdc498a22..9617386b8 100644 --- a/core/fixtures/basic_campaign_test.json +++ b/core/fixtures/basic_campaign_test.json @@ -65,7 +65,7 @@ "goodreads_auth_token": null, "goodreads_user_link": null, "user": 1, - "facebook_id": null, + "facebook_id": "", "librarything_id": "", "home_url": "", "pic_url": "", @@ -85,7 +85,7 @@ "goodreads_auth_token": null, "goodreads_user_link": null, "user": 2, - "facebook_id": null, + "facebook_id": "", "librarything_id": "", "home_url": "", "pic_url": "", @@ -105,7 +105,7 @@ "goodreads_auth_token": null, "goodreads_user_link": null, "user": 3, - "facebook_id": null, + "facebook_id": "", "librarything_id": "", "home_url": "", "pic_url": "", From 725f616811394e3d5c38f4b77c9e6fd3936fb7e0 Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 20 Jul 2018 15:41:48 -0400 Subject: [PATCH 017/703] privacy updates --- frontend/templates/privacy.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/templates/privacy.html b/frontend/templates/privacy.html index 8c45a10a2..ac0b3d6d6 100644 --- a/frontend/templates/privacy.html +++ b/frontend/templates/privacy.html @@ -86,7 +86,7 @@

Other people we allow to spy on you.

  • -We use avatar images from Twitter, Facebook, and Automattic's Gravatar service. If you see an avatar on a page at unglue.it and you use an older web browser that doesn't use Referrer meta tags, one or more of these companies can tell what page on our site you're looking at. As you're probably aware, facebook doesn't put much stock in privacy. You can judge privacy policies at Twitter and Automattic for yourself. +We use avatar images from Automattic's Gravatar service. If you see an avatar on a page at unglue.it and you use an older web browser that doesn't use Referrer meta tags, Automattic can tell what page on our site you're looking at. You can judge the privacy policy at Automattic for yourself. We no longer use images from Facebook or Twitter services.
  • From b35aa2ce933c86bfb74d08ab252af06890963cf8 Mon Sep 17 00:00:00 2001 From: eric Date: Sun, 22 Jul 2018 13:14:27 -0400 Subject: [PATCH 018/703] fix test failures for django 1.10.8 --- context_processors.py | 27 +++++++++++++++++---------- core/loaders/utils.py | 3 +++ core/models/__init__.py | 4 ++-- libraryauth/models.py | 2 +- requirements_versioned.pip | 9 +++++---- 5 files changed, 28 insertions(+), 17 deletions(-) diff --git a/context_processors.py b/context_processors.py index 02db6a844..20bb0a7c8 100644 --- a/context_processors.py +++ b/context_processors.py @@ -1,12 +1,19 @@ def is_preview(request): - from django.conf import settings - return {'jquery_home': settings.JQUERY_HOME, 'jquery_ui_home': settings.JQUERY_UI_HOME, 'is_preview': settings.IS_PREVIEW, 'show_google_analytics': settings.SHOW_GOOGLE_ANALYTICS} - + from django.conf import settings + return { + 'jquery_home': settings.JQUERY_HOME, + 'jquery_ui_home': settings.JQUERY_UI_HOME, + 'is_preview': settings.IS_PREVIEW, + 'show_google_analytics': settings.SHOW_GOOGLE_ANALYTICS + } + def count_unseen(request): - - if request.user.is_anonymous(): - count = 0 - else: - from notification.models import Notice - count = Notice.objects.unseen_count_for(request.user) - return {'unseen_count': count} \ No newline at end of file + try: + if request.user.is_anonymous(): + count = 0 + else: + from notification.models import Notice + count = Notice.objects.unseen_count_for(request.user) + except AttributeError: + count = 0 + return {'unseen_count': count} \ No newline at end of file diff --git a/core/loaders/utils.py b/core/loaders/utils.py index f559870d1..02825fe8c 100644 --- a/core/loaders/utils.py +++ b/core/loaders/utils.py @@ -375,6 +375,9 @@ def dl_online(ebook): if ebook.format != 'online': pass elif ebook.url.find(u'dropbox.com/s/') >= 0: + if ebook.url.find(u'dl=0') >= 0: + dl_url = ebook.url.replace(u'dl=0', u'dl=1') + return make_dl_ebook(dl_url, ebook) response = requests.get(ebook.url, headers={"User-Agent": settings.USER_AGENT}) if response.status_code == 200: match_dl = DROPBOX_DL.search(response.content) diff --git a/core/models/__init__.py b/core/models/__init__.py index 76de86dcd..6e6702c84 100755 --- a/core/models/__init__.py +++ b/core/models/__init__.py @@ -391,7 +391,7 @@ class Campaign(models.Model): paypal_receiver = models.CharField(max_length=100, blank=True) amazon_receiver = models.CharField(max_length=100, blank=True) work = models.ForeignKey("Work", related_name="campaigns", null=False) - managers = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name="campaigns", null=False) + managers = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name="campaigns") # status: INITIALIZED, ACTIVE, SUSPENDED, WITHDRAWN, SUCCESSFUL, UNSUCCESSFUL status = models.CharField( max_length=15, null=True, blank=False, default="INITIALIZED", db_index=True, choices=STATUS_CHOICES) @@ -1034,7 +1034,7 @@ def make_unglued_ebf(self, format, watermarked): rights=self.license, provider="Unglue.it", url=settings.BASE_URL_SECURE + reverse('download_campaign', args=[self.work_id, format]), - version='unglued', + version_label='unglued', ) old_ebooks = Ebook.objects.exclude(pk=ebook.pk).filter( edition=self.work.preferred_edition, diff --git a/libraryauth/models.py b/libraryauth/models.py index 527c2a82d..1a14fc61b 100644 --- a/libraryauth/models.py +++ b/libraryauth/models.py @@ -178,7 +178,6 @@ def to_python(self, value): code='invalid') class IPAddressModelField(models.GenericIPAddressField): - __metaclass__ = models.SubfieldBase empty_strings_allowed = False def __init__(self, *args, **kwargs): @@ -211,6 +210,7 @@ def deconstruct(self): name, path, args, kwargs = super(models.GenericIPAddressField, self).deconstruct() return name, path, args, kwargs + class Block(models.Model): library = models.ForeignKey(Library, related_name='ip_auths') lower = IPAddressModelField(db_index=True, unique=True) diff --git a/requirements_versioned.pip b/requirements_versioned.pip index e0916ca3e..405de45d6 100644 --- a/requirements_versioned.pip +++ b/requirements_versioned.pip @@ -1,4 +1,5 @@ Django==1.8.14 +#Django==1.10.8 Fabric==1.6.0 MySQL-python==1.2.5 Pillow==3.4.2 @@ -21,17 +22,17 @@ chardet==3.0.4 django-celery==3.1.17 django-ckeditor==4.5.1 #django-email-change==0.2.3 -git+git://github.com/eshellman/django-email-change.git@57169bdef1c8a41d122e2bab2dcd8564b8fb231d -django-compat==1.0.10 +git+git://github.com/eshellman/django-email-change.git@87cd33bb7467b6203986d7d5763e2699155cedd4 +django-compat==1.0.15 django-contrib-comments==1.7.1 django-el-pagination==3.2.4 django-extensions==1.6.1 django-jsonfield==1.0.0 #django-kombu==0.9.4 django-maintenancemode==0.11.2 -django-mptt==0.8.5 +django-mptt==0.8.6 #django-notification==0.2 -git+git://github.com/eshellman/django-notification.git@a4620e893e2da220994e0189bf5d980bfbdcf0ad +git+git://github.com/eshellman/django-notification.git@2768cf4863b152e5f9347660bb0b1d8fd1f972b2 django-registration==2.1.2 django-selectable==0.9.0 django-smtp-ssl==1.0 From 147822b2a5851eaa6c42a50ca4af8a35011e3ae9 Mon Sep 17 00:00:00 2001 From: eric Date: Mon, 23 Jul 2018 10:02:03 -0400 Subject: [PATCH 019/703] update dj selectable Also put jquery-ui-theme in settings --- context_processors.py | 1 + frontend/templates/agreed.html | 2 +- frontend/templates/campaign_admin.html | 2 +- frontend/templates/edit_edition.html | 2 +- frontend/templates/gift.html | 2 +- frontend/templates/libraryauth/edit.html | 2 +- frontend/templates/manage_ebooks.html | 2 +- frontend/templates/map_subject.html | 2 +- frontend/templates/marc/upload.html | 2 +- frontend/templates/merge.html | 2 +- frontend/templates/new_edition.html | 2 +- frontend/templates/rh_agree.html | 2 +- frontend/templates/rh_tools.html | 2 +- frontend/templates/rights_holders.html | 2 +- frontend/templates/work.html | 3 ++- requirements_versioned.pip | 2 +- settings/common.py | 5 +++-- static/css/ui-lightness/jquery-ui-1.11.4.min.css | 7 +++++++ static/js/jquery-1.12.4.min.js | 5 +++++ static/js/jquery-ui-1.12.1.custom.min.js | 13 +++++++++++++ 20 files changed, 45 insertions(+), 17 deletions(-) create mode 100644 static/css/ui-lightness/jquery-ui-1.11.4.min.css create mode 100644 static/js/jquery-1.12.4.min.js create mode 100644 static/js/jquery-ui-1.12.1.custom.min.js diff --git a/context_processors.py b/context_processors.py index 20bb0a7c8..62a56d474 100644 --- a/context_processors.py +++ b/context_processors.py @@ -3,6 +3,7 @@ def is_preview(request): return { 'jquery_home': settings.JQUERY_HOME, 'jquery_ui_home': settings.JQUERY_UI_HOME, + 'jquery_ui_theme': settings.JQUERY_UI_THEME, 'is_preview': settings.IS_PREVIEW, 'show_google_analytics': settings.SHOW_GOOGLE_ANALYTICS } diff --git a/frontend/templates/agreed.html b/frontend/templates/agreed.html index f2d8535b0..4b16772b1 100644 --- a/frontend/templates/agreed.html +++ b/frontend/templates/agreed.html @@ -3,7 +3,7 @@ {% block title %} Agreement Submitted {% endblock %} {% block extra_extra_head %} {{ block.super }} - + {% endblock %} diff --git a/frontend/templates/campaign_admin.html b/frontend/templates/campaign_admin.html index 8af3f5034..b1e6cf4aa 100644 --- a/frontend/templates/campaign_admin.html +++ b/frontend/templates/campaign_admin.html @@ -2,7 +2,7 @@ {% block extra_extra_head %} {{ block.super }} - + {{ form.media.css }} {{ form.media.js }} diff --git a/frontend/templates/edit_edition.html b/frontend/templates/edit_edition.html index 21a457e73..c7a471092 100644 --- a/frontend/templates/edit_edition.html +++ b/frontend/templates/edit_edition.html @@ -3,7 +3,7 @@ {% block extra_extra_head %} {{ block.super }} - + ").appendTo(a)),o.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",o.opacity)),o.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",o.zIndex)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(n=this.containers.length-1;n>=0;n--)this.containers[n]._trigger("activate",t,this._uiHash(this));return e.ui.ddmanager&&(e.ui.ddmanager.current=this),e.ui.ddmanager&&!o.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this._addClass(this.helper,"ui-sortable-helper"),this._mouseDrag(t),!0},_mouseDrag:function(t){var i,s,n,a,o=this.options,r=!1;for(this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageY=0;i--)if(s=this.items[i],n=s.item[0],a=this._intersectsWithPointer(s),a&&s.instance===this.currentContainer&&n!==this.currentItem[0]&&this.placeholder[1===a?"next":"prev"]()[0]!==n&&!e.contains(this.placeholder[0],n)&&("semi-dynamic"===this.options.type?!e.contains(this.element[0],n):!0)){if(this.direction=1===a?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(t,s),this._trigger("change",t,this._uiHash());break}return this._contactContainers(t),e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),this._trigger("sort",t,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(t,i){if(t){if(e.ui.ddmanager&&!this.options.dropBehaviour&&e.ui.ddmanager.drop(this,t),this.options.revert){var s=this,n=this.placeholder.offset(),a=this.options.axis,o={};a&&"x"!==a||(o.left=n.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollLeft)),a&&"y"!==a||(o.top=n.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,e(this.helper).animate(o,parseInt(this.options.revert,10)||500,function(){s._clear(t)})}else this._clear(t,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp(new e.Event("mouseup",{target:null})),"original"===this.options.helper?(this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")):this.currentItem.show();for(var t=this.containers.length-1;t>=0;t--)this.containers[t]._trigger("deactivate",null,this._uiHash(this)),this.containers[t].containerCache.over&&(this.containers[t]._trigger("out",null,this._uiHash(this)),this.containers[t].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),e.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?e(this.domPosition.prev).after(this.currentItem):e(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(t){var i=this._getItemsAsjQuery(t&&t.connected),s=[];return t=t||{},e(i).each(function(){var i=(e(t.item||this).attr(t.attribute||"id")||"").match(t.expression||/(.+)[\-=_](.+)/);i&&s.push((t.key||i[1]+"[]")+"="+(t.key&&t.expression?i[1]:i[2]))}),!s.length&&t.key&&s.push(t.key+"="),s.join("&")},toArray:function(t){var i=this._getItemsAsjQuery(t&&t.connected),s=[];return t=t||{},i.each(function(){s.push(e(t.item||this).attr(t.attribute||"id")||"")}),s},_intersectsWith:function(e){var t=this.positionAbs.left,i=t+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,a=e.left,o=a+e.width,r=e.top,h=r+e.height,l=this.offset.click.top,u=this.offset.click.left,c="x"===this.options.axis||s+l>r&&h>s+l,d="y"===this.options.axis||t+u>a&&o>t+u,p=c&&d;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>e[this.floating?"width":"height"]?p:t+this.helperProportions.width/2>a&&o>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>r&&h>n-this.helperProportions.height/2},_intersectsWithPointer:function(e){var t,i,s="x"===this.options.axis||this._isOverAxis(this.positionAbs.top+this.offset.click.top,e.top,e.height),n="y"===this.options.axis||this._isOverAxis(this.positionAbs.left+this.offset.click.left,e.left,e.width),a=s&&n;return a?(t=this._getDragVerticalDirection(),i=this._getDragHorizontalDirection(),this.floating?"right"===i||"down"===t?2:1:t&&("down"===t?2:1)):!1},_intersectsWithSides:function(e){var t=this._isOverAxis(this.positionAbs.top+this.offset.click.top,e.top+e.height/2,e.height),i=this._isOverAxis(this.positionAbs.left+this.offset.click.left,e.left+e.width/2,e.width),s=this._getDragVerticalDirection(),n=this._getDragHorizontalDirection();return this.floating&&n?"right"===n&&i||"left"===n&&!i:s&&("down"===s&&t||"up"===s&&!t)},_getDragVerticalDirection:function(){var e=this.positionAbs.top-this.lastPositionAbs.top;return 0!==e&&(e>0?"down":"up")},_getDragHorizontalDirection:function(){var e=this.positionAbs.left-this.lastPositionAbs.left;return 0!==e&&(e>0?"right":"left")},refresh:function(e){return this._refreshItems(e),this._setHandleClassName(),this.refreshPositions(),this},_connectWith:function(){var e=this.options;return e.connectWith.constructor===String?[e.connectWith]:e.connectWith},_getItemsAsjQuery:function(t){function i(){r.push(this)}var s,n,a,o,r=[],h=[],l=this._connectWith();if(l&&t)for(s=l.length-1;s>=0;s--)for(a=e(l[s],this.document[0]),n=a.length-1;n>=0;n--)o=e.data(a[n],this.widgetFullName),o&&o!==this&&!o.options.disabled&&h.push([e.isFunction(o.options.items)?o.options.items.call(o.element):e(o.options.items,o.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),o]);for(h.push([e.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):e(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),s=h.length-1;s>=0;s--)h[s][0].each(i);return e(r)},_removeCurrentsFromItems:function(){var t=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=e.grep(this.items,function(e){for(var i=0;t.length>i;i++)if(t[i]===e.item[0])return!1;return!0})},_refreshItems:function(t){this.items=[],this.containers=[this];var i,s,n,a,o,r,h,l,u=this.items,c=[[e.isFunction(this.options.items)?this.options.items.call(this.element[0],t,{item:this.currentItem}):e(this.options.items,this.element),this]],d=this._connectWith();if(d&&this.ready)for(i=d.length-1;i>=0;i--)for(n=e(d[i],this.document[0]),s=n.length-1;s>=0;s--)a=e.data(n[s],this.widgetFullName),a&&a!==this&&!a.options.disabled&&(c.push([e.isFunction(a.options.items)?a.options.items.call(a.element[0],t,{item:this.currentItem}):e(a.options.items,a.element),a]),this.containers.push(a));for(i=c.length-1;i>=0;i--)for(o=c[i][1],r=c[i][0],s=0,l=r.length;l>s;s++)h=e(r[s]),h.data(this.widgetName+"-item",o),u.push({item:h,instance:o,width:0,height:0,left:0,top:0})},refreshPositions:function(t){this.floating=this.items.length?"x"===this.options.axis||this._isFloating(this.items[0].item):!1,this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,n,a;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(n=this.options.toleranceElement?e(this.options.toleranceElement,s.item):s.item,t||(s.width=n.outerWidth(),s.height=n.outerHeight()),a=n.offset(),s.left=a.left,s.top=a.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)a=this.containers[i].element.offset(),this.containers[i].containerCache.left=a.left,this.containers[i].containerCache.top=a.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(t){t=t||this;var i,s=t.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=t.currentItem[0].nodeName.toLowerCase(),n=e("<"+s+">",t.document[0]);return t._addClass(n,"ui-sortable-placeholder",i||t.currentItem[0].className)._removeClass(n,"ui-sortable-helper"),"tbody"===s?t._createTrPlaceholder(t.currentItem.find("tr").eq(0),e("",t.document[0]).appendTo(n)):"tr"===s?t._createTrPlaceholder(t.currentItem,n):"img"===s&&n.attr("src",t.currentItem.attr("src")),i||n.css("visibility","hidden"),n},update:function(e,n){(!i||s.forcePlaceholderSize)&&(n.height()||n.height(t.currentItem.innerHeight()-parseInt(t.currentItem.css("paddingTop")||0,10)-parseInt(t.currentItem.css("paddingBottom")||0,10)),n.width()||n.width(t.currentItem.innerWidth()-parseInt(t.currentItem.css("paddingLeft")||0,10)-parseInt(t.currentItem.css("paddingRight")||0,10)))}}),t.placeholder=e(s.placeholder.element.call(t.element,t.currentItem)),t.currentItem.after(t.placeholder),s.placeholder.update(t,t.placeholder)},_createTrPlaceholder:function(t,i){var s=this;t.children().each(function(){e(" ",s.document[0]).attr("colspan",e(this).attr("colspan")||1).appendTo(i)})},_contactContainers:function(t){var i,s,n,a,o,r,h,l,u,c,d=null,p=null;for(i=this.containers.length-1;i>=0;i--)if(!e.contains(this.currentItem[0],this.containers[i].element[0]))if(this._intersectsWith(this.containers[i].containerCache)){if(d&&e.contains(this.containers[i].element[0],d.element[0]))continue;d=this.containers[i],p=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",t,this._uiHash(this)),this.containers[i].containerCache.over=0);if(d)if(1===this.containers.length)this.containers[p].containerCache.over||(this.containers[p]._trigger("over",t,this._uiHash(this)),this.containers[p].containerCache.over=1);else{for(n=1e4,a=null,u=d.floating||this._isFloating(this.currentItem),o=u?"left":"top",r=u?"width":"height",c=u?"pageX":"pageY",s=this.items.length-1;s>=0;s--)e.contains(this.containers[p].element[0],this.items[s].item[0])&&this.items[s].item[0]!==this.currentItem[0]&&(h=this.items[s].item.offset()[o],l=!1,t[c]-h>this.items[s][r]/2&&(l=!0),n>Math.abs(t[c]-h)&&(n=Math.abs(t[c]-h),a=this.items[s],this.direction=l?"up":"down"));if(!a&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[p])return this.currentContainer.containerCache.over||(this.containers[p]._trigger("over",t,this._uiHash()),this.currentContainer.containerCache.over=1),void 0;a?this._rearrange(t,a,null,!0):this._rearrange(t,null,this.containers[p].element,!0),this._trigger("change",t,this._uiHash()),this.containers[p]._trigger("change",t,this._uiHash(this)),this.currentContainer=this.containers[p],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[p]._trigger("over",t,this._uiHash(this)),this.containers[p].containerCache.over=1}},_createHelper:function(t){var i=this.options,s=e.isFunction(i.helper)?e(i.helper.apply(this.element[0],[t,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||e("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(t){"string"==typeof t&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==this.document[0]&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===this.document[0].body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&e.ui.ie)&&(t={top:0,left:0}),{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var e=this.currentItem.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,i,s,n=this.options;"parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,"document"===n.containment?this.document.width():this.window.width()-this.helperProportions.width-this.margins.left,("document"===n.containment?this.document.height()||document.body.parentNode.scrollHeight:this.window.height()||this.document[0].body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||(t=e(n.containment)[0],i=e(n.containment).offset(),s="hidden"!==e(t).css("overflow"),this.containment=[i.left+(parseInt(e(t).css("borderLeftWidth"),10)||0)+(parseInt(e(t).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(e(t).css("borderTopWidth"),10)||0)+(parseInt(e(t).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(t.scrollWidth,t.offsetWidth):t.offsetWidth)-(parseInt(e(t).css("borderLeftWidth"),10)||0)-(parseInt(e(t).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(t.scrollHeight,t.offsetHeight):t.offsetHeight)-(parseInt(e(t).css("borderTopWidth"),10)||0)-(parseInt(e(t).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(t,i){i||(i=this.position);var s="absolute"===t?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,a=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():a?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():a?0:n.scrollLeft())*s}},_generatePosition:function(t){var i,s,n=this.options,a=t.pageX,o=t.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(t.pageX-this.offset.click.leftthis.containment[2]&&(a=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(o=this.containment[3]+this.offset.click.top)),n.grid&&(i=this.originalPageY+Math.round((o-this.originalPageY)/n.grid[1])*n.grid[1],o=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-n.grid[1]:i+n.grid[1]:i,s=this.originalPageX+Math.round((a-this.originalPageX)/n.grid[0])*n.grid[0],a=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-n.grid[0]:s+n.grid[0]:s)),{top:o-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:r.scrollTop()),left:a-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:r.scrollLeft())}},_rearrange:function(e,t,i,s){i?i[0].appendChild(this.placeholder[0]):t.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?t.item[0]:t.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(e,t){function i(e,t,i){return function(s){i._trigger(e,s,t._uiHash(t))}}this.reverting=!1;var s,n=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(s in this._storedCSS)("auto"===this._storedCSS[s]||"static"===this._storedCSS[s])&&(this._storedCSS[s]="");this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!t&&n.push(function(e){this._trigger("receive",e,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||t||n.push(function(e){this._trigger("update",e,this._uiHash())}),this!==this.currentContainer&&(t||(n.push(function(e){this._trigger("remove",e,this._uiHash())}),n.push(function(e){return function(t){e._trigger("receive",t,this._uiHash(this))}}.call(this,this.currentContainer)),n.push(function(e){return function(t){e._trigger("update",t,this._uiHash(this))}}.call(this,this.currentContainer)))),s=this.containers.length-1;s>=0;s--)t||n.push(i("deactivate",this,this.containers[s])),this.containers[s].containerCache.over&&(n.push(i("out",this,this.containers[s])),this.containers[s].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,t||this._trigger("beforeStop",e,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!t){for(s=0;n.length>s;s++)n[s].call(this,e);this._trigger("stop",e,this._uiHash())}return this.fromOutside=!1,!this.cancelHelperRemoval},_trigger:function(){e.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(t){var i=t||this;return{helper:i.helper,placeholder:i.placeholder||e([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:t?t.element:null}}}),e.widget("ui.accordion",{version:"1.12.1",options:{active:0,animate:{},classes:{"ui-accordion-header":"ui-corner-top","ui-accordion-header-collapsed":"ui-corner-all","ui-accordion-content":"ui-corner-bottom"},collapsible:!1,event:"click",header:"> li > :first-child, > :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},hideProps:{borderTopWidth:"hide",borderBottomWidth:"hide",paddingTop:"hide",paddingBottom:"hide",height:"hide"},showProps:{borderTopWidth:"show",borderBottomWidth:"show",paddingTop:"show",paddingBottom:"show",height:"show"},_create:function(){var t=this.options;this.prevShow=this.prevHide=e(),this._addClass("ui-accordion","ui-widget ui-helper-reset"),this.element.attr("role","tablist"),t.collapsible||t.active!==!1&&null!=t.active||(t.active=0),this._processPanels(),0>t.active&&(t.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():e()}},_createIcons:function(){var t,i,s=this.options.icons;s&&(t=e(""),this._addClass(t,"ui-accordion-header-icon","ui-icon "+s.header),t.prependTo(this.headers),i=this.active.children(".ui-accordion-header-icon"),this._removeClass(i,s.header)._addClass(i,null,s.activeHeader)._addClass(this.headers,"ui-accordion-icons")) +},_destroyIcons:function(){this._removeClass(this.headers,"ui-accordion-icons"),this.headers.children(".ui-accordion-header-icon").remove()},_destroy:function(){var e;this.element.removeAttr("role"),this.headers.removeAttr("role aria-expanded aria-selected aria-controls tabIndex").removeUniqueId(),this._destroyIcons(),e=this.headers.next().css("display","").removeAttr("role aria-hidden aria-labelledby").removeUniqueId(),"content"!==this.options.heightStyle&&e.css("height","")},_setOption:function(e,t){return"active"===e?(this._activate(t),void 0):("event"===e&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(t)),this._super(e,t),"collapsible"!==e||t||this.options.active!==!1||this._activate(0),"icons"===e&&(this._destroyIcons(),t&&this._createIcons()),void 0)},_setOptionDisabled:function(e){this._super(e),this.element.attr("aria-disabled",e),this._toggleClass(null,"ui-state-disabled",!!e),this._toggleClass(this.headers.add(this.headers.next()),null,"ui-state-disabled",!!e)},_keydown:function(t){if(!t.altKey&&!t.ctrlKey){var i=e.ui.keyCode,s=this.headers.length,n=this.headers.index(t.target),a=!1;switch(t.keyCode){case i.RIGHT:case i.DOWN:a=this.headers[(n+1)%s];break;case i.LEFT:case i.UP:a=this.headers[(n-1+s)%s];break;case i.SPACE:case i.ENTER:this._eventHandler(t);break;case i.HOME:a=this.headers[0];break;case i.END:a=this.headers[s-1]}a&&(e(t.target).attr("tabIndex",-1),e(a).attr("tabIndex",0),e(a).trigger("focus"),t.preventDefault())}},_panelKeyDown:function(t){t.keyCode===e.ui.keyCode.UP&&t.ctrlKey&&e(t.currentTarget).prev().trigger("focus")},refresh:function(){var t=this.options;this._processPanels(),t.active===!1&&t.collapsible===!0||!this.headers.length?(t.active=!1,this.active=e()):t.active===!1?this._activate(0):this.active.length&&!e.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(t.active=!1,this.active=e()):this._activate(Math.max(0,t.active-1)):t.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){var e=this.headers,t=this.panels;this.headers=this.element.find(this.options.header),this._addClass(this.headers,"ui-accordion-header ui-accordion-header-collapsed","ui-state-default"),this.panels=this.headers.next().filter(":not(.ui-accordion-content-active)").hide(),this._addClass(this.panels,"ui-accordion-content","ui-helper-reset ui-widget-content"),t&&(this._off(e.not(this.headers)),this._off(t.not(this.panels)))},_refresh:function(){var t,i=this.options,s=i.heightStyle,n=this.element.parent();this.active=this._findActive(i.active),this._addClass(this.active,"ui-accordion-header-active","ui-state-active")._removeClass(this.active,"ui-accordion-header-collapsed"),this._addClass(this.active.next(),"ui-accordion-content-active"),this.active.next().show(),this.headers.attr("role","tab").each(function(){var t=e(this),i=t.uniqueId().attr("id"),s=t.next(),n=s.uniqueId().attr("id");t.attr("aria-controls",n),s.attr("aria-labelledby",i)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}).next().attr({"aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}).next().attr({"aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(i.event),"fill"===s?(t=n.height(),this.element.siblings(":visible").each(function(){var i=e(this),s=i.css("position");"absolute"!==s&&"fixed"!==s&&(t-=i.outerHeight(!0))}),this.headers.each(function(){t-=e(this).outerHeight(!0)}),this.headers.next().each(function(){e(this).height(Math.max(0,t-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):"auto"===s&&(t=0,this.headers.next().each(function(){var i=e(this).is(":visible");i||e(this).show(),t=Math.max(t,e(this).css("height","").height()),i||e(this).hide()}).height(t))},_activate:function(t){var i=this._findActive(t)[0];i!==this.active[0]&&(i=i||this.active[0],this._eventHandler({target:i,currentTarget:i,preventDefault:e.noop}))},_findActive:function(t){return"number"==typeof t?this.headers.eq(t):e()},_setupEvents:function(t){var i={keydown:"_keydown"};t&&e.each(t.split(" "),function(e,t){i[t]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(t){var i,s,n=this.options,a=this.active,o=e(t.currentTarget),r=o[0]===a[0],h=r&&n.collapsible,l=h?e():o.next(),u=a.next(),c={oldHeader:a,oldPanel:u,newHeader:h?e():o,newPanel:l};t.preventDefault(),r&&!n.collapsible||this._trigger("beforeActivate",t,c)===!1||(n.active=h?!1:this.headers.index(o),this.active=r?e():o,this._toggle(c),this._removeClass(a,"ui-accordion-header-active","ui-state-active"),n.icons&&(i=a.children(".ui-accordion-header-icon"),this._removeClass(i,null,n.icons.activeHeader)._addClass(i,null,n.icons.header)),r||(this._removeClass(o,"ui-accordion-header-collapsed")._addClass(o,"ui-accordion-header-active","ui-state-active"),n.icons&&(s=o.children(".ui-accordion-header-icon"),this._removeClass(s,null,n.icons.header)._addClass(s,null,n.icons.activeHeader)),this._addClass(o.next(),"ui-accordion-content-active")))},_toggle:function(t){var i=t.newPanel,s=this.prevShow.length?this.prevShow:t.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=i,this.prevHide=s,this.options.animate?this._animate(i,s,t):(s.hide(),i.show(),this._toggleComplete(t)),s.attr({"aria-hidden":"true"}),s.prev().attr({"aria-selected":"false","aria-expanded":"false"}),i.length&&s.length?s.prev().attr({tabIndex:-1,"aria-expanded":"false"}):i.length&&this.headers.filter(function(){return 0===parseInt(e(this).attr("tabIndex"),10)}).attr("tabIndex",-1),i.attr("aria-hidden","false").prev().attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_animate:function(e,t,i){var s,n,a,o=this,r=0,h=e.css("box-sizing"),l=e.length&&(!t.length||e.index()",delay:300,options:{icons:{submenu:"ui-icon-caret-1-e"},items:"> *",menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().attr({role:this.options.role,tabIndex:0}),this._addClass("ui-menu","ui-widget ui-widget-content"),this._on({"mousedown .ui-menu-item":function(e){e.preventDefault()},"click .ui-menu-item":function(t){var i=e(t.target),s=e(e.ui.safeActiveElement(this.document[0]));!this.mouseHandled&&i.not(".ui-state-disabled").length&&(this.select(t),t.isPropagationStopped()||(this.mouseHandled=!0),i.has(".ui-menu").length?this.expand(t):!this.element.is(":focus")&&s.closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(t){if(!this.previousFilter){var i=e(t.target).closest(".ui-menu-item"),s=e(t.currentTarget);i[0]===s[0]&&(this._removeClass(s.siblings().children(".ui-state-active"),null,"ui-state-active"),this.focus(t,s))}},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(e,t){var i=this.active||this.element.find(this.options.items).eq(0);t||this.focus(e,i)},blur:function(t){this._delay(function(){var i=!e.contains(this.element[0],e.ui.safeActiveElement(this.document[0]));i&&this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(e){this._closeOnDocumentClick(e)&&this.collapseAll(e),this.mouseHandled=!1}})},_destroy:function(){var t=this.element.find(".ui-menu-item").removeAttr("role aria-disabled"),i=t.children(".ui-menu-item-wrapper").removeUniqueId().removeAttr("tabIndex role aria-haspopup");this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeAttr("role aria-labelledby aria-expanded aria-hidden aria-disabled tabIndex").removeUniqueId().show(),i.children().each(function(){var t=e(this);t.data("ui-menu-submenu-caret")&&t.remove()})},_keydown:function(t){var i,s,n,a,o=!0;switch(t.keyCode){case e.ui.keyCode.PAGE_UP:this.previousPage(t);break;case e.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case e.ui.keyCode.HOME:this._move("first","first",t);break;case e.ui.keyCode.END:this._move("last","last",t);break;case e.ui.keyCode.UP:this.previous(t);break;case e.ui.keyCode.DOWN:this.next(t);break;case e.ui.keyCode.LEFT:this.collapse(t);break;case e.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case e.ui.keyCode.ENTER:case e.ui.keyCode.SPACE:this._activate(t);break;case e.ui.keyCode.ESCAPE:this.collapse(t);break;default:o=!1,s=this.previousFilter||"",a=!1,n=t.keyCode>=96&&105>=t.keyCode?""+(t.keyCode-96):String.fromCharCode(t.keyCode),clearTimeout(this.filterTimer),n===s?a=!0:n=s+n,i=this._filterMenuItems(n),i=a&&-1!==i.index(this.active.next())?this.active.nextAll(".ui-menu-item"):i,i.length||(n=String.fromCharCode(t.keyCode),i=this._filterMenuItems(n)),i.length?(this.focus(t,i),this.previousFilter=n,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}o&&t.preventDefault()},_activate:function(e){this.active&&!this.active.is(".ui-state-disabled")&&(this.active.children("[aria-haspopup='true']").length?this.expand(e):this.select(e))},refresh:function(){var t,i,s,n,a,o=this,r=this.options.icons.submenu,h=this.element.find(this.options.menus);this._toggleClass("ui-menu-icons",null,!!this.element.find(".ui-icon").length),s=h.filter(":not(.ui-menu)").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var t=e(this),i=t.prev(),s=e("").data("ui-menu-submenu-caret",!0);o._addClass(s,"ui-menu-icon","ui-icon "+r),i.attr("aria-haspopup","true").prepend(s),t.attr("aria-labelledby",i.attr("id"))}),this._addClass(s,"ui-menu","ui-widget ui-widget-content ui-front"),t=h.add(this.element),i=t.find(this.options.items),i.not(".ui-menu-item").each(function(){var t=e(this);o._isDivider(t)&&o._addClass(t,"ui-menu-divider","ui-widget-content")}),n=i.not(".ui-menu-item, .ui-menu-divider"),a=n.children().not(".ui-menu").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),this._addClass(n,"ui-menu-item")._addClass(a,"ui-menu-item-wrapper"),i.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!e.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(e,t){if("icons"===e){var i=this.element.find(".ui-menu-icon");this._removeClass(i,null,this.options.icons.submenu)._addClass(i,null,t.submenu)}this._super(e,t)},_setOptionDisabled:function(e){this._super(e),this.element.attr("aria-disabled",e+""),this._toggleClass(null,"ui-state-disabled",!!e)},focus:function(e,t){var i,s,n;this.blur(e,e&&"focus"===e.type),this._scrollIntoView(t),this.active=t.first(),s=this.active.children(".ui-menu-item-wrapper"),this._addClass(s,null,"ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",s.attr("id")),n=this.active.parent().closest(".ui-menu-item").children(".ui-menu-item-wrapper"),this._addClass(n,null,"ui-state-active"),e&&"keydown"===e.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),i=t.children(".ui-menu"),i.length&&e&&/^mouse/.test(e.type)&&this._startOpening(i),this.activeMenu=t.parent(),this._trigger("focus",e,{item:t})},_scrollIntoView:function(t){var i,s,n,a,o,r;this._hasScroll()&&(i=parseFloat(e.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(e.css(this.activeMenu[0],"paddingTop"))||0,n=t.offset().top-this.activeMenu.offset().top-i-s,a=this.activeMenu.scrollTop(),o=this.activeMenu.height(),r=t.outerHeight(),0>n?this.activeMenu.scrollTop(a+n):n+r>o&&this.activeMenu.scrollTop(a+n-o+r))},blur:function(e,t){t||clearTimeout(this.timer),this.active&&(this._removeClass(this.active.children(".ui-menu-item-wrapper"),null,"ui-state-active"),this._trigger("blur",e,{item:this.active}),this.active=null)},_startOpening:function(e){clearTimeout(this.timer),"true"===e.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(e)},this.delay))},_open:function(t){var i=e.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(t.parents(".ui-menu")).hide().attr("aria-hidden","true"),t.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(i)},collapseAll:function(t,i){clearTimeout(this.timer),this.timer=this._delay(function(){var s=i?this.element:e(t&&t.target).closest(this.element.find(".ui-menu"));s.length||(s=this.element),this._close(s),this.blur(t),this._removeClass(s.find(".ui-state-active"),null,"ui-state-active"),this.activeMenu=s},this.delay)},_close:function(e){e||(e=this.active?this.active.parent():this.element),e.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false")},_closeOnDocumentClick:function(t){return!e(t.target).closest(".ui-menu").length},_isDivider:function(e){return!/[^\-\u2014\u2013\s]/.test(e.text())},collapse:function(e){var t=this.active&&this.active.parent().closest(".ui-menu-item",this.element);t&&t.length&&(this._close(),this.focus(e,t))},expand:function(e){var t=this.active&&this.active.children(".ui-menu ").find(this.options.items).first();t&&t.length&&(this._open(t.parent()),this._delay(function(){this.focus(e,t)}))},next:function(e){this._move("next","first",e)},previous:function(e){this._move("prev","last",e)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(e,t,i){var s;this.active&&(s="first"===e||"last"===e?this.active["first"===e?"prevAll":"nextAll"](".ui-menu-item").eq(-1):this.active[e+"All"](".ui-menu-item").eq(0)),s&&s.length&&this.active||(s=this.activeMenu.find(this.options.items)[t]()),this.focus(i,s)},nextPage:function(t){var i,s,n;return this.active?(this.isLastItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return i=e(this),0>i.offset().top-s-n}),this.focus(t,i)):this.focus(t,this.activeMenu.find(this.options.items)[this.active?"last":"first"]())),void 0):(this.next(t),void 0)},previousPage:function(t){var i,s,n;return this.active?(this.isFirstItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return i=e(this),i.offset().top-s+n>0}),this.focus(t,i)):this.focus(t,this.activeMenu.find(this.options.items).first())),void 0):(this.next(t),void 0)},_hasScroll:function(){return this.element.outerHeight()",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,_create:function(){var t,i,s,n=this.element[0].nodeName.toLowerCase(),a="textarea"===n,o="input"===n;this.isMultiLine=a||!o&&this._isContentEditable(this.element),this.valueMethod=this.element[a||o?"val":"text"],this.isNewMenu=!0,this._addClass("ui-autocomplete-input"),this.element.attr("autocomplete","off"),this._on(this.element,{keydown:function(n){if(this.element.prop("readOnly"))return t=!0,s=!0,i=!0,void 0;t=!1,s=!1,i=!1;var a=e.ui.keyCode;switch(n.keyCode){case a.PAGE_UP:t=!0,this._move("previousPage",n);break;case a.PAGE_DOWN:t=!0,this._move("nextPage",n);break;case a.UP:t=!0,this._keyEvent("previous",n);break;case a.DOWN:t=!0,this._keyEvent("next",n);break;case a.ENTER:this.menu.active&&(t=!0,n.preventDefault(),this.menu.select(n));break;case a.TAB:this.menu.active&&this.menu.select(n);break;case a.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(n),n.preventDefault());break;default:i=!0,this._searchTimeout(n)}},keypress:function(s){if(t)return t=!1,(!this.isMultiLine||this.menu.element.is(":visible"))&&s.preventDefault(),void 0;if(!i){var n=e.ui.keyCode;switch(s.keyCode){case n.PAGE_UP:this._move("previousPage",s);break;case n.PAGE_DOWN:this._move("nextPage",s);break;case n.UP:this._keyEvent("previous",s);break;case n.DOWN:this._keyEvent("next",s)}}},input:function(e){return s?(s=!1,e.preventDefault(),void 0):(this._searchTimeout(e),void 0)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(e){return this.cancelBlur?(delete this.cancelBlur,void 0):(clearTimeout(this.searching),this.close(e),this._change(e),void 0)}}),this._initSource(),this.menu=e(" + {% else %} +

    + We're sorry; we don't have a file format suitable for ereaders. +

    + {% endif %} + +

    + Not using an ereader? Try the instructions for iPhone/iPad, Android, or desktop computers. +

    +
  • +
    +

    Dropbox

    +

    Dropbox is a good way to share your ebooks between desktop, tablet and smartphone. If you see a dropbox button above, click it to load your books into your dropbox folder. Then load the file into your reader application on your device. +

    - {% endif %} - {% endif %} + +
    +

    Need more help?

    +

    Ask us a question!

    + +
    + DefectiveByDesign.org All downloads from Unglue.it are DRM free. Hooray! +
    + +{% else %} +{% endif %} +{% endif %} + {% endblock %} diff --git a/frontend/templates/faceted_list.html b/frontend/templates/faceted_list.html index 49c4e9656..043fe7f35 100644 --- a/frontend/templates/faceted_list.html +++ b/frontend/templates/faceted_list.html @@ -14,6 +14,7 @@ {% block extra_head %} + diff --git a/frontend/templates/faq_b2u.html b/frontend/templates/faq_b2u.html index 9baef0df3..33f37af44 100644 --- a/frontend/templates/faq_b2u.html +++ b/frontend/templates/faq_b2u.html @@ -16,11 +16,11 @@

    Buy-to-Unglue Campaigns

    The ungluing date is the date a book gets released under a Creative Commons License. After the ungluing date, the ebook will be available for free at unglue.it, Internet Archive and any library, anywhere. You'll be able to make copies for all your friends, if that's what you want to do.
    How does that work?
    -
    The rights holder for the book picks +
    The rights holder for the book picks
    1. an initial ungluing date some time in the future, and
    2. a revenue goal
    3. -
    When an ebook license is purchased, the ungluing date is recalculated according to these formulae:
    + When an ebook license is purchased, the ungluing date is recalculated according to these formulae:
     
     (days per dollar) = [(initial ungluing date) - (launch date)] / (campaign goal)
     
     (current ungluing date) = (initial ungluing date) - (gross revenue)*(days per dollar)
    @@ -35,12 +35,12 @@ 

    Buy-to-Unglue Campaigns

    {{ form.cc_date_initial.errors }}{{ form.cc_date_initial }}

    {% else %} {% endif %} -

    and a revenue goal of +

    and a revenue goal of {{ form.target.errors }}${{ form.target }},

    {% if form.instance.dollar_per_day %} -

    If you launch today, when the Book has earned +

    If you launch today, when the Book has earned ${{ form.revenue.errors }}{{ form.revenue }}, the new Ungluing Date will be {{ form.instance.cc_date }} and every additional ${{ form.instance.dollar_per_day|floatformat:2|intcomma }} received will advance the Ungluing Date by one day.

    another Ungluing Date

    diff --git a/frontend/templates/faqmenu.html b/frontend/templates/faqmenu.html index 3b8537d49..2efad932a 100644 --- a/frontend/templates/faqmenu.html +++ b/frontend/templates/faqmenu.html @@ -1,62 +1,62 @@ -
    -

    FAQs

    - +
    diff --git a/frontend/templates/home.html b/frontend/templates/home.html index 1e9a1fd81..17b5e0626 100755 --- a/frontend/templates/home.html +++ b/frontend/templates/home.html @@ -12,11 +12,8 @@ {% block extra_css %} - - - + {% endblock %} {% block extra_js %} @@ -24,19 +21,20 @@ + + @@ -45,10 +43,10 @@ {% block topsection %} {% include "learn_more.html" %} {% endblock %} - + {% block content %}
    -
    +
    @@ -69,7 +67,7 @@
    -
    +
    @@ -79,13 +77,13 @@ {% endif %}{% if work.relators.count > 2 %}{% for author in work.relators %}{% if not forloop.first %}, {{ author.name }}{% endif %}{% endfor %} {% endif %}
    -
    +
    {% if work.last_campaign.publisher %} {{ work.last_campaign.publisher }} {% endif %} {{ work.publication_date }}
    -
    {{ work.description|safe }}
    +
    {{ work.description|safe }}
    @@ -96,94 +94,76 @@
    -
    - {% for work in faves %} - {% with work.googlebooks_id as googlebooks_id %} - {% include "book_panel.html" %} - {% endwith %} - {% endfor %} - -
    - See More + {% for work in faves %} + {% with work.googlebooks_id as googlebooks_id %} + {% include "book_panel.html" %} + {% endwith %} + {% endfor %} +
    - + {% endif %} {% if top_pledge %}
    -
    -
    - {% for campaign in top_pledge %} - {% with campaign.work as work %} - {% with work.googlebooks_id as googlebooks_id %} - {% include "book_panel.html" %} - {% endwith %}{% endwith %} - {% endfor %} - -
    -
    - See More - {% endif %} -
    - -
    -
    - {% for work in cc_books %} +
    + {% for campaign in top_pledge %} + {% with campaign.work as work %} {% with work.googlebooks_id as googlebooks_id %} {% include "book_panel.html" %} - {% endwith %} + {% endwith %}{% endwith %} {% endfor %} - +
    - See More + {% endif %} +
    + +
    + {% for work in cc_books %} + {% with work.googlebooks_id as googlebooks_id %} + {% include "book_panel.html" %} + {% endwith %} + {% endfor %} +
    {% if top_b2u %} -
    -
    - {% for campaign in top_b2u %} - {% with campaign.work as work %} - {% with work.googlebooks_id as googlebooks_id %} - {% include "book_panel.html" %} - {% endwith %}{% endwith %} - {% endfor %} - -
    +
    + {% for campaign in top_b2u %} + {% with campaign.work as work %} + {% with work.googlebooks_id as googlebooks_id %} + {% include "book_panel.html" %} + {% endwith %}{% endwith %} + {% endfor %} +
    - See More {% endif %}
    {% if top_t4u %} -
    -
    - {% for campaign in top_t4u %} - {% with campaign.work as work %} - {% with work.googlebooks_id as googlebooks_id %} - {% include "book_panel.html" %} - {% endwith %}{% endwith %} - {% endfor %} - -
    -
    - See More - {% endif %} -
    - -
    -
    - {% for work in unglued_books %} +
    + {% for campaign in top_t4u %} + {% with campaign.work as work %} {% with work.googlebooks_id as googlebooks_id %} {% include "book_panel.html" %} - {% endwith %} + {% endwith %}{% endwith %} {% endfor %} - +
    + {% endif %} +
    + +
    + {% for work in unglued_books %} + {% with work.googlebooks_id as googlebooks_id %} + {% include "book_panel.html" %} + {% endwith %} + {% endfor %} +
    - See More
    - +
    @@ -208,7 +188,7 @@

    Start Ungluing Now!

    - {% endif %} -
    -

    Donate!

    +

    Donate!

    +
    Please help support Unglue.it by making a tax-deductible donation to the Free Ebook Foundation.
    +
    + +
    + +
    + +
    -
    Please help support Unglue.it by making a tax-deductible donation to the Free Ebook Foundation.
    -
    - - -
    -
    -
    -

    Latest Ungluing

    + +
    +

    Latest Ungluing

    -
      - {% for event in events %} +
    -

    Questions?

    +

    Questions?

    +
    + + +
      +
    • boingboing
    • +
    • die zeit
    • +
    • huffington post
    • +
    • techcrunch
    • +
    • library journal
    • +
    • networkworld
    • +
    +
    For readers it’s a gold mine of great books they can have a say in bringing to market.
    +
    -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/frontend/templates/learn_more.html b/frontend/templates/learn_more.html index 415717291..048abec03 100644 --- a/frontend/templates/learn_more.html +++ b/frontend/templates/learn_more.html @@ -16,6 +16,131 @@
    -
    +
    +

    Find over 10,000 free ebooks here.
    Help us make more ebooks free!

    + +
    +
    + MAKE +
      
    +
    +
    + Creators make ebooks in EPUB, MOBI, and PDF.
    + Ungluers love them for doing it.
    +
    +
    +
    +
    +
    + GIVE +
    Read it Now
    +
    +
    + Creators apply Creative Commons licenses to ebooks.
    + Ungluers read them at home, at a library, anywhere.
    +
    +
    +
    +
    +
    + + ASK + +
    +
    + Creators ask downloaders to contribute what they choose.
    + Ungluers say thank you with their support. +
    +
    + +
    +
    +
    + MAKE +
      
    +
    +
    + Creators make ebooks in EPUB.
    + Ungluers love them for doing it.
    +
    +
    +
    +
    +
    + + ASK + +
    +
    + Creators set a funding goal and a per-copy price.
    + Ungluers purchase the ebook to advance the campaign. +
    +
    +
    +
    +
    + GIVE +
    Read it Now
    +
    +
    + When the funding goal is met, Creative Commons licenses are automatically applied.
    +
    +
    +
    + +
    +
    +
    +
    + + ASK + +
    +
    + Creators set a funding goal and rewards for supporters.
    + Ungluers pledge to support the campaign. +
    +
    +
    +
    +
    + MAKE +
      
    +
    +
    + When the campaign succeeds, We collect Ungluer pledges.
    + The ebook is created and rewards are distributed. +
    +
    +
    +
    +
    + GIVE +
    Read it Now
    +
    +
    + Creative Commons licenses are applied.
    + Ungluers read them at home, at a library, anywhere.
    +
    +
    + +
    +
    diff --git a/frontend/templates/libraryauth/library.html b/frontend/templates/libraryauth/library.html index 183e6a13d..62287860c 100644 --- a/frontend/templates/libraryauth/library.html +++ b/frontend/templates/libraryauth/library.html @@ -13,6 +13,7 @@ {% block extra_js %} + @@ -231,4 +232,4 @@

    Your Unglue.it faves will be listed here.

    -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/frontend/templates/pledge_complete.html b/frontend/templates/pledge_complete.html index decd85a26..59a8a904d 100644 --- a/frontend/templates/pledge_complete.html +++ b/frontend/templates/pledge_complete.html @@ -12,6 +12,7 @@ + + {% endblock %} @@ -82,4 +84,4 @@

    Thank you!

    -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/frontend/templates/read.html b/frontend/templates/read.html deleted file mode 100644 index 48e7f4ecc..000000000 --- a/frontend/templates/read.html +++ /dev/null @@ -1,123 +0,0 @@ -{% load sass_tags %} - - - - Read {{ work.title }} online at unglue.it - - - - - - {% for author in work.relators %} - - {% endfor %} - {% if work.first_isbn_13 %} - - {% endif %} - - - - - - - - - - - - - - - - - - - - - - - - - - - - -{% with work.id as work_id %} - - -
    - -
    -
    - Menu -
    -
    - -   –   - -
    - -
    - -
    - -
    - - -
    -
    - -
    - -{% endwith %} diff --git a/frontend/templates/registration/login.html b/frontend/templates/registration/login.html index 36009c72f..f81aca4e2 100644 --- a/frontend/templates/registration/login.html +++ b/frontend/templates/registration/login.html @@ -2,6 +2,7 @@ {% block title %}Log in to Unglue.it{% endblock %} {% block doccontent %} + {% endblock %} diff --git a/frontend/templates/registration/login_form.html b/frontend/templates/registration/login_form.html index 75765df09..9c313d487 100644 --- a/frontend/templates/registration/login_form.html +++ b/frontend/templates/registration/login_form.html @@ -1,10 +1,11 @@ diff --git a/frontend/templates/registration/registration_base.html b/frontend/templates/registration/registration_base.html index 3cb5747f0..c130b6db0 100644 --- a/frontend/templates/registration/registration_base.html +++ b/frontend/templates/registration/registration_base.html @@ -34,15 +34,18 @@ {% block extra_head %} {% block extra_extra_head %} - + {% endblock %} {% endblock %} {% block content %} -
    - +
    +
    +
    +{% block doccontent %} +{% endblock %} +
    +
    +
    {% endblock %} diff --git a/frontend/templates/registration/registration_form.html b/frontend/templates/registration/registration_form.html index dc9a14cae..580475862 100644 --- a/frontend/templates/registration/registration_form.html +++ b/frontend/templates/registration/registration_form.html @@ -1,47 +1,40 @@ {% extends "registration/registration_base.html" %} {% block title %}Register for an account{% endblock %} - {% block extra_js %} {{ block.super }} {% endblock %} - - {% block doccontent %} {% if not user.is_authenticated %}

    Sign up for a Unglue.it account:

    -
    {% csrf_token %} -
    {{ form.username.label }}: {{ form.username.errors }}
    {{ form.username }}
    -
    {{ form.email.label }}: {{ form.email.errors }}
    {{ form.email }}
    -
    {{ form.password1.label }}: {{ form.password1.errors }}
    {{ form.password1 }}
    -
    {{ form.password2.label }}: {{ form.password2.errors }}
    {{ form.password2 }}
    - -
    +
    {% csrf_token %} +
    {{ form.username.label }}: {{ form.username.errors }}
    {{ form.username }}
    +
    {{ form.email.label }}: {{ form.email.errors }}
    {{ form.email }}
    +
    {{ form.password1.label }}: {{ form.password1.errors }}
    {{ form.password1 }}
    +
    {{ form.password2.label }}: {{ form.password2.errors }}
    {{ form.password2 }}
    + +
    - + {% endblock %} diff --git a/frontend/templates/registration/welcome.html b/frontend/templates/registration/welcome.html index b792538c2..ab693bd11 100644 --- a/frontend/templates/registration/welcome.html +++ b/frontend/templates/registration/welcome.html @@ -2,31 +2,18 @@ {% block title %}Welcome to Unglue.It{% endblock %} -{% block extra_css %} - -{% endblock %} {% block doccontent %} - -
    -
    - -

    Welcome, {{user.username}}!

    -

    - -

    - -
    - -
    +
    +

    Welcome, {{user.username}}!

    + +
    + + +
    +
    +
    + {% endblock %} diff --git a/frontend/templates/search.html b/frontend/templates/search.html index ecb14076e..c58fa5fc3 100644 --- a/frontend/templates/search.html +++ b/frontend/templates/search.html @@ -13,6 +13,7 @@ {% endblock %} {% block extra_head %} + + @@ -410,4 +411,4 @@

    More

    -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/frontend/templates/unglued_list.html b/frontend/templates/unglued_list.html index 3670d8214..fb9e2191d 100644 --- a/frontend/templates/unglued_list.html +++ b/frontend/templates/unglued_list.html @@ -14,6 +14,7 @@ {% block extra_head %} + diff --git a/frontend/templates/work.html b/frontend/templates/work.html index eb97184e8..3ec96e7a3 100644 --- a/frontend/templates/work.html +++ b/frontend/templates/work.html @@ -5,7 +5,8 @@ {% load lib_acqs %} {% load purchased %} {% load sass_tags %} -{% block title %}— + +{% block title %}— {% if work.is_free %} {{ work.title }} is a Free eBook. {% for fmt in work.formats %}[{{ fmt }}]{% endfor %} {% else %} @@ -23,7 +24,6 @@ {% endblock %} {% block extra_css %} - {% if user.is_staff or user in work.last_campaign.managers.all %} {{ kwform.media.css }} @@ -31,218 +31,514 @@ {% endif %} {% endblock %} -{% block content %} -{% with work.id as work_id %} -
    -
    - {% if work.uses_google_cover %} - - Find {{ work.title }} at Google Books - - {% else %} - {{ work.title }} - {% endif %} -
    -
    -
    -

    {{ work.title }}

    -

    - - {% if work.authors.count == 2 %} - and - {% endif %}{% if work.relators.count > 2 %}{% for author in work.relators %}{% if not forloop.first %}, {% endif %}{% endfor %} - {% endif %} -

    -

    - {% if work.last_campaign.publisher %} - {{ work.last_campaign.publisher }} - {% endif %} - - - -

    -
    -
    - {% if status == 'ACTIVE' %} - {% if work.last_campaign.type != 3 %} - {{ work.last_campaign.description|safe }} - {% else %} - {{ work.description|safe }} - {% endif %} - {% elif work.description %} - {{ work.description|safe }} - {% else %} - {{ work.last_campaign.description|safe }} - {% endif %} +{% block extra_js %} + + + + + + +{% if user.is_staff or user in work.last_campaign.managers.all %} + {{ kwform.media.js }} +{% endif %} -
    - {% if action == 'display' %} - {% if status == 'ACTIVE' %} - {% if work.last_campaign.type == 1 %} -

    A campaign is running to unglue {{work.title}}!

    -

    The rights holder, {% for claim in work.claim.all %} - {% if claim.status == 'active' %} - {{ claim.rights_holder.rights_holder_name }} - {% endif %} - {% endfor %} - , has agreed to release {{work.title}} to the world as a Creative Commons licensed ebook ({{ work.last_campaign.license }}) if ungluers can join together to raise ${{ work.last_campaign.target|floatformat:0|intcomma }} by {{ work.last_campaign.deadline }}. - You can help!

    - {% endif %} - {% if work.last_campaign.type == 2 %} -

    A Buy-to-Unglue Campaign is running to unglue {{work.title}}!

    -

    The rights holder, {% for claim in work.claim.all %} - {% if claim.status == 'active' %} - {{ claim.rights_holder.rights_holder_name }} - {% endif %} - {% endfor %} - , has agreed to release {{work.title}} to the world as a Creative Commons licensed ebook ({{ work.last_campaign.license }}) on {{ work.last_campaign.cc_date }}. For every copy that ungluers purchase, that date gets sooner. ${{ work.last_campaign.left|floatformat:0|intcomma }} of sales will unglue the book TODAY. - You can help!

    - {% endif %} - {% if work.last_campaign.type == 3 %} -

    A Thanks-for-Ungluing Campaign is running to reward the creators of {{work.title}}!

    -

    The rights holder, {% for claim in work.claim.all %} - {% if claim.status == 'active' %} - {{ claim.rights_holder.rights_holder_name }} - {% endif %} - {% endfor %} - , has released {{work.title}} to the world as a Creative Commons licensed ebook ({{ work.last_campaign.license }}) . - You can help us say "Thank You!" so that other creators will do the same.

    - {% endif %} -

    Campaign details: the fine print

    - {{ work.last_campaign.details|safe }} - {% endif %} + + - {% if status == 'SUCCESSFUL' %} -

    A campaign has succeeded to unglue {{work.title}}!

    -

    The rights holder, {% for claim in work.claim.all %} - {% if claim.status == 'active' %} - {{ claim.rights_holder.rights_holder_name }} - {% endif %} - {% endfor %} - , has agreed to release {{work.title}} to the world as a Creative Commons licensed ebook ({{ work.last_campaign.license }}) thanks to the efforts of ungluers like you.

    -

    Campaign details: the fine print

    - {{ work.last_campaign.details|safe }} - {% endif %} - {% if status != 'ACTIVE' and status != 'SUCCESSFUL' %} -

    Rights Information

    - {% if claimstatus == 'one_active' %} -

    This work has been claimed by {{ rights_holder_name }}.

    - {% else %} - {% if claimstatus == 'disputed' %} -

    Rights claims are pending.

    +{% endblock %} + +{% block topsection %} +{% if work.last_campaign.status == 'ACTIVE' %} + {% if request.user in work.last_campaign.managers.all %} +
    Hi, {{ request.user.username }}. Since you're a manager for this campaign, you can edit this campaign.
    + {% endif %} +{% elif not work.user_with_rights %} + {% if request.user.rights_holder.all %} +
    Hi, {{ request.user.username }}. Since you're an authorized Unglue.it rights holder, if you own the worldwide electronic rights to this work, you may claim it through the More... tab. Need help? Check out the rights holder tools page.
    + {% endif %} +{% elif request.user == work.user_with_rights %} + {% if work.last_campaign.status != 'SUCCESSFUL' %} +
    Hi, {{ request.user.username }}. Since you're a rights holder for this work, you can launch a campaign.
    + {% endif %} +{% endif %} +{% endblock %} + +{% block content %} +{% purchased %} +{% lib_acqs %} +{% with work.last_campaign_status as status %} +{% with work.id as work_id %} +
    +
    +
    + {% include "explore.html" %} +
    +
    +
    +
    +
    + {% if work.uses_google_cover %} +
    + + Find {{ work.title }} at Google Books +
    {% else %} - {% if claimstatus == 'one_pending' %} -

    A claim for this work by {{ rights_holder_name }} is pending.

    +
    + {{ work.title }} +
    + {% endif %} +
    +
    +

    {{ work.title }}

    +
    +
    +

    + {% if work.authors.count == 2 %} + and + {% endif %}{% if work.relators.count > 2 %}{% for author in work.relators %}{% if not forloop.first %}, {% endif %}{% endfor %} + {% endif %} +

    +

    + {% if work.last_campaign.publisher %} + {{ work.last_campaign.publisher }} + {% endif %} + + + +

    +
    +
    +
    + {% if status == 'ACTIVE' %} + {% if work.last_campaign.type != 3 %} +
    +
    +
    + {{ work.percent_of_goal }}% of goal +
    + {% endif %} +
    +
    + {% if work.last_campaign.type == 1 %} + ${{ work.last_campaign.current_total|floatformat:0|intcomma }} pledged + {% endif %} + {% if work.last_campaign.type == 2 %} + current ungluing date: + {% endif %} + {% if work.last_campaign.type == 3 %} + ${{ work.last_campaign.current_total|floatformat:0|intcomma }} of thanks from + {% endif %} +
    +
    + {% if work.last_campaign.type == 1 %} + ${{ work.last_campaign.target|floatformat:0|intcomma }} goal + {% endif %} + {% if work.last_campaign.type == 2 %} + {{ work.last_campaign.cc_date|date:"M j, Y" }} + After {{ work.last_campaign.cc_date|date:"M j, Y" }} this book will be available for free to anyone, anywhere. Every purchase before then brings that date closer. + {% endif %} + {% if work.last_campaign.type != 3 %} +
    +
    + {% endif %} + {% if work.last_campaign.supporters_count == 1 %} + 1 ungluer + {% else %} + {{ work.last_campaign.supporters_count }} ungluers + {% endif %} + {% if work.last_campaign.type == 3 %} +
    + {% if work.last_campaign.anon_count == 1 %} + 1 other + {% else %} + {{ work.last_campaign.anon_count }} others + {% endif %} + {% endif %} +
    + {% if work.last_campaign.type == 2 %} +
    + {% if work.lib_acqs.count == 1 %} + 1 copy in a library + {% else %} + {{ work.lib_acqs.count }} in libraries + {% endif %} +
    + {% endif %} + {% if work.last_campaign.type != 3 %} +
    + {% if work.last_campaign.type == 1 %} + {{ work.last_campaign.countdown }} to go + {% else %} + ${{ work.last_campaign.left|floatformat:0|intcomma }} to go + ${{ work.last_campaign.left|floatformat:0|intcomma }} is the amount it would take to make this ebook free to the world tomorrow. + {% endif %} +
    + {% endif %} +
    {% else %} - {% if request.user.rights_holder.all.count %} - Is this work yours? Claim it:

    - -
    - {% csrf_token %} - {{ claimform.user }} - {{ claimform.work }} - {{ claimform.rights_holder }} - -

    - {% else %} - Are you the author or publisher of this work? If so, you can claim it as yours by registering as an Unglue.it rights holder. + {% if status == 'SUCCESSFUL' %} +
    + This campaign succeeded on {{ work.last_campaign.success_date|date:"M j, Y" }}. +
    +
    +
    + {% if work.last_campaign.supporters_count == 1 %} + 1 ungluer + {% else %} + {{ work.last_campaign.supporters_count }} ungluers + {% endif %} +
    +
    + ${{ work.last_campaign.current_total|floatformat:0|intcomma }} raised +
    +
    + ${{ work.last_campaign.target|floatformat:0|intcomma }} goal +
    +
    + Unglued! +
    +
    {% endif %} + +
    + {% if wishers == 1 %} + 1 Ungluer has + {% else %} + {{ wishers }} Ungluers have + {% endif %} Faved this Work +
    {% endif %} - {% endif %} - {% endif %} - {% endif %} - {% if work.is_free %} -

    Downloads

    -
    - This work has been downloaded {{ work.download_count }} times via unglue.it ebook links. -
      - {% for ebook in work.ebooks.all %} -
    1. {{ ebook.download_count }} - {{ ebook.format }} {% if ebook.version_label %} ({{ ebook.version_label }}) {% endif %}({{ ebook.rights }}) at {{ ebook.provider }}.
    2. - {% endfor %} -
    -
    - {% if user.is_staff %} -

    - Feature this work today. -

    - {% endif %} - {% endif %} - {% if user.is_staff %} -

    Related Works

    - - {% endif %} - {% endif %} -
    -
    -
    -
    - {% if has_online_book %} - - {% endif %} - - -
    -
    - {% if request.user.is_anonymous %} -
    - {% elif request.user.id in work.last_campaign.supporters %} -
    - Faved! + {% get_comment_count for work as comment_count %} + {% if action == 'editions' %} + - {% elif work in request.user.wishlist.works.all %} -
    - Remove from My Faves + {% else %} + - {% else %} -
    - Add to My Faves + {% endif %} +
    +
    +
    +
    + {% if status == 'ACTIVE' %} + {% if work.last_campaign.type != 3 %} + {{ work.last_campaign.description|safe }} + {% else %} + {{ work.description|safe }} + {% endif %} + {% elif work.description %} + {{ work.description|safe }} + {% else %} + {{ work.last_campaign.description|safe }} + {% endif %} +
    +
    + {% for work_rel in work.works_related_to.all %} + {% if work_rel.from_work.language != 'xx' and work.language != 'xx' %} +

    + This work is a {{ work_rel.relation }} of {{ work_rel.from_work }}. +

    + {% endif %} + {% endfor %} + {% for work_rel in work.works_related_from.all %} + {% if work.language != 'xx' and work_rel.to_work.language != 'xx' %} +

    + {{ work_rel.to_work }} is a {{ work_rel.relation }} of this work. +

    + {% endif %} + {% endfor %} + {% if work.doab %} +

    + This book is included in DOAB. +

    + {% endif %} + {% if work.gtbg %} +

    + This book is included in Project Gutenberg. +

    + {% endif %} +
    +
    +
    +
    +

    Why {% if work.ebooks.all %}read{% else %}unglue{% endif %} this book? Have your say.

    +
    + {% render_comment_list for work %} + {% if user.is_authenticated %} + {% render_comment_form for work %} + {% else %} +

    You must be logged in to comment.

    + {% endif %} +
    +
    +
    +
    + {% if request.user.is_staff or request.user in work.last_campaign.managers.all %} +
    + {% csrf_token %} + + {% for wish in work.wishes.all reversed %} + {% with wish.wishlist.user as supporter %} +
    + + + Avatar for {{ supporter }} + + +
    + email +
    +
    + {{ supporter }}
    + Wished: {{ wish.created }}
    + {% if supporter.id in work.last_campaign.supporters %}Pledged!
    {% endif %} + {% if supporter in work.last_campaign.ungluers.all %}Supported!
    {% endif %} +
    +
    +
    + + {% endwith %} + {% endfor %} +
    + {% else %} + {% for wish in work.wishes.all reversed %} + {% with wish.wishlist.user as supporter %} + + {% endwith %} + {% endfor %} + {% endif %} +
    +
    +
    +
    + {% if action == 'display' %} + {% if status == 'ACTIVE' %} + {% if work.last_campaign.type == 1 %} +

    A campaign is running to unglue {{work.title}}!

    +

    The rights holder, {% for claim in work.claim.all %} + {% if claim.status == 'active' %} + {{ claim.rights_holder.rights_holder_name }} + {% endif %} + {% endfor %} + , has agreed to release {{work.title}} to the world as a Creative Commons licensed ebook ({{ work.last_campaign.license }}) if ungluers can join together to raise ${{ work.last_campaign.target|floatformat:0|intcomma }} by {{ work.last_campaign.deadline }}. + You can help!

    + {% endif %} + {% if work.last_campaign.type == 2 %} +

    A Buy-to-Unglue Campaign is running to unglue {{work.title}}!

    +

    The rights holder, {% for claim in work.claim.all %} + {% if claim.status == 'active' %} + {{ claim.rights_holder.rights_holder_name }} + {% endif %} + {% endfor %} + , has agreed to release {{work.title}} to the world as a Creative Commons licensed ebook ({{ work.last_campaign.license }}) on {{ work.last_campaign.cc_date }}. For every copy that ungluers purchase, that date gets sooner. ${{ work.last_campaign.left|floatformat:0|intcomma }} of sales will unglue the book TODAY. + You can help!

    + {% endif %} + {% if work.last_campaign.type == 3 %} +

    A Thanks-for-Ungluing Campaign is running to reward the creators of {{work.title}}!

    +

    The rights holder, {% for claim in work.claim.all %} + {% if claim.status == 'active' %} + {{ claim.rights_holder.rights_holder_name }} + {% endif %} + {% endfor %} + , has released {{work.title}} to the world as a Creative Commons licensed ebook ({{ work.last_campaign.license }}) . + You can help us say "Thank You!" so that other creators will do the same.

    + {% endif %} +

    Campaign details: the fine print

    + {{ work.last_campaign.details|safe }} + {% endif %} + + {% if status == 'SUCCESSFUL' %} +

    A campaign has succeeded to unglue {{work.title}}!

    +

    The rights holder, {% for claim in work.claim.all %} + {% if claim.status == 'active' %} + {{ claim.rights_holder.rights_holder_name }} + {% endif %} + {% endfor %} + , has agreed to release {{work.title}} to the world as a Creative Commons licensed ebook ({{ work.last_campaign.license }}) thanks to the efforts of ungluers like you.

    +

    Campaign details: the fine print

    + {{ work.last_campaign.details|safe }} + {% endif %} + {% if status != 'ACTIVE' and status != 'SUCCESSFUL' %} +

    Rights Information

    + {% if claimstatus == 'one_active' %} +

    This work has been claimed by {{ rights_holder_name }}.

    + {% else %} + {% if claimstatus == 'disputed' %} +

    Rights claims are pending.

    + {% else %} + {% if claimstatus == 'one_pending' %} +

    A claim for this work by {{ rights_holder_name }} is pending.

    + {% else %} + {% if request.user.rights_holder.all.count %} + Is this work yours? Claim it:

    + +
    + {% csrf_token %} + {{ claimform.user }} + {{ claimform.work }} + {{ claimform.rights_holder }} + +

    + {% else %} + Are you the author or publisher of this work? If so, you can claim it as yours by registering as an Unglue.it rights holder. + {% endif %} + {% endif %} + {% endif %} + {% endif %} + {% endif %} + {% if work.is_free %} +

    Downloads

    +
    + This work has been downloaded {{ work.download_count }} times via unglue.it ebook links. +
      + {% for ebook in work.ebooks.all %} +
    1. {{ ebook.download_count }} - {{ ebook.format }} {% if ebook.version_label %} ({{ ebook.version_label }}) {% endif %}({{ ebook.rights }}) at {{ ebook.provider }}.
    2. + {% endfor %} +
    +
    + {% if user.is_staff %} +

    + Feature this work today. +

    + {% endif %} + {% endif %} + {% if user.is_staff %} +

    Related Works

    + + + {% endif %} +

    Keywords

    + {% if work.subjects.all.count > 0 %} +
      + {% for subject in work.subjects.all %} +
    • {{ subject.name }} + {% if user.is_staff or user in work.last_campaign.managers.all %} + x + {% endif %} +
    • + {% endfor %} +
    + {% else %} + No keywords yet. +
      + + {% endif %} + {% if user_can_edit_work %} +
      {% csrf_token %} + {{ kwform.add_kw }} +
      + {% endif %} + {% endif %} + {% with doi=work.doi http_id=work.http_id %} + {% if doi or http_id %} +

      Links

      + {% if doi %} + DOI: {{ doi }}
      + {% endif %} + {% if http_id %} + web: {{ http_id }}
      + {% endif %} + {% endif %} + {% endwith %} +

      Editions

      + {% if alert %} +

      {{ alert }}
      + {% endif %} + {% if user_can_edit_work %} + + {% endif %} + + {% if action == 'editions' %} + {% include 'split.html' %} + {% else %} + {% with work.preferred_edition as edition %} + {% include 'edition_display.html' %} + {% endwith %} + {% if not campaign %} + {% for edition in editions %} + {% if edition != work.preferred_edition %} + {% include 'edition_display.html' %} + {% endif %} + {% endfor %} + {% endif %} + + {% endif %} + +
      +
      - {% endif %} +
      - -
      - - Find on LibraryThing - LibraryThing - +
      + {% include 'work_action.html' %}
      -
      - {% include "explore.html" %} -
      -
      -
      -

      Comments

      - {% render_comment_list for work %} - {% if user.is_authenticated %} - {% render_comment_form for work %} - {% else %} -

      You must be logged in to comment.

      - {% endif %}
      {% endwith %} +{% endwith %} {% endblock %} diff --git a/frontend/templates/work_list.html b/frontend/templates/work_list.html index dcf4c1c1c..c2a421a69 100644 --- a/frontend/templates/work_list.html +++ b/frontend/templates/work_list.html @@ -14,6 +14,7 @@ {% block extra_head %} + {% endblock %} diff --git a/frontend/urls.py b/frontend/urls.py index f8dbc8c3e..9868b0078 100644 --- a/frontend/urls.py +++ b/frontend/urls.py @@ -90,7 +90,6 @@ url(r"^work/(?P\d+)/librarything/$", views.work_librarything, name="work_librarything"), url(r"^work/(?P\d+)/goodreads/$", views.work_goodreads, name="work_goodreads"), url(r"^work/(?P\d+)/openlibrary/$", views.work_openlibrary, name="work_openlibrary"), - url(r"^read/(?P\d+)/$", views.read, name="read"), url(r"^new_edition/(?P)(?P)$", views.edit_edition, name="new_edition"), url(r"^new_edition/(?P\d*)/(?P\d*)$", views.edit_edition, name="new_edition"), url(r"^manage_ebooks/(?P\d*)$", views.manage_ebooks, name="manage_ebooks"), @@ -153,4 +152,4 @@ url(r"^goodreads/$", login_required(views.GoodreadsDisplayView.as_view()), name="goodreads_display"), url(r"^goodreads/clear_wishlist/$", views.clear_wishlist, name="clear_wishlist"), url(r"^celery/clear/$", views.clear_celery_tasks, name="clear_celery_tasks"), -] +] \ No newline at end of file diff --git a/frontend/views/__init__.py b/frontend/views/__init__.py index e2d55747a..44429089e 100755 --- a/frontend/views/__init__.py +++ b/frontend/views/__init__.py @@ -298,18 +298,6 @@ def stub(request): def acks(request, work): return render(request, 'front_matter.html', {'campaign': work.last_campaign()}) -def read(request, work_id): - work = safe_get_work(work_id) - try: - ebook_id = work.first_epub().id - url = get_object_or_404(models.Ebook, id=ebook_id).url - except (ValueError, AttributeError): - raise Http404 - return render(request, 'read.html', { - 'work': work, - 'url': url, - }) - def work(request, work_id, action='display'): work = safe_get_work(work_id) alert = '' @@ -423,8 +411,7 @@ def work(request, work_id, action='display'): 'cover_width': cover_width_number, 'action': action, 'formset': formset, - 'kwform': SubjectSelectForm(), - 'has_online_book': work.first_epub() != None, + 'kwform': SubjectSelectForm() }) def edition_uploads(request, edition_id): diff --git a/settings/common.py b/settings/common.py index 2ecda1c90..04e37d513 100644 --- a/settings/common.py +++ b/settings/common.py @@ -44,11 +44,9 @@ # set once instead of in all the templates JQUERY_HOME = "/static/js/jquery-1.12.4.min.js" - JQUERY_UI_HOME = "/static/js/jquery-ui-1.11.4.min.js" JQUERY_UI_THEME = "/static/css/ui-lightness/jquery-ui-1.11.4.min.css" - CKEDITOR_UPLOAD_PATH = '' CKEDITOR_RESTRICT_BY_USER = True CKEDITOR_CONFIGS = { @@ -145,7 +143,7 @@ INSTALLED_APPS = ( 'django.contrib.auth', - 'django.contrib.contenttypes', + 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.sitemaps', @@ -174,26 +172,22 @@ 'ckeditor_uploader', 'storages', 'sorl.thumbnail', - 'mptt', - # this must appear *after* django.frontend or else it overrides the + 'mptt', + # this must appear *after* django.frontend or else it overrides the # registration templates in frontend/templates/registration 'django.contrib.admin', - 'regluit.distro', + 'regluit.distro', 'regluit.booxtream', 'regluit.pyepub', - 'regluit.libraryauth', + 'regluit.libraryauth', 'transmeta', 'questionnaire', - 'questionnaire.page', + 'questionnaire.page', 'sass_processor', ) SASS_PROCESSOR_INCLUDE_DIRS = [ os.path.join(PROJECT_DIR, 'static', 'scss'), - os.path.join('static', 'scss'), - os.path.join(PROJECT_DIR, 'static', 'scss', 'foundation', 'scss'), - os.path.join('static', 'scss', 'foundation', 'scss'), - # static/scss/foundation/scss/foundation.scss ] SASS_PROCESSOR_AUTO_INCLUDE = False @@ -304,13 +298,11 @@ # there's any collision. 'social_core.pipeline.user.get_username', - # make username < 222 in length 'regluit.libraryauth.auth.chop_username', - + # Send a validation email to the user to verify its email address. # Disabled by default. - # 'social_core.pipeline.mail.mail_validation', # Associates the current social details with another user account with @@ -321,7 +313,6 @@ 'social_core.pipeline.user.create_user', # Create the record that associated the social account with this user. - 'social_core.pipeline.social_auth.associate_user', # Populate the extra_data field in the social record with the values @@ -344,7 +335,7 @@ USER_AGENT = "unglue.it.bot v0.0.1 " -# The amount of the transaction that Gluejar takes +# The amount of the transaction that Gluejar takes GLUEJAR_COMMISSION = 0.06 PREAPPROVAL_PERIOD = 365 # days to ask for in a preapproval PREAPPROVAL_PERIOD_AFTER_CAMPAIGN = 90 # if we ask for preapproval time after a campaign deadline @@ -392,7 +383,7 @@ EBOOK_NOTIFICATIONS_JOB = { "task": "regluit.core.tasks.report_new_ebooks", "schedule": crontab(hour=0, minute=30), - "args": () + "args": () } NOTIFY_ENDING_SOON_JOB = { @@ -416,13 +407,13 @@ NOTIFY_EXPIRING_ACCOUNTS = { "task": "regluit.payment.tasks.notify_expiring_accounts", "schedule": crontab(day_of_month=22, hour=0, minute=30), - "args": () + "args": () } NOTIFY_UNCLAIMED_GIFTS = { "task": "regluit.core.tasks.notify_unclaimed_gifts", "schedule": crontab( hour=2, minute=15), - "args": () + "args": () } # by default, in common, we don't turn any of the celerybeat jobs on -- turn them on in the local settings file @@ -433,12 +424,11 @@ PAYMENT_PROCESSOR = 'stripelib' - # we should suppress Google Analytics outside of production SHOW_GOOGLE_ANALYTICS = False # to enable uploading to S3 and integration of django-storages + django-ckeditor -# some variables to be overriddden in more specific settings files -- e.g., prod.py, +# some variables to be overriddden in more specific settings files -- e.g., prod.py, CKEDITOR_ALLOW_NONIMAGE_FILES = False AWS_ACCESS_KEY_ID = '' @@ -508,4 +498,5 @@ if AWS_SECRET_ACCESS_KEY: DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' else: - DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage' + DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage' + diff --git a/setup.py b/setup.py deleted file mode 100644 index 1e225e383..000000000 --- a/setup.py +++ /dev/null @@ -1,25 +0,0 @@ -import os -from setuptools import find_packages, setup - -with open(os.path.join(os.path.dirname(__file__), 'README.md')) as readme: - README = readme.read() - -# allow setup.py to be run from any path -os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir))) - -setup( - name='regluit', - version='3.0.0', - description='Web application for Unglue.it', - author='Free Ebook Foundation', - author_email='info@ebookfoundation.org', - url='https://unglue.it', - packages=find_packages(exclude=[ - 'bookdata', - 'deploy' - 'logs', - 'selenium', - 'static', - 'vagrant', - ]), -) \ No newline at end of file diff --git a/start.sh b/start.sh deleted file mode 100755 index 90fab66e8..000000000 --- a/start.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -django-admin.py celeryd --loglevel=INFO & -django-admin.py celerybeat -l INFO & -django-admin.py runserver 0.0.0.0:8000 diff --git a/static/css/reader/annotations.css b/static/css/reader/annotations.css deleted file mode 100644 index 7a77e668d..000000000 --- a/static/css/reader/annotations.css +++ /dev/null @@ -1,3 +0,0 @@ -.annotator-adder { - width: 80px; -} diff --git a/static/css/reader/main.css b/static/css/reader/main.css deleted file mode 100755 index 953a40b74..000000000 --- a/static/css/reader/main.css +++ /dev/null @@ -1,817 +0,0 @@ -@font-face { - font-family: 'fontello'; - src: url('../../fonts/fontello.eot?60518104'); - src: url('../../fonts/fontello.eot?60518104#iefix') format('embedded-opentype'), - url('../../fonts/fontello.woff?60518104') format('woff'), - url('../../fonts/fontello.ttf?60518104') format('truetype'), - url('../../fonts/fontello.svg?60518104#fontello') format('svg'); - font-weight: normal; - font-style: normal; -} - -body { - background: #4e4e4e; - overflow: hidden; -} - -#main { - /* height: 500px; */ - position: absolute; - width: 100%; - height: 100%; - right: 0; - /* left: 40px; */ -/* -webkit-transform: translate(40px, 0); - -moz-transform: translate(40px, 0); */ - - /* border-radius: 5px 0px 0px 5px; */ - border-radius: 5px; - background: #fff; - overflow: hidden; - -webkit-transition: -webkit-transform .4s, width .2s; - -moz-transition: -webkit-transform .4s, width .2s; - -ms-transition: -webkit-transform .4s, width .2s; - - -moz-box-shadow: inset 0 0 50px rgba(0,0,0,.1); - -webkit-box-shadow: inset 0 0 50px rgba(0,0,0,.1); - -ms-box-shadow: inset 0 0 50px rgba(0,0,0,.1); - box-shadow: inset 0 0 50px rgba(0,0,0,.1); -} - - -#titlebar { - height: 8%; - min-height: 20px; - padding: 10px; - /* margin: 0 50px 0 50px; */ - position: relative; - color: #4f4f4f; - font-weight: 100; - font-family: Georgia, "Times New Roman", Times, serif; - opacity: .5; - text-align: center; - -webkit-transition: opacity .5s; - -moz-transition: opacity .5s; - -ms-transition: opacity .5s; - z-index: 10; -} - -#titlebar:hover { - opacity: 1; -} - -#titlebar a { - width: 18px; - height: 19px; - line-height: 20px; - overflow: hidden; - display: inline-block; - opacity: .5; - padding: 4px; - border-radius: 4px; -} - -#titlebar a::before { - visibility: visible; -} - -#titlebar a:hover { - opacity: .8; - border: 1px rgba(0,0,0,.2) solid; - padding: 3px; -} - -#titlebar a:active { - opacity: 1; - color: rgba(0,0,0,.6); - /* margin: 1px -1px -1px 1px; */ - -moz-box-shadow: inset 0 0 6px rgba(155,155,155,.8); - -webkit-box-shadow: inset 0 0 6px rgba(155,155,155,.8); - -ms-box-shadow: inset 0 0 6px rgba(155,155,155,.8); - box-shadow: inset 0 0 6px rgba(155,155,155,.8); -} - -#book-title { - font-weight: 600; -} - -#title-seperator { - display: none; -} - -#viewer { - width: 80%; - height: 80%; - /* margin-left: 10%; */ - margin: 0 auto; - max-width: 1250px; - z-index: 2; - position: relative; - overflow: hidden; -} - -#viewer iframe { - border: none; -} - -#prev { - left: 40px; -} - -#next { - right: 40px; -} - -.arrow { - position: absolute; - top: 50%; - margin-top: -32px; - font-size: 64px; - color: #E2E2E2; - font-family: arial, sans-serif; - font-weight: bold; - cursor: pointer; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.arrow:hover { - color: #777; -} - -.arrow:active, -.arrow.active { - color: #000; -} - -#sidebar { - background: #6b6b6b; - position: absolute; - /* left: -260px; */ - /* -webkit-transform: translate(-260px, 0); - -moz-transform: translate(-260px, 0); */ - top: 0; - min-width: 300px; - width: 25%; - height: 100%; - -webkit-transition: -webkit-transform .5s; - -moz-transition: -moz-transform .5s; - -ms-transition: -moz-transform .5s; - - overflow: hidden; -} - -#sidebar.open { - /* left: 0; */ - /* -webkit-transform: translate(0, 0); - -moz-transform: translate(0, 0); */ -} - -#main.closed { - /* left: 300px; */ - -webkit-transform: translate(300px, 0); - -moz-transform: translate(300px, 0); - -ms-transform: translate(300px, 0); -} - -#main.single { - width: 75%; -} - -#main.single #viewer { - /* width: 60%; - margin-left: 20%; */ -} - -#panels { - background: #4e4e4e; - position: absolute; - left: 0; - top: 0; - width: 100%; - padding: 13px 0; - height: 14px; - -moz-box-shadow: 0px 1px 3px rgba(0,0,0,.6); - -webkit-box-shadow: 0px 1px 3px rgba(0,0,0,.6); - -ms-box-shadow: 0px 1px 3px rgba(0,0,0,.6); - box-shadow: 0px 1px 3px rgba(0,0,0,.6); -} - -#opener { - /* padding: 10px 10px; */ - float: left; -} - -/* #opener #slider { - width: 25px; -} */ - -#metainfo { - display: inline-block; - text-align: center; - max-width: 80%; -} - -#title-controls { - float: right; -} - -#panels a { - visibility: hidden; - width: 18px; - height: 20px; - overflow: hidden; - display: inline-block; - color: #ccc; - margin-left: 6px; -} - -#panels a::before { - visibility: visible; -} - -#panels a:hover { - color: #AAA; -} - -#panels a:active { - color: #AAA; - margin: 1px 0 -1px 6px; -} - -#panels a.active, -#panels a.active:hover { - color: #AAA; -} - -#searchBox { - width: 165px; - float: left; - margin-left: 10px; - margin-top: -1px; - /* - border-radius: 5px; - background: #9b9b9b; - float: left; - margin-left: 5px; - margin-top: -5px; - padding: 3px 10px; - color: #000; - border: none; - outline: none; */ - -} - -input::-webkit-input-placeholder { - color: #454545; -} -input:-moz-placeholder { - color: #454545; -} -input:-ms-placeholder { - color: #454545; -} - -#divider { - position: absolute; - width: 1px; - border-right: 1px #000 solid; - height: 80%; - z-index: 1; - left: 50%; - margin-left: -1px; - top: 10%; - opacity: .15; - box-shadow: -2px 0 15px rgba(0, 0, 0, 1); - display: none; -} - -#divider.show { - display: block; -} - -#loader { - position: absolute; - z-index: 10; - left: 50%; - top: 50%; - margin: -33px 0 0 -33px; -} - -#tocView, -#bookmarksView { - overflow-x: hidden; - overflow-y: hidden; - min-width: 300px; - width: 25%; - height: 100%; - visibility: hidden; - -webkit-transition: visibility 0 ease .5s; - -moz-transition: visibility 0 ease .5s; - -ms-transition: visibility 0 ease .5s; -} - - - -#sidebar.open #tocView, -#sidebar.open #bookmarksView { - overflow-y: auto; - visibility: visible; - -webkit-transition: visibility 0 ease 0; - -moz-transition: visibility 0 ease 0; - -ms-transition: visibility 0 ease 0; -} - -#sidebar.open #tocView { - display: block; -} - -#tocView > ul, -#bookmarksView > ul { - margin-top: 15px; - margin-bottom: 50px; - padding-left: 20px; - display: block; -} - -#tocView li, -#bookmarksView li { - margin-bottom:10px; - width: 225px; - font-family: Georgia, "Times New Roman", Times, serif; - list-style: none; - text-transform: capitalize; -} - -#tocView li:active, -#tocView li.currentChapter -{ - list-style: none; -} - -.list_item a { - color: #AAA; - text-decoration: none; -} - -.list_item a.chapter { - font-size: 1em; -} - -.list_item a.section { - font-size: .8em; -} - -.list_item.currentChapter > a, -.list_item a:hover { - color: #f1f1f1 -} - -/* #tocView li.openChapter > a, */ -.list_item a:hover { - color: #E2E2E2; -} - -.list_item ul { - padding-left:10px; - margin-top: 8px; - display: none; -} - -.list_item.currentChapter > ul, -.list_item.openChapter > ul { - display: block; -} - -#tocView.hidden { - display: none; -} - -.toc_toggle { - display: inline-block; - width: 14px; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.toc_toggle:before { - content: '▸'; - color: #fff; - margin-right: -4px; -} - -.currentChapter > .toc_toggle:before, -.openChapter > .toc_toggle:before { - content: '▾'; -} - -.view { - width: 300px; - height: 100%; - display: none; - padding-top: 50px; - overflow-y: auto; -} - -#searchResults { - margin-bottom: 50px; - padding-left: 20px; - display: block; -} - -#searchResults li { - margin-bottom:10px; - width: 225px; - font-family: Georgia, "Times New Roman", Times, serif; - list-style: none; -} - -#searchResults a { - color: #AAA; - text-decoration: none; -} - -#searchResults p { - text-decoration: none; - font-size: 12px; - line-height: 16px; -} - -#searchResults p .match { - background: #ccc; - color: #000; -} - -#searchResults li > p { - color: #AAA; -} - -#searchResults li a:hover { - color: #E2E2E2; -} - -#searchView.shown { - display: block; - overflow-y: scroll; -} - -#notes { - padding: 0 0 0 34px; -} - -#notes li { - color: #eee; - font-size: 12px; - width: 240px; - border-top: 1px #fff solid; - padding-top: 6px; - margin-bottom: 6px; -} - -#notes li a { - color: #fff; - display: inline-block; - margin-left: 6px; -} - -#notes li a:hover { - text-decoration: underline; -} - -#notes li img { - max-width: 240px; -} - -#note-text { - display: block; - width: 260px; - height: 80px; - margin: 0 auto; - padding: 5px; - border-radius: 5px; -} - -#note-text[disabled], #note-text[disabled="disabled"]{ - opacity: .5; -} - -#note-anchor { - margin-left: 218px; - margin-top: 5px; -} - -#settingsPanel { - display:none; -} - -#settingsPanel h3 { - color:#f1f1f1; - font-family:Georgia, "Times New Roman", Times, serif; - margin-bottom:10px; -} - -#settingsPanel ul { - margin-top:60px; - list-style-type:none; -} - -#settingsPanel li { - font-size:1em; - color:#f1f1f1; -} - -#settingsPanel .xsmall { font-size:x-small; } -#settingsPanel .small { font-size:small; } -#settingsPanel .medium { font-size:medium; } -#settingsPanel .large { font-size:large; } -#settingsPanel .xlarge { font-size:x-large; } - -.highlight { background-color: yellow } - -.modal { - position: fixed; - top: 50%; - left: 50%; - width: 50%; - width: 630px; - - height: auto; - z-index: 2000; - visibility: hidden; - margin-left: -320px; - margin-top: -160px; - -} - -.overlay { - position: fixed; - width: 100%; - height: 100%; - visibility: hidden; - top: 0; - left: 0; - z-index: 1000; - opacity: 0; - background: rgba(255,255,255,0.8); - -webkit-transition: all 0.3s; - -moz-transition: all 0.3s; - -ms-transition: all 0.3s; - transition: all 0.3s; -} - -.md-show { - visibility: visible; -} - -.md-show ~ .overlay { - opacity: 1; - visibility: visible; -} - -/* Content styles */ -.md-content { - color: #fff; - background: #6b6b6b; - position: relative; - border-radius: 3px; - margin: 0 auto; - height: 320px; -} - -.md-content h3 { - margin: 0; - padding: 6px; - text-align: center; - font-size: 22px; - font-weight: 300; - opacity: 0.8; - background: rgba(0,0,0,0.1); - border-radius: 3px 3px 0 0; -} - -.md-content > div { - padding: 15px 40px 30px; - margin: 0; - font-weight: 300; - font-size: 14px; -} - -.md-content > div p { - margin: 0; - padding: 10px 0; -} - -.md-content > div ul { - margin: 0; - padding: 0 0 30px 20px; -} - -.md-content > div ul li { - padding: 5px 0; -} - -.md-content button { - display: block; - margin: 0 auto; - font-size: 0.8em; -} - -/* Effect 1: Fade in and scale up */ -.md-effect-1 .md-content { - -webkit-transform: scale(0.7); - -moz-transform: scale(0.7); - -ms-transform: scale(0.7); - transform: scale(0.7); - opacity: 0; - -webkit-transition: all 0.3s; - -moz-transition: all 0.3s; - -ms-transition: all 0.3s; - transition: all 0.3s; -} - -.md-show.md-effect-1 .md-content { - -webkit-transform: scale(1); - -moz-transform: scale(1); - -ms-transform: scale(1); - transform: scale(1); - opacity: 1; -} - -.md-content > .closer { - font-size: 18px; - position: absolute; - right: 0; - top: 0; - font-size: 24px; - padding: 4px; -} - -@media only screen and (max-width: 1040px) { - #viewer{ - width: 50%; - margin-left: 25%; - } - - #divider, - #divider.show { - display: none; - } -} - -@media only screen and (max-width: 900px) { - #viewer{ - width: 60%; - margin-left: 20%; - } - - #prev { - left: 20px; - } - - #next { - right: 20px; - } -} - -@media only screen and (max-width: 550px) { - #viewer{ - width: 80%; - margin-left: 10%; - } - - #prev { - left: 0; - } - - #next { - right: 0; - } - - .arrow { - height: 100%; - top: 45px; - width: 10%; - text-indent: -10000px; - } - - #main { - -webkit-transform: translate(0, 0); - -moz-transform: translate(0, 0); - -ms-transform: translate(0, 0); - -webkit-transition: -webkit-transform .3s; - -moz-transition: -moz-transform .3s; - -ms-transition: -moz-transform .3s; - } - - #main.closed { - -webkit-transform: translate(260px, 0); - -moz-transform: translate(260px, 0); - -ms-transform: translate(260px, 0); - } - - #titlebar { - /* font-size: 16px; */ - /* margin: 0 50px 0 50px; */ - } - - #metainfo { - font-size: 10px; - } - - #tocView { - width: 260px; - } - - #tocView li { - font-size: 12px; - } - - #tocView > ul{ - padding-left: 10px; - } -} - - -/* For iPad portrait layouts only */ -@media only screen and (min-device-width: 481px) and (max-device-width: 1024px) and (orientation: portrait) { - #viewer iframe { - width: 460px; - height: 740px; - } -} - /*For iPad landscape layouts only */ -@media only screen and (min-device-width: 481px) and (max-device-width: 1024px) and (orientation: landscape) { - #viewer iframe { - width: 460px; - height: 415px; - } -} -/* For iPhone portrait layouts only */ -@media only screen and (max-device-width: 480px) and (orientation: portrait) { - #viewer { - width: 256px; - height: 432px; - } - #viewer iframe { - width: 256px; - height: 432px; - } -} -/* For iPhone landscape layouts only */ -@media only screen and (max-device-width: 480px) and (orientation: landscape) { - #viewer iframe { - width: 256px; - height: 124px; - } -} - -[class^="icon-"]:before, [class*=" icon-"]:before { - font-family: "fontello"; - font-style: normal; - font-weight: normal; - speak: none; - - display: inline-block; - text-decoration: inherit; - width: 1em; - margin-right: .2em; - text-align: center; - /* opacity: .8; */ - - /* For safety - reset parent styles, that can break glyph codes*/ - font-variant: normal; - text-transform: none; - - /* you can be more comfortable with increased icons size */ - font-size: 112%; -} - - -.icon-search:before { content: '\e807'; } /* '' */ -.icon-resize-full-1:before { content: '\e804'; } /* '' */ -.icon-cancel-circled2:before { content: '\e80f'; } /* '' */ -.icon-link:before { content: '\e80d'; } /* '' */ -.icon-bookmark:before { content: '\e805'; } /* '' */ -.icon-bookmark-empty:before { content: '\e806'; } /* '' */ -.icon-download-cloud:before { content: '\e811'; } /* '' */ -.icon-edit:before { content: '\e814'; } /* '' */ -.icon-menu:before { content: '\e802'; } /* '' */ -.icon-cog:before { content: '\e813'; } /* '' */ -.icon-resize-full:before { content: '\e812'; } /* '' */ -.icon-cancel-circled:before { content: '\e80e'; } /* '' */ -.icon-up-dir:before { content: '\e80c'; } /* '' */ -.icon-right-dir:before { content: '\e80b'; } /* '' */ -.icon-angle-right:before { content: '\e809'; } /* '' */ -.icon-angle-down:before { content: '\e80a'; } /* '' */ -.icon-right:before { content: '\e815'; } /* '' */ -.icon-list-1:before { content: '\e803'; } /* '' */ -.icon-list-numbered:before { content: '\e801'; } /* '' */ -.icon-columns:before { content: '\e810'; } /* '' */ -.icon-list:before { content: '\e800'; } /* '' */ -.icon-resize-small:before { content: '\e808'; } /* '' */ diff --git a/static/css/reader/normalize.css b/static/css/reader/normalize.css deleted file mode 100755 index c3e014d95..000000000 --- a/static/css/reader/normalize.css +++ /dev/null @@ -1,505 +0,0 @@ -/*! normalize.css v1.0.1 | MIT License | git.io/normalize */ - -/* ========================================================================== - HTML5 display definitions - ========================================================================== */ - -/* - * Corrects `block` display not defined in IE 6/7/8/9 and Firefox 3. - */ - -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -nav, -section, -summary { - display: block; -} - -/* - * Corrects `inline-block` display not defined in IE 6/7/8/9 and Firefox 3. - */ - -audio, -canvas, -video { - display: inline-block; - *display: inline; - *zoom: 1; -} - -/* - * Prevents modern browsers from displaying `audio` without controls. - * Remove excess height in iOS 5 devices. - */ - -audio:not([controls]) { - display: none; - height: 0; -} - -/* - * Addresses styling for `hidden` attribute not present in IE 7/8/9, Firefox 3, - * and Safari 4. - * Known issue: no IE 6 support. - */ - -[hidden] { - display: none; -} - -/* ========================================================================== - Base - ========================================================================== */ - -/* - * 1. Corrects text resizing oddly in IE 6/7 when body `font-size` is set using - * `em` units. - * 2. Prevents iOS text size adjust after orientation change, without disabling - * user zoom. - */ - -html { - font-size: 100%; /* 1 */ - -webkit-text-size-adjust: 100%; /* 2 */ - -ms-text-size-adjust: 100%; /* 2 */ -} - -/* - * Addresses `font-family` inconsistency between `textarea` and other form - * elements. - */ - -html, -button, -input, -select, -textarea { - font-family: sans-serif; -} - -/* - * Addresses margins handled incorrectly in IE 6/7. - */ - -body { - margin: 0; -} - -/* ========================================================================== - Links - ========================================================================== */ - -/* - * Addresses `outline` inconsistency between Chrome and other browsers. - */ - -a:focus { - outline: thin dotted; -} - -/* - * Improves readability when focused and also mouse hovered in all browsers. - */ - -a:active, -a:hover { - outline: 0; -} - -/* ========================================================================== - Typography - ========================================================================== */ - -/* - * Addresses font sizes and margins set differently in IE 6/7. - * Addresses font sizes within `section` and `article` in Firefox 4+, Safari 5, - * and Chrome. - */ - -h1 { - font-size: 2em; - margin: 0.67em 0; -} - -h2 { - font-size: 1.5em; - margin: 0.83em 0; -} - -h3 { - font-size: 1.17em; - margin: 1em 0; -} - -h4 { - font-size: 1em; - margin: 1.33em 0; -} - -h5 { - font-size: 0.83em; - margin: 1.67em 0; -} - -h6 { - font-size: 0.75em; - margin: 2.33em 0; -} - -/* - * Addresses styling not present in IE 7/8/9, Safari 5, and Chrome. - */ - -abbr[title] { - border-bottom: 1px dotted; -} - -/* - * Addresses style set to `bolder` in Firefox 3+, Safari 4/5, and Chrome. - */ - -b, -strong { - font-weight: bold; -} - -blockquote { - margin: 1em 40px; -} - -/* - * Addresses styling not present in Safari 5 and Chrome. - */ - -dfn { - font-style: italic; -} - -/* - * Addresses styling not present in IE 6/7/8/9. - */ - -mark { - background: #ff0; - color: #000; -} - -/* - * Addresses margins set differently in IE 6/7. - */ - -p, -pre { - margin: 1em 0; -} - -/* - * Corrects font family set oddly in IE 6, Safari 4/5, and Chrome. - */ - -code, -kbd, -pre, -samp { - font-family: monospace, serif; - _font-family: 'courier new', monospace; - font-size: 1em; -} - -/* - * Improves readability of pre-formatted text in all browsers. - */ - -pre { - white-space: pre; - white-space: pre-wrap; - word-wrap: break-word; -} - -/* - * Addresses CSS quotes not supported in IE 6/7. - */ - -q { - quotes: none; -} - -/* - * Addresses `quotes` property not supported in Safari 4. - */ - -q:before, -q:after { - content: ''; - content: none; -} - -/* - * Addresses inconsistent and variable font size in all browsers. - */ - -small { - font-size: 80%; -} - -/* - * Prevents `sub` and `sup` affecting `line-height` in all browsers. - */ - -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sup { - top: -0.5em; -} - -sub { - bottom: -0.25em; -} - -/* ========================================================================== - Lists - ========================================================================== */ - -/* - * Addresses margins set differently in IE 6/7. - */ - -dl, -menu, -ol, -ul { - margin: 1em 0; -} - -dd { - margin: 0 0 0 40px; -} - -/* - * Addresses paddings set differently in IE 6/7. - */ - -menu, -ol, -ul { - padding: 0 0 0 40px; -} - -/* - * Corrects list images handled incorrectly in IE 7. - */ - -nav ul, -nav ol { - list-style: none; - list-style-image: none; -} - -/* ========================================================================== - Embedded content - ========================================================================== */ - -/* - * 1. Removes border when inside `a` element in IE 6/7/8/9 and Firefox 3. - * 2. Improves image quality when scaled in IE 7. - */ - -img { - border: 0; /* 1 */ - -ms-interpolation-mode: bicubic; /* 2 */ -} - -/* - * Corrects overflow displayed oddly in IE 9. - */ - -svg:not(:root) { - overflow: hidden; -} - -/* ========================================================================== - Figures - ========================================================================== */ - -/* - * Addresses margin not present in IE 6/7/8/9, Safari 5, and Opera 11. - */ - -figure { - margin: 0; -} - -/* ========================================================================== - Forms - ========================================================================== */ - -/* - * Corrects margin displayed oddly in IE 6/7. - */ - -form { - margin: 0; -} - -/* - * Define consistent border, margin, and padding. - */ - -fieldset { - border: 1px solid #c0c0c0; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; -} - -/* - * 1. Corrects color not being inherited in IE 6/7/8/9. - * 2. Corrects text not wrapping in Firefox 3. - * 3. Corrects alignment displayed oddly in IE 6/7. - */ - -legend { - border: 0; /* 1 */ - padding: 0; - white-space: normal; /* 2 */ - *margin-left: -7px; /* 3 */ -} - -/* - * 1. Corrects font size not being inherited in all browsers. - * 2. Addresses margins set differently in IE 6/7, Firefox 3+, Safari 5, - * and Chrome. - * 3. Improves appearance and consistency in all browsers. - */ - -button, -input, -select, -textarea { - font-size: 100%; /* 1 */ - margin: 0; /* 2 */ - vertical-align: baseline; /* 3 */ - *vertical-align: middle; /* 3 */ -} - -/* - * Addresses Firefox 3+ setting `line-height` on `input` using `!important` in - * the UA stylesheet. - */ - -button, -input { - line-height: normal; -} - -/* - * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` - * and `video` controls. - * 2. Corrects inability to style clickable `input` types in iOS. - * 3. Improves usability and consistency of cursor style between image-type - * `input` and others. - * 4. Removes inner spacing in IE 7 without affecting normal text inputs. - * Known issue: inner spacing remains in IE 6. - */ - -button, -html input[type="button"], /* 1 */ -input[type="reset"], -input[type="submit"] { - -webkit-appearance: button; /* 2 */ - cursor: pointer; /* 3 */ - *overflow: visible; /* 4 */ -} - -/* - * Re-set default cursor for disabled elements. - */ - -button[disabled], -input[disabled] { - cursor: default; -} - -/* - * 1. Addresses box sizing set to content-box in IE 8/9. - * 2. Removes excess padding in IE 8/9. - * 3. Removes excess padding in IE 7. - * Known issue: excess padding remains in IE 6. - */ - -input[type="checkbox"], -input[type="radio"] { - box-sizing: border-box; /* 1 */ - padding: 0; /* 2 */ - *height: 13px; /* 3 */ - *width: 13px; /* 3 */ -} - -/* - * 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome. - * 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome - * (include `-moz` to future-proof). - */ -/* -input[type="search"] { - -webkit-appearance: textfield; - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; - box-sizing: content-box; -} -*/ - -/* - * Removes inner padding and search cancel button in Safari 5 and Chrome - * on OS X. - */ - -/* input[type="search"]::-webkit-search-cancel-button, -input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} */ - -/* - * Removes inner padding and border in Firefox 3+. - */ - -button::-moz-focus-inner, -input::-moz-focus-inner { - border: 0; - padding: 0; -} - -/* - * 1. Removes default vertical scrollbar in IE 6/7/8/9. - * 2. Improves readability and alignment in all browsers. - */ - -textarea { - overflow: auto; /* 1 */ - vertical-align: top; /* 2 */ -} - -/* ========================================================================== - Tables - ========================================================================== */ - -/* - * Remove most spacing between table cells. - */ - -table { - border-collapse: collapse; - border-spacing: 0; -} diff --git a/static/css/reader/popup.css b/static/css/reader/popup.css deleted file mode 100644 index c41aac716..000000000 --- a/static/css/reader/popup.css +++ /dev/null @@ -1,96 +0,0 @@ -/* http://davidwalsh.name/css-tooltips */ -/* base CSS element */ -.popup { - background: #eee; - border: 1px solid #ccc; - padding: 10px; - border-radius: 8px; - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); - position: fixed; - max-width: 300px; - font-size: 12px; - - display: none; - margin-left: 2px; - - margin-top: 30px; -} - -.popup.above { - margin-top: -10px; -} - -.popup.left { - margin-left: -20px; -} - -.popup.right { - margin-left: 40px; -} - -.pop_content { - max-height: 225px; - overflow-y: auto; -} - -.pop_content > p { - margin-top: 0; -} - -/* below */ -.popup:before { - position: absolute; - display: inline-block; - border-bottom: 10px solid #eee; - border-right: 10px solid transparent; - border-left: 10px solid transparent; - border-bottom-color: rgba(0, 0, 0, 0.2); - left: 50%; - top: -10px; - margin-left: -6px; - content: ''; -} - -.popup:after { - position: absolute; - display: inline-block; - border-bottom: 9px solid #eee; - border-right: 9px solid transparent; - border-left: 9px solid transparent; - left: 50%; - top: -9px; - margin-left: -5px; - content: ''; -} - -/* above */ -.popup.above:before { - border-bottom: none; - border-top: 10px solid #eee; - border-top-color: rgba(0, 0, 0, 0.2); - top: 100%; -} - -.popup.above:after { - border-bottom: none; - border-top: 9px solid #eee; - top: 100%; -} - -.popup.left:before, -.popup.left:after -{ - left: 20px; -} - -.popup.right:before, -.popup.right:after -{ - left: auto; - right: 20px; -} - - -.popup.show, .popup.on { - display: block; -} \ No newline at end of file diff --git a/static/fonts/fontello.eot b/static/fonts/fontello.eot deleted file mode 100644 index f63ffa043ea29008e7f5b161b87c44ce567d15fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10204 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 K{$I9!LjD)8G->Dn diff --git a/static/fonts/fontello.svg b/static/fonts/fontello.svg deleted file mode 100644 index 2db13984a..000000000 --- a/static/fonts/fontello.svg +++ /dev/null @@ -1,33 +0,0 @@ - - - -Copyright (C) 2013 by original authors @ fontello.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/static/fonts/fontello.ttf b/static/fonts/fontello.ttf deleted file mode 100644 index 95715f86629cdbe17012ceb0595caaf61c8c15cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10036 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 A2mk;8 diff --git a/static/images/reader/loader.gif b/static/images/reader/loader.gif deleted file mode 100644 index 68005bcbe63e2924bc8f6eccf5175db07490d3a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6820 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 diff --git a/static/js/greenpanel.js b/static/js/greenpanel.js new file mode 100644 index 000000000..c7a129c1b --- /dev/null +++ b/static/js/greenpanel.js @@ -0,0 +1,14 @@ +var $j = jQuery.noConflict(); + +$j().ready(function(){ + var contentblock = $j('#content-block, .user-block-hide'); + contentblock.on('mouseenter', '.panelview', function() { + $j(this).children('.panelfront').removeClass('side1').addClass('side2'); + $j(this).children('.panelback').removeClass('side2').addClass('side1'); + }); + + contentblock.on('mouseleave', '.panelview', function() { + $j(this).children('.panelback').removeClass('side1').addClass('side2'); + $j(this).children('.panelfront').removeClass('side2').addClass('side1'); + }); +}); diff --git a/static/js/reader/epub.min.js b/static/js/reader/epub.min.js deleted file mode 100644 index fff280087..000000000 --- a/static/js/reader/epub.min.js +++ /dev/null @@ -1,8 +0,0 @@ -/*! - * @overview RSVP - a tiny implementation of Promises/A+. - * @copyright Copyright (c) 2016 Yehuda Katz, Tom Dale, Stefan Penner and contributors - * @license Licensed under MIT license - * See https://raw.githubusercontent.com/tildeio/rsvp.js/master/LICENSE - * @version 3.5.0 - */ -"use strict";!function(a,b){"object"==typeof exports&&"undefined"!=typeof module?b(exports):"function"==typeof define&&define.amd?define(["exports"],b):b(a.RSVP=a.RSVP||{})}(this,function(a){function b(a,b){for(var c=0,d=a.length;c1)throw new Error("Second argument not supported");if("object"!=typeof a)throw new TypeError("Argument must be an object");return h.prototype=a,new h},Aa=[],Ba=void 0,Ca=1,Da=2,Ea=new y,Fa=new y;E.prototype._validateInput=function(a){return xa(a)},E.prototype._validationError=function(){return new Error("Array Methods must be provided an Array")},E.prototype._init=function(){this._result=new Array(this.length)},E.prototype._enumerate=function(){for(var a=this.length,b=this.promise,c=this._input,d=0;b._state===Ba&&d=i)l.resolve();else{if(c&&c.cancelled)return e.remove(),this.element.removeChild(f),void l.reject(new Error("User cancelled"));h=g,b=new EPUBJS.Chapter(this.spine[h],this.store),e.displayChapter(b,this.globalLayoutProperties).then(function(a){e.pageMap.forEach(function(a){j+=1,d.push({cfi:a.start,page:j})}),e.pageMap.length%2>0&&e.spreads&&(j+=1,d.push({cfi:e.pageMap[e.pageMap.length-1].end,page:j})),setTimeout(function(){k(l)},1)})}return l.promise}.bind(this);k().then(function(){e.remove(),this.element.removeChild(f),g.resolve(d)}.bind(this),function(a){g.reject(a)});return g.promise},EPUBJS.Book.prototype.generatePagination=function(a,b,c){var d=this,e=new RSVP.defer;return this.ready.spine.promise.then(function(){d.generatePageList(a,b,c).then(function(a){d.pageList=d.contents.pageList=a,d.pagination.process(a),d.ready.pageList.resolve(d.pageList),e.resolve(d.pageList)},function(a){e.reject(a)})}),e.promise},EPUBJS.Book.prototype.loadPagination=function(a){var b;return b="string"==typeof a?JSON.parse(a):a,b&&b.length&&(this.pageList=b,this.pagination.process(this.pageList),this.ready.pageList.resolve(this.pageList)),this.pageList},EPUBJS.Book.prototype.getPageList=function(){return this.ready.pageList.promise},EPUBJS.Book.prototype.getMetadata=function(){return this.ready.metadata.promise},EPUBJS.Book.prototype.getToc=function(){return this.ready.toc.promise},EPUBJS.Book.prototype.networkListeners=function(){var a=this;window.addEventListener("offline",function(b){a.online=!1,a.settings.storage&&a.fromStorage(!0),a.trigger("book:offline")},!1),window.addEventListener("online",function(b){a.online=!0,a.settings.storage&&a.fromStorage(!1),a.trigger("book:online")},!1)},EPUBJS.Book.prototype.listenToRenderer=function(a){var b=this;a.Events.forEach(function(c){a.on(c,function(a){b.trigger(c,a)})}),a.on("renderer:visibleRangeChanged",function(a){var b,c,d,e=[];this.pageList.length>0&&(b=this.pagination.pageFromCfi(a.start),d=this.pagination.percentageFromPage(b),e.push(b),a.end&&(c=this.pagination.pageFromCfi(a.end),e.push(c)),this.trigger("book:pageChanged",{anchorPage:b,percentage:d,pageRange:e}))}.bind(this)),a.on("render:loaded",this.loadChange.bind(this))},EPUBJS.Book.prototype.loadChange=function(a){var b,c,d=EPUBJS.core.uri(a),e=EPUBJS.core.uri(this.currentChapter.absolute);d.path!=e.path?(console.warn("Miss Match",d.path,this.currentChapter.absolute),b=this.spineIndexByURL[d.filename],c=new EPUBJS.Chapter(this.spine[b],this.store),this.currentChapter=c,this.renderer.currentChapter=c,this.renderer.afterLoad(this.renderer.render.docEl),this.renderer.beforeDisplay(function(){this.renderer.afterDisplay()}.bind(this))):this._rendering||this.renderer.reformat()},EPUBJS.Book.prototype.unlistenToRenderer=function(a){a.Events.forEach(function(b){a.off(b)})},EPUBJS.Book.prototype.coverUrl=function(){var a=this.ready.cover.promise.then(function(a){return this.settings.fromStorage?this.store.getUrl(this.contents.cover):this.settings.contained?this.zip.getUrl(this.contents.cover):this.contents.cover}.bind(this));return a.then(function(a){this.cover=a}.bind(this)),a},EPUBJS.Book.prototype.loadXml=function(a){return this.settings.fromStorage?this.store.getXml(a,this.settings.encoding):this.settings.contained?this.zip.getXml(a,this.settings.encoding):EPUBJS.core.request(a,"xml",this.settings.withCredentials)},EPUBJS.Book.prototype.urlFrom=function(a){var b,c=EPUBJS.core.uri(a),d=c.protocol,e="/"==c.path[0],f=window.location,g=f.origin||f.protocol+"//"+f.host,h=document.getElementsByTagName("base");return h.length&&(b=h[0].href),c.protocol?c.origin+c.path:!d&&e?(b||g)+c.path:d||e?void 0:EPUBJS.core.resolveUrl(b||f.pathname,c.path)},EPUBJS.Book.prototype.unarchive=function(a){return this.zip=new EPUBJS.Unarchiver,this.store=this.zip,this.zip.open(a)},EPUBJS.Book.prototype.isContained=function(a){if(a instanceof ArrayBuffer)return!0;var b=EPUBJS.core.uri(a);return!(!b.extension||"epub"!=b.extension&&"zip"!=b.extension)},EPUBJS.Book.prototype.isSaved=function(a){var b;return!!localStorage&&(b=localStorage.getItem(a),!(!localStorage||null===b))},EPUBJS.Book.prototype.generateBookKey=function(a){return"epubjs:"+EPUBJS.VERSION+":"+window.location.host+":"+a},EPUBJS.Book.prototype.saveContents=function(){if(!localStorage)return!1;localStorage.setItem(this.settings.bookKey,JSON.stringify(this.contents))},EPUBJS.Book.prototype.removeSavedContents=function(){if(!localStorage)return!1;localStorage.removeItem(this.settings.bookKey)},EPUBJS.Book.prototype.renderTo=function(a){var b=this;if(EPUBJS.core.isElement(a))this.element=a;else{if("string"!=typeof a)return void console.error("Not an Element");this.element=EPUBJS.core.getEl(a)}return this.opened.then(function(){return b.renderer.initialize(b.element,b.settings.width,b.settings.height),b.metadata.direction&&b.renderer.setDirection(b.metadata.direction),b._rendered(),b.startDisplay()})},EPUBJS.Book.prototype.startDisplay=function(){return this.settings.goto?this.goto(this.settings.goto):this.settings.previousLocationCfi?this.gotoCfi(this.settings.previousLocationCfi):this.displayChapter(this.spinePos,this.settings.displayLastPage)},EPUBJS.Book.prototype.restore=function(a){var b,c=this,d=["manifest","spine","metadata","cover","toc","spineNodeIndex","spineIndexByURL","globalLayoutProperties"],e=!1,f=this.generateBookKey(a),g=localStorage.getItem(f),h=d.length;if(this.settings.clearSaved&&(e=!0),!e&&"undefined"!=g&&null!==g)for(c.contents=JSON.parse(g),b=0;b=this.spine.length)&&(console.warn("Not A Valid Location"),f=0,b=!1,e=!1),g=new EPUBJS.Chapter(this.spine[f],this.store),this._rendering=!0,this._needsAssetReplacement()&&g.registerHook("beforeChapterRender",[EPUBJS.replace.head,EPUBJS.replace.resources,EPUBJS.replace.posters,EPUBJS.replace.svg],!0),h.currentChapter=g,d=h.renderer.displayChapter(g,this.globalLayoutProperties),e?h.renderer.gotoCfi(e):b&&h.renderer.lastPage(),d.then(function(a){h.spinePos=f,i.resolve(h.renderer),h.settings.fromStorage===!1&&h.settings.contained===!1&&h.preloadNextChapter(),h._rendering=!1,h._displayQ.dequeue(),0===h._displayQ.length()&&h._gotoQ.dequeue()},function(a){console.error("Could not load Chapter: "+g.absolute,a),h.trigger("book:chapterLoadFailed",g.absolute),h._rendering=!1,i.reject(a)}),i.promise):(this._q.enqueue("displayChapter",arguments),i.reject({message:"Rendering",stack:(new Error).stack}),i.promise)},EPUBJS.Book.prototype.nextPage=function(a){var a=a||new RSVP.defer;return this.isRendered?this.renderer.nextPage()?(a.resolve(!0),a.promise):this.nextChapter(a):(this._q.enqueue("nextPage",[a]),a.promise)},EPUBJS.Book.prototype.prevPage=function(a){var a=a||new RSVP.defer;return this.isRendered?this.renderer.prevPage()?(a.resolve(!0),a.promise):this.prevChapter(a):(this._q.enqueue("prevPage",[a]),a.promise)},EPUBJS.Book.prototype.nextChapter=function(a){var a=a||new RSVP.defer;if(this.spinePos0){for(var b=this.spinePos-1;this.spine[b]&&this.spine[b].linear&&"no"==this.spine[b].linear;)b--;if(b>=0)return this.displayChapter(b,!0,a)}return this.trigger("book:atStart"),a.resolve(!0),a.promise},EPUBJS.Book.prototype.getCurrentLocationCfi=function(){return!!this.isRendered&&this.renderer.currentLocationCfi},EPUBJS.Book.prototype.goto=function(a){return 0===a.indexOf("epubcfi(")?this.gotoCfi(a):a.indexOf("%")===a.length-1?this.gotoPercentage(parseInt(a.substring(0,a.length-1))/100):"number"==typeof a||isNaN(a)===!1?this.gotoPage(a):this.gotoHref(a)},EPUBJS.Book.prototype.gotoCfi=function(a,b){var c,d,e,f,g,h=b||new RSVP.defer;return this.isRendered?this._moving||this._rendering?(console.warn("Renderer is moving"),this._gotoQ.enqueue("gotoCfi",[a,h]),!1):(c=new EPUBJS.EpubCFI(a),(d=c.spinePos)!=-1&&(e=this.spine[d],f=h.promise,this._moving=!0,this.currentChapter&&this.spinePos===d?(this.renderer.gotoCfi(c),this._moving=!1,h.resolve(this.renderer.currentLocationCfi)):(e&&d!=-1||(d=0,e=this.spine[d]),g=this.displayChapter(a),g.then(function(a){this._moving=!1,h.resolve(a.currentLocationCfi)}.bind(this),function(){this._moving=!1}.bind(this))),f.then(function(){this._gotoQ.dequeue()}.bind(this)),f)):(console.warn("Not yet Rendered"),this.settings.previousLocationCfi=a,!1)},EPUBJS.Book.prototype.gotoHref=function(a,b){var c,d,e,f,g,h=b||new RSVP.defer;return this.isRendered?this._moving||this._rendering?(this._gotoQ.enqueue("gotoHref",[a,h]),!1):(c=a.split("#"),d=c[0],e=c[1]||!1,f=d.search("://")==-1?d.replace(EPUBJS.core.uri(this.settings.contentsPath).path,""):d.replace(this.settings.contentsPath,""),g=this.spineIndexByURL[f],d||(g=this.currentChapter?this.currentChapter.spinePos:0),"number"==typeof g&&(this.currentChapter&&g==this.currentChapter.spinePos?(e?this.renderer.section(e):this.renderer.firstPage(),h.resolve(this.renderer.currentLocationCfi),h.promise.then(function(){this._gotoQ.dequeue()}.bind(this)),h.promise):this.displayChapter(g).then(function(){e&&this.renderer.section(e),h.resolve(this.renderer.currentLocationCfi)}.bind(this)))):(this.settings.goto=a,!1)},EPUBJS.Book.prototype.gotoPage=function(a){var b=this.pagination.cfiFromPage(a);return this.gotoCfi(b)},EPUBJS.Book.prototype.gotoPercentage=function(a){var b=this.pagination.pageFromPercentage(a);return this.gotoPage(b)},EPUBJS.Book.prototype.preloadNextChapter=function(){var a,b=this.spinePos+1;if(b>=this.spine.length)return!1;(a=new EPUBJS.Chapter(this.spine[b]))&&EPUBJS.core.request(a.absolute)},EPUBJS.Book.prototype.storeOffline=function(){var a=this,b=EPUBJS.core.values(this.manifest);return this.store.put(b).then(function(){a.settings.stored=!0,a.trigger("book:stored")})},EPUBJS.Book.prototype.availableOffline=function(){return this.settings.stored>0},EPUBJS.Book.prototype.toStorage=function(){var a=this.settings.bookKey;this.store.isStored(a).then(function(b){return b===!0?(this.settings.stored=!0,!0):this.storeOffline().then(function(){this.store.token(a,!0)}.bind(this))}.bind(this))},EPUBJS.Book.prototype.fromStorage=function(a){EPUBJS.replace.head,EPUBJS.replace.resources,EPUBJS.replace.posters,EPUBJS.replace.svg;this.contained||this.settings.contained||(this.online&&this.opened.then(this.toStorage.bind(this)),this.store&&this.settings.fromStorage&&a===!1?(this.settings.fromStorage=!1,this.store.off("offline"),this.store=!1):this.settings.fromStorage||(this.store=new EPUBJS.Storage(this.settings.credentials),this.store.on("offline",function(a){a?(this.offline=!0,this.settings.fromStorage=!0,this.trigger("book:offline")):(this.offline=!1,this.settings.fromStorage=!1,this.trigger("book:online"))}.bind(this))))},EPUBJS.Book.prototype.setStyle=function(a,b,c){var d=["color","background","background-color"];if(!this.isRendered)return this._q.enqueue("setStyle",arguments);this.settings.styles[a]=b,this.renderer.setStyle(a,b,c),d.indexOf(a)===-1&&this.renderer.reformat()},EPUBJS.Book.prototype.removeStyle=function(a){if(!this.isRendered)return this._q.enqueue("removeStyle",arguments);this.renderer.removeStyle(a),this.renderer.reformat(),delete this.settings.styles[a]},EPUBJS.Book.prototype.resetClasses=function(a){if(!this.isRendered)return this._q.enqueue("setClasses",arguments);a.constructor===String&&(a=[a]),this.settings.classes=a,this.renderer.setClasses(this.settings.classes),this.renderer.reformat()},EPUBJS.Book.prototype.addClass=function(a){if(!this.isRendered)return this._q.enqueue("addClass",arguments);this.settings.classes.indexOf(a)==-1&&this.settings.classes.push(a),this.renderer.setClasses(this.settings.classes),this.renderer.reformat()},EPUBJS.Book.prototype.removeClass=function(a){if(!this.isRendered)return this._q.enqueue("removeClass",arguments);var b=this.settings.classes.indexOf(a);b!=-1&&(delete this.settings.classes[b],this.renderer.setClasses(this.settings.classes),this.renderer.reformat())},EPUBJS.Book.prototype.addHeadTag=function(a,b){if(!this.isRendered)return this._q.enqueue("addHeadTag",arguments);this.settings.headTags[a]=b},EPUBJS.Book.prototype.useSpreads=function(a){console.warn("useSpreads is deprecated, use forceSingle or set a layoutOveride instead"),a===!1?this.forceSingle(!0):this.forceSingle(!1)},EPUBJS.Book.prototype.forceSingle=function(a){var b=void 0===a||a;this.renderer.forceSingle(b),this.settings.forceSingle=b,this.isRendered&&this.renderer.reformat()},EPUBJS.Book.prototype.setMinSpreadWidth=function(a){this.settings.minSpreadWidth=a,this.isRendered&&(this.renderer.setMinSpreadWidth(this.settings.minSpreadWidth),this.renderer.reformat())},EPUBJS.Book.prototype.setGap=function(a){this.settings.gap=a,this.isRendered&&(this.renderer.setGap(this.settings.gap),this.renderer.reformat())},EPUBJS.Book.prototype.chapter=function(a){var b,c,d=this.spineIndexByURL[a];return d&&(b=this.spine[d],c=new EPUBJS.Chapter(b,this.store,this.settings.withCredentials),c.load()),c},EPUBJS.Book.prototype.unload=function(){this.settings.restore&&localStorage&&this.saveContents(),this.unlistenToRenderer(this.renderer),this.trigger("book:unload")},EPUBJS.Book.prototype.destroy=function(){window.removeEventListener("beforeunload",this.unload),this.currentChapter&&this.currentChapter.unload(),this.unload(),this.renderer&&this.renderer.remove()},EPUBJS.Book.prototype._ready=function(){this.trigger("book:ready")},EPUBJS.Book.prototype._rendered=function(a){this.isRendered=!0,this.trigger("book:rendered"),this._q.flush()},EPUBJS.Book.prototype.applyStyles=function(a,b){a.applyStyles(this.settings.styles),b()},EPUBJS.Book.prototype.applyClasses=function(a,b){a.setClasses(this.settings.classes),b()},EPUBJS.Book.prototype.applyHeadTags=function(a,b){a.applyHeadTags(this.settings.headTags),b()},EPUBJS.Book.prototype._registerReplacements=function(a){a.registerHook("beforeChapterDisplay",this.applyStyles.bind(this,a),!0),a.registerHook("beforeChapterDisplay",this.applyHeadTags.bind(this,a),!0),a.registerHook("beforeChapterDisplay",this.applyClasses.bind(this,a),!0),a.registerHook("beforeChapterDisplay",EPUBJS.replace.hrefs.bind(this),!0)},EPUBJS.Book.prototype._needsAssetReplacement=function(){return!!this.settings.fromStorage||!!this.settings.contained},EPUBJS.Book.prototype.parseLayoutProperties=function(a){return{layout:this.settings.layoutOveride&&this.settings.layoutOveride.layout||a.layout||"reflowable",spread:this.settings.layoutOveride&&this.settings.layoutOveride.spread||a.spread||"auto",orientation:this.settings.layoutOveride&&this.settings.layoutOveride.orientation||a.orientation||"auto"}},RSVP.EventTarget.mixin(EPUBJS.Book.prototype),RSVP.on("error",function(a){console.error(a)}),RSVP.configure("instrument",!0),EPUBJS.Chapter=function(a,b,c){this.href=a.href,this.absolute=a.url,this.id=a.id,this.spinePos=a.index,this.cfiBase=a.cfiBase,this.properties=a.properties,this.manifestProperties=a.manifestProperties,this.linear=a.linear,this.pages=1,this.store=b,this.credentials=c,this.epubcfi=new EPUBJS.EpubCFI,this.deferred=new RSVP.defer,this.loaded=this.deferred.promise,EPUBJS.Hooks.mixin(this),this.getHooks("beforeChapterRender"),this.caches={}},EPUBJS.Chapter.prototype.load=function(a,b){var c,d=a||this.store,e=b||this.credentials;return c=d?d.getXml(this.absolute):EPUBJS.core.request(this.absolute,!1,e),c.then(function(a){try{this.setDocument(a),this.deferred.resolve(this)}catch(a){this.deferred.reject({message:this.absolute+" -> "+a.message,stack:(new Error).stack})}}.bind(this)),c},EPUBJS.Chapter.prototype.render=function(a){return this.load().then(function(a){var b=a.querySelector("head"),c=a.createElement("base");return c.setAttribute("href",this.absolute),b.insertBefore(c,b.firstChild),this.contents=a,new RSVP.Promise(function(b,c){this.triggerHooks("beforeChapterRender",function(){b(a)}.bind(this),this)}.bind(this))}.bind(this)).then(function(a){return(new XMLSerializer).serializeToString(a)}.bind(this))},EPUBJS.Chapter.prototype.url=function(a){var b,c=new RSVP.defer,d=a||this.store,e=this;return d?this.tempUrl?(b=this.tempUrl,c.resolve(b)):d.getUrl(this.absolute).then(function(a){e.tempUrl=a,c.resolve(a)}):(b=this.absolute,c.resolve(b)),c.promise},EPUBJS.Chapter.prototype.setPages=function(a){this.pages=a},EPUBJS.Chapter.prototype.getPages=function(a){return this.pages},EPUBJS.Chapter.prototype.getID=function(){return this.ID},EPUBJS.Chapter.prototype.unload=function(a){this.document=null,this.tempUrl&&a&&(a.revokeUrl(this.tempUrl),this.tempUrl=!1)},EPUBJS.Chapter.prototype.setDocument=function(a){this.document=a,this.contents=a.documentElement,!this.document.evaluate&&document.evaluate&&(this.document.evaluate=document.evaluate)},EPUBJS.Chapter.prototype.cfiFromRange=function(a){var b,c,d,e,f,g,h;if(this.document){if(void 0!==document.evaluate){if(c=EPUBJS.core.getElementXPath(a.startContainer),d=EPUBJS.core.getElementXPath(a.endContainer),e=this.document.evaluate(c,this.document,EPUBJS.core.nsResolver,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue,a.collapsed||(f=this.document.evaluate(d,this.document,EPUBJS.core.nsResolver,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue),b=this.document.createRange(),e)try{b.setStart(e,a.startOffset),!a.collapsed&&f&&b.setEnd(f,a.endOffset)}catch(a){console.log("missed"),e=!1}e||(console.log("not found, try fuzzy match"),g=EPUBJS.core.cleanStringForXpath(a.startContainer.textContent),c="//text()[contains(.,"+g+")]",(e=this.document.evaluate(c,this.document,EPUBJS.core.nsResolver,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue)&&(b.setStart(e,a.startOffset),a.collapsed||(h=EPUBJS.core.cleanStringForXpath(a.endContainer.textContent),d="//text()[contains(.,"+h+")]",(f=this.document.evaluate(d,this.document,EPUBJS.core.nsResolver,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue)&&b.setEnd(f,a.endOffset))))}else b=a;return this.epubcfi.generateCfiFromRange(b,this.cfiBase)}},EPUBJS.Chapter.prototype.find=function(a){var b=this,c=[],d=a.toLowerCase(),e=function(a){for(var e,f,g,h=a.textContent.toLowerCase(),i=b.document.createRange(),j=-1,k=150;f!=-1;)f=h.indexOf(d,j+1),f!=-1&&(i=b.document.createRange(),i.setStart(a,f),i.setEnd(a,f+d.length),e=b.cfiFromRange(i),a.textContent.lengthb?1:a0?i:i+1:0===f?i:f===-1?EPUBJS.core.locationOf(a,b,c,i,h):EPUBJS.core.locationOf(a,b,c,g,i))},EPUBJS.core.indexOfSorted=function(a,b,c,d,e){var f,g=d||0,h=e||b.length,i=parseInt(g+(h-g)/2);return c||(c=function(a,b){return a>b?1:a0;){if(c=d.shift(),"text"===c.type?(e=g.childNodes[c.index],g=e.parentNode||g):g=c.id?f.getElementById(c.id):h[c.index],!g||void 0===g)return console.error("No Element For",c,a.str),!1;h=Array.prototype.slice.call(g.children)}return g},EPUBJS.EpubCFI.prototype.compare=function(a,b){if("string"==typeof a&&(a=new EPUBJS.EpubCFI(a)),"string"==typeof b&&(b=new EPUBJS.EpubCFI(b)),a.spinePos>b.spinePos)return 1;if(a.spinePosb.steps[c].index)return 1;if(a.steps[c].indexb.characterOffset?1:a.characterOffset")},EPUBJS.EpubCFI.prototype.generateRangeFromCfi=function(a,b){var c,d,e,f,g,h,i=b||document,j=i.createRange();return"string"==typeof a&&(a=this.parse(a)),a.spinePos!==-1&&(c=a.steps[a.steps.length-1],void 0!==document.evaluate?(d=this.generateXpathFromSteps(a.steps),e=i.evaluate(d,i,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue):(g=this.generateQueryFromSteps(a.steps),(h=i.querySelector(g))&&"text"==c.type&&(e=h.childNodes[c.index])),e?(e&&a.characterOffset>=0?(f=e.length,a.characterOffset-1&&this.hooks[a].splice(c,1):Array.isArray(b)&&b.forEach(function(b){(c=this.hooks[a].indexOf(b))>-1&&this.hooks[a].splice(c,1)},this))},a.prototype.triggerHooks=function(a,b,c){function d(){--f<=0&&b&&b()}var e,f;if(void 0===this.hooks[a])return!1;e=this.hooks[a],f=e.length,0===f&&b&&b(),e.forEach(function(a){a(d,c)})},{register:function(a){if(void 0===EPUBJS.hooks[a]&&(EPUBJS.hooks[a]={}),"object"!=typeof EPUBJS.hooks[a])throw"Already registered: "+a;return EPUBJS.hooks[a]},mixin:function(b){for(var c in a.prototype)b[c]=a.prototype[c]}}}(),EPUBJS.Layout=EPUBJS.Layout||{},EPUBJS.Layout.isFixedLayout=function(a){var b=a.querySelector("[name=viewport]");if(!b||!b.hasAttribute("content"))return!1;var c=b.getAttribute("content");return/width=(\d+)/.test(c)&&/height=(\d+)/.test(c)},EPUBJS.Layout.Reflowable=function(){this.documentElement=null,this.spreadWidth=null},EPUBJS.Layout.Reflowable.prototype.format=function(a,b,c,d){var e=EPUBJS.core.prefixed("columnAxis"),f=EPUBJS.core.prefixed("columnGap"),g=EPUBJS.core.prefixed("columnWidth"),h=EPUBJS.core.prefixed("columnFill"),i=Math.floor(b),j=Math.floor(i/8),k=d>=0?d:j%2==0?j:j-1;return this.documentElement=a,this.spreadWidth=i+k,a.style.overflow="hidden",a.style.width=i+"px",a.style.height=c+"px",a.style[e]="horizontal",a.style[h]="auto",a.style[g]=i+"px",a.style[f]=k+"px",this.colWidth=i,this.gap=k,{pageWidth:this.spreadWidth,pageHeight:c}},EPUBJS.Layout.Reflowable.prototype.calculatePages=function(){var a,b;return this.documentElement.style.width="auto",a=this.documentElement.scrollWidth,b=Math.ceil(a/this.spreadWidth),{displayedPages:b,pageCount:b}},EPUBJS.Layout.ReflowableSpreads=function(){this.documentElement=null,this.spreadWidth=null},EPUBJS.Layout.ReflowableSpreads.prototype.format=function(a,b,c,d){var e=EPUBJS.core.prefixed("columnAxis"),f=EPUBJS.core.prefixed("columnGap"),g=EPUBJS.core.prefixed("columnWidth"),h=EPUBJS.core.prefixed("columnFill"),i=2,j=Math.floor(b),k=j%2==0?j:j-1,l=Math.floor(k/8),m=d>=0?d:l%2==0?l:l-1,n=Math.floor((k-m)/i);return this.documentElement=a,this.spreadWidth=(n+m)*i,a.style.overflow="hidden",a.style.width=k+"px",a.style.height=c+"px",a.style[e]="horizontal",a.style[h]="auto",a.style[f]=m+"px",a.style[g]=n+"px",this.colWidth=n,this.gap=m,{pageWidth:this.spreadWidth,pageHeight:c}},EPUBJS.Layout.ReflowableSpreads.prototype.calculatePages=function(){var a=this.documentElement.scrollWidth,b=Math.ceil(a/this.spreadWidth);return this.documentElement.style.width=b*this.spreadWidth-this.gap+"px",{displayedPages:b,pageCount:2*b}},EPUBJS.Layout.Fixed=function(){this.documentElement=null},EPUBJS.Layout.Fixed.prototype.format=function(a,b,c,d){var e,f,g,h,i=EPUBJS.core.prefixed("columnWidth"),j=EPUBJS.core.prefixed("transform"),k=EPUBJS.core.prefixed("transformOrigin"),l=a.querySelector("[name=viewport]");this.documentElement=a,l&&l.hasAttribute("content")&&(e=l.getAttribute("content"),f=e.split(","),f[0]&&(g=f[0].replace("width=","")),f[1]&&(h=f[1].replace("height=","")));var m=b/g,n=c/h,o=m=d?g.resolve():(c=f,b=new EPUBJS.Chapter(this.spine[c],this.store,this.credentials),this.process(b).then(function(){setTimeout(function(){e(g)},1)})),g.promise}.bind(this);return"number"==typeof a&&(this.break=a),e().then(function(){this.total=this._locations.length-1,this._currentCfi&&(this.currentLocation=this._currentCfi),b.resolve(this._locations)}.bind(this)),b.promise},EPUBJS.Locations.prototype.process=function(a){return a.load().then(function(b){var c,d,e,f=b,g=f.documentElement.querySelector("body"),h=0,i=this.break;this.sprint(g,function(b){var g,j=b.length,k=0;if(0===b.textContent.trim().length)return!1;for(0===h&&(c=f.createRange(),c.setStart(b,0)),g=i-h,g>j&&(h+=j,k=j);k=j?(h+=j-k,k=j):(k+=g,c.setEnd(b,k),e=a.cfiFromRange(c),this._locations.push(e),h=0);d=b}.bind(this)),c&&(c.setEnd(d,d.length),e=a.cfiFromRange(c),this._locations.push(e),h=0)}.bind(this))},EPUBJS.Locations.prototype.sprint=function(a,b){for(var c,d=document.createTreeWalker(a,NodeFilter.SHOW_TEXT,null,!1);c=d.nextNode();)b(c)},EPUBJS.Locations.prototype.locationFromCfi=function(a){return 0===this._locations.length?-1:EPUBJS.core.locationOf(a,this._locations,this.epubcfi.compare)},EPUBJS.Locations.prototype.percentageFromCfi=function(a){var b=this.locationFromCfi(a);return this.percentageFromLocation(b)},EPUBJS.Locations.prototype.percentageFromLocation=function(a){return a&&this.total?a/this.total:0},EPUBJS.Locations.prototype.cfiFromLocation=function(a){var b=-1;return"number"!=typeof a&&(a=parseInt(a)),a>=0&&a1?a/100:a,c=Math.ceil(this.total*b);return this.cfiFromLocation(c)},EPUBJS.Locations.prototype.load=function(a){return this._locations=JSON.parse(a),this.total=this._locations.length-1,this._locations},EPUBJS.Locations.prototype.save=function(a){return JSON.stringify(this._locations)},EPUBJS.Locations.prototype.getCurrent=function(a){return this._current},EPUBJS.Locations.prototype.setCurrent=function(a){var b;if("string"==typeof a)this._currentCfi=a;else{if("number"!=typeof a)return;this._current=a}0!==this._locations.length&&("string"==typeof a?(b=this.locationFromCfi(a),this._current=b):b=a,this.trigger("changed",{percentage:this.percentageFromLocation(b)}))},Object.defineProperty(EPUBJS.Locations.prototype,"currentLocation",{get:function(){return this._current},set:function(a){this.setCurrent(a)}}),RSVP.EventTarget.mixin(EPUBJS.Locations.prototype),EPUBJS.Pagination=function(a){this.pages=[],this.locations=[],this.epubcfi=new EPUBJS.EpubCFI,a&&a.length&&this.process(a)},EPUBJS.Pagination.prototype.process=function(a){a.forEach(function(a){this.pages.push(a.page),this.locations.push(a.cfi)},this),this.pageList=a,this.firstPage=parseInt(this.pages[0]),this.lastPage=parseInt(this.pages[this.pages.length-1]),this.totalPages=this.lastPage-this.firstPage},EPUBJS.Pagination.prototype.pageFromCfi=function(a){var b=-1;if(0===this.locations.length)return-1;var c=EPUBJS.core.indexOfSorted(a,this.locations,this.epubcfi.compare);return c!=-1?b=this.pages[c]:(c=EPUBJS.core.locationOf(a,this.locations,this.epubcfi.compare),void 0!==(b=c-1>=0?this.pages[c-1]:this.pages[0])||(b=-1)),b},EPUBJS.Pagination.prototype.cfiFromPage=function(a){var b=-1;"number"!=typeof a&&(a=parseInt(a));var c=this.pages.indexOf(a);return c!=-1&&(b=this.locations[c]),b},EPUBJS.Pagination.prototype.pageFromPercentage=function(a){return Math.round(this.totalPages*a)},EPUBJS.Pagination.prototype.percentageFromPage=function(a){var b=(a-this.firstPage)/this.totalPages;return Math.round(1e3*b)/1e3},EPUBJS.Pagination.prototype.percentageFromCfi=function(a){var b=this.pageFromCfi(a);return this.percentageFromPage(b)},EPUBJS.Parser=function(a){this.baseUrl=a||""},EPUBJS.Parser.prototype.container=function(a){var b,c,d,e;return a?(b=a.querySelector("rootfile"))?(c=b.getAttribute("full-path"),d=EPUBJS.core.uri(c).directory,e=a.xmlEncoding,{packagePath:c,basePath:d,encoding:e}):void console.error("No RootFile Found"):void console.error("Container File Not Found")},EPUBJS.Parser.prototype.identifier=function(a){var b;return a?(b=a.querySelector("metadata"),b?this.getElementText(b,"identifier"):void console.error("No Metadata Found")):void console.error("Package File Not Found")},EPUBJS.Parser.prototype.packageContents=function(a,b){var c,d,e,f,g,h,i,j,k,l,m,n=this;return b&&(this.baseUrl=b),a?(c=a.querySelector("metadata"))?(d=a.querySelector("manifest"))?(e=a.querySelector("spine"))?(f=n.manifest(d),g=n.findNavPath(d),h=n.findTocPath(d,e),i=n.findCoverPath(a),j=Array.prototype.indexOf.call(e.parentNode.childNodes,e),k=n.spine(e,f),l={},k.forEach(function(a){l[a.href]=a.index}),m=n.metadata(c),m.direction=e.getAttribute("page-progression-direction"),{metadata:m,spine:k,manifest:f,navPath:g,tocPath:h,coverPath:i,spineNodeIndex:j,spineIndexByURL:l}):void console.error("No Spine Found"):void console.error("No Manifest Found"):void console.error("No Metadata Found"):void console.error("Package File Not Found")},EPUBJS.Parser.prototype.findNavPath=function(a){var b=a.querySelector("item[properties$='nav'], item[properties^='nav '], item[properties*=' nav ']");return!!b&&b.getAttribute("href")},EPUBJS.Parser.prototype.findTocPath=function(a,b){var c,d=a.querySelector("item[media-type='application/x-dtbncx+xml']");return d||(c=b.getAttribute("toc"))&&(d=a.querySelector("item[id='"+c+"']")),!!d&&d.getAttribute("href")},EPUBJS.Parser.prototype.metadata=function(a){var b={},c=this;return b.bookTitle=c.getElementText(a,"title"),b.creator=c.getElementText(a,"creator"),b.description=c.getElementText(a,"description"),b.pubdate=c.getElementText(a,"date"),b.publisher=c.getElementText(a,"publisher"),b.identifier=c.getElementText(a,"identifier"),b.language=c.getElementText(a,"language"),b.rights=c.getElementText(a,"rights"),b.modified_date=c.querySelectorText(a,"meta[property='dcterms:modified']"),b.layout=c.querySelectorText(a,"meta[property='rendition:layout']"),b.orientation=c.querySelectorText(a,"meta[property='rendition:orientation']"),b.spread=c.querySelectorText(a,"meta[property='rendition:spread']"),b},EPUBJS.Parser.prototype.findCoverPath=function(a){if("2.0"===a.querySelector("package").getAttribute("version")){var b=a.querySelector('meta[name="cover"]');if(b){var c=b.getAttribute("content"),d=a.querySelector("item[id='"+c+"']");return!!d&&d.getAttribute("href")}return!1}var e=a.querySelector("item[properties='cover-image']");return!!e&&e.getAttribute("href")},EPUBJS.Parser.prototype.getElementText=function(a,b){var c,d=a.getElementsByTagNameNS("http://purl.org/dc/elements/1.1/",b);return d&&0!==d.length?(c=d[0],c.childNodes.length?c.childNodes[0].nodeValue:""):""},EPUBJS.Parser.prototype.querySelectorText=function(a,b){var c=a.querySelector(b);return c&&c.childNodes.length?c.childNodes[0].nodeValue:""},EPUBJS.Parser.prototype.manifest=function(a){var b=this.baseUrl,c={},d=a.querySelectorAll("item");return Array.prototype.slice.call(d).forEach(function(a){var d=a.getAttribute("id"),e=a.getAttribute("href")||"",f=a.getAttribute("media-type")||"",g=a.getAttribute("properties")||"";c[d]={href:e,url:b+e,type:f,properties:g}}),c},EPUBJS.Parser.prototype.spine=function(a,b){var c=a.getElementsByTagName("itemref"),d=Array.prototype.slice.call(c),e=EPUBJS.core.indexOfElementNode(a),f=new EPUBJS.EpubCFI;return d.map(function(a,c){var d=a.getAttribute("idref"),g=f.generateChapterComponent(e,c,d),h=a.getAttribute("properties")||"",i=h.length?h.split(" "):[],j=b[d].properties,k=j.length?j.split(" "):[];return{id:d,linear:a.getAttribute("linear")||"",properties:i,manifestProperties:k,href:b[d].href,url:b[d].url,index:c,cfiBase:g,cfi:"epubcfi("+g+")"}})},EPUBJS.Parser.prototype.querySelectorByType=function(a,b,c){var d=a.querySelector(b+'[*|type="'+c+'"]');if(null!==d&&0!==d.length)return d;d=a.querySelectorAll(b);for(var e=0;e1&&d[1],{cfi:f,href:h,packageUrl:e,page:j}):{href:h,page:j}},EPUBJS.Render.Iframe=function(){this.iframe=null,this.document=null,this.window=null,this.docEl=null,this.bodyEl=null,this.leftPos=0,this.pageWidth=0,this.id=EPUBJS.core.uuid()},EPUBJS.Render.Iframe.prototype.create=function(){return this.element=document.createElement("div"),this.element.id="epubjs-view:"+this.id,this.isMobile=navigator.userAgent.match(/(iPad|iPhone|iPod|Mobile|Android)/g),this.transform=EPUBJS.core.prefixed("transform"),this.element},EPUBJS.Render.Iframe.prototype.addIframe=function(){return this.iframe=document.createElement("iframe"),this.iframe.id="epubjs-iframe:"+this.id,this.iframe.scrolling=this.scrolling||"no",this.iframe.seamless="seamless",this.iframe.style.border="none",this.iframe.addEventListener("load",this.loaded.bind(this),!1),(this._width||this._height)&&(this.iframe.height=this._height,this.iframe.width=this._width),this.iframe},EPUBJS.Render.Iframe.prototype.load=function(a,b){var c=this,d=new RSVP.defer;return this.window&&this.unload(),this.iframe&&this.element.removeChild(this.iframe),this.iframe=this.addIframe(),this.element.appendChild(this.iframe),this.iframe.onload=function(a){c.document=c.iframe.contentDocument,c.docEl=c.document.documentElement,c.headEl=c.document.head,c.bodyEl=c.document.body||c.document.querySelector("body"),c.window=c.iframe.contentWindow,c.window.addEventListener("resize",c.resized.bind(c),!1),c.leftPos=0,c.setLeft(0),c.bodyEl&&(c.bodyEl.style.margin="0"),d.resolve(c.docEl)},this.iframe.onerror=function(a){d.reject({message:"Error Loading Contents: "+a,stack:(new Error).stack})},this.document=this.iframe.contentDocument,this.document?(this.iframe.contentDocument.open(),this.iframe.contentDocument.write(a),this.iframe.contentDocument.close(),d.promise):(d.reject(new Error("No Document Available")),d.promise)},EPUBJS.Render.Iframe.prototype.loaded=function(a){var b,c,d=this.iframe.contentWindow.location.href;this.document=this.iframe.contentDocument,this.docEl=this.document.documentElement,this.headEl=this.document.head,this.bodyEl=this.document.body||this.document.querySelector("body"),this.window=this.iframe.contentWindow,this.window.focus(),"about:blank"!=d&&(b=this.iframe.contentDocument.querySelector("base"),c=b.getAttribute("href"),this.trigger("render:loaded",c))},EPUBJS.Render.Iframe.prototype.resize=function(a,b){this.element&&(this.element.style.height=b,isNaN(a)||a%2==0||(a+=1),this.element.style.width=a,this.iframe&&(this.iframe.height=b,this.iframe.width=a),this._height=b,this._width=a,this.width=this.element.getBoundingClientRect().width||a,this.height=this.element.getBoundingClientRect().height||b)},EPUBJS.Render.Iframe.prototype.resized=function(a){this.width=this.iframe.getBoundingClientRect().width,this.height=this.iframe.getBoundingClientRect().height},EPUBJS.Render.Iframe.prototype.totalWidth=function(){return this.docEl.scrollWidth},EPUBJS.Render.Iframe.prototype.totalHeight=function(){return this.docEl.scrollHeight},EPUBJS.Render.Iframe.prototype.setPageDimensions=function(a,b){this.pageWidth=a,this.pageHeight=b},EPUBJS.Render.Iframe.prototype.setDirection=function(a){this.direction=a,this.docEl&&"rtl"==this.docEl.dir&&(this.docEl.dir="rtl","pre-paginated"!==this.layout&&(this.docEl.style.position="static",this.docEl.style.right="auto"))},EPUBJS.Render.Iframe.prototype.setLeft=function(a){this.isMobile?this.docEl.style[this.transform]="translate("+-a+"px, 0)":this.document.defaultView.scrollTo(a,0)},EPUBJS.Render.Iframe.prototype.setLayout=function(a){this.layout=a},EPUBJS.Render.Iframe.prototype.setStyle=function(a,b,c){c&&(a=EPUBJS.core.prefixed(a)),this.bodyEl&&(this.bodyEl.style[a]=b)},EPUBJS.Render.Iframe.prototype.removeStyle=function(a){this.bodyEl&&(this.bodyEl.style[a]="")},EPUBJS.Render.Iframe.prototype.setClasses=function(a){this.bodyEl&&(this.bodyEl.className=a.join(" "))},EPUBJS.Render.Iframe.prototype.addHeadTag=function(a,b,c){var d=c||this.document,e=d.createElement(a),f=d.head;for(var g in b)e.setAttribute(g,b[g]);f&&f.insertBefore(e,f.firstChild)},EPUBJS.Render.Iframe.prototype.page=function(a){this.leftPos=this.pageWidth*(a-1),"rtl"===this.direction&&(this.leftPos=this.leftPos*-1),this.setLeft(this.leftPos)},EPUBJS.Render.Iframe.prototype.getPageNumberByElement=function(a){var b;if(a)return b=this.leftPos+a.getBoundingClientRect().left,Math.floor(b/this.pageWidth)+1},EPUBJS.Render.Iframe.prototype.getPageNumberByRect=function(a){var b;return b=this.leftPos+a.left,Math.floor(b/this.pageWidth)+1},EPUBJS.Render.Iframe.prototype.getBaseElement=function(){return this.bodyEl},EPUBJS.Render.Iframe.prototype.getDocumentElement=function(){return this.docEl},EPUBJS.Render.Iframe.prototype.isElementVisible=function(a){var b,c;return!!(a&&"function"==typeof a.getBoundingClientRect&&(b=a.getBoundingClientRect(),c=b.left,0!==b.width&&0!==b.height&&c>=0&&c=1&&a<=this.displayedPages&&(this.chapterPos=a,this.render.page(a),this.visibleRangeCfi=this.getVisibleRangeCfi(),this.currentLocationCfi=this.visibleRangeCfi.start,this.trigger("renderer:locationChanged",this.currentLocationCfi),this.trigger("renderer:visibleRangeChanged",this.visibleRangeCfi),!0):(console.warn("pageMap not set, queuing"),this._q.enqueue("page",arguments),!0)},EPUBJS.Renderer.prototype.nextPage=function(){return this.page(this.chapterPos+1)},EPUBJS.Renderer.prototype.prevPage=function(){return this.page(this.chapterPos-1)},EPUBJS.Renderer.prototype.pageByElement=function(a){var b;a&&(b=this.render.getPageNumberByElement(a),this.page(b))},EPUBJS.Renderer.prototype.lastPage=function(){if(this._moving)return this._q.enqueue("lastPage",arguments);this.page(this.displayedPages)},EPUBJS.Renderer.prototype.firstPage=function(){if(this._moving)return this._q.enqueue("firstPage",arguments);this.page(1)},EPUBJS.Renderer.prototype.section=function(a){var b=this.doc.getElementById(a);b&&this.pageByElement(b)},EPUBJS.Renderer.prototype.firstElementisTextNode=function(a){var b=a.childNodes;return!!(b.length&&b[0]&&3===b[0].nodeType&&b[0].textContent.trim().length)},EPUBJS.Renderer.prototype.isGoodNode=function(a){return["audio","canvas","embed","iframe","img","math","object","svg","video"].indexOf(a.tagName.toLowerCase())!==-1||this.firstElementisTextNode(a)},EPUBJS.Renderer.prototype.walk=function(a,b,c){for(var d,e,f,g,h=a,i=[h],j=1e4,k=0;!d&&i.length;){if(a=i.shift(),this.containsPoint(a,b,c)&&this.isGoodNode(a)&&(d=a),!d&&a&&a.childElementCount>0){if(!(e=a.children)||!e.length)return d;f=e.length?e.length:0;for(var l=f-1;l>=0;l--)e[l]!=g&&i.unshift(e[l])}if(!d&&0===i.length&&h&&null!==h.parentNode&&(i.push(h.parentNode),g=h,h=h.parentNode),++k>j){console.error("ENDLESS LOOP");break}}return d},EPUBJS.Renderer.prototype.containsPoint=function(a,b,c){var d;return!!(a&&"function"==typeof a.getBoundingClientRect&&(d=a.getBoundingClientRect(),0!==d.width&&0!==d.height&&d.left>=b&&b<=d.left+d.width))},EPUBJS.Renderer.prototype.textSprint=function(a,b){var c,d,e=function(a){return/^\s*$/.test(a.data)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT};try{for(c=document.createTreeWalker(a,NodeFilter.SHOW_TEXT,{acceptNode:e},!1);d=c.nextNode();)b(d)}catch(f){for(c=document.createTreeWalker(a,NodeFilter.SHOW_TEXT,e,!1);d=c.nextNode();)b(d)}},EPUBJS.Renderer.prototype.sprint=function(a,b){for(var c,d=document.createTreeWalker(a,NodeFilter.SHOW_ELEMENT,null,!1);c=d.nextNode();)b(c)},EPUBJS.Renderer.prototype.mapPage=function(){var a,b,c,d,e,f,g,h,i=this,j=[],k=this.render.getBaseElement(),l=1,m=this.layout.colWidth+this.layout.gap,n=this.formated.pageWidth*(this.chapterPos-1),o=m*l-n,p=0,q=function(b){var c,e,f;if(b.nodeType==Node.TEXT_NODE){if(e=document.createRange(),e.selectNodeContents(b),!(c=e.getBoundingClientRect())||0===c.width&&0===c.height)return;c.left>p&&(f=r(b)),c.right>p&&(f=r(b)),d=b,f&&(a=null)}},r=function(e){var f;return i.splitTextNodeIntoWordsRanges(e).forEach(function(e){var g=e.getBoundingClientRect();!g||0===g.width&&0===g.height||(g.left+g.width0&&(b&&(b.setEnd(a,e),c.push(b)),b=this.doc.createRange(),b.setStart(a,e+1));return b&&(b.setEnd(a,d.length),c.push(b)),c},EPUBJS.Renderer.prototype.rangePosition=function(a){var b;return b=a.getClientRects(),b.length?b[0]:null},EPUBJS.Renderer.prototype.getPageCfi=function(){var a=2*this.chapterPos-1;return this.pageMap[a].start},EPUBJS.Renderer.prototype.getRange=function(a,b,c){var d,e=this.doc.createRange();return c=!0,void 0===document.caretPositionFromPoint||c?void 0===document.caretRangeFromPoint||c?(this.visibileEl=this.findElementAfter(a,b),e.setStart(this.visibileEl,1)):e=this.doc.caretRangeFromPoint(a,b):(d=this.doc.caretPositionFromPoint(a,b),e.setStart(d.offsetNode,d.offset)),e},EPUBJS.Renderer.prototype.pagesInCurrentChapter=function(){return this.pageMap?this.pageMap.length:(console.warn("page map not loaded"),!1)},EPUBJS.Renderer.prototype.currentRenderedPage=function(){return this.pageMap?this.spreads&&this.pageMap.length>1?2*this.chapterPos-1:this.chapterPos:(console.warn("page map not loaded"),!1)},EPUBJS.Renderer.prototype.getRenderedPagesLeft=function(){var a,b;return this.pageMap?(b=this.pageMap.length,a=this.spreads?2*this.chapterPos-1:this.chapterPos,b-a):(console.warn("page map not loaded"),!1)},EPUBJS.Renderer.prototype.getVisibleRangeCfi=function(){var a,b,c;return this.pageMap?(this.spreads?(a=2*this.chapterPos,b=this.pageMap[a-2],c=b,this.pageMap.length>1&&this.pageMap.length>a-1&&(c=this.pageMap[a-1])):(a=this.chapterPos,b=this.pageMap[a-1],c=b),b||(console.warn("page range miss:",a,this.pageMap),b=this.pageMap[this.pageMap.length-1],c=b),{start:b.start,end:c.end}):(console.warn("page map not loaded"),!1)},EPUBJS.Renderer.prototype.gotoCfi=function(a){var b,c,d;if(this._moving)return this._q.enqueue("gotoCfi",arguments);if(EPUBJS.core.isString(a)&&(a=this.epubcfi.parse(a)),void 0===document.evaluate)(c=this.epubcfi.addMarker(a,this.doc))&&(b=this.render.getPageNumberByElement(c),this.epubcfi.removeMarker(c,this.doc),this.page(b));else if(d=this.epubcfi.generateRangeFromCfi(a,this.doc)){var e=d.getBoundingClientRect();b=e?this.render.getPageNumberByRect(e):1,this.page(b),this.currentLocationCfi=a.str}else this.page(1)},EPUBJS.Renderer.prototype.findFirstVisible=function(a){var b,c=a||this.render.getBaseElement();return b=this.walk(c,0,0),b?b:a},EPUBJS.Renderer.prototype.findElementAfter=function(a,b,c){var d,e=c||this.render.getBaseElement();return d=this.walk(e,a,b),d?d:e},EPUBJS.Renderer.prototype.resize=function(a,b,c){this.width=a,this.height=b,c!==!1&&this.render.resize(this.width,this.height),this.contents&&this.reformat(),this.trigger("renderer:resized",{width:this.width,height:this.height})},EPUBJS.Renderer.prototype.onResized=function(a){this.trigger("renderer:beforeResize");var b=this.container.clientWidth,c=this.container.clientHeight;this.resize(b,c,!1)},EPUBJS.Renderer.prototype.addEventListeners=function(){this.render.document&&this.listenedEvents.forEach(function(a){this.render.document.addEventListener(a,this.triggerEvent.bind(this),!1)},this)},EPUBJS.Renderer.prototype.removeEventListeners=function(){this.render.document&&this.listenedEvents.forEach(function(a){this.render.document.removeEventListener(a,this.triggerEvent,!1)},this)},EPUBJS.Renderer.prototype.triggerEvent=function(a){this.trigger("renderer:"+a.type,a)},EPUBJS.Renderer.prototype.addSelectionListeners=function(){this.render.document.addEventListener("selectionchange",this.onSelectionChange.bind(this),!1)},EPUBJS.Renderer.prototype.removeSelectionListeners=function(){this.render.document&&this.doc.removeEventListener("selectionchange",this.onSelectionChange,!1)},EPUBJS.Renderer.prototype.onSelectionChange=function(a){this.selectionEndTimeout&&clearTimeout(this.selectionEndTimeout),this.selectionEndTimeout=setTimeout(function(){this.selectedRange=this.render.window.getSelection(),this.trigger("renderer:selected",this.selectedRange)}.bind(this),500)},EPUBJS.Renderer.prototype.setMinSpreadWidth=function(a){this.minSpreadWidth=a,this.spreads=this.determineSpreads(a)},EPUBJS.Renderer.prototype.determineSpreads=function(a){return!(this.isForcedSingle||!a||this.width=d?h.resolve():(c=a[e].url,g=window.encodeURIComponent(c),EPUBJS.core.request(c,"binary").then(function(a){return localforage.setItem(g,a)}).then(function(a){e++,setTimeout(function(){f(h)},1)})),h.promise}.bind(this);return Array.isArray(a)||(a=[a]),f().then(function(){c.resolve()}.bind(this)),c.promise},EPUBJS.Storage.prototype.token=function(a,b){var c=window.encodeURIComponent(a);return localforage.setItem(c,b).then(function(a){return null!==a})},EPUBJS.Storage.prototype.isStored=function(a){var b=window.encodeURIComponent(a);return localforage.getItem(b).then(function(a){return null!==a})},EPUBJS.Storage.prototype.getText=function(a){var b=window.encodeURIComponent(a);return EPUBJS.core.request(a,"arraybuffer",this.withCredentials).then(function(a){return this.offline&&(this.offline=!1,this.trigger("offline",!1)),localforage.setItem(b,a),a}.bind(this)).then(function(b){var c=new RSVP.defer,d=EPUBJS.core.getMimeType(a),e=new Blob([b],{type:d}),f=new FileReader;return f.addEventListener("loadend",function(){c.resolve(f.result)}),f.readAsText(e,d),c.promise}).catch(function(){var c=new RSVP.defer,d=localforage.getItem(b);return this.offline||(this.offline=!0,this.trigger("offline",!0)),d?(d.then(function(b){var d=EPUBJS.core.getMimeType(a),e=new Blob([b],{type:d}),f=new FileReader;f.addEventListener("loadend",function(){c.resolve(f.result)}),f.readAsText(e,d)}),c.promise):(c.reject({message:"File not found in the storage: "+a,stack:(new Error).stack}),c.promise)}.bind(this))},EPUBJS.Storage.prototype.getUrl=function(a){var b=window.encodeURIComponent(a);return EPUBJS.core.request(a,"arraybuffer",this.withCredentials).then(function(c){return this.offline&&(this.offline=!1,this.trigger("offline",!1)),localforage.setItem(b,c),a}.bind(this)).catch(function(){var c,d,e=new RSVP.defer,f=window.URL||window.webkitURL||window.mozURL;return this.offline||(this.offline=!0,this.trigger("offline",!0)),b in this.urlCache?(e.resolve(this.urlCache[b]),e.promise):(c=localforage.getItem(b))?(c.then(function(c){var g=new Blob([c],{type:EPUBJS.core.getMimeType(a)});d=f.createObjectURL(g),e.resolve(d),this.urlCache[b]=d}.bind(this)),e.promise):(e.reject({message:"File not found in the storage: "+a,stack:(new Error).stack}),e.promise)}.bind(this))},EPUBJS.Storage.prototype.getXml=function(a){var b=window.encodeURIComponent(a);return EPUBJS.core.request(a,"arraybuffer",this.withCredentials).then(function(a){return this.offline&&(this.offline=!1,this.trigger("offline",!1)),localforage.setItem(b,a),a}.bind(this)).then(function(b){var c=new RSVP.defer,d=EPUBJS.core.getMimeType(a),e=new Blob([b],{type:d}),f=new FileReader;return f.addEventListener("loadend",function(){var a=new DOMParser,b=a.parseFromString(f.result,"text/xml");c.resolve(b)}),f.readAsText(e,d),c.promise}).catch(function(){var c=new RSVP.defer,d=localforage.getItem(b);return this.offline||(this.offline=!0,this.trigger("offline",!0)),d?(d.then(function(b){var d=EPUBJS.core.getMimeType(a),e=new Blob([b],{type:d}),f=new FileReader;f.addEventListener("loadend",function(){var a=new DOMParser,b=a.parseFromString(f.result,"text/xml");c.resolve(b)}),f.readAsText(e,d)}),c.promise):(c.reject({message:"File not found in the storage: "+a,stack:(new Error).stack}),c.promise)}.bind(this))},EPUBJS.Storage.prototype.revokeUrl=function(a){var b=window.URL||window.webkitURL||window.mozURL,c=this.urlCache[a];c&&b.revokeObjectURL(c)},EPUBJS.Storage.prototype.failed=function(a){console.error(a)},RSVP.EventTarget.mixin(EPUBJS.Storage.prototype),EPUBJS.Unarchiver=function(a){this.checkRequirements(),this.urlCache={}},EPUBJS.Unarchiver.prototype.checkRequirements=function(a){"undefined"==typeof JSZip&&console.error("JSZip lib not loaded")},EPUBJS.Unarchiver.prototype.open=function(a,b){if(a instanceof ArrayBuffer){this.zip=new JSZip(a);var c=new RSVP.defer;return c.resolve(),c.promise}return EPUBJS.core.request(a,"binary").then(function(a){this.zip=new JSZip(a)}.bind(this))},EPUBJS.Unarchiver.prototype.getXml=function(a,b){var c=window.decodeURIComponent(a);return this.getText(c,b).then(function(b){var c=new DOMParser,d=EPUBJS.core.getMimeType(a);return 65279===b.charCodeAt(0)&&(b=b.slice(1)),c.parseFromString(b,d)})},EPUBJS.Unarchiver.prototype.getUrl=function(a,b){var c,d,e=this,f=new RSVP.defer,g=window.decodeURIComponent(a),h=this.zip.file(g),i=window.URL||window.webkitURL||window.mozURL;return h?a in this.urlCache?(f.resolve(this.urlCache[a]),f.promise):(d=new Blob([h.asUint8Array()],{type:EPUBJS.core.getMimeType(h.name)}),c=i.createObjectURL(d),f.resolve(c),e.urlCache[a]=c,f.promise):(f.reject({message:"File not found in the epub: "+a,stack:(new Error).stack}),f.promise)},EPUBJS.Unarchiver.prototype.getText=function(a,b){var c,d=new RSVP.defer,e=window.decodeURIComponent(a),f=this.zip.file(e);return f?(c=f.asText(),d.resolve(c),d.promise):(d.reject({message:"File not found in the epub: "+a,stack:(new Error).stack}),d.promise)},EPUBJS.Unarchiver.prototype.revokeUrl=function(a){var b=window.URL||window.webkitURL||window.mozURL,c=this.urlCache[a];c&&b.revokeObjectURL(c)},EPUBJS.Unarchiver.prototype.failed=function(a){console.error(a)},EPUBJS.Unarchiver.prototype.afterSaved=function(a){this.callback()},EPUBJS.Unarchiver.prototype.toStorage=function(a){function b(){0===--e&&d.afterSaved()}var c=0,d=this,e=a.length;a.forEach(function(a){setTimeout(function(a){d.saveEntryFileToStorage(a,b)},c,a),c+=20}),console.log("time",c)},function(){var a={application:{ecmascript:["es","ecma"],javascript:"js",ogg:"ogx",pdf:"pdf",postscript:["ps","ai","eps","epsi","epsf","eps2","eps3"],"rdf+xml":"rdf",smil:["smi","smil"],"xhtml+xml":["xhtml","xht"],xml:["xml","xsl","xsd","opf","ncx"],zip:"zip","x-httpd-eruby":"rhtml","x-latex":"latex","x-maker":["frm","maker","frame","fm","fb","book","fbdoc"],"x-object":"o","x-shockwave-flash":["swf","swfl"],"x-silverlight":"scr","epub+zip":"epub","font-tdpfr":"pfr","inkml+xml":["ink","inkml"],json:"json","jsonml+json":"jsonml","mathml+xml":"mathml","metalink+xml":"metalink",mp4:"mp4s","omdoc+xml":"omdoc",oxps:"oxps","vnd.amazon.ebook":"azw",widget:"wgt","x-dtbook+xml":"dtb","x-dtbresource+xml":"res","x-font-bdf":"bdf","x-font-ghostscript":"gsf","x-font-linux-psf":"psf","x-font-otf":"otf","x-font-pcf":"pcf","x-font-snf":"snf","x-font-ttf":["ttf","ttc"],"x-font-type1":["pfa","pfb","pfm","afm"],"x-font-woff":"woff","x-mobipocket-ebook":["prc","mobi"],"x-mspublisher":"pub","x-nzb":"nzb","x-tgif":"obj","xaml+xml":"xaml","xml-dtd":"dtd","xproc+xml":"xpl","xslt+xml":"xslt","internet-property-stream":"acx","x-compress":"z","x-compressed":"tgz","x-gzip":"gz"},audio:{flac:"flac",midi:["mid","midi","kar","rmi"],mpeg:["mpga","mpega","mp2","mp3","m4a","mp2a","m2a","m3a"],mpegurl:"m3u",ogg:["oga","ogg","spx"],"x-aiff":["aif","aiff","aifc"],"x-ms-wma":"wma","x-wav":"wav",adpcm:"adp",mp4:"mp4a",webm:"weba","x-aac":"aac","x-caf":"caf","x-matroska":"mka","x-pn-realaudio-plugin":"rmp",xm:"xm",mid:["mid","rmi"]},image:{gif:"gif",ief:"ief",jpeg:["jpeg","jpg","jpe"],pcx:"pcx",png:"png","svg+xml":["svg","svgz"],tiff:["tiff","tif"],"x-icon":"ico",bmp:"bmp",webp:"webp","x-pict":["pic","pct"],"x-tga":"tga","cis-cod":"cod"},message:{rfc822:["eml","mime","mht","mhtml","nws"]},text:{"cache-manifest":["manifest","appcache"],calendar:["ics","icz","ifb"],css:"css",csv:"csv",h323:"323",html:["html","htm","shtml","stm"],iuls:"uls",mathml:"mml",plain:["txt","text","brf","conf","def","list","log","in","bas"],richtext:"rtx","tab-separated-values":"tsv","x-bibtex":"bib","x-dsrc":"d","x-diff":["diff","patch"],"x-haskell":"hs","x-java":"java","x-literate-haskell":"lhs","x-moc":"moc","x-pascal":["p","pas"],"x-pcs-gcd":"gcd","x-perl":["pl","pm"],"x-python":"py","x-scala":"scala","x-setext":"etx","x-tcl":["tcl","tk"],"x-tex":["tex","ltx","sty","cls"],"x-vcard":"vcf",sgml:["sgml","sgm"],"x-c":["c","cc","cxx","cpp","h","hh","dic"],"x-fortran":["f","for","f77","f90"],"x-opml":"opml","x-nfo":"nfo","x-sfv":"sfv","x-uuencode":"uu",webviewhtml:"htt"},video:{mpeg:["mpeg","mpg","mpe","m1v","m2v","mp2","mpa","mpv2"],mp4:["mp4","mp4v","mpg4"],quicktime:["qt","mov"],ogg:"ogv","vnd.mpegurl":["mxu","m4u"],"x-flv":"flv","x-la-asf":["lsf","lsx"],"x-mng":"mng","x-ms-asf":["asf","asx","asr"],"x-ms-wm":"wm","x-ms-wmv":"wmv","x-ms-wmx":"wmx","x-ms-wvx":"wvx","x-msvideo":"avi","x-sgi-movie":"movie","x-matroska":["mpv","mkv","mk3d","mks"],"3gpp2":"3g2",h261:"h261",h263:"h263",h264:"h264",jpeg:"jpgv",jpm:["jpm","jpgm"],mj2:["mj2","mjp2"],"vnd.ms-playready.media.pyv":"pyv","vnd.uvvu.mp4":["uvu","uvvu"],"vnd.vivo":"viv",webm:"webm","x-f4v":"f4v","x-m4v":"m4v","x-ms-vob":"vob","x-smv":"smv"}},b=function(){var b,c,d,e,f={};for(b in a)if(a.hasOwnProperty(b))for(c in a[b])if(a[b].hasOwnProperty(c))if("string"==typeof(d=a[b][c]))f[d]=b+"/"+c;else for(e=0;en/2.5&&(p=n/2.5,pop_content.style.maxHeight=p+"px"),popRect.height+l>=n-25?(c.style.top=l-popRect.height+"px",c.classList.add("above")):c.classList.remove("above"),k-popRect.width<=0?(c.style.left=k+"px",c.classList.add("left")):c.classList.remove("left"),k+popRect.width/2>=o?(c.style.left=k-300+"px",popRect=c.getBoundingClientRect(),c.style.left=k-popRect.width+"px",popRect.height+l>=n-25?(c.style.top=l-popRect.height+"px",c.classList.add("above")):c.classList.remove("above"),c.classList.add("right")):c.classList.remove("right")}function d(){f[i].classList.add("on")}function e(){f[i].classList.remove("on")}function g(){setTimeout(function(){f[i].classList.remove("show")},100)}var h,i,j,k,l,m;"noteref"==a.getAttribute("epub:type")&&(h=a.getAttribute("href"),i=h.replace("#",""),j=b.render.document.getElementById(i),a.addEventListener("mouseover",c,!1),a.addEventListener("mouseout",g,!1))}),a&&a()},EPUBJS.Hooks.register("beforeChapterDisplay").mathml=function(a,b){if(b.currentChapter.manifestProperties.indexOf("mathml")!==-1){b.render.iframe.contentWindow.mathmlCallback=a;var c=document.createElement("script");c.type="text/x-mathjax-config",c.innerHTML=' MathJax.Hub.Register.StartupHook("End",function () { window.mathmlCallback(); }); MathJax.Hub.Config({jax: ["input/TeX","input/MathML","output/SVG"],extensions: ["tex2jax.js","mml2jax.js","MathEvents.js"],TeX: {extensions: ["noErrors.js","noUndefined.js","autoload-all.js"]},MathMenu: {showRenderer: false},menuSettings: {zoom: "Click"},messageStyle: "none"}); ',b.doc.body.appendChild(c),EPUBJS.core.addScript("http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML",null,b.doc.head)}else a&&a()},EPUBJS.Hooks.register("beforeChapterDisplay").smartimages=function(a,b){var c=b.contents.querySelectorAll("img"),d=Array.prototype.slice.call(c),e=b.height;if("reflowable"!=b.layoutSettings.layout)return void a();d.forEach(function(a){var c=function(){var c,d=a.getBoundingClientRect(),f=d.height,g=d.top,h=a.getAttribute("data-height"),i=h||f,j=Number(getComputedStyle(a,"").fontSize.match(/(\d*(\.\d*)?)px/)[1]),k=j?j/2:0;e=b.contents.clientHeight,g<0&&(g=0),a.style.maxWidth="100%",i+g>=e?(ge&&(a.style.maxHeight=e+"px",a.style.width="auto",d=a.getBoundingClientRect(),i=d.height),a.style.display="block",a.style.WebkitColumnBreakBefore="always",a.style.breakBefore="column"),a.setAttribute("data-height",c)):(a.style.removeProperty("max-height"),a.style.removeProperty("margin-top"))},d=function(){b.off("renderer:resized",c),b.off("renderer:chapterUnload",this)};a.addEventListener("load",c,!1),b.on("renderer:resized",c),b.on("renderer:chapterUnload",d),c()}),a&&a()},EPUBJS.Hooks.register("beforeChapterDisplay").transculsions=function(a,b){var c=b.contents.querySelectorAll("[transclusion]");Array.prototype.slice.call(c).forEach(function(a){function c(){j=g,k=h,j>chapter.colWidth&&(d=chapter.colWidth/j,j=chapter.colWidth,k*=d),f.width=j,f.height=k}var d,e=a.getAttribute("ref"),f=document.createElement("iframe"),g=a.getAttribute("width"),h=a.getAttribute("height"),i=a.parentNode,j=g,k=h;c(),b.listenUntil("renderer:resized","renderer:chapterUnloaded",c),f.src=e,i.replaceChild(f,a)}),a&&a()}; \ No newline at end of file diff --git a/static/js/reader/hooks.min.map b/static/js/reader/hooks.min.map deleted file mode 100644 index 5da22bee6..000000000 --- a/static/js/reader/hooks.min.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"hooks.min.js","sources":["../../hooks/default/endnotes.js","../../hooks/default/mathml.js","../../hooks/default/smartimages.js","../../hooks/default/transculsions.js"],"names":["EPUBJS","Hooks","register","endnotes","callback","renderer","notes","contents","querySelectorAll","items","Array","prototype","slice","call","attr","type","folder","core","location","pathname","popups","cssPath","addCss","render","document","head","forEach","item","showPop","pop","itemRect","iheight","height","iwidth","width","maxHeight","txt","el","cloneNode","querySelector","id","createElement","setAttribute","pop_content","appendChild","body","addEventListener","onPop","offPop","on","hidePop","this","getBoundingClientRect","left","top","classList","add","popRect","style","remove","setTimeout","href","epubType","getAttribute","replace","getElementById","mathml","currentChapter","manifestProperties","indexOf","iframe","contentWindow","mathmlCallback","s","innerHTML","doc","addScript","smartimages","images","layoutSettings","layout","size","newHeight","rectHeight","oHeight","fontSize","Number","getComputedStyle","match","fontAdjust","clientHeight","display","removeProperty","unloaded","off","transculsions","trans","orginal_width","orginal_height","chapter","colWidth","ratio","src","parent","parentNode","listenUntil","replaceChild"],"mappings":"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"} \ No newline at end of file diff --git a/static/js/reader/hooks/extensions/highlight.js b/static/js/reader/hooks/extensions/highlight.js deleted file mode 100644 index 1dd1c6714..000000000 --- a/static/js/reader/hooks/extensions/highlight.js +++ /dev/null @@ -1,14 +0,0 @@ -EPUBJS.Hooks.register("beforeChapterDisplay").highlight = function(callback, renderer){ - - // EPUBJS.core.addScript("js/libs/jquery.highlight.js", null, renderer.doc.head); - - var s = document.createElement("style"); - s.innerHTML =".highlight { background: yellow; font-weight: normal; }"; - - renderer.render.document.head.appendChild(s); - - if(callback) callback(); - -} - - diff --git a/static/js/reader/libs/jquery.min.js b/static/js/reader/libs/jquery.min.js deleted file mode 100644 index 4024b6622..000000000 --- a/static/js/reader/libs/jquery.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! jQuery v2.2.4 | (c) jQuery Foundation | jquery.org/license */ -!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="2.2.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isPlainObject:function(a){var b;if("object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype||{},"isPrototypeOf"))return!1;for(b in a);return void 0===b||k.call(a,b)},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=d.createElement("script"),b.text=a,d.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:h.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(d=e.call(arguments,2),f=function(){return a.apply(b||this,d.concat(e.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return h.call(b,a)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&f.parentNode&&(this.length=1,this[0]=f),this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?void 0!==c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?h.call(n(a),this[0]):h.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||n.uniqueSort(e),D.test(a)&&e.reverse()),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.removeEventListener("DOMContentLoaded",J),a.removeEventListener("load",J),n.ready()}n.ready.promise=function(b){return I||(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(n.ready):(d.addEventListener("DOMContentLoaded",J),a.addEventListener("load",J))),I.promise(b)},n.ready.promise();var K=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)K(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},L=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function M(){this.expando=n.expando+M.uid++}M.uid=1,M.prototype={register:function(a,b){var c=b||{};return a.nodeType?a[this.expando]=c:Object.defineProperty(a,this.expando,{value:c,writable:!0,configurable:!0}),a[this.expando]},cache:function(a){if(!L(a))return{};var b=a[this.expando];return b||(b={},L(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[b]=c;else for(d in b)e[d]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=a[this.expando];if(void 0!==f){if(void 0===b)this.register(a);else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in f?d=[b,e]:(d=e,d=d in f?[d]:d.match(G)||[])),c=d.length;while(c--)delete f[d[c]]}(void 0===b||n.isEmptyObject(f))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!n.isEmptyObject(b)}};var N=new M,O=new M,P=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Q=/[A-Z]/g;function R(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Q,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:P.test(c)?n.parseJSON(c):c; -}catch(e){}O.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return O.hasData(a)||N.hasData(a)},data:function(a,b,c){return O.access(a,b,c)},removeData:function(a,b){O.remove(a,b)},_data:function(a,b,c){return N.access(a,b,c)},_removeData:function(a,b){N.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=O.get(f),1===f.nodeType&&!N.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),R(f,d,e[d])));N.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){O.set(this,a)}):K(this,function(b){var c,d;if(f&&void 0===b){if(c=O.get(f,a)||O.get(f,a.replace(Q,"-$&").toLowerCase()),void 0!==c)return c;if(d=n.camelCase(a),c=O.get(f,d),void 0!==c)return c;if(c=R(f,d,void 0),void 0!==c)return c}else d=n.camelCase(a),this.each(function(){var c=O.get(this,d);O.set(this,d,b),a.indexOf("-")>-1&&void 0!==c&&O.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){O.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=N.get(a,b),c&&(!d||n.isArray(c)?d=N.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return N.get(a,c)||N.access(a,c,{empty:n.Callbacks("once memory").add(function(){N.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length",""],thead:[1,"","
      "],col:[2,"","
      "],tr:[2,"","
      "],td:[3,"","
      "],_default:[0,"",""]};$.optgroup=$.option,$.tbody=$.tfoot=$.colgroup=$.caption=$.thead,$.th=$.td;function _(a,b){var c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function aa(a,b){for(var c=0,d=a.length;d>c;c++)N.set(a[c],"globalEval",!b||N.get(b[c],"globalEval"))}var ba=/<|&#?\w+;/;function ca(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],o=0,p=a.length;p>o;o++)if(f=a[o],f||0===f)if("object"===n.type(f))n.merge(m,f.nodeType?[f]:f);else if(ba.test(f)){g=g||l.appendChild(b.createElement("div")),h=(Y.exec(f)||["",""])[1].toLowerCase(),i=$[h]||$._default,g.innerHTML=i[1]+n.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;n.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",o=0;while(f=m[o++])if(d&&n.inArray(f,d)>-1)e&&e.push(f);else if(j=n.contains(f.ownerDocument,f),g=_(l.appendChild(f),"script"),j&&aa(g),c){k=0;while(f=g[k++])Z.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var da=/^key/,ea=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,fa=/^([^.]*)(?:\.(.+)|)/;function ga(){return!0}function ha(){return!1}function ia(){try{return d.activeElement}catch(a){}}function ja(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ja(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=ha;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=N.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return"undefined"!=typeof n&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(G)||[""],j=b.length;while(j--)h=fa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=N.hasData(a)&&N.get(a);if(r&&(i=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=fa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&N.remove(a,"handle events")}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(N.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!==this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,la=/\s*$/g;function pa(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function qa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function ra(a){var b=na.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function sa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(N.hasData(a)&&(f=N.access(a),g=N.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}O.hasData(a)&&(h=O.access(a),i=n.extend({},h),O.set(b,i))}}function ta(a,b){var c=b.nodeName.toLowerCase();"input"===c&&X.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function ua(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&ma.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),ua(f,b,c,d)});if(o&&(e=ca(b,a[0].ownerDocument,!1,a,d),g=e.firstChild,1===e.childNodes.length&&(e=g),g||d)){for(h=n.map(_(e,"script"),qa),i=h.length;o>m;m++)j=e,m!==p&&(j=n.clone(j,!0,!0),i&&n.merge(h,_(j,"script"))),c.call(a[m],j,m);if(i)for(k=h[h.length-1].ownerDocument,n.map(h,ra),m=0;i>m;m++)j=h[m],Z.test(j.type||"")&&!N.access(j,"globalEval")&&n.contains(k,j)&&(j.src?n._evalUrl&&n._evalUrl(j.src):n.globalEval(j.textContent.replace(oa,"")))}return a}function va(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(_(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&aa(_(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(ka,"<$1>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=_(h),f=_(a),d=0,e=f.length;e>d;d++)ta(f[d],g[d]);if(b)if(c)for(f=f||_(a),g=g||_(h),d=0,e=f.length;e>d;d++)sa(f[d],g[d]);else sa(a,h);return g=_(h,"script"),g.length>0&&aa(g,!i&&_(a,"script")),h},cleanData:function(a){for(var b,c,d,e=n.event.special,f=0;void 0!==(c=a[f]);f++)if(L(c)){if(b=c[N.expando]){if(b.events)for(d in b.events)e[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);c[N.expando]=void 0}c[O.expando]&&(c[O.expando]=void 0)}}}),n.fn.extend({domManip:ua,detach:function(a){return va(this,a,!0)},remove:function(a){return va(this,a)},text:function(a){return K(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return ua(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=pa(this,a);b.appendChild(a)}})},prepend:function(){return ua(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=pa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return ua(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return ua(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(_(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return K(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!la.test(a)&&!$[(Y.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(_(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return ua(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(_(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),f=e.length-1,h=0;f>=h;h++)c=h===f?this:this.clone(!0),n(e[h])[b](c),g.apply(d,c.get());return this.pushStack(d)}});var wa,xa={HTML:"block",BODY:"block"};function ya(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function za(a){var b=d,c=xa[a];return c||(c=ya(a,b),"none"!==c&&c||(wa=(wa||n("