From 005f3f5e5157bddf792f46a983bfadd0d4398a89 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Mon, 25 Apr 2016 21:36:47 -0400 Subject: update debian changelog to 0.9.2 --- debian/changelog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/debian/changelog b/debian/changelog index 32fb5ece..e2086175 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +bitmask (0.9.2) UNRELEASED; urgency=medium + + * Update to 0.9.2 release "panis et circenses" + + -- Ben Carrillo Mon, 25 Apr 2016 21:33:01 -0400 + bitmask (0.9.1) unstable; urgency=medium * Update to 0.9.1 release "the day of the calaca" -- cgit v1.2.3 From 3b3731d873664db00c02603363f61d34c41a3990 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Mon, 25 Apr 2016 22:13:19 -0400 Subject: embed pixelated --- debian/bitmask.install | 8 + pkg/pyinst/bitmask.spec.orig | 38 -- pkg/pyinst/pyinst-build.mk | 3 +- src/leap/bitmask/auth/auth.py | 336 +++++++++++++ src/leap/bitmask/auth/exceptions.py | 65 +++ src/leap/bitmask/auth/srp_session.py | 7 + src/pixelated/__init__.py | 0 src/pixelated/adapter/__init__.py | 15 + src/pixelated/adapter/listeners/__init__.py | 15 + .../adapter/listeners/mailbox_indexer_listener.py | 69 +++ src/pixelated/adapter/mailstore/__init__.py | 20 + src/pixelated/adapter/mailstore/body_parser.py | 68 +++ .../adapter/mailstore/leap_attachment_store.py | 67 +++ src/pixelated/adapter/mailstore/leap_mailstore.py | 429 +++++++++++++++++ src/pixelated/adapter/mailstore/mailstore.py | 61 +++ .../adapter/mailstore/maintenance/__init__.py | 104 +++++ .../adapter/mailstore/searchable_mailstore.py | 82 ++++ src/pixelated/adapter/model/__init__.py | 15 + src/pixelated/adapter/model/mail.py | 235 ++++++++++ src/pixelated/adapter/model/status.py | 43 ++ src/pixelated/adapter/model/tag.py | 73 +++ src/pixelated/adapter/search/__init__.py | 218 +++++++++ src/pixelated/adapter/search/contacts.py | 56 +++ src/pixelated/adapter/search/index_storage_key.py | 42 ++ src/pixelated/adapter/services/__init__.py | 15 + src/pixelated/adapter/services/draft_service.py | 40 ++ src/pixelated/adapter/services/feedback_service.py | 20 + src/pixelated/adapter/services/mail_sender.py | 102 ++++ src/pixelated/adapter/services/mail_service.py | 152 ++++++ src/pixelated/adapter/services/tag_service.py | 24 + src/pixelated/adapter/welcome_mail.py | 29 ++ src/pixelated/application.py | 222 +++++++++ src/pixelated/assets/Interstitial.html | 18 + src/pixelated/assets/Interstitial.js | 58 +++ src/pixelated/assets/__init__.py | 0 src/pixelated/assets/_login_disclaimer_banner.html | 9 + src/pixelated/assets/favicon.png | Bin 0 -> 592 bytes src/pixelated/assets/hive-bg.png | Bin 0 -> 3356 bytes src/pixelated/assets/index.html | 9 + src/pixelated/assets/jquery-2.1.3.min.js | 4 + src/pixelated/assets/login.html | 36 ++ src/pixelated/assets/normalize.min.css | 1 + src/pixelated/assets/opensans.css | 69 +++ src/pixelated/assets/pixelated-logo-orange.svg | 29 ++ src/pixelated/assets/pixelated.css | 128 +++++ src/pixelated/assets/snap.svg-min.js | 20 + src/pixelated/assets/welcome.mail | 72 +++ src/pixelated/bitmask_libraries/__init__.py | 0 src/pixelated/bitmask_libraries/certs.py | 56 +++ src/pixelated/bitmask_libraries/config.py | 46 ++ src/pixelated/bitmask_libraries/nicknym.py | 63 +++ src/pixelated/bitmask_libraries/provider.py | 171 +++++++ src/pixelated/bitmask_libraries/session.py | 320 +++++++++++++ src/pixelated/bitmask_libraries/smtp.py | 24 + src/pixelated/bitmask_libraries/soledad.py | 48 ++ src/pixelated/certificates/__init__.py | 0 .../unstable.pixelated-project.org.ca.crt | 33 ++ src/pixelated/config/__init__.py | 0 src/pixelated/config/arguments.py | 98 ++++ src/pixelated/config/credentials.py | 54 +++ src/pixelated/config/leap.py | 92 ++++ src/pixelated/config/logger.py | 37 ++ src/pixelated/config/services.py | 84 ++++ src/pixelated/config/site.py | 32 ++ src/pixelated/extensions/__init__.py | 0 src/pixelated/extensions/esmtp_sender_factory.py | 28 ++ src/pixelated/extensions/protobuf_socket.py | 37 ++ src/pixelated/extensions/requests_urllib3.py | 84 ++++ src/pixelated/extensions/shared_db.py | 16 + src/pixelated/extensions/sqlcipher_wal.py | 24 + src/pixelated/maintenance.py | 325 +++++++++++++ src/pixelated/register.py | 88 ++++ src/pixelated/resources/__init__.py | 118 +++++ src/pixelated/resources/attachments_resource.py | 113 +++++ src/pixelated/resources/auth.py | 150 ++++++ src/pixelated/resources/contacts_resource.py | 44 ++ src/pixelated/resources/features_resource.py | 52 +++ src/pixelated/resources/feedback_resource.py | 31 ++ src/pixelated/resources/keys_resource.py | 30 ++ src/pixelated/resources/login_resource.py | 182 ++++++++ src/pixelated/resources/logout_resource.py | 45 ++ src/pixelated/resources/mail_resource.py | 79 ++++ src/pixelated/resources/mails_resource.py | 239 ++++++++++ src/pixelated/resources/root_resource.py | 150 ++++++ src/pixelated/resources/sandbox_resource.py | 37 ++ src/pixelated/resources/session.py | 39 ++ src/pixelated/resources/tags_resource.py | 39 ++ src/pixelated/resources/user_settings_resource.py | 45 ++ src/pixelated/support/__init__.py | 81 ++++ src/pixelated/support/date.py | 29 ++ src/pixelated/support/encrypted_file_storage.py | 153 ++++++ src/pixelated/support/error_handler.py | 27 ++ src/pixelated/support/functional.py | 37 ++ src/pixelated/support/mail_generator.py | 157 +++++++ src/pixelated/support/markov.py | 94 ++++ src/pixelated/support/replier.py | 35 ++ src/pixelated/support/tls_adapter.py | 47 ++ src/pixelated_www/404.html | 157 +++++++ src/pixelated_www/__init__.py | 0 src/pixelated_www/app.min.js | 27 ++ .../font-awesome/css/font-awesome.min.css | 4 + .../font-awesome/fonts/FontAwesome.otf | Bin 0 -> 85908 bytes .../font-awesome/fonts/fontawesome-webfont.eot | Bin 0 -> 56006 bytes .../font-awesome/fonts/fontawesome-webfont.svg | 520 +++++++++++++++++++++ .../font-awesome/fonts/fontawesome-webfont.ttf | Bin 0 -> 112160 bytes .../font-awesome/fonts/fontawesome-webfont.woff | Bin 0 -> 65452 bytes .../jquery-file-upload/css/jquery.fileupload.css | 37 ++ src/pixelated_www/css/sandbox.css | 1 + src/pixelated_www/css/style.css | 1 + src/pixelated_www/fonts/OpenSans-Bold.woff | Bin 0 -> 14504 bytes src/pixelated_www/fonts/OpenSans-BoldItalic.woff | Bin 0 -> 15488 bytes src/pixelated_www/fonts/OpenSans-Extrabold.woff | Bin 0 -> 15312 bytes .../fonts/OpenSans-ExtraboldItalic.woff | Bin 0 -> 15932 bytes src/pixelated_www/fonts/OpenSans-Italic.woff | Bin 0 -> 15768 bytes src/pixelated_www/fonts/OpenSans-Light.woff | Bin 0 -> 15048 bytes src/pixelated_www/fonts/OpenSans-Semibold.woff | Bin 0 -> 15236 bytes .../fonts/OpenSans-SemiboldItalic.woff | Bin 0 -> 15736 bytes src/pixelated_www/fonts/OpenSans.woff | Bin 0 -> 14604 bytes src/pixelated_www/fonts/OpenSansLight-Italic.woff | Bin 0 -> 15956 bytes src/pixelated_www/index.html | 18 + src/pixelated_www/locales/en-us/translation.json | 71 +++ src/pixelated_www/locales/pt/translation.json | 71 +++ src/pixelated_www/locales/sv/translation.json | 66 +++ src/pixelated_www/sandbox.html | 1 + src/pixelated_www/sandbox.min.js | 1 + 125 files changed, 7875 insertions(+), 39 deletions(-) delete mode 100644 pkg/pyinst/bitmask.spec.orig create mode 100644 src/leap/bitmask/auth/auth.py create mode 100644 src/leap/bitmask/auth/exceptions.py create mode 100644 src/leap/bitmask/auth/srp_session.py create mode 100644 src/pixelated/__init__.py create mode 100644 src/pixelated/adapter/__init__.py create mode 100644 src/pixelated/adapter/listeners/__init__.py create mode 100644 src/pixelated/adapter/listeners/mailbox_indexer_listener.py create mode 100644 src/pixelated/adapter/mailstore/__init__.py create mode 100644 src/pixelated/adapter/mailstore/body_parser.py create mode 100644 src/pixelated/adapter/mailstore/leap_attachment_store.py create mode 100644 src/pixelated/adapter/mailstore/leap_mailstore.py create mode 100644 src/pixelated/adapter/mailstore/mailstore.py create mode 100644 src/pixelated/adapter/mailstore/maintenance/__init__.py create mode 100644 src/pixelated/adapter/mailstore/searchable_mailstore.py create mode 100644 src/pixelated/adapter/model/__init__.py create mode 100644 src/pixelated/adapter/model/mail.py create mode 100644 src/pixelated/adapter/model/status.py create mode 100644 src/pixelated/adapter/model/tag.py create mode 100644 src/pixelated/adapter/search/__init__.py create mode 100644 src/pixelated/adapter/search/contacts.py create mode 100644 src/pixelated/adapter/search/index_storage_key.py create mode 100644 src/pixelated/adapter/services/__init__.py create mode 100644 src/pixelated/adapter/services/draft_service.py create mode 100644 src/pixelated/adapter/services/feedback_service.py create mode 100644 src/pixelated/adapter/services/mail_sender.py create mode 100644 src/pixelated/adapter/services/mail_service.py create mode 100644 src/pixelated/adapter/services/tag_service.py create mode 100644 src/pixelated/adapter/welcome_mail.py create mode 100644 src/pixelated/application.py create mode 100644 src/pixelated/assets/Interstitial.html create mode 100644 src/pixelated/assets/Interstitial.js create mode 100644 src/pixelated/assets/__init__.py create mode 100644 src/pixelated/assets/_login_disclaimer_banner.html create mode 100644 src/pixelated/assets/favicon.png create mode 100644 src/pixelated/assets/hive-bg.png create mode 100644 src/pixelated/assets/index.html create mode 100644 src/pixelated/assets/jquery-2.1.3.min.js create mode 100644 src/pixelated/assets/login.html create mode 100644 src/pixelated/assets/normalize.min.css create mode 100644 src/pixelated/assets/opensans.css create mode 100644 src/pixelated/assets/pixelated-logo-orange.svg create mode 100644 src/pixelated/assets/pixelated.css create mode 100644 src/pixelated/assets/snap.svg-min.js create mode 100644 src/pixelated/assets/welcome.mail create mode 100644 src/pixelated/bitmask_libraries/__init__.py create mode 100644 src/pixelated/bitmask_libraries/certs.py create mode 100644 src/pixelated/bitmask_libraries/config.py create mode 100644 src/pixelated/bitmask_libraries/nicknym.py create mode 100644 src/pixelated/bitmask_libraries/provider.py create mode 100644 src/pixelated/bitmask_libraries/session.py create mode 100644 src/pixelated/bitmask_libraries/smtp.py create mode 100644 src/pixelated/bitmask_libraries/soledad.py create mode 100644 src/pixelated/certificates/__init__.py create mode 100644 src/pixelated/certificates/unstable.pixelated-project.org.ca.crt create mode 100644 src/pixelated/config/__init__.py create mode 100644 src/pixelated/config/arguments.py create mode 100644 src/pixelated/config/credentials.py create mode 100644 src/pixelated/config/leap.py create mode 100644 src/pixelated/config/logger.py create mode 100644 src/pixelated/config/services.py create mode 100644 src/pixelated/config/site.py create mode 100644 src/pixelated/extensions/__init__.py create mode 100644 src/pixelated/extensions/esmtp_sender_factory.py create mode 100644 src/pixelated/extensions/protobuf_socket.py create mode 100644 src/pixelated/extensions/requests_urllib3.py create mode 100644 src/pixelated/extensions/shared_db.py create mode 100644 src/pixelated/extensions/sqlcipher_wal.py create mode 100644 src/pixelated/maintenance.py create mode 100644 src/pixelated/register.py create mode 100644 src/pixelated/resources/__init__.py create mode 100644 src/pixelated/resources/attachments_resource.py create mode 100644 src/pixelated/resources/auth.py create mode 100644 src/pixelated/resources/contacts_resource.py create mode 100644 src/pixelated/resources/features_resource.py create mode 100644 src/pixelated/resources/feedback_resource.py create mode 100644 src/pixelated/resources/keys_resource.py create mode 100644 src/pixelated/resources/login_resource.py create mode 100644 src/pixelated/resources/logout_resource.py create mode 100644 src/pixelated/resources/mail_resource.py create mode 100644 src/pixelated/resources/mails_resource.py create mode 100644 src/pixelated/resources/root_resource.py create mode 100644 src/pixelated/resources/sandbox_resource.py create mode 100644 src/pixelated/resources/session.py create mode 100644 src/pixelated/resources/tags_resource.py create mode 100644 src/pixelated/resources/user_settings_resource.py create mode 100644 src/pixelated/support/__init__.py create mode 100644 src/pixelated/support/date.py create mode 100644 src/pixelated/support/encrypted_file_storage.py create mode 100644 src/pixelated/support/error_handler.py create mode 100644 src/pixelated/support/functional.py create mode 100644 src/pixelated/support/mail_generator.py create mode 100644 src/pixelated/support/markov.py create mode 100644 src/pixelated/support/replier.py create mode 100644 src/pixelated/support/tls_adapter.py create mode 100644 src/pixelated_www/404.html create mode 100644 src/pixelated_www/__init__.py create mode 100644 src/pixelated_www/app.min.js create mode 100644 src/pixelated_www/bower_components/font-awesome/css/font-awesome.min.css create mode 100644 src/pixelated_www/bower_components/font-awesome/fonts/FontAwesome.otf create mode 100644 src/pixelated_www/bower_components/font-awesome/fonts/fontawesome-webfont.eot create mode 100644 src/pixelated_www/bower_components/font-awesome/fonts/fontawesome-webfont.svg create mode 100644 src/pixelated_www/bower_components/font-awesome/fonts/fontawesome-webfont.ttf create mode 100644 src/pixelated_www/bower_components/font-awesome/fonts/fontawesome-webfont.woff create mode 100644 src/pixelated_www/bower_components/jquery-file-upload/css/jquery.fileupload.css create mode 100644 src/pixelated_www/css/sandbox.css create mode 100644 src/pixelated_www/css/style.css create mode 100644 src/pixelated_www/fonts/OpenSans-Bold.woff create mode 100644 src/pixelated_www/fonts/OpenSans-BoldItalic.woff create mode 100644 src/pixelated_www/fonts/OpenSans-Extrabold.woff create mode 100644 src/pixelated_www/fonts/OpenSans-ExtraboldItalic.woff create mode 100644 src/pixelated_www/fonts/OpenSans-Italic.woff create mode 100644 src/pixelated_www/fonts/OpenSans-Light.woff create mode 100644 src/pixelated_www/fonts/OpenSans-Semibold.woff create mode 100644 src/pixelated_www/fonts/OpenSans-SemiboldItalic.woff create mode 100644 src/pixelated_www/fonts/OpenSans.woff create mode 100644 src/pixelated_www/fonts/OpenSansLight-Italic.woff create mode 100644 src/pixelated_www/index.html create mode 100644 src/pixelated_www/locales/en-us/translation.json create mode 100644 src/pixelated_www/locales/pt/translation.json create mode 100644 src/pixelated_www/locales/sv/translation.json create mode 100644 src/pixelated_www/sandbox.html create mode 100644 src/pixelated_www/sandbox.min.js diff --git a/debian/bitmask.install b/debian/bitmask.install index f72dc8c6..34943e9b 100644 --- a/debian/bitmask.install +++ b/debian/bitmask.install @@ -3,3 +3,11 @@ pkg/linux/polkit/se.leap.bitmask.policy usr/share/polkit-1/actions/ debian/bitmask.xpm usr/share/pixmaps debian/bitmask.desktop usr/share/applications debian/icons/hicolor usr/share/icons + +# pixelated hacks!!! +src/pixelated usr/lib/python2.7/dist-packages/ +src/pixelated_www usr/lib/python2.7/dist-packages/ +src/leap/bitmask/auth/auth.py usr/lib/python2.7/dist-packages/leap/ +src/leap/bitmask/auth/exceptions.py usr/lib/python2.7/dist-packages/leap/ +src/leap/bitmask/auth/srp_session.py usr/lib/python2.7/dist-packages/leap/ + diff --git a/pkg/pyinst/bitmask.spec.orig b/pkg/pyinst/bitmask.spec.orig deleted file mode 100644 index 617104b9..00000000 --- a/pkg/pyinst/bitmask.spec.orig +++ /dev/null @@ -1,38 +0,0 @@ -# -*- mode: python -*- - -block_cipher = None - - -a = Analysis([os.path.join('bitmask.py')], - hiddenimports=[ - 'zope.interface', 'zope.proxy', - 'PySide.QtCore', 'PySide.QtGui'], - hookspath=None, - runtime_hooks=None, - excludes=None, - cipher=block_cipher) -pyz = PYZ(a.pure, - cipher=block_cipher) -exe = EXE(pyz, - a.scripts, - exclude_binaries=True, - name='bitmask', - debug=False, - strip=False, - upx=True, - console=False ) -coll = COLLECT(exe, - a.binaries, - a.zipfiles, - a.datas, - strip=False, - upx=True, - name='bitmask') -if sys.platform.startswith("darwin"): - app = BUNDLE(coll, - name=os.path.join( - 'dist', 'Bitmask.app'), - appname='Bitmask', - version='0.9.0rc2', - icon='pkg/osx/bitmask.icns', - bundle_identifier='bitmask-0.9.0rc2') diff --git a/pkg/pyinst/pyinst-build.mk b/pkg/pyinst/pyinst-build.mk index 92a1cbb3..3c514a02 100644 --- a/pkg/pyinst/pyinst-build.mk +++ b/pkg/pyinst/pyinst-build.mk @@ -22,7 +22,8 @@ reset-ver: pyinst-hacks-linux: # XXX this should be taken care of by pyinstaller data collector - cp $(VIRTUAL_ENV)/lib/python2.7/site-packages/leap/common/cacert.pem $(DIST) + #cp $(VIRTUAL_ENV)/lib/python2.7/site-packages/leap/common/cacert.pem $(DIST) + cp ../leap_common/src/leap/common/cacert.pem $(DIST) mkdir -p $(DIST)pysqlcipher mkdir -p $(DIST)pixelated mkdir -p $(DIST)twisted/web diff --git a/src/leap/bitmask/auth/auth.py b/src/leap/bitmask/auth/auth.py new file mode 100644 index 00000000..03065571 --- /dev/null +++ b/src/leap/bitmask/auth/auth.py @@ -0,0 +1,336 @@ +import binascii +import logging +import os.path +import requests +import srp +import json +import re + +from requests.adapters import HTTPAdapter + +from leap.exceptions import (SRPAuthenticationError, + SRPAuthConnectionError, + SRPAuthBadStatusCode, + SRPAuthNoSalt, + SRPAuthNoB, + SRPAuthBadDataFromServer, + SRPAuthBadUserOrPassword, + SRPAuthVerificationFailed, + SRPAuthNoSessionId) + +from leap.srp_session import SRPSession + +logger = logging.getLogger(__name__) + + +class SRPAuth(object): + + def __init__(self, api_uri, verify_certificate=True, api_version=1): + self.api_uri = api_uri + self.api_version = api_version + + if verify_certificate is None: + verify_certificate = True + + if isinstance(verify_certificate, (str, unicode)) and not os.path.isfile(verify_certificate): + raise ValueError( + 'Path {0} is not a valid file'.format(verify_certificate)) + + self.verify_certificate = verify_certificate + + def reset_session(self): + adapter = HTTPAdapter(max_retries=50) + self._session = requests.session() + self._session.mount('https://', adapter) + self.session_id = None + + def _authentication_preprocessing(self, username, password): + + logger.debug('Authentication preprocessing...') + + user = srp.User(username.encode('utf-8'), + password.encode('utf-8'), + srp.SHA256, srp.NG_1024) + _, A = user.start_authentication() + + return user, A + + def _start_authentication(self, username, A): + + logger.debug('Starting authentication process...') + try: + auth_data = { + 'login': username, + 'A': binascii.hexlify(A) + } + sessions_url = '%s/%s/%s/' % \ + (self.api_uri, + self.api_version, + 'sessions') + + verify_certificate = self.verify_certificate + + init_session = self._session.post(sessions_url, + data=auth_data, + verify=verify_certificate, + timeout=30) + except requests.exceptions.ConnectionError as e: + logger.error('No connection made (salt): {0!r}'.format(e)) + raise SRPAuthConnectionError() + except Exception as e: + logger.error('Unknown error: %r' % (e,)) + raise SRPAuthenticationError() + + if init_session.status_code not in (200,): + logger.error('No valid response (salt): ' + 'Status code = %r. Content: %r' % + (init_session.status_code, init_session.content)) + if init_session.status_code == 422: + logger.error('Invalid username or password.') + raise SRPAuthBadUserOrPassword() + + logger.error('There was a problem with authentication.') + raise SRPAuthBadStatusCode() + + json_content = json.loads(init_session.content) + salt = json_content.get('salt', None) + B = json_content.get('B', None) + + if salt is None: + logger.error('The server didn\'t send the salt parameter.') + raise SRPAuthNoSalt() + if B is None: + logger.error('The server didn\'t send the B parameter.') + raise SRPAuthNoB() + + return salt, B + + def _process_challenge(self, user, salt_B, username): + logger.debug('Processing challenge...') + try: + salt, B = salt_B + unhex_salt = _safe_unhexlify(salt) + unhex_B = _safe_unhexlify(B) + except (TypeError, ValueError) as e: + logger.error('Bad data from server: %r' % (e,)) + raise SRPAuthBadDataFromServer() + M = user.process_challenge(unhex_salt, unhex_B) + + auth_url = '%s/%s/%s/%s' % (self.api_uri, + self.api_version, + 'sessions', + username) + + auth_data = { + 'client_auth': binascii.hexlify(M) + } + + try: + auth_result = self._session.put(auth_url, + data=auth_data, + verify=self.verify_certificate, + timeout=30) + except requests.exceptions.ConnectionError as e: + logger.error('No connection made (HAMK): %r' % (e,)) + raise SRPAuthConnectionError() + + if auth_result.status_code == 422: + error = '' + try: + error = json.loads(auth_result.content).get('errors', '') + except ValueError: + logger.error('Problem parsing the received response: %s' + % (auth_result.content,)) + except AttributeError: + logger.error('Expecting a dict but something else was ' + 'received: %s', (auth_result.content,)) + logger.error('[%s] Wrong password (HAMK): [%s]' % + (auth_result.status_code, error)) + raise SRPAuthBadUserOrPassword() + + if auth_result.status_code not in (200,): + logger.error('No valid response (HAMK): ' + 'Status code = %s. Content = %r' % + (auth_result.status_code, auth_result.content)) + raise SRPAuthBadStatusCode() + + return json.loads(auth_result.content) + + def _extract_data(self, json_content): + + try: + M2 = json_content.get('M2', None) + uuid = json_content.get('id', None) + token = json_content.get('token', None) + except Exception as e: + logger.error(e) + raise SRPAuthBadDataFromServer() + + if M2 is None or uuid is None: + logger.error('Something went wrong. Content = %r' % + (json_content,)) + raise SRPAuthBadDataFromServer() + + return uuid, token, M2 + + def _verify_session(self, user, M2): + + logger.debug('Verifying session...') + try: + unhex_M2 = _safe_unhexlify(M2) + except TypeError: + logger.error('Bad data from server (HAMK)') + raise SRPAuthBadDataFromServer() + + user.verify_session(unhex_M2) + + if not user.authenticated(): + logger.error('Auth verification failed.') + raise SRPAuthVerificationFailed() + logger.debug('Session verified.') + + session_id = self._session.cookies.get('_session_id', None) + if not session_id: + logger.error('Bad cookie from server (missing _session_id)') + raise SRPAuthNoSessionId() + + logger.debug('SUCCESS LOGIN') + return session_id + + def authenticate(self, username, password): + + self.reset_session() + + user, A = self._authentication_preprocessing(username, password) + salt_B = self._start_authentication(username, A) + + json_content = self._process_challenge(user, salt_B, username) + + uuid, token, M2 = self._extract_data(json_content) + session_id = self._verify_session(user, M2) + + self.session_id = session_id + + return SRPSession(username, token, uuid, session_id) + + def logout(self): + logger.debug('Starting logout...') + + if self.session_id is None: + logger.debug('Already logged out') + return + + logout_url = '%s/%s/%s/' % (self.api_uri, + self.api_version, + 'logout') + try: + self._session.delete(logout_url, + data=self.session_id, + verify=self.verify_certificate, + timeout=30) + self.reset_session() + except Exception as e: + logger.warning('Something went wrong with the logout: %r' % + (e,)) + raise + else: + logger.debug('Successfully logged out.') + + def change_password(self, + username, + current_password, + new_password, + token, + uuid): + + if self.session_id is None: + logger.debug('Already logged out') + return + + url = '%s/%s/users/%s.json' % ( + self.api_uri, + self.api_version, + uuid) + + salt, verifier = srp.create_salted_verification_key( + username, new_password.encode('utf-8'), + srp.SHA256, srp.NG_1024) + + cookies = {'_session_id': self.session_id} + headers = { + 'Authorization': + 'Token token={0}'.format(token) + } + user_data = { + 'user[password_verifier]': binascii.hexlify(verifier), + 'user[password_salt]': binascii.hexlify(salt) + } + + change_password = self._session.put( + url, data=user_data, + verify=self.verify_certificate, + cookies=cookies, + timeout=30, + headers=headers) + + change_password.raise_for_status() + + def register(self, username, password): + self.reset_session() + + username = username.encode('utf-8') + password = password.encode('utf-8') + + validate_username(username) + + salt, verifier = srp.create_salted_verification_key( + username, + password, + srp.SHA256, + srp.NG_1024) + + user_data = { + 'user[login]': username, + 'user[password_verifier]': binascii.hexlify(verifier), + 'user[password_salt]': binascii.hexlify(salt) + } + + url = "%s/%s/users" % ( + self.api_uri, + self.api_version) + + logger.debug("Registering user: %s" % username) + + try: + response = self._session.post( + url, + data=user_data, + timeout=30, + verify=self.verify_certificate) + + except requests.exceptions.RequestException as exc: + logger.error(exc.message) + raise + + if not response.ok: + try: + json_content = json.loads(response.content) + error_msg = json_content.get("errors").get("login")[0] + if not error_msg.istitle(): + error_msg = "%s %s" % (username, error_msg) + logger.error(error_msg) + except Exception as e: + logger.error("Unknown error: %s" % e.message) + + return response.ok + + +def _safe_unhexlify(val): + return binascii.unhexlify(val) \ + if (len(val) % 2 == 0) else binascii.unhexlify('0' + val) + + +def validate_username(username): + accepted_characters = '^[a-z0-9\-\_\.]*$' + if not re.match(accepted_characters, username): + raise ValueError('Only lowercase letters, digits, . - and _ allowed.') diff --git a/src/leap/bitmask/auth/exceptions.py b/src/leap/bitmask/auth/exceptions.py new file mode 100644 index 00000000..3dea3f76 --- /dev/null +++ b/src/leap/bitmask/auth/exceptions.py @@ -0,0 +1,65 @@ +class SRPAuthenticationError(Exception): + """ + Exception raised for authentication errors + """ + pass + + +class SRPAuthConnectionError(SRPAuthenticationError): + """ + Exception raised when there's a connection error + """ + pass + + +class SRPAuthBadStatusCode(SRPAuthenticationError): + """ + Exception raised when we received an unknown bad status code + """ + pass + + +class SRPAuthNoSalt(SRPAuthenticationError): + """ + Exception raised when we don't receive the salt param at a + specific point in the auth process + """ + pass + + +class SRPAuthNoB(SRPAuthenticationError): + """ + Exception raised when we don't receive the B param at a specific + point in the auth process + """ + pass + + +class SRPAuthBadDataFromServer(SRPAuthenticationError): + """ + Generic exception when we receive bad data from the server. + """ + pass + + +class SRPAuthBadUserOrPassword(SRPAuthenticationError): + """ + Exception raised when the user provided a bad password to auth. + """ + pass + + +class SRPAuthVerificationFailed(SRPAuthenticationError): + """ + Exception raised when we can't verify the SRP data received from + the server. + """ + pass + + +class SRPAuthNoSessionId(SRPAuthenticationError): + """ + Exception raised when we don't receive a session id from the + server. + """ + pass diff --git a/src/leap/bitmask/auth/srp_session.py b/src/leap/bitmask/auth/srp_session.py new file mode 100644 index 00000000..861a7cc0 --- /dev/null +++ b/src/leap/bitmask/auth/srp_session.py @@ -0,0 +1,7 @@ +class SRPSession(object): + + def __init__(self, username, token, uuid, session_id): + self.username = username + self.token = token + self.uuid = uuid + self.session_id = session_id diff --git a/src/pixelated/__init__.py b/src/pixelated/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/pixelated/adapter/__init__.py b/src/pixelated/adapter/__init__.py new file mode 100644 index 00000000..2756a319 --- /dev/null +++ b/src/pixelated/adapter/__init__.py @@ -0,0 +1,15 @@ +# +# Copyright (c) 2014 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . diff --git a/src/pixelated/adapter/listeners/__init__.py b/src/pixelated/adapter/listeners/__init__.py new file mode 100644 index 00000000..2756a319 --- /dev/null +++ b/src/pixelated/adapter/listeners/__init__.py @@ -0,0 +1,15 @@ +# +# Copyright (c) 2014 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . diff --git a/src/pixelated/adapter/listeners/mailbox_indexer_listener.py b/src/pixelated/adapter/listeners/mailbox_indexer_listener.py new file mode 100644 index 00000000..bde3b25f --- /dev/null +++ b/src/pixelated/adapter/listeners/mailbox_indexer_listener.py @@ -0,0 +1,69 @@ +# +# Copyright (c) 2014 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PCULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . +import logging +from twisted.internet import defer + + +logger = logging.getLogger(__name__) + + +class MailboxIndexerListener(object): + """ Listens for new mails, keeping the index updated """ + + @classmethod + @defer.inlineCallbacks + def listen(cls, account, mailbox_name, mail_store, search_engine): + listener = MailboxIndexerListener( + mailbox_name, mail_store, search_engine) + mail_collection = yield account.get_collection_by_mailbox(mailbox_name) + mail_collection.addListener(listener) + + defer.returnValue(listener) + + def __init__(self, mailbox_name, mail_store, search_engine): + self.mailbox_name = mailbox_name + self.mail_store = mail_store + self.search_engine = search_engine + + @defer.inlineCallbacks + def notify_new(self): + try: + indexed_idents = set(self.search_engine.search( + 'tag:' + self.mailbox_name.lower(), all_mails=True)) + soledad_idents = yield self.mail_store.get_mailbox_mail_ids(self.mailbox_name) + soledad_idents = set(soledad_idents) + + missing_idents = soledad_idents.difference(indexed_idents) + + self.search_engine.index_mails((yield self.mail_store.get_mails(missing_idents, include_body=True))) + except Exception, e: # this is a event handler, don't let exceptions escape + logger.error(e) + + def __eq__(self, other): + return other and other.mailbox_name == self.mailbox_name + + def __hash__(self): + return self.mailbox_name.__hash__() + + def __repr__(self): + return 'MailboxListener: ' + self.mailbox_name + + +@defer.inlineCallbacks +def listen_all_mailboxes(account, search_engine, mail_store): + mailboxes = yield account.list_all_mailbox_names() + for mailbox_name in mailboxes: + yield MailboxIndexerListener.listen(account, mailbox_name, mail_store, search_engine) diff --git a/src/pixelated/adapter/mailstore/__init__.py b/src/pixelated/adapter/mailstore/__init__.py new file mode 100644 index 00000000..978df45d --- /dev/null +++ b/src/pixelated/adapter/mailstore/__init__.py @@ -0,0 +1,20 @@ +# +# Copyright (c) 2015 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . + +from pixelated.adapter.mailstore.mailstore import MailStore, underscore_uuid +from pixelated.adapter.mailstore.leap_mailstore import LeapMailStore + +__all__ = ['MailStore', 'LeapMailStore', 'underscore_uuid'] diff --git a/src/pixelated/adapter/mailstore/body_parser.py b/src/pixelated/adapter/mailstore/body_parser.py new file mode 100644 index 00000000..25e0c29a --- /dev/null +++ b/src/pixelated/adapter/mailstore/body_parser.py @@ -0,0 +1,68 @@ +# +# Copyright (c) 2015 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . + +from email.parser import Parser +import re +import logging + +logger = logging.getLogger(__name__) + + +def _parse_charset_header(content_type_and_charset_header, default_charset='us-ascii'): + try: + return re.compile('.*charset="?([a-zA-Z0-9-]+)"?', re.MULTILINE | re.DOTALL).match(content_type_and_charset_header).group(1) + except: + return default_charset + + +class BodyParser(object): + + def __init__(self, content, content_type='text/plain; charset="us-ascii"', content_transfer_encoding=None): + self._content = content + self._content_type = content_type + self._content_transfer_encoding = content_transfer_encoding + + def parsed_content(self): + charset = _parse_charset_header(self._content_type) + text = self._serialize_for_parser(charset) + + decoded_body = self._parse_and_decode(text) + return unicode(decoded_body, charset, errors='replace') + + def _parse_and_decode(self, text): + parsed_body = Parser().parsestr(text) + decoded_body = self._unwrap_content_transfer_encoding(parsed_body) + return decoded_body + + def _unwrap_content_transfer_encoding(self, parsed_body): + return parsed_body.get_payload(decode=True) + + def _serialize_for_parser(self, charset): + text = u'Content-Type: %s\n' % self._content_type + if self._content_transfer_encoding is not None: + text += u'Content-Transfer-Encoding: %s\n' % self._content_transfer_encoding + + text += u'\n' + encoded_text = text.encode(charset) + if isinstance(self._content, unicode): + try: + return encoded_text + self._content.encode(charset) + except UnicodeError, e: + logger.warn( + 'Failed to encode content for charset %s. Ignoring invalid chars: %s' % (charset, e)) + return encoded_text + self._content.encode(charset, 'ignore') + else: + return encoded_text + self._content diff --git a/src/pixelated/adapter/mailstore/leap_attachment_store.py b/src/pixelated/adapter/mailstore/leap_attachment_store.py new file mode 100644 index 00000000..81893675 --- /dev/null +++ b/src/pixelated/adapter/mailstore/leap_attachment_store.py @@ -0,0 +1,67 @@ + +import quopri +import base64 +from email import encoders +from leap.mail.adaptors.soledad import SoledadMailAdaptor, ContentDocWrapper +from twisted.internet import defer +from email.mime.nonmultipart import MIMENonMultipart +from email.mime.multipart import MIMEMultipart +from leap.mail.mail import Message + + +class LeapAttachmentStore(object): + + def __init__(self, soledad): + self.soledad = soledad + + @defer.inlineCallbacks + def get_mail_attachment(self, attachment_id): + results = yield self.soledad.get_from_index('by-type-and-payloadhash', 'cnt', attachment_id) if attachment_id else [] + if results: + content = ContentDocWrapper(**results[0].content) + defer.returnValue({'content-type': content.content_type, 'content': self._try_decode( + content.raw, content.content_transfer_encoding)}) + else: + raise ValueError('No attachment with id %s found!' % attachment_id) + + @defer.inlineCallbacks + def add_attachment(self, content, content_type): + cdoc = self._attachment_to_cdoc(content, content_type) + attachment_id = cdoc.phash + try: + yield self.get_mail_attachment(attachment_id) + except ValueError: + yield self.soledad.create_doc(cdoc.serialize(), doc_id=attachment_id) + defer.returnValue(attachment_id) + + def _try_decode(self, raw, encoding): + encoding = encoding.lower() + if encoding == 'base64': + data = base64.decodestring(raw) + elif encoding == 'quoted-printable': + data = quopri.decodestring(raw) + else: + data = str(raw) + + return bytearray(data) + + def _attachment_to_cdoc(self, content, content_type, encoder=encoders.encode_base64): + major, sub = content_type.split('/') + attachment = MIMENonMultipart(major, sub) + attachment.set_payload(content) + encoder(attachment) + attachment.add_header('Content-Disposition', + 'attachment', filename='does_not_matter.txt') + + pseudo_mail = MIMEMultipart() + pseudo_mail.attach(attachment) + + tmp_mail = SoledadMailAdaptor().get_msg_from_string( + MessageClass=Message, raw_msg=pseudo_mail.as_string()) + + cdoc = tmp_mail.get_wrapper().cdocs[1] + return cdoc + + def _calc_attachment_id_(self, content, content_type, encoder=encoders.encode_base64): + cdoc = self._attachment_to_cdoc(content, content_type, encoder) + return cdoc.phash diff --git a/src/pixelated/adapter/mailstore/leap_mailstore.py b/src/pixelated/adapter/mailstore/leap_mailstore.py new file mode 100644 index 00000000..e8f0c2a6 --- /dev/null +++ b/src/pixelated/adapter/mailstore/leap_mailstore.py @@ -0,0 +1,429 @@ +# +# Copyright (c) 2015 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . +import re +from email.header import decode_header +from uuid import uuid4 + +from leap.mail.adaptors.soledad import SoledadMailAdaptor +from leap.mail.mail import Message +from twisted.internet import defer +from twisted.internet.defer import FirstError, DeferredList + +from pixelated.adapter.mailstore.body_parser import BodyParser +from pixelated.adapter.mailstore.mailstore import MailStore, underscore_uuid +from pixelated.adapter.model.mail import Mail, InputMail +from pixelated.support.functional import to_unicode +from pixelated.support import date + + +MIME_PGP_KEY = 'application/pgp-keys' + + +class AttachmentInfo(object): + + def __init__(self, ident, name, encoding=None, ctype='application/octet-stream', size=0): + self.ident = ident + self.name = name + self.encoding = encoding + self.ctype = ctype + self.size = size + + def __repr__(self): + return 'AttachmentInfo[%s, %s, %s]' % (self.ident, self.name, self.encoding) + + def __str__(self): + return 'AttachmentInfo[%s, %s, %s]' % (self.ident, self.name, self.encoding) + + def as_dict(self): + return {'ident': self.ident, 'name': self.name, 'encoding': self.encoding, 'size': self.size, 'content-type': self.ctype} + + +class LeapMail(Mail): + + def __init__(self, mail_id, mailbox_name, headers=None, tags=set(), flags=set(), body=None, attachments=[]): + self._mail_id = mail_id + self._mailbox_name = mailbox_name + self._headers = headers if headers is not None else {} + self._body = to_unicode(body) + self.tags = set(tags) # TODO test that asserts copy + self._flags = set(flags) # TODO test that asserts copy + self._attachments = attachments + + @property + def headers(self): + cpy = dict(self._headers) + for name in set(self._headers.keys()).intersection(['To', 'Cc', 'Bcc']): + cpy[name] = [address.strip() for address in ( + self._headers[name].split(',') if self._headers[name] else [])] + + return cpy + + @property + def ident(self): + return self._mail_id + + @property + def mail_id(self): + return self._mail_id + + @property + def body(self): + return self._body + + @property + def flags(self): + return self._flags + + @property + def mailbox_name(self): + return self._mailbox_name + + @property + def security_casing(self): + casing = dict(imprints=self._signature_information(), locks=[]) + if self._encrypted() == "decrypted": + casing["locks"] = [{"state": "valid"}] + return casing + + def _encrypted(self): + return self.headers.get("X-Leap-Encryption", "false") + + def _signature_information(self): + signature = self.headers.get("X-Leap-Signature", None) + if signature is None or signature.startswith("could not verify"): + return [{"state": "no_signature_information"}] + else: + if signature.startswith("valid"): + return [{"state": "valid", "seal": {"validity": "valid"}}] + else: + return [] + + @property + def raw(self): + result = u'' + for k, v in self._headers.items(): + content, encoding = decode_header(v)[0] + if encoding: + result += '%s: %s\n' % (k, unicode(content, encoding=encoding)) + else: + result += '%s: %s\n' % (k, v) + result += '\n' + + if self._body: + result = result + self._body + + return result + + def _remove_duplicates(self, values): + return list(set(values)) + + def _decoded_header_utf_8(self, header_value): + if isinstance(header_value, list): + return self._remove_duplicates([self._decoded_header_utf_8(v) for v in header_value]) + elif header_value is not None: + def encode_chunk(content, encoding): + return unicode(content.strip(), encoding=encoding or 'ascii', errors='ignore') + + try: + encoded_chunks = [encode_chunk( + content, encoding) for content, encoding in decode_header(header_value)] + # decode_header strips whitespaces on all chunks, joining over + # ' ' is only a workaround, not a proper fix + return ' '.join(encoded_chunks) + except UnicodeEncodeError: + return unicode(header_value.encode('ascii', errors='ignore')) + + def as_dict(self): + return { + 'header': {k.lower(): self._decoded_header_utf_8(v) for k, v in self.headers.items()}, + 'ident': self._mail_id, + 'tags': self.tags, + 'status': list(self.status), + 'body': self._body, + 'security_casing': self.security_casing, + 'textPlainBody': self._body, + 'mailbox': self._mailbox_name.lower(), + 'attachments': [attachment.as_dict() for attachment in self._attachments] + } + + @staticmethod + def from_dict(mail_dict): + # TODO: implement this method and also write tests for it + headers = {key.capitalize(): value for key, + value in mail_dict.get('header', {}).items()} + headers['Date'] = date.mail_date_now() + body = mail_dict.get('body', '') + tags = set(mail_dict.get('tags', [])) + status = set(mail_dict.get('status', [])) + attachments = [] + + # mail_id, mailbox_name, headers=None, tags=set(), flags=set(), + # body=None, attachments=[] + return LeapMail(None, None, headers, tags, set(), body, attachments) + + +def _extract_filename(headers, default_filename='UNNAMED'): + content_disposition = headers.get('Content-Disposition', '') + filename = _extract_filename_from_name_header_part(content_disposition) + if not filename: + filename = headers.get('Content-Description', '') + if not filename: + content_type = headers.get('Content-Type', '') + filename = _extract_filename_from_name_header_part(content_type) + + if not filename: + filename = default_filename + + return filename + + +def _extract_filename_from_name_header_part(header_value): + match = re.compile('.*name=\"?(.*[^\"\'])').search(header_value) + filename = '' + if match: + filename = match.group(1) + return filename + + +class LeapMailStore(MailStore): + __slots__ = ('soledad') + + def __init__(self, soledad): + self.soledad = soledad + + @defer.inlineCallbacks + def get_mail(self, mail_id, include_body=False): + message = yield self._fetch_msg_from_soledad(mail_id) + if not _is_empty_message(message): + leap_mail = yield self._leap_message_to_leap_mail(mail_id, message, include_body) + else: + leap_mail = None + + defer.returnValue(leap_mail) + + @defer.inlineCallbacks + def get_mails(self, mail_ids, gracefully_ignore_errors=False, include_body=False): + deferreds = [] + for mail_id in mail_ids: + deferreds.append(self.get_mail(mail_id, include_body=include_body)) + + if gracefully_ignore_errors: + results = yield DeferredList(deferreds, consumeErrors=True) + defer.returnValue( + [mail for ok, mail in results if ok and mail is not None]) + else: + result = yield defer.gatherResults(deferreds, consumeErrors=True) + defer.returnValue(result) + + @defer.inlineCallbacks + def update_mail(self, mail): + message = yield self._fetch_msg_from_soledad(mail.mail_id) + message.get_wrapper().set_tags(tuple(mail.tags)) + message.get_wrapper().set_flags(tuple(mail.flags)) + # TODO assert this is yielded (otherwise asynchronous) + yield self._update_mail(message) + + @defer.inlineCallbacks + def all_mails(self, gracefully_ignore_errors=False): + mdocs = yield self.soledad.get_from_index('by-type', 'meta') + + mail_ids = map(lambda doc: doc.doc_id, mdocs) + + mails = yield self.get_mails(mail_ids, gracefully_ignore_errors=gracefully_ignore_errors, include_body=True) + defer.returnValue(mails) + + @defer.inlineCallbacks + def add_mailbox(self, mailbox_name): + mailbox = yield self._get_or_create_mailbox(mailbox_name) + defer.returnValue(mailbox) + + @defer.inlineCallbacks + def get_mailbox_names(self): + mbox_map = set((yield self._mailbox_uuid_to_name_map()).values()) + + defer.returnValue(mbox_map.union({'INBOX'})) + + @defer.inlineCallbacks + def _mailbox_uuid_to_name_map(self): + map = {} + mbox_docs = yield self.soledad.get_from_index('by-type', 'mbox') + for doc in mbox_docs: + map[underscore_uuid(doc.content.get('uuid')) + ] = doc.content.get('mbox') + + defer.returnValue(map) + + @defer.inlineCallbacks + def add_mail(self, mailbox_name, raw_msg): + mailbox = yield self._get_or_create_mailbox(mailbox_name) + message = SoledadMailAdaptor().get_msg_from_string(Message, raw_msg) + message.get_wrapper().set_mbox_uuid(mailbox.uuid) + + yield SoledadMailAdaptor().create_msg(self.soledad, message) + + # add behavious from insert_mdoc_id from mail.py + # TODO test that asserts include_body + mail = yield self._leap_message_to_leap_mail(message.get_wrapper().mdoc.doc_id, message, include_body=True) + defer.returnValue(mail) + + @defer.inlineCallbacks + def delete_mail(self, mail_id): + message = yield self._fetch_msg_from_soledad(mail_id) + if message and message.get_wrapper().mdoc.doc_id: + yield message.get_wrapper().delete(self.soledad) + defer.returnValue(True) + defer.returnValue(False) + + @defer.inlineCallbacks + def get_mailbox_mail_ids(self, mailbox_name): + mailbox = yield self._get_or_create_mailbox(mailbox_name) + fdocs = yield self.soledad.get_from_index('by-type-and-mbox-uuid', 'flags', underscore_uuid(mailbox.uuid)) + + mail_ids = map(lambda doc: _fdoc_id_to_mdoc_id(doc.doc_id), fdocs) + + defer.returnValue(mail_ids) + + @defer.inlineCallbacks + def delete_mailbox(self, mailbox_name): + mbx_wrapper = yield self._get_or_create_mailbox(mailbox_name) + yield SoledadMailAdaptor().delete_mbox(self.soledad, mbx_wrapper) + + @defer.inlineCallbacks + def copy_mail_to_mailbox(self, mail_id, mailbox_name): + message = yield self._fetch_msg_from_soledad(mail_id, load_body=True) + mailbox = yield self._get_or_create_mailbox(mailbox_name) + copy_wrapper = yield message.get_wrapper().copy(self.soledad, mailbox.uuid) + + leap_message = Message(copy_wrapper) + + mail = yield self._leap_message_to_leap_mail(copy_wrapper.mdoc.doc_id, leap_message, include_body=False) + + defer.returnValue(mail) + + @defer.inlineCallbacks + def move_mail_to_mailbox(self, mail_id, mailbox_name): + mail_copy = yield self.copy_mail_to_mailbox(mail_id, mailbox_name) + yield self.delete_mail(mail_id) + defer.returnValue(mail_copy) + + def _update_mail(self, message): + return message.get_wrapper().update(self.soledad) + + @defer.inlineCallbacks + def _leap_message_to_leap_mail(self, mail_id, message, include_body): + if include_body: + # TODO use body from message if available + body = yield self._raw_message_body(message) + else: + body = None + + # fetch mailbox name by mbox_uuid + mbox_uuid = message.get_wrapper().fdoc.mbox_uuid + mbox_name = yield self._mailbox_name_from_uuid(mbox_uuid) + attachments = self._extract_attachment_info_from(message) + attachments = self._filter_public_keys_from_attachments(attachments) + mail = LeapMail(mail_id, mbox_name, message.get_wrapper().hdoc.headers, set(message.get_tags()), set( + message.get_flags()), body=body, attachments=attachments) # TODO assert flags are passed on + + defer.returnValue(mail) + + def _filter_public_keys_from_attachments(self, attachments): + return filter(lambda attachment: attachment.ctype != MIME_PGP_KEY, attachments) + + @defer.inlineCallbacks + def _raw_message_body(self, message): + content_doc = (yield message.get_wrapper().get_body(self.soledad)) + parser = BodyParser('', content_type='text/plain', + content_transfer_encoding='UTF-8') + # It fix the problem when leap doesn'r found body_phash and returns + # empty string + if not isinstance(content_doc, str): + parser = BodyParser(content_doc.raw, content_type=content_doc.content_type, + content_transfer_encoding=content_doc.content_transfer_encoding) + + defer.returnValue(parser.parsed_content()) + + @defer.inlineCallbacks + def _mailbox_name_from_uuid(self, uuid): + map = (yield self._mailbox_uuid_to_name_map()) + defer.returnValue(map.get(uuid, '')) + + @defer.inlineCallbacks + def _get_or_create_mailbox(self, mailbox_name): + mailbox_name_upper = mailbox_name.upper() + mbx = yield SoledadMailAdaptor().get_or_create_mbox(self.soledad, mailbox_name_upper) + if mbx.uuid is None: + mbx.uuid = str(uuid4()) + yield mbx.update(self.soledad) + defer.returnValue(mbx) + + def _fetch_msg_from_soledad(self, mail_id, load_body=False): + return SoledadMailAdaptor().get_msg_from_mdoc_id(Message, self.soledad, mail_id, get_cdocs=load_body) + + @defer.inlineCallbacks + def _dump_soledad(self): + gen, docs = yield self.soledad.get_all_docs() + for doc in docs: + print '\n%s\n' % doc + + def _extract_attachment_info_from(self, message): + wrapper = message.get_wrapper() + part_maps = wrapper.hdoc.part_map + return self._extract_part_map(part_maps) + + def _is_attachment(self, part_map, headers): + disposition = headers.get('Content-Disposition', None) + content_type = part_map['ctype'] + + if 'multipart' in content_type: + return False + + if 'text/plain' == content_type and ((disposition == 'inline') or (disposition is None)): + return False + + return True + + def _create_attachment_info_from(self, part_map, headers): + ident = part_map['phash'] + name = _extract_filename(headers) + encoding = headers.get('Content-Transfer-Encoding', None) + ctype = part_map.get('ctype') or headers.get('Content-Type') + size = part_map.get('size', 0) + + return AttachmentInfo(ident, name, encoding, ctype, size) + + def _extract_part_map(self, part_maps): + result = [] + + for nr, part_map in part_maps.items(): + if 'headers' in part_map and 'phash' in part_map: + headers = {header[0]: header[1] + for header in part_map['headers']} + if self._is_attachment(part_map, headers): + result.append( + self._create_attachment_info_from(part_map, headers)) + if 'part_map' in part_map: + result += self._extract_part_map(part_map['part_map']) + + return result + + +def _is_empty_message(message): + return (message is None) or (message.get_wrapper().mdoc.doc_id is None) + + +def _fdoc_id_to_mdoc_id(fdoc_id): + return 'M' + fdoc_id[1:] diff --git a/src/pixelated/adapter/mailstore/mailstore.py b/src/pixelated/adapter/mailstore/mailstore.py new file mode 100644 index 00000000..9aba6e62 --- /dev/null +++ b/src/pixelated/adapter/mailstore/mailstore.py @@ -0,0 +1,61 @@ +# +# Copyright (c) 2015 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . + + +class MailStore(object): + + def get_mail(self, mail_id): + pass + + def get_mail_attachment(self, attachment_id): + pass + + def get_mails(self, mail_ids, gracefully_ignore_errors=False, include_body=False): + pass + + def all_mails(self): + pass + + def delete_mail(self, mail_id): + pass + + def update_mail(self, mail): + pass + + def add_mail(self, mailbox_name, mail): + pass + + def get_mailbox_names(self): + pass + + def add_mailbox(self, mailbox_name): + pass + + def delete_mailbox(self, mailbox_name): + pass + + def get_mailbox_mail_ids(self, mailbox_name): + pass + + def copy_mail_to_mailbox(self, mail_id, mailbox_name): + pass + + def move_mail_to_mailbox(self, mail_id, mailbox_name): + pass + + +def underscore_uuid(uuid): + return uuid.replace('-', '_') diff --git a/src/pixelated/adapter/mailstore/maintenance/__init__.py b/src/pixelated/adapter/mailstore/maintenance/__init__.py new file mode 100644 index 00000000..02b38a10 --- /dev/null +++ b/src/pixelated/adapter/mailstore/maintenance/__init__.py @@ -0,0 +1,104 @@ +# +# Copyright (c) 2015 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . +from leap.keymanager.keys import KEY_TYPE_KEY, KEY_PRIVATE_KEY, KEY_FINGERPRINT_KEY, KEY_ADDRESS_KEY +from leap.keymanager.openpgp import OpenPGPKey + +from twisted.internet import defer +import logging + + +TYPE_OPENPGP_KEY = 'OpenPGPKey' +TYPE_OPENPGP_ACTIVE = 'OpenPGPKey-active' + +KEY_DOC_TYPES = {TYPE_OPENPGP_ACTIVE, TYPE_OPENPGP_KEY} + +logger = logging.getLogger(__name__) + + +def _is_key_doc(doc): + return doc.content.get(KEY_TYPE_KEY, None) in KEY_DOC_TYPES + + +def _is_private_key_doc(doc): + return _is_key_doc(doc) and doc.content.get(KEY_PRIVATE_KEY, False) + + +def _is_active_key_doc(doc): + return _is_key_doc(doc) and doc.content.get(KEY_TYPE_KEY, None) == TYPE_OPENPGP_ACTIVE + + +def _is_public_key(doc): + return _is_key_doc(doc) and not doc.content.get(KEY_PRIVATE_KEY, False) + + +def _key_fingerprint(doc): + return doc.content.get(KEY_FINGERPRINT_KEY, None) + + +def _address(doc): + return doc.content.get(KEY_ADDRESS_KEY, None) + + +class SoledadMaintenance(object): + + def __init__(self, soledad): + self._soledad = soledad + + @defer.inlineCallbacks + def repair(self): + _, docs = yield self._soledad.get_all_docs() + + private_key_fingerprints = self._key_fingerprints_with_private_key( + docs) + + for doc in docs: + if _is_key_doc(doc) and _key_fingerprint(doc) not in private_key_fingerprints: + logger.warn('Deleting doc %s for key %s of <%s>' % + (doc.doc_id, _key_fingerprint(doc), _address(doc))) + yield self._soledad.delete_doc(doc) + + yield self._repair_missing_active_docs(docs, private_key_fingerprints) + + @defer.inlineCallbacks + def _repair_missing_active_docs(self, docs, private_key_fingerprints): + missing = self._missing_active_docs(docs, private_key_fingerprints) + for fingerprint in missing: + emails = self._emails_for_key_fingerprint(docs, fingerprint) + for email in emails: + logger.warn('Re-creating active doc for key %s, email %s' % + (fingerprint, email)) + yield self._soledad.create_doc_from_json(OpenPGPKey(email, fingerprint=fingerprint, private=False).get_active_json()) + + def _key_fingerprints_with_private_key(self, docs): + return [doc.content[KEY_FINGERPRINT_KEY] for doc in docs if _is_private_key_doc(doc)] + + def _missing_active_docs(self, docs, private_key_fingerprints): + active_doc_ids = self._active_docs_for_key_fingerprint(docs) + + return set([private_key_fingerprint for private_key_fingerprint in private_key_fingerprints if private_key_fingerprint not in active_doc_ids]) + + def _emails_for_key_fingerprint(self, docs, fingerprint): + for doc in docs: + if _is_private_key_doc(doc) and _key_fingerprint(doc) == fingerprint: + email = _address(doc) + if email is None: + return [] + if isinstance(email, list): + return email + return [email] + + def _active_docs_for_key_fingerprint(self, docs): + return [doc.content[KEY_FINGERPRINT_KEY] for doc in docs if _is_active_key_doc(doc) and _is_public_key(doc)] diff --git a/src/pixelated/adapter/mailstore/searchable_mailstore.py b/src/pixelated/adapter/mailstore/searchable_mailstore.py new file mode 100644 index 00000000..e578e6a7 --- /dev/null +++ b/src/pixelated/adapter/mailstore/searchable_mailstore.py @@ -0,0 +1,82 @@ +# +# Copyright (c) 2015 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . +from twisted.internet import defer +from types import FunctionType +from pixelated.adapter.mailstore import MailStore + + +class SearchableMailStore(object): # implementes MailStore + + def __init__(self, delegate, search_engine): + self._delegate = delegate + self._search_engine = search_engine + + @classmethod + def _create_delegator(cls, method_name): + def delegator(self, *args, **kw): + return getattr(self._delegate, method_name)(*args, **kw) + + setattr(cls, method_name, delegator) + + @defer.inlineCallbacks + def add_mail(self, mailbox_name, mail): + stored_mail = yield self._delegate.add_mail(mailbox_name, mail) + self._search_engine.index_mail(stored_mail) + defer.returnValue(stored_mail) + + @defer.inlineCallbacks + def delete_mail(self, mail_id): + removed = yield self._delegate.delete_mail(mail_id) + self._search_engine.remove_from_index(mail_id) + defer.returnValue(removed) + + @defer.inlineCallbacks + def update_mail(self, mail): + yield self._delegate.update_mail(mail) + self._search_engine.index_mail(mail) + + @defer.inlineCallbacks + def move_mail_to_mailbox(self, mail_id, mailbox_name): + moved_mail = yield self._delegate.move_mail_to_mailbox(mail_id, mailbox_name) + self._search_engine.remove_from_index(mail_id) + self._search_engine.index_mail(moved_mail) + defer.returnValue(moved_mail) + + @defer.inlineCallbacks + def copy_mail_to_mailbox(self, mail_id, mailbox_name): + copied_mail = yield self._delegate.copy_mail_to_mailbox(mail_id, mailbox_name) + self._search_engine.index_mail(copied_mail) + defer.returnValue(copied_mail) + + def delete_mailbox(self, mailbox_name): + raise NotImplementedError() + + def __getattr__(self, name): + """ + Acts like method missing. If a method of MailStore is not implemented in this class, + a delegate method is created. + + :param name: attribute name + :return: method or attribute + """ + methods = ([key for key, value in MailStore.__dict__.items() + if type(value) == FunctionType]) + + if name in methods: + SearchableMailStore._create_delegator(name) + return super(SearchableMailStore, self).__getattribute__(name) + else: + raise NotImplementedError('No attribute %s' % name) diff --git a/src/pixelated/adapter/model/__init__.py b/src/pixelated/adapter/model/__init__.py new file mode 100644 index 00000000..2756a319 --- /dev/null +++ b/src/pixelated/adapter/model/__init__.py @@ -0,0 +1,15 @@ +# +# Copyright (c) 2014 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . diff --git a/src/pixelated/adapter/model/mail.py b/src/pixelated/adapter/model/mail.py new file mode 100644 index 00000000..7043af56 --- /dev/null +++ b/src/pixelated/adapter/model/mail.py @@ -0,0 +1,235 @@ +# +# Copyright (c) 2014 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PCULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . +import os +import re +import logging +from email import message_from_file +from email.mime.text import MIMEText +from email.header import Header +from hashlib import sha256 + +import binascii +from email.MIMEMultipart import MIMEMultipart +from email.mime.nonmultipart import MIMENonMultipart +import leap.mail.walk as walk +from pixelated.adapter.model.status import Status +from pixelated.support import date + + +logger = logging.getLogger(__name__) + + +class Mail(object): + + @property + def from_sender(self): + return self.headers['From'] + + @property + def to(self): + return self.headers['To'] + + @property + def cc(self): + return self.headers['Cc'] + + @property + def bcc(self): + return self.headers['Bcc'] + + @property + def subject(self): + return self.headers['Subject'] + + @property + def date(self): + return self.headers['Date'] + + @property + def status(self): + return Status.from_flags(self.flags) + + @property + def flags(self): + return self.fdoc.content.get('flags') + + @property + def mailbox_name(self): + # FIXME mbox is no longer available, instead we now have mbox_uuid + return self.fdoc.content.get('mbox', 'INBOX') + + def _encode_header_value_list(self, header_value_list): + encoded_header_list = [self._encode_header_value( + v) for v in header_value_list] + return ', '.join(encoded_header_list) + + def _encode_header_value(self, header_value): + if isinstance(header_value, unicode): + return str(Header(header_value, 'utf-8')) + return str(header_value) + + def _add_message_content(self, mime_multipart, body_to_use=None): + body_to_use = body_to_use or self.body + if isinstance(body_to_use, list): + for part in body_to_use: + mime_multipart.attach( + MIMEText(part['raw'], part['content-type'])) + else: + mime_multipart.attach( + MIMEText(body_to_use, 'plain', self._charset())) + + def _add_body(self, mime): + body_to_use = getattr(self, 'body', None) or getattr( + self, 'text_plain_body', None) + self._add_message_content(mime, body_to_use) + self._add_attachments(mime) + + def _generate_mime_multipart(self): + mime = MIMEMultipart() + self._add_headers(mime) + self._add_body(mime) + return mime + + @property + def _mime_multipart(self): + self._mime = self._mime or self._generate_mime_multipart() + return self._mime + + def _add_headers(self, mime): + for key, value in self.headers.items(): + if isinstance(value, list): + mime[str(key)] = self._encode_header_value_list(value) + else: + mime[str(key)] = self._encode_header_value(value) + + def _add_attachments(self, mime): + for attachment in getattr(self, '_attachments', []): + major, sub = attachment['content-type'].split('/') + attachment_mime = MIMENonMultipart(major, sub) + base64_attachment_file = binascii.b2a_base64(attachment['raw']) + attachment_mime.set_payload(base64_attachment_file) + attachment_mime[ + 'Content-Disposition'] = 'attachment; filename="%s"' % attachment['name'] + attachment_mime['Content-Transfer-Encoding'] = 'base64' + mime.attach(attachment_mime) + + def _charset(self): + content_type = self.headers.get('content_type', {}) + if 'charset' in content_type: + return self._parse_charset_header(content_type) + return 'utf-8' + + def _parse_charset_header(self, charset_header, default_charset='utf-8'): + try: + return re.compile('.*charset=([a-zA-Z0-9-]+)', re.MULTILINE | re.DOTALL).match(charset_header).group(1) + except: + return default_charset + + @property + def raw(self): + return self._mime_multipart.as_string() + + def _get_chash(self): + return sha256(self.raw).hexdigest() + + +class InputMail(Mail): + + def __init__(self): + self._raw_message = None + self._fd = None + self._hd = None + self._bd = None + self._chash = None + self._mime = None + self.headers = {} + self.body = '' + self._status = [] + self._attachments = [] + + @property + def ident(self): + return self._get_chash() + + def _get_body_phash(self): + return walk.get_body_phash(self._mime_multipart) + + def _add_predefined_headers(self, mime_multipart): + for header in ['To', 'Cc', 'Bcc']: + if self.headers.get(header): + mime_multipart[header] = ", ".join(self.headers[header]) + for header in ['Subject', 'From']: + if self.headers.get(header): + mime_multipart[header] = self.headers[header] + mime_multipart['Date'] = self.headers['Date'] + + def to_mime_multipart(self): + mime = MIMEMultipart() + self._add_predefined_headers(mime) + self._add_body(mime) + return mime + + def to_smtp_format(self): + mime_multipart = self.to_mime_multipart() + return mime_multipart.as_string() + + @staticmethod + def delivery_error_template(delivery_address): + return InputMail.from_dict({ + 'body': "Mail undelivered for %s" % delivery_address, + 'header': { + 'bcc': [], + 'cc': [], + 'subject': "Mail undelivered for %s" % delivery_address + } + }) + + @staticmethod + def from_dict(mail_dict, from_address): + input_mail = InputMail() + input_mail.headers = { + key.capitalize(): value for key, value in mail_dict.get('header', {}).items()} + + input_mail.headers['Date'] = date.mail_date_now() + input_mail.headers['From'] = from_address + + input_mail.body = mail_dict.get('body', '') + input_mail.tags = set(mail_dict.get('tags', [])) + input_mail._status = set(mail_dict.get('status', [])) + input_mail._attachments = mail_dict.get('attachments', []) + return input_mail + + @staticmethod + def from_python_mail(mail): + input_mail = InputMail() + input_mail.headers = {unicode(key.capitalize()): unicode( + value) for key, value in mail.items()} + input_mail.headers[u'Date'] = unicode(date.mail_date_now()) + input_mail.headers[u'To'] = [u''] + + for payload in mail.get_payload(): + input_mail._mime_multipart.attach(payload) + if payload.get_content_type() == 'text/plain': + input_mail.body = unicode(payload.as_string()) + input_mail._mime = input_mail.to_mime_multipart() + return input_mail + + +def welcome_mail(): + current_path = os.path.dirname(os.path.abspath(__file__)) + with open(os.path.join(current_path, '..', '..', 'assets', 'welcome.mail')) as mail_template_file: + mail_template = message_from_file(mail_template_file) + return InputMail.from_python_mail(mail_template) diff --git a/src/pixelated/adapter/model/status.py b/src/pixelated/adapter/model/status.py new file mode 100644 index 00000000..7101f4c0 --- /dev/null +++ b/src/pixelated/adapter/model/status.py @@ -0,0 +1,43 @@ +# +# Copyright (c) 2014 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . + + +class Status: + + SEEN = u'\\Seen' + ANSWERED = u'\\Answered' + DELETED = u'\\Deleted' + RECENT = u'\\Recent' + + FLAGS_TO_STATUSES = { + SEEN: 'read', + ANSWERED: 'replied', + RECENT: 'recent' + } + + @staticmethod + def from_flag(flag): + return Status.FLAGS_TO_STATUSES[flag] + + @staticmethod + def from_flags(flags): + return set(Status.from_flag(flag) for flag in flags if flag in Status.FLAGS_TO_STATUSES.keys()) + + @staticmethod + def to_flags(statuses): + statuses_to_flags = dict( + zip(Status.FLAGS_TO_STATUSES.values(), Status.FLAGS_TO_STATUSES.keys())) + return [statuses_to_flags[status] for status in statuses] diff --git a/src/pixelated/adapter/model/tag.py b/src/pixelated/adapter/model/tag.py new file mode 100644 index 00000000..ca62a1fe --- /dev/null +++ b/src/pixelated/adapter/model/tag.py @@ -0,0 +1,73 @@ +# +# Copyright (c) 2014 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . + +import json + + +class Tag(object): + + @classmethod + def from_dict(cls, tag_dict): + tag = Tag(tag_dict['name'], tag_dict['default']) + tag.mails = set(tag_dict['mails']) + return tag + + @classmethod + def from_json_string(cls, json_string): + tag_dict = json.loads(json_string) + tag_dict['mails'] = set(tag_dict['mails']) + return Tag.from_dict(tag_dict) + + @property + def total(self): + return len(self.mails) + + def __init__(self, name, default=False): + self.name = name.lower() + self.ident = self.name.__hash__() + self.default = default + self.mails = set() + + def __eq__(self, other): + return self.name == other.name + + def __hash__(self): + return self.name.__hash__() + + def increment(self, mail_ident): + self.mails.add(mail_ident) + + def decrement(self, mail_ident): + self.mails.discard(mail_ident) + + def as_dict(self): + return { + 'name': self.name, + 'default': self.default, + 'ident': self.ident, + 'counts': {'total': self.total, + 'read': 0, + 'starred': 0, + 'replied': 0}, + 'mails': list(self.mails) + } + + def as_json_string(self): + tag_dict = self.as_dict() + return json.dumps(tag_dict) + + def __repr__(self): + return self.name diff --git a/src/pixelated/adapter/search/__init__.py b/src/pixelated/adapter/search/__init__.py new file mode 100644 index 00000000..79f0b281 --- /dev/null +++ b/src/pixelated/adapter/search/__init__.py @@ -0,0 +1,218 @@ +# +# Copyright (c) 2014 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . +from pixelated.support.encrypted_file_storage import EncryptedFileStorage + +import os +import re +import dateutil.parser +import time +from pixelated.adapter.model.status import Status +from pixelated.adapter.search.contacts import contacts_suggestions +from whoosh.index import FileIndex +from whoosh.fields import Schema, ID, KEYWORD, TEXT, NUMERIC, NGRAMWORDS +from whoosh.qparser import QueryParser +from whoosh.qparser import MultifieldParser +from whoosh.writing import AsyncWriter +from whoosh import sorting +from pixelated.support.functional import unique, to_unicode +import traceback +from pixelated.support import date + + +class SearchEngine(object): + DEFAULT_INDEX_HOME = os.path.join(os.environ['HOME'], '.leap') + DEFAULT_TAGS = ['inbox', 'sent', 'drafts', 'trash'] + + def __init__(self, key, user_home=DEFAULT_INDEX_HOME): + self.key = key + self.index_folder = os.path.join(user_home, 'search_index') + if not os.path.exists(self.index_folder): + os.makedirs(self.index_folder) + self._index = self._create_index() + + def _add_to_tags(self, tags, group, skip_default_tags, count_type, query=None): + query_matcher = re.compile( + ".*%s.*" % query.lower()) if query else re.compile(".*") + + for tag, count in group.iteritems(): + + if skip_default_tags and tag in self.DEFAULT_TAGS or not query_matcher.match(tag): + continue + + if not tags.get(tag): + tags[tag] = {'ident': tag, 'name': tag, 'default': False, 'counts': {'total': 0, 'read': 0}, + 'mails': []} + tags[tag]['counts'][count_type] += count + + def _search_tag_groups(self, is_filtering_tags): + seen = None + query_parser = QueryParser('tag', self._index.schema) + options = {'limit': None, 'groupedby': sorting.FieldFacet( + 'tag', allow_overlap=True), 'maptype': sorting.Count} + + with self._index.searcher() as searcher: + total = searcher.search( + query_parser.parse('*'), **options).groups() + if not is_filtering_tags: + seen = searcher.search(query_parser.parse( + "* AND flags:%s" % Status.SEEN), **options).groups() + return seen, total + + def _init_tags_defaults(self): + tags = {} + for default_tag in self.DEFAULT_TAGS: + tags[default_tag] = { + 'ident': default_tag, + 'name': default_tag, + 'default': True, + 'counts': { + 'total': 0, + 'read': 0 + }, + 'mails': [] + } + return tags + + def _build_tags(self, seen, total, skip_default_tags, query): + tags = {} + if not skip_default_tags: + tags = self._init_tags_defaults() + self._add_to_tags(tags, total, skip_default_tags, + count_type='total', query=query) + if seen: + self._add_to_tags(tags, seen, skip_default_tags, count_type='read') + return tags.values() + + def tags(self, query, skip_default_tags): + is_filtering_tags = True if query else False + seen, total = self._search_tag_groups( + is_filtering_tags=is_filtering_tags) + return self._build_tags(seen, total, skip_default_tags, query) + + def _mail_schema(self): + return Schema( + ident=ID(stored=True, unique=True), + sender=ID(stored=False), + to=KEYWORD(stored=False, commas=True), + cc=KEYWORD(stored=False, commas=True), + bcc=KEYWORD(stored=False, commas=True), + subject=NGRAMWORDS(stored=False), + date=NUMERIC(stored=False, sortable=True, bits=64, signed=False), + body=NGRAMWORDS(stored=False), + tag=KEYWORD(stored=True, commas=True), + flags=KEYWORD(stored=True, commas=True), + raw=TEXT(stored=False)) + + def _create_index(self): + storage = EncryptedFileStorage(self.index_folder, self.key) + return FileIndex.create(storage, self._mail_schema(), indexname='mails') + + def index_mail(self, mail): + if mail is not None: + with AsyncWriter(self._index) as writer: + self._index_mail(writer, mail) + + def _index_mail(self, writer, mail): + mdict = mail.as_dict() + header = mdict['header'] + tags = set(mdict.get('tags', {})) + tags.add(mail.mailbox_name.lower()) + + index_data = { + 'sender': self._empty_string_to_none(header.get('from', '')), + 'subject': self._empty_string_to_none(header.get('subject', '')), + 'date': self._format_utc_integer(header.get('date', date.mail_date_now())), + 'to': self._format_recipient(header, 'to'), + 'cc': self._format_recipient(header, 'cc'), + 'bcc': self._format_recipient(header, 'bcc'), + 'tag': u','.join(unique(tags)), + 'body': to_unicode(mdict.get('textPlainBody', mdict.get('body', ''))), + 'ident': unicode(mdict['ident']), + 'flags': unicode(','.join(unique(mail.flags))), + 'raw': unicode(mail.raw) + } + + writer.update_document(**index_data) + + def _format_utc_integer(self, date): + timetuple = dateutil.parser.parse(date).utctimetuple() + return time.strftime('%s', timetuple) + + def _format_recipient(self, headers, name): + list = headers.get(name, ['']) + return u','.join(list) if list else u'' + + def _empty_string_to_none(self, field_value): + if not field_value: + return None + else: + return field_value + + def index_mails(self, mails, callback=None): + try: + with AsyncWriter(self._index) as writer: + for mail in mails: + self._index_mail(writer, mail) + if callback: + callback() + except Exception, e: + traceback.print_exc(e) + raise + + def _search_with_options(self, options, query): + with self._index.searcher() as searcher: + query = QueryParser('raw', self._index.schema).parse(query) + results = searcher.search(query, **options) + return results + + def search(self, query, window=25, page=1, all_mails=False): + query = self.prepare_query(query) + return self._search_all_mails(query) if all_mails else self._paginated_search_mails(query, window, page) + + def _search_all_mails(self, query): + with self._index.searcher() as searcher: + sorting_facet = sorting.FieldFacet('date', reverse=True) + results = searcher.search( + query, sortedby=sorting_facet, reverse=True, limit=None) + return unique([mail['ident'] for mail in results]) + + def _paginated_search_mails(self, query, window, page): + page = int(page) if page is not None and int(page) > 1 else 1 + window = int(window) if window is not None else 25 + + with self._index.searcher() as searcher: + tags_facet = sorting.FieldFacet( + 'tag', allow_overlap=True, maptype=sorting.Count) + sorting_facet = sorting.FieldFacet('date', reverse=True) + results = searcher.search_page( + query, page, pagelen=window, groupedby=tags_facet, sortedby=sorting_facet) + return unique([mail['ident'] for mail in results]), sum(results.results.groups().values()) + + def prepare_query(self, query): + query = ( + query + .replace('-in:', 'AND NOT tag:') + .replace('in:all', '*') + ) + return MultifieldParser(['body', 'subject', 'raw'], self._index.schema).parse(query) + + def remove_from_index(self, mail_id): + with AsyncWriter(self._index) as writer: + writer.delete_by_term('ident', mail_id) + + def contacts(self, query): + with self._index.searcher() as searcher: + return contacts_suggestions(query, searcher) diff --git a/src/pixelated/adapter/search/contacts.py b/src/pixelated/adapter/search/contacts.py new file mode 100644 index 00000000..733489b0 --- /dev/null +++ b/src/pixelated/adapter/search/contacts.py @@ -0,0 +1,56 @@ +# +# Copyright (c) 2014 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . +from email.utils import parseaddr +from pixelated.support.functional import flatten +from whoosh.qparser import QueryParser +from whoosh import sorting +from whoosh.query import Term + + +def address_duplication_filter(contacts): + contacts_by_mail = dict() + + for contact in contacts: + mail_address = extract_mail_address(contact) + current = contacts_by_mail.get(mail_address, '') + current = contact if len(contact) > len(current) else current + contacts_by_mail[mail_address] = current + return contacts_by_mail.values() + + +def extract_mail_address(text): + return parseaddr(text)[1] + + +def contacts_suggestions(query, searcher): + return address_duplication_filter(search_addresses(searcher, query)) if query else [] + + +def search_addresses(searcher, query): + restrict_q = Term("tag", "drafts") | Term("tag", "trash") + results = [] + for field in ['to', 'cc', 'bcc', 'sender']: + query_parser = QueryParser(field, searcher.schema) + results.append( + searcher.search( + query_parser.parse("*%s* OR *%s*" % (query.title(), query)), + limit=None, + mask=restrict_q, + groupedby=sorting.FieldFacet( + field, + allow_overlap=True), + terms=True).matched_terms()) + return [address[1] for address in flatten(results)] diff --git a/src/pixelated/adapter/search/index_storage_key.py b/src/pixelated/adapter/search/index_storage_key.py new file mode 100644 index 00000000..b2761849 --- /dev/null +++ b/src/pixelated/adapter/search/index_storage_key.py @@ -0,0 +1,42 @@ +# +# Copyright (c) 2015 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . +import base64 +from twisted.internet import defer +import os + + +class SearchIndexStorageKey(object): + __slots__ = '_soledad' + + def __init__(self, soledad): + self._soledad = soledad + + @defer.inlineCallbacks + def get_or_create_key(self): + docs = yield self._soledad.get_from_index('by-type', 'index_key') + + if len(docs): + key = docs[0].content['value'] + else: + key = self._new_index_key() + yield self._store_key_in_soledad(key) + defer.returnValue(key) + + def _new_index_key(self): + return os.urandom(64) # 32 for encryption, 32 for hmac + + def _store_key_in_soledad(self, index_key): + return self._soledad.create_doc(dict(type='index_key', value=base64.encodestring(index_key))) diff --git a/src/pixelated/adapter/services/__init__.py b/src/pixelated/adapter/services/__init__.py new file mode 100644 index 00000000..2756a319 --- /dev/null +++ b/src/pixelated/adapter/services/__init__.py @@ -0,0 +1,15 @@ +# +# Copyright (c) 2014 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . diff --git a/src/pixelated/adapter/services/draft_service.py b/src/pixelated/adapter/services/draft_service.py new file mode 100644 index 00000000..504d92db --- /dev/null +++ b/src/pixelated/adapter/services/draft_service.py @@ -0,0 +1,40 @@ +# +# Copyright (c) 2014 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . +from twisted.internet import defer + + +class DraftService(object): + __slots__ = '_mail_store' + + def __init__(self, mail_store): + self._mail_store = mail_store + + @defer.inlineCallbacks + def create_draft(self, input_mail): + mail = yield self._mail_store.add_mail('DRAFTS', input_mail.raw) + defer.returnValue(mail) + + @defer.inlineCallbacks + def update_draft(self, ident, input_mail): + removed = yield self._mail_store.delete_mail(ident) + if removed: + new_draft = yield self.create_draft(input_mail) + defer.returnValue(new_draft) + + def process_draft(self, ident, input_mail): + if ident: + return self.update_draft(ident, input_mail) + return self.create_draft(input_mail) diff --git a/src/pixelated/adapter/services/feedback_service.py b/src/pixelated/adapter/services/feedback_service.py new file mode 100644 index 00000000..5200a9ff --- /dev/null +++ b/src/pixelated/adapter/services/feedback_service.py @@ -0,0 +1,20 @@ +import os +import requests + + +class FeedbackService(object): + FEEDBACK_URL = os.environ.get('FEEDBACK_URL') + + def __init__(self, leap_session): + self.leap_session = leap_session + + def open_ticket(self, feedback): + account_mail = self.leap_session.account_email() + data = { + "ticket[comments_attributes][0][body]": feedback, + "ticket[subject]": "Feedback user-agent from {0}".format(account_mail), + "ticket[email]": account_mail, + "ticket[regarding_user]": account_mail + } + + return requests.post(self.FEEDBACK_URL, data=data, verify=False) diff --git a/src/pixelated/adapter/services/mail_sender.py b/src/pixelated/adapter/services/mail_sender.py new file mode 100644 index 00000000..4933ce4e --- /dev/null +++ b/src/pixelated/adapter/services/mail_sender.py @@ -0,0 +1,102 @@ +# +# Copyright (c) 2014 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . +from StringIO import StringIO +from email.utils import parseaddr +from leap.mail.outgoing.service import OutgoingMail + +from twisted.internet.defer import Deferred, fail +from twisted.mail.smtp import SMTPSenderFactory +from twisted.internet import reactor, defer +from pixelated.support.functional import flatten +from twisted.mail.smtp import User + + +class SMTPDownException(Exception): + + def __init__(self): + Exception.__init__(self, "Couldn't send mail now, try again later.") + + +NOT_NEEDED = None + + +class MailSenderException(Exception): + + def __init__(self, message, email_error_map): + super(MailSenderException, self).__init__(message, email_error_map) + self.email_error_map = email_error_map + + +class MailSender(object): + + def __init__(self, smtp_config, keymanager): + self._smtp_config = smtp_config + self._keymanager = keymanager + + @defer.inlineCallbacks + def sendmail(self, mail): + recipients = flatten([mail.to, mail.cc, mail.bcc]) + + results = yield self._send_mail_to_all_recipients(mail, recipients) + all_succeeded = reduce(lambda a, b: a and b, [r[0] for r in results]) + + if not all_succeeded: + error_map = self._build_error_map(recipients, results) + raise MailSenderException( + 'Failed to send mail to all recipients', error_map) + + defer.returnValue(all_succeeded) + + def _send_mail_to_all_recipients(self, mail, recipients): + outgoing_mail = self._create_outgoing_mail() + bccs = mail.bcc + deferreds = [] + + for recipient in recipients: + self._define_bcc_field(mail, recipient, bccs) + smtp_recipient = self._create_twisted_smtp_recipient(recipient) + deferreds.append(outgoing_mail.send_message( + mail.to_smtp_format(), smtp_recipient)) + + return defer.DeferredList(deferreds, fireOnOneErrback=False, consumeErrors=True) + + def _define_bcc_field(self, mail, recipient, bccs): + if recipient in bccs: + mail.headers['Bcc'] = [recipient] + else: + mail.headers['Bcc'] = [] + + def _build_error_map(self, recipients, results): + error_map = {} + for email, error in [(recipients[idx], r[1]) for idx, r in enumerate(results)]: + error_map[email] = error + return error_map + + def _create_outgoing_mail(self): + return OutgoingMail(str(self._smtp_config.account_email), + self._keymanager, + self._smtp_config.cert_path, + self._smtp_config.cert_path, + str(self._smtp_config.remote_smtp_host), + int(self._smtp_config.remote_smtp_port)) + + def _create_twisted_smtp_recipient(self, recipient): + # TODO: Better is fix Twisted instead + recipient = self._remove_canonical_recipient(recipient) + return User(str(recipient), NOT_NEEDED, NOT_NEEDED, NOT_NEEDED) + + def _remove_canonical_recipient(self, recipient): + return recipient.split('<')[1][0:-1] if '<' in recipient else recipient diff --git a/src/pixelated/adapter/services/mail_service.py b/src/pixelated/adapter/services/mail_service.py new file mode 100644 index 00000000..884a205a --- /dev/null +++ b/src/pixelated/adapter/services/mail_service.py @@ -0,0 +1,152 @@ +# +# Copyright (c) 2014 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . +from email import encoders +from email.mime.nonmultipart import MIMENonMultipart +from email.mime.multipart import MIMEMultipart +from leap.mail.mail import Message + +from twisted.internet import defer + +from pixelated.adapter.model.mail import InputMail +from pixelated.adapter.model.status import Status +from pixelated.adapter.services.tag_service import extract_reserved_tags +from leap.mail.adaptors.soledad import SoledadMailAdaptor + + +class MailService(object): + + def __init__(self, mail_sender, mail_store, search_engine, account_email, attachment_store): + self.mail_store = mail_store + self.search_engine = search_engine + self.mail_sender = mail_sender + self.account_email = account_email + self.attachment_store = attachment_store + + @defer.inlineCallbacks + def all_mails(self): + mails = yield self.mail_store.all_mails(gracefully_ignore_errors=True) + defer.returnValue(mails) + + def save_attachment(self, content, content_type): + return self.attachment_store.add_attachment(content, content_type) + + @defer.inlineCallbacks + def mails(self, query, window_size, page): + mail_ids, total = self.search_engine.search(query, window_size, page) + + try: + mails = yield self.mail_store.get_mails(mail_ids) + defer.returnValue((mails, total)) + except Exception, e: + import traceback + traceback.print_exc() + raise + + @defer.inlineCallbacks + def update_tags(self, mail_id, new_tags): + new_tags = self._filter_white_space_tags(new_tags) + reserved_words = extract_reserved_tags(new_tags) + if len(reserved_words): + raise ValueError( + 'None of the following words can be used as tags: ' + ' '.join(reserved_words)) + new_tags = self._favor_existing_tags_casing(new_tags) + mail = yield self.mail(mail_id) + mail.tags = set(new_tags) + yield self.mail_store.update_mail(mail) + + defer.returnValue(mail) + + def _filter_white_space_tags(self, tags): + return [tag.strip() for tag in tags if not tag.isspace()] + + def _favor_existing_tags_casing(self, new_tags): + current_tags = [tag['name'] for tag in self.search_engine.tags( + query='', skip_default_tags=True)] + current_tags_lower = [tag.lower() for tag in current_tags] + + def _use_current_casing(new_tag_lower): + return current_tags[current_tags_lower.index(new_tag_lower)] + + return [_use_current_casing(new_tag.lower()) if new_tag.lower() in current_tags_lower else new_tag for new_tag in new_tags] + + def mail(self, mail_id): + return self.mail_store.get_mail(mail_id, include_body=True) + + def attachment(self, attachment_id): + return self.attachment_store.get_mail_attachment(attachment_id) + + @defer.inlineCallbacks + def mail_exists(self, mail_id): + try: + mail = yield self.mail_store.get_mail(mail_id, include_body=False) + defer.returnValue(mail is not None) + except Exception, e: + defer.returnValue(False) + + @defer.inlineCallbacks + def send_mail(self, content_dict): + mail = InputMail.from_dict(content_dict, self.account_email) + draft_id = content_dict.get('ident') + yield self.mail_sender.sendmail(mail) + + sent_mail = yield self.move_to_sent(draft_id, mail) + defer.returnValue(sent_mail) + + @defer.inlineCallbacks + def move_to_sent(self, last_draft_ident, mail): + if last_draft_ident: + try: + yield self.mail_store.delete_mail(last_draft_ident) + except Exception as error: + pass + sent_mail = yield self.mail_store.add_mail('SENT', mail.raw) + sent_mail.flags.add(Status.SEEN) + yield self.mail_store.update_mail(sent_mail) + defer.returnValue(sent_mail) + + @defer.inlineCallbacks + def mark_as_read(self, mail_id): + mail = yield self.mail(mail_id) + mail.flags.add(Status.SEEN) + yield self.mail_store.update_mail(mail) + + @defer.inlineCallbacks + def mark_as_unread(self, mail_id): + mail = yield self.mail(mail_id) + mail.flags.remove(Status.SEEN) + yield self.mail_store.update_mail(mail) + + @defer.inlineCallbacks + def delete_mail(self, mail_id): + mail = yield self.mail(mail_id) + if mail is not None: + if mail.mailbox_name.upper() in (u'TRASH', u'DRAFTS'): + yield self.mail_store.delete_mail(mail_id) + else: + yield self.mail_store.move_mail_to_mailbox(mail_id, 'TRASH') + + @defer.inlineCallbacks + def recover_mail(self, mail_id): + yield self.mail_store.move_mail_to_mailbox(mail_id, 'INBOX') + + @defer.inlineCallbacks + def archive_mail(self, mail_id): + yield self.mail_store.add_mailbox('ARCHIVE') + yield self.mail_store.move_mail_to_mailbox(mail_id, 'ARCHIVE') + + @defer.inlineCallbacks + def delete_permanent(self, mail_id): + yield self.mail_store.delete_mail(mail_id) diff --git a/src/pixelated/adapter/services/tag_service.py b/src/pixelated/adapter/services/tag_service.py new file mode 100644 index 00000000..ad94170b --- /dev/null +++ b/src/pixelated/adapter/services/tag_service.py @@ -0,0 +1,24 @@ +# +# Copyright (c) 2014 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . +from pixelated.adapter.model.tag import Tag + +SPECIAL_TAGS = {Tag('inbox', True), Tag('sent', True), Tag( + 'drafts', True), Tag('trash', True), Tag('ALL', True)} + + +def extract_reserved_tags(tags): + tags = [tag.lower() for tag in tags] + return {tag.name for tag in SPECIAL_TAGS if tag.name in tags} diff --git a/src/pixelated/adapter/welcome_mail.py b/src/pixelated/adapter/welcome_mail.py new file mode 100644 index 00000000..8e6e957b --- /dev/null +++ b/src/pixelated/adapter/welcome_mail.py @@ -0,0 +1,29 @@ +# +# Copyright (c) 2015 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . +import pkg_resources +from email import message_from_file +from pixelated.adapter.model.mail import InputMail + + +def add_welcome_mail(mail_store): + welcome_mail = pkg_resources.resource_filename( + 'pixelated.assets', 'welcome.mail') + + with open(welcome_mail) as mail_template_file: + mail_template = message_from_file(mail_template_file) + + input_mail = InputMail.from_python_mail(mail_template) + mail_store.add_mail('INBOX', input_mail.raw) diff --git a/src/pixelated/application.py b/src/pixelated/application.py new file mode 100644 index 00000000..e24e388b --- /dev/null +++ b/src/pixelated/application.py @@ -0,0 +1,222 @@ +# +# Copyright (c) 2015 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . + +import logging + +from OpenSSL import SSL +from OpenSSL import crypto +from leap.common.events import (server as events_server, + register, catalog as events) +from twisted.cred import portal +from twisted.cred.checkers import AllowAnonymousAccess +from twisted.internet import defer +from twisted.internet import reactor +from twisted.internet import ssl + +from pixelated.adapter.welcome_mail import add_welcome_mail +from pixelated.config import arguments +from pixelated.config import logger +from pixelated.config.leap import initialize_leap_single_user, init_monkeypatches, initialize_leap_provider +from pixelated.config import services +from pixelated.config.site import PixelatedSite +from pixelated.resources.auth import LeapPasswordChecker, PixelatedRealm, PixelatedAuthSessionWrapper, SessionChecker +from pixelated.resources.login_resource import LoginResource +from pixelated.resources.root_resource import RootResource + +log = logging.getLogger(__name__) + + +class ServicesFactory(object): + + def __init__(self, mode): + self._services_by_user = {} + self.mode = mode + + def is_logged_in(self, user_id): + return user_id in self._services_by_user + + def services(self, user_id): + return self._services_by_user[user_id] + + def log_out_user(self, user_id): + if self.is_logged_in(user_id): + _services = self._services_by_user[user_id] + _services.close() + del self._services_by_user[user_id] + + def add_session(self, user_id, services): + self._services_by_user[user_id] = services + + @defer.inlineCallbacks + def create_services_from(self, leap_session): + _services = services.Services(leap_session) + yield _services.setup() + self._services_by_user[leap_session.user_auth.uuid] = _services + + +class SingleUserServicesFactory(object): + + def __init__(self, mode): + self._services = None + self.mode = mode + + def add_session(self, user_id, services): + self._services = services + + def services(self, user_id): + return self._services + + +class UserAgentMode(object): + + def __init__(self, is_single_user): + self.is_single_user = is_single_user + + +@defer.inlineCallbacks +def start_user_agent_in_single_user_mode(root_resource, services_factory, leap_home, leap_session): + log.info('Bootstrap done, loading services for user %s' % + leap_session.user_auth.username) + + _services = services.Services(leap_session) + yield _services.setup() + + if leap_session.fresh_account: + yield add_welcome_mail(leap_session.mail_store) + + services_factory.add_session(leap_session.user_auth.uuid, _services) + + root_resource.initialize() + + # soledad needs lots of threads + reactor.getThreadPool().adjustPoolsize(5, 15) + log.info('Done, the user agent is ready to be used') + + +def _ssl_options(sslkey, sslcert): + with open(sslkey) as keyfile: + pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, keyfile.read()) + with open(sslcert) as certfile: + cert = crypto.load_certificate(crypto.FILETYPE_PEM, certfile.read()) + + acceptable = ssl.AcceptableCiphers.fromOpenSSLCipherString( + u'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:!RC4:HIGH:!MD5:!aNULL:!EDH') + options = ssl.CertificateOptions(privateKey=pkey, + certificate=cert, + method=SSL.TLSv1_2_METHOD, + acceptableCiphers=acceptable) + return options + + +def _create_service_factory(args): + if args.single_user: + return SingleUserServicesFactory(UserAgentMode(is_single_user=True)) + else: + return ServicesFactory(UserAgentMode(is_single_user=False)) + + +def initialize(): + log.info('Starting the Pixelated user agent') + args = arguments.parse_user_agent_args() + logger.init(debug=args.debug) + services_factory = _create_service_factory(args) + resource = RootResource(services_factory) + + deferred = _start_mode(args, resource, services_factory) + + def _quit_on_error(failure): + failure.printTraceback() + reactor.stop() + + def _register_shutdown_on_token_expire(leap_session): + register(events.SOLEDAD_INVALID_AUTH_TOKEN, + lambda *unused: reactor.stop()) + return leap_session + + deferred.addCallback(_register_shutdown_on_token_expire) + deferred.addErrback(_quit_on_error) + + log.info('Running the reactor') + + reactor.run() + + +def _start_mode(args, resource, services_factory): + if services_factory.mode.is_single_user: + deferred = _start_in_single_user_mode(args, resource, services_factory) + else: + deferred = _start_in_multi_user_mode(args, resource, services_factory) + return deferred + + +def _start_in_multi_user_mode(args, root_resource, services_factory): + if args.provider is None: + raise ValueError('provider name is required') + + init_monkeypatches() + events_server.ensure_server() + + config, provider = initialize_leap_provider( + args.provider, args.leap_provider_cert, args.leap_provider_cert_fingerprint, args.leap_home) + protected_resource = set_up_protected_resources( + root_resource, provider, services_factory, banner=args.banner) + start_site(args, protected_resource) + reactor.getThreadPool().adjustPoolsize(5, 15) + return defer.succeed(None) + + +def set_up_protected_resources(root_resource, provider, services_factory, checker=None, banner=None): + if not checker: + checker = LeapPasswordChecker(provider) + session_checker = SessionChecker(services_factory) + anonymous_resource = LoginResource( + services_factory, disclaimer_banner=banner) + + realm = PixelatedRealm(root_resource, anonymous_resource) + _portal = portal.Portal( + realm, [checker, session_checker, AllowAnonymousAccess()]) + + protected_resource = PixelatedAuthSessionWrapper( + _portal, root_resource, anonymous_resource, []) + anonymous_resource.set_portal(_portal) + root_resource.initialize(_portal, disclaimer_banner=banner) + return protected_resource + + +def _start_in_single_user_mode(args, resource, services_factory): + start_site(args, resource) + deferred = initialize_leap_single_user(args.leap_provider_cert, + args.leap_provider_cert_fingerprint, + args.credentials_file, + args.organization_mode, + args.leap_home) + deferred.addCallback( + lambda leap_session: start_user_agent_in_single_user_mode( + resource, + services_factory, + args.leap_home, + leap_session)) + return deferred + + +def start_site(config, resource): + log.info('Starting the API on port %s' % config.port) + if config.sslkey and config.sslcert: + reactor.listenSSL(config.port, PixelatedSite(resource), _ssl_options(config.sslkey, config.sslcert), + interface=config.host) + else: + reactor.listenTCP(config.port, PixelatedSite( + resource), interface=config.host) diff --git a/src/pixelated/assets/Interstitial.html b/src/pixelated/assets/Interstitial.html new file mode 100644 index 00000000..bc6cc738 --- /dev/null +++ b/src/pixelated/assets/Interstitial.html @@ -0,0 +1,18 @@ + + + + + + + + + + + +
+ +
+ + + + diff --git a/src/pixelated/assets/Interstitial.js b/src/pixelated/assets/Interstitial.js new file mode 100644 index 00000000..ac5a789a --- /dev/null +++ b/src/pixelated/assets/Interstitial.js @@ -0,0 +1,58 @@ +if ($('#hive').length) { + var hive = new Snap('#hive'); + var img_width = $('#hive').width(); + var left_pos = img_width * .5; + + var pixelated = hive.path("M12.4,20.3v31.8l28,15.8l28-15.8V20.3l-28-15.8L12.4,20.3z M39.2,56.4l-16.3-9V27.9l16.3,9.3L39.2,56.4z M57.7,47.4l-16.1,9l0-19.2l16.1-9.4V47.4z M57.7,25.2L40.4,35.5L22.9,25.2l17.5-9.4L57.7,25.2z").transform("translate(319, 50)").attr("fill", "#908e8e"); + var all = hive.group().transform("matrix(2, 0, 0, 2, -100, -100)"); + + var height = 50; + var width = 58; + var rows = (($(window).height() / height) / 2) + 1; + var cols = (($(window).width() / width) / 2) + 1; + + + for (var j = 0; j < rows; j++) { + for (var i = 0; i < cols; i++) { + x = i * width + (j%2*width/2); + y = j * height; + all.add(pixelated.clone().transform("translate("+x+","+y+")")); + } + } + + all.add(pixelated); + + var brightenLogo = function () { + var glowPosition = Math.floor(Math.random()*rows*cols); + + all[glowPosition].animate({fill: "#FFF"}, 1000, function() { + darkenLogo(all[glowPosition]); + }); + }; + + var darkenLogo = function (el) { + el.animate({fill: "#908e8e"}, 1000, brightenLogo); + }; + + brightenLogo(); + +} + +$(function () { + var handler = setInterval(function () { + $.ajax({ + method: 'GET', + url: '/' + }).success(function (data) { + if (/Pixelated Mail/g.test(data)) { + window.location="/"; + } + }); + }, 2000); + + $('#hive-section').height($(window).height()); + + $(window).resize(function() { + window.location.reload(true); + }); +}); diff --git a/src/pixelated/assets/__init__.py b/src/pixelated/assets/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/pixelated/assets/_login_disclaimer_banner.html b/src/pixelated/assets/_login_disclaimer_banner.html new file mode 100644 index 00000000..dfc63030 --- /dev/null +++ b/src/pixelated/assets/_login_disclaimer_banner.html @@ -0,0 +1,9 @@ +
+
    +

    Some disclaimer

    +
  • + please supply the option --banner with an XML compatible file +
    to override this default message
    +
  • +
+
diff --git a/src/pixelated/assets/favicon.png b/src/pixelated/assets/favicon.png new file mode 100644 index 00000000..e14841c7 Binary files /dev/null and b/src/pixelated/assets/favicon.png differ diff --git a/src/pixelated/assets/hive-bg.png b/src/pixelated/assets/hive-bg.png new file mode 100644 index 00000000..77316967 Binary files /dev/null and b/src/pixelated/assets/hive-bg.png differ diff --git a/src/pixelated/assets/index.html b/src/pixelated/assets/index.html new file mode 100644 index 00000000..c095577e --- /dev/null +++ b/src/pixelated/assets/index.html @@ -0,0 +1,9 @@ + + + + + + click here + + + diff --git a/src/pixelated/assets/jquery-2.1.3.min.js b/src/pixelated/assets/jquery-2.1.3.min.js new file mode 100644 index 00000000..25714ed2 --- /dev/null +++ b/src/pixelated/assets/jquery-2.1.3.min.js @@ -0,0 +1,4 @@ +/*! jQuery v2.1.3 | (c) 2005, 2014 jQuery Foundation, Inc. | 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=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.3",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 d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.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(null)},push:f,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){return!n.isArray(a)&&a-parseFloat(a)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},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?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.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,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),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):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.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,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"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=hb(),z=hb(),A=hb(),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=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),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")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),db=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)},eb=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fb){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 gb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+rb(o[l]);w=ab.test(a)&&pb(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function hb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ib(a){return a[u]=!0,a}function jb(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function kb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function lb(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 mb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function nb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function ob(a){return ib(function(b){return b=+b,ib(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 pb(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=gb.support={},f=gb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=gb.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",eb,!1):e.attachEvent&&e.attachEvent("onunload",eb)),p=!f(g),c.attributes=jb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=jb(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=jb(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.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.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);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 p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(jb(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(".#.+[+~]")}),jb(function(a){var b=g.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=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&jb(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.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===g||a.ownerDocument===v&&t(v,a)?-1:b===g||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,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return lb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?lb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},gb.matches=function(a,b){return gb(a,null,null,b)},gb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||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 gb(b,n,null,[a]).length>0},gb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},gb.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},gb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},gb.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=gb.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=gb.selectors={cacheLength:50,createPseudo:ib,match:X,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(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===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]||gb.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]&&gb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.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(cb,db).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=gb.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(Q," ")+" ").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;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||gb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ib(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:ib(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ib(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:ib(function(a){return function(b){return gb(a,b).length>0}}),contains:ib(function(a){return a=a.replace(cb,db),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ib(function(a){return W.test(a||"")||gb.error("unsupported lang: "+a),a=a.replace(cb,db).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 Z.test(a.nodeName)},input:function(a){return Y.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:ob(function(){return[0]}),last:ob(function(a,b){return[b-1]}),eq:ob(function(a,b,c){return[0>c?c+b:c]}),even:ob(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:ob(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:ob(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:ob(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sb(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=[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(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function tb(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 ub(a,b,c){for(var d=0,e=b.length;e>d;d++)gb(a,b[d],c);return c}function vb(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 wb(a,b,c,d,e,f){return d&&!d[u]&&(d=wb(d)),e&&!e[u]&&(e=wb(e,f)),ib(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ub(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:vb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=vb(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=vb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sb(function(a){return a===b},h,!0),l=sb(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=[sb(tb(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 wb(i>1&&tb(m),i>1&&rb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xb(a.slice(i,e)),f>e&&xb(a=a.slice(e)),f>e&&rb(a))}m.push(c)}return tb(m)}function yb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=vb(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&gb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ib(f):f}return h=gb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,yb(e,d)),f.selector=a}return f},i=gb.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(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.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(cb,db),ab.test(j[0].type)&&pb(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&rb(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&pb(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=jb(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),jb(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||kb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&jb(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||kb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),jb(function(a){return null==a.getAttribute("disabled")})||kb(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}),gb}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(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(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==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(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir: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},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),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=u.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.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.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.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(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 n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(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&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},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().done(c.resolve).fail(c.reject).progress(c.notify):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=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;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||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=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)n.access(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};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+K.uid++}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[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=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c) +},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.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=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.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 L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.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.lengthx",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.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 typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.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,!1)),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=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.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)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.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.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!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&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(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)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,bb=/<([\w:]+)/,cb=/<|&#?\w+;/,db=/<(?:script|style|link)/i,eb=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/^$|\/(?:java|ecma)script/i,gb=/^true\/(.*)/,hb=/^\s*\s*$/g,ib={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(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 kb(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.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])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,"script"),g.length>0&&mb(g,!i&&ob(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement("div")),g=(bb.exec(e)||["",""])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,"<$1>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=ob(k.appendChild(e),"script"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(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 this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(ob(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&mb(ob(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(ob(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 J(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&&!db.test(a)&&!ib[(bb.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ab,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ob(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(ob(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&eb.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(ob(c,"script"),kb),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,ob(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(hb,"")))}return this}}),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),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function tb(a){var b=l,c=rb[a];return c||(c=sb(a,b),"none"!==c&&c||(qb=(qb||n("\n\n',s=e["if"].call(t,null!=t?t.attachments:t,{name:"if",hash:{},fn:this.program(11,n),inverse:this.noop,data:n}),null!=s&&(u+=s),u+"\n\n"},useData:!0}),e["app/templates/mails/mail_actions.hbs"]=t({compiler:[6,">= 2.0.0-beta.1"],main:function(t,e,i,n){var s=e.helperMissing,a=this.escapeExpression;return'\n\n
    \n
  • '+a((e.t||t&&t.t||s).call(t,"Reply to All",{name:"t",hash:{},data:n}))+'
  • \n
  • '+a((e.t||t&&t.t||s).call(t,"Delete this message",{name:"t",hash:{},data:n}))+"
  • \n
\n"},useData:!0}),e["app/templates/mails/sent.hbs"]=t({1:function(t,e,i,n){return'checked="true"'},3:function(t,e,i,n){var s,a=this.lambda,r=this.escapeExpression;return" "+r(a(null!=(s=null!=t?t.header:t)?s.to:s,t))+"\n"},5:function(t,e,i,n){var s=e.helperMissing,a=this.escapeExpression;return" "+a((e.t||t&&t.t||s).call(t,"no_recipient",{name:"t",hash:{},data:n}))+"\n"},7:function(t,e,i,n){var s,a=this.lambda,r=this.escapeExpression;return" "+r(a(null!=(s=null!=t?t.header:t)?s.subject:s,t))+"\n"},9:function(t,e,i,n){var s=e.helperMissing,a=this.escapeExpression;return" "+a((e.t||t&&t.t||s).call(t,"no_subject",{name:"t",hash:{},data:n}))+"\n"},11:function(t,e,i,n){return'
\n'},13:function(t,e,i,n){var s=this.lambda,a=this.escapeExpression;return'
  • '+a(s(t,t))+"
  • \n"},compiler:[6,">= 2.0.0-beta.1"],main:function(t,e,i,n){var s,a,r="function",o=e.helperMissing,l=this.escapeExpression,c='
    \n \n
    \n\n
    \n
    \n '+l((e.t||t&&t.t||o).call(t,"to:",{name:"t",hash:{},data:n}))+"\n",s=e["if"].call(t,null!=(s=null!=t?t.header:t)?s.to:s,{name:"if",hash:{},fn:this.program(3,n),inverse:this.program(5,n),data:n}),null!=s&&(c+=s),c+='
    \n\n '+l((e.formatDate||t&&t.formatDate||o).call(t,null!=(s=null!=t?t.header:t)?s.date:s,{name:"formatDate",hash:{},data:n}))+' \n
    \n
    \n
    \n',s=e["if"].call(t,null!=(s=null!=t?t.header:t)?s.subject:s,{name:"if",hash:{},fn:this.program(7,n),inverse:this.program(9,n),data:n}),null!=s&&(c+=s),c+="
    \n\n",s=e["if"].call(t,null!=t?t.attachments:t,{name:"if",hash:{},fn:this.program(11,n),inverse:this.noop,data:n}),null!=s&&(c+=s),c+='
    \n
      \n',s=e.each.call(t,null!=t?t.tagsForListView:t,{name:"each",hash:{},fn:this.program(13,n),inverse:this.noop,data:n}),null!=s&&(c+=s),c+"
    \n
    \n\n"},useData:!0}),e["app/templates/mails/single.hbs"]=t({1:function(t,e,i,n){return'checked="true"'},3:function(t,e,i,n){var s,a=this.lambda,r=this.escapeExpression;return" "+r(a(null!=(s=null!=t?t.header:t)?s.from:s,t))+"\n"},5:function(t,e,i,n){var s=e.helperMissing,a=this.escapeExpression;return" "+a((e.t||t&&t.t||s).call(t,"you",{name:"t",hash:{},data:n}))+"\n"},7:function(t,e,i,n){return'
    \n'},9:function(t,e,i,n){var s=this.lambda,a=this.escapeExpression;return'
  • '+a(s(t,t))+"
  • \n"},compiler:[6,">= 2.0.0-beta.1"],main:function(t,e,i,n){var s,a,r="function",o=e.helperMissing,l=this.escapeExpression,c=this.lambda,u='
    \n \n
    \n\n
    \n
    \n',s=e["if"].call(t,null!=(s=null!=t?t.header:t)?s.from:s,{name:"if",hash:{},fn:this.program(3,n),inverse:this.program(5,n),data:n}),null!=s&&(u+=s),u+='
    \n\n '+l((e.formatDate||t&&t.formatDate||o).call(t,null!=(s=null!=t?t.header:t)?s.date:s,{name:"formatDate",hash:{},data:n}))+' \n
    \n
    \n
    '+l(c(null!=(s=null!=t?t.header:t)?s.subject:s,t))+"
    \n\n",s=e["if"].call(t,null!=t?t.attachments:t,{name:"if",hash:{},fn:this.program(7,n),inverse:this.noop,data:n}),null!=s&&(u+=s),u+='
    \n
      \n',s=e.each.call(t,null!=t?t.tagsForListView:t,{name:"each",hash:{},fn:this.program(9,n),inverse:this.noop,data:n}),null!=s&&(u+=s),u+"
    \n
    \n"},useData:!0}),e["app/templates/mails/trash.hbs"]=t({1:function(t,e,i,n){return'checked="true"'},3:function(t,e,i,n){var s,a=this.lambda,r=this.escapeExpression;return" "+r(a(null!=(s=null!=t?t.header:t)?s.from:s,t))+"\n"},5:function(t,e,i,n){var s=e.helperMissing,a=this.escapeExpression;return" "+a((e.t||t&&t.t||s).call(t,"you",{name:"t",hash:{},data:n}))+"\n"},7:function(t,e,i,n){return'
    \n'},9:function(t,e,i,n){var s=this.lambda,a=this.escapeExpression;return'
  • '+a(s(t,t))+"
  • \n"},compiler:[6,">= 2.0.0-beta.1"],main:function(t,e,i,n){var s,a,r="function",o=e.helperMissing,l=this.escapeExpression,c=this.lambda,u='
    \n \n
    \n\n
    \n
    \n',s=e["if"].call(t,null!=(s=null!=t?t.header:t)?s.from:s,{name:"if",hash:{},fn:this.program(3,n),inverse:this.program(5,n),data:n}),null!=s&&(u+=s),u+='
    \n\n '+l((e.formatDate||t&&t.formatDate||o).call(t,null!=(s=null!=t?t.header:t)?s.date:s,{name:"formatDate",hash:{},data:n}))+' \n
    \n
    \n
    \n \n '+l(c(null!=(s=null!=t?t.header:t)?s.subject:s,t))+"\n
    \n\n",s=e["if"].call(t,null!=t?t.attachments:t,{name:"if",hash:{},fn:this.program(7,n),inverse:this.noop,data:n}),null!=s&&(u+=s),u+='
    \n
      \n',s=e.each.call(t,null!=t?t.tagsForListView:t,{name:"each",hash:{},fn:this.program(9,n),inverse:this.noop,data:n}),null!=s&&(u+=s),u+"
    \n
    \n\n"},useData:!0}),e["app/templates/page/logout.hbs"]=t({compiler:[6,">= 2.0.0-beta.1"],main:function(t,e,i,n){var s,a="function",r=e.helperMissing,o=this.escapeExpression;return'
      \n
      \n \n
    • \n
      \n Logout\n
    • \n
      \n
    \n'},useData:!0}),e["app/templates/page/logout_shortcut.hbs"]=t({compiler:[6,">= 2.0.0-beta.1"],main:function(t,e,i,n){return'
  • \n \n \n
    Logout
    \n
    \n
  • \n'},useData:!0}),e["app/templates/page/user_settings_box.hbs"]=t({compiler:[6,">= 2.0.0-beta.1"],main:function(t,e,i,n){var s,a="function",r=e.helperMissing,o=this.escapeExpression;return'
    \n \n \n

    User Settings

    \n \n
    \n

    E-Mail address

    \n

    '+o((s=null!=(s=e.account_email||(null!=t?t.account_email:t))?s:r,typeof s===a?s.call(t,{name:"account_email",hash:{},data:n}):s))+'

    \n

    Public key fingerprint

    \n

    '+o((e.formatFingerPrint||t&&t.formatFingerPrint||r).call(t,null!=t?t.fingerprint:t,{name:"formatFingerPrint",hash:{},data:n}))+"

    \n"},useData:!0}),e["app/templates/page/user_settings_icon.hbs"]=t({compiler:[6,">= 2.0.0-beta.1"],main:function(t,e,i,n){return'\n'},useData:!0}),e["app/templates/page/version.hbs"]=t({compiler:[6,">= 2.0.0-beta.1"],main:function(t,e,i,n){return"version: a48f917
    \n2 minutes ago\n"},useData:!0}),e["app/templates/search/search_trigger.hbs"]=t({compiler:[6,">= 2.0.0-beta.1"],main:function(t,e,i,n){var s=e.helperMissing,a=this.escapeExpression;return'
    \n \n
    \n'},useData:!0}),e["app/templates/tags/shortcut.hbs"]=t({1:function(t,e,i,n){var s,a="function",r=e.helperMissing,o=this.escapeExpression;return' '+o((s=null!=(s=e.count||(null!=t?t.count:t))?s:r,typeof s===a?s.call(t,{name:"count",hash:{},data:n}):s))+"\n"},compiler:[6,">= 2.0.0-beta.1"],main:function(t,e,i,n){var s,a,r="function",o=e.helperMissing,l=this.escapeExpression,c='
  • \n \n';return s=e["if"].call(t,null!=t?t.displayBadge:t,{name:"if",hash:{},fn:this.program(1,n),inverse:this.noop,data:n}),null!=s&&(c+=s),c+' \n
    '+l((a=null!=(a=e.tagName||(null!=t?t.tagName:t))?a:o,typeof a===r?a.call(t,{name:"tagName",hash:{},data:n}):a))+"
    \n
    \n
  • \n"},useData:!0}),e["app/templates/tags/tag.hbs"]=t({compiler:[6,">= 2.0.0-beta.1"],main:function(t,e,i,n){var s,a,r="function",o=e.helperMissing,l=this.escapeExpression,c='
  • \n ';return s=this.invokePartial(i.tag_inner,"","tag_inner",t,void 0,e,i,n),null!=s&&(c+=s),c+"\n
  • \n"},usePartial:!0,useData:!0}),e["app/templates/tags/tag_inner.hbs"]=t({1:function(t,e,i,n){var s,a="function",r=e.helperMissing,o=this.escapeExpression;return''+o((s=null!=(s=e.count||(null!=t?t.count:t))?s:r,typeof s===a?s.call(t,{name:"count",hash:{},data:n}):s))+"\n"},compiler:[6,">= 2.0.0-beta.1"],main:function(t,e,i,n){var s,a,r="function",o=e.helperMissing,l=this.escapeExpression,c=l((a=null!=(a=e.tagName||(null!=t?t.tagName:t))?a:o,typeof a===r?a.call(t,{name:"tagName",hash:{},data:n}):a))+"\n";return s=e["if"].call(t,null!=t?t.displayBadge:t,{name:"if",hash:{},fn:this.program(1,n),inverse:this.noop,data:n}),null!=s&&(c+=s),c},useData:!0}),e["app/templates/tags/tag_list.hbs"]=t({compiler:[6,">= 2.0.0-beta.1"],main:function(t,e,i,n){return'
      \n
      \n \n Tags\n
      \n
        '},useData:!0}),e["app/templates/user_alerts/message.hbs"]=t({compiler:[6,">= 2.0.0-beta.1"],main:function(t,e,i,n){var s,a=this.lambda,r=this.escapeExpression;return''+r(a(null!=(s=null!=t?t.message:t)?s.content:s,t))+"\n"},useData:!0})}(),i("hbs/templates",function(){}),i("views/templates",["hbs/templates"],function(t){"use strict";var e={compose:{box:window.Pixelated["app/templates/compose/compose_box.hbs"],inlineBox:window.Pixelated["app/templates/compose/inline_box.hbs"],replySection:window.Pixelated["app/templates/compose/reply_section.hbs"],recipientInput:window.Pixelated["app/templates/compose/recipient_input.hbs"],fixedRecipient:window.Pixelated["app/templates/compose/fixed_recipient.hbs"], +recipients:window.Pixelated["app/templates/compose/recipients.hbs"],feedback:window.Pixelated["app/templates/compose/feedback_box.hbs"],attachmentsList:window.Pixelated["app/templates/compose/attachments_list.hbs"],attachmentItem:window.Pixelated["app/templates/compose/attachment_item.hbs"],attachmentUploadItem:window.Pixelated["app/templates/compose/attachment_upload_item.hbs"],uploadAttachmentFailed:window.Pixelated["app/templates/compose/upload_attachment_failed.hbs"]},tags:{tagList:window.Pixelated["app/templates/tags/tag_list.hbs"],tag:window.Pixelated["app/templates/tags/tag.hbs"],tagInner:window.Pixelated["app/templates/tags/tag_inner.hbs"],shortcut:window.Pixelated["app/templates/tags/shortcut.hbs"]},userAlerts:{message:window.Pixelated["app/templates/user_alerts/message.hbs"]},mails:{single:window.Pixelated["app/templates/mails/single.hbs"],fullView:window.Pixelated["app/templates/mails/full_view.hbs"],mailActions:window.Pixelated["app/templates/mails/mail_actions.hbs"],draft:window.Pixelated["app/templates/mails/draft.hbs"],sent:window.Pixelated["app/templates/mails/sent.hbs"],trash:window.Pixelated["app/templates/mails/trash.hbs"]},mailActions:{actionsBox:window.Pixelated["app/templates/mail_actions/actions_box.hbs"],trashActionsBox:window.Pixelated["app/templates/mail_actions/trash_actions_box.hbs"],composeTrigger:window.Pixelated["app/templates/mail_actions/compose_trigger.hbs"],refreshTrigger:window.Pixelated["app/templates/mail_actions/refresh_trigger.hbs"],paginationTrigger:window.Pixelated["app/templates/mail_actions/pagination_trigger.hbs"]},noMessageSelected:window.Pixelated["app/templates/compose/no_message_selected.hbs"],noMailsAvailable:window.Pixelated["app/templates/compose/no_mails_available.hbs"],search:{trigger:window.Pixelated["app/templates/search/search_trigger.hbs"]},page:{userSettingsIcon:window.Pixelated["app/templates/page/user_settings_icon.hbs"],userSettingsBox:window.Pixelated["app/templates/page/user_settings_box.hbs"],logout:window.Pixelated["app/templates/page/logout.hbs"],logoutShortcut:window.Pixelated["app/templates/page/logout_shortcut.hbs"],version:window.Pixelated["app/templates/page/version.hbs"]},feedback:{feedback:window.Pixelated["app/templates/feedback/feedback_trigger.hbs"]}};return Handlebars.registerPartial("tag_inner",e.tags.tagInner),Handlebars.registerPartial("recipients",e.compose.recipients),Handlebars.registerPartial("attachments_list",e.compose.attachmentsList),Handlebars.registerPartial("attachments_upload",e.compose.attachmentsList),Handlebars.registerPartial("attachment_item",e.compose.attachmentItem),Handlebars.registerPartial("attachment_upload_item",e.compose.attachmentUploadItem),Handlebars.registerPartial("uploadAttachmentFailed",e.compose.uploadAttachmentFailed),e}),i("helpers/contenttype",[],function(){"use strict";function t(i,n){this.type="",this.params={};var s,a,r;if("string"==typeof i)for(s=e(i),this.type=s.shift(),a=0;aa?e:Math.min(a,e)}e=e||";",i=i||'"';for(var s=[],a=0,r=0;r>=0&&(r=[e,i].reduce(n,1/0),r!==1/0);)switch(t[r]){case i:for(;;){if(r=t.indexOf(i,r+1),0>r)break;if("\\"!==t[r-1])break}continue;case e:s.push(t.substr(a,r-a).trim()),a=++r}return s.push(t.substr(a).trim()),s}function i(t){return e(t,",")}function n(e){var i=new t(e);return void 0===i.q&&(i.q=1),i}function s(t,e){for(var i={q:0},n={q:0},s=0,r=0;r=0&&h*l>s&&(n=u,i=o,s=n.q*i.q,1===s&&i.type))return i}return i.type&&i}function a(t,e){if("*/*"===t.type&&"*/*"!==e.type)return 1;if("*/*"!==t.type&&"*/*"===e.type)return-1;var i=(t.type||"").split("/"),n=(e.type||"").split("/");if("*"===i[0]&&"*"!==n[0])return 1;if("*"!==i[0]&&"*"===n[0])return-1;if(t.type!==e.type)return null;var s=t.params||{},a=e.params||{},r=Object.keys(s),o=Object.keys(a);if(r.lengtho.length)return-1;var l=(r.concat(o).sort(),0);for(var c in s){if(s[c]&&!a[c]){if(0>l)return null;l=1}if(!s[c]&&a[c]){if(l>0)return null;l=-1}}return l}var r={};return t.prototype.parseParameter=function(t){var e=t.split("=",1),i=e[0].trim(),n=t.substr(e[0].length+1).trim();n&&i&&("q"===i&&void 0===this.q?this.q=parseFloat(n):('"'===n[0]&&'"'===n[n.length-1]&&(n=n.substr(1,n.length-2),n=n.replace(/\\(.)/g,function(t,e){return e})),this.params[i]=n))},t.prototype.toString=function(){var t=this.type+";q="+this.q;for(var e in this.params)t+=";"+e+"=",t+=this.params[e].match(/["=;<>\[\]\(\) ,\-]/)?'"'+this.params[e].replace(/["\\]/g,function(t){return"\\"+t})+'"':this.params[e];return t},r.MediaType=t,r.splitQuotedString=e,r.splitContentTypes=i,r.parseMedia=n,r.select=s,r.mediaCmp=a,r}),function(t,e){"object"==typeof exports?module.exports=e():"function"==typeof i&&i.amd&&i("i18next",[],e)}(this,function(){function t(t,e){if(!e||"function"==typeof e)return t;for(var i in e)t[i]=e[i];return t}function e(t,i){for(var n in i)n in t?e(t[n],i[n]):t[n]=i[n];return t}function i(t,e,i){var n,s=0,a=t.length,r=void 0===a||"[object Array]"!==Object.prototype.toString.apply(t)||"function"==typeof t;if(i)if(r){for(n in t)if(e.apply(t[n],i)===!1)break}else for(;a>s&&e.apply(t[s++],i)!==!1;);else if(r){for(n in t)if(e.call(t[n],n,t[n])===!1)break}else for(;a>s&&e.call(t[s],s,t[s++])!==!1;);return t}function n(t){return"string"==typeof t?t.replace(/[&<>"'\/]/g,function(t){return z[t]}):t}function s(t){var e=function(t){if(window.XMLHttpRequest)return t(null,new XMLHttpRequest);if(window.ActiveXObject)try{return t(null,new ActiveXObject("Msxml2.XMLHTTP"))}catch(e){return t(null,new ActiveXObject("Microsoft.XMLHTTP"))}return t(new Error)},i=function(t){if("string"==typeof t)return t;var e=[];for(var i in t)t.hasOwnProperty(i)&&e.push(encodeURIComponent(i)+"="+encodeURIComponent(t[i]));return e.join("&")},n=function(t){t=t.replace(/\r\n/g,"\n");for(var e="",i=0;in?e+=String.fromCharCode(n):n>127&&2048>n?(e+=String.fromCharCode(n>>6|192),e+=String.fromCharCode(63&n|128)):(e+=String.fromCharCode(n>>12|224),e+=String.fromCharCode(n>>6&63|128),e+=String.fromCharCode(63&n|128))}return e},s=function(t){var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";t=n(t);var i,s,a,r,o,l,c,u="",h=0;do i=t.charCodeAt(h++),s=t.charCodeAt(h++),a=t.charCodeAt(h++),r=i>>2,o=(3&i)<<4|s>>4,l=(15&s)<<2|a>>6,c=63&a,isNaN(s)?l=c=64:isNaN(a)&&(c=64),u+=e.charAt(r)+e.charAt(o)+e.charAt(l)+e.charAt(c),i=s=a="",r=o=l=c="";while(h1&&(n+=n.indexOf("?")>-1?"&"+u:"?"+u),s.jsonp){var h=document.getElementsByTagName("head")[0],d=document.createElement("script");return d.type="text/javascript",d.src=n,void h.appendChild(d)}}e(function(e,i){if(e)return o(e);i.open(t,n,s.async);for(var a in c)c.hasOwnProperty(a)&&i.setRequestHeader(a,c[a]);i.onreadystatechange=function(){if(4===i.readyState){var t=i.responseText||"";if(!o)return;o(i.status,{text:function(){return t},json:function(){try{return JSON.parse(t)}catch(e){return $.error("Can not parse JSON. URL: "+n),{}}}})}},i.send(l)})},o={authBasic:function(t,e){r.headers.Authorization="Basic "+s(t+":"+e)},connect:function(t,e,i){return r("CONNECT",t,e,i)},del:function(t,e,i){return r("DELETE",t,e,i)},get:function(t,e,i){return r("GET",t,e,i)},head:function(t,e,i){return r("HEAD",t,e,i)},headers:function(t){r.headers=t||{}},isAllowed:function(t,e,i){this.options(t,function(t,n){i(-1!==n.text().indexOf(e))})},options:function(t,e,i){return r("OPTIONS",t,e,i)},patch:function(t,e,i){return r("PATCH",t,e,i)},post:function(t,e,i){return r("POST",t,e,i)},put:function(t,e,i){return r("PUT",t,e,i)},trace:function(t,e,i){return r("TRACE",t,e,i)}},l=t.type?t.type.toLowerCase():"get";o[l](t.url,t,function(e,i){200===e||0===e&&i.text()?t.success(i.json(),e,null):t.error(i.text(),e,null)})}function a(t,e){"function"==typeof t&&(e=t,t={}),t=t||{},$.extend(H,t),delete H.fixLng,H.functions&&(delete H.functions,$.extend($,t.functions)),"string"==typeof H.ns&&(H.ns={namespaces:[H.ns],defaultNs:H.ns}),"string"==typeof H.fallbackNS&&(H.fallbackNS=[H.fallbackNS]),"string"!=typeof H.fallbackLng&&"boolean"!=typeof H.fallbackLng||(H.fallbackLng=[H.fallbackLng]),H.interpolationPrefixEscaped=$.regexEscape(H.interpolationPrefix),H.interpolationSuffixEscaped=$.regexEscape(H.interpolationSuffix),H.lng||(H.lng=$.detectLanguage()),R=$.toLanguages(H.lng),P=R[0],$.log("currentLng set to: "+P),H.useCookie&&$.cookie.read(H.cookieName)!==P&&$.cookie.create(H.cookieName,P,H.cookieExpirationTime,H.cookieDomain),H.detectLngFromLocalStorage&&"undefined"!=typeof document&&window.localStorage&&$.localStorage.setItem("i18next_lng",P);var i=S;t.fixLng&&(i=function(t,e){return e=e||{},e.lng=e.lng||i.lng,S(t,e)},i.lng=P),V.setCurrentLng(P),I&&H.setJqueryExt&&b();var n;if(I&&I.Deferred&&(n=I.Deferred()),!H.resStore){var s=$.toLanguages(H.lng);"string"==typeof H.preload&&(H.preload=[H.preload]);for(var a=0,r=H.preload.length;r>a;a++)for(var o=$.toLanguages(H.preload[a]),l=0,c=o.length;c>l;l++)s.indexOf(o[l])<0&&s.push(o[l]);return N.sync.load(s,H,function(t,s){F=s,j=!0,e&&e(i),n&&n.resolve(i)}),n?n.promise():void 0}return F=H.resStore,j=!0,e&&e(i),n&&n.resolve(i),n?n.promise():void 0}function r(t,e){"string"==typeof t&&(t=[t]);for(var i=0,n=t.length;n>i;i++)H.preload.indexOf(t[i])<0&&H.preload.push(t[i]);return a(e)}function o(t,e,i,n){"string"!=typeof e?(i=e,e=H.ns.defaultNs):H.ns.namespaces.indexOf(e)<0&&H.ns.namespaces.push(e),F[t]=F[t]||{},F[t][e]=F[t][e]||{},n?$.deepExtend(F[t][e],i):$.extend(F[t][e],i)}function l(t,e){"string"!=typeof e&&(e=H.ns.defaultNs),F[t]=F[t]||{};var i=F[t][e]||{},n=!1;for(var s in i)i.hasOwnProperty(s)&&(n=!0);return n}function c(t,e){"string"!=typeof e&&(e=H.ns.defaultNs),F[t]=F[t]||{},F[t][e]={}}function u(t,e,i,n){"string"!=typeof e?(resource=e,e=H.ns.defaultNs):H.ns.namespaces.indexOf(e)<0&&H.ns.namespaces.push(e),F[t]=F[t]||{},F[t][e]=F[t][e]||{};for(var s=i.split(H.keyseparator),a=0,r=F[t][e];s[a];)a==s.length-1?r[s[a]]=n:(null==r[s[a]]&&(r[s[a]]={}),r=r[s[a]]),a++}function h(t,e,i){"string"!=typeof e?(resource=e,e=H.ns.defaultNs):H.ns.namespaces.indexOf(e)<0&&H.ns.namespaces.push(e);for(var n in i)"string"==typeof i[n]&&u(t,e,n,i[n])}function d(t){H.ns.defaultNs=t}function p(t,e){f([t],e)}function f(t,e){var i={dynamicLoad:H.dynamicLoad,resGetPath:H.resGetPath,getAsync:H.getAsync,customLoad:H.customLoad,ns:{namespaces:t,defaultNs:""}},n=$.toLanguages(H.lng);"string"==typeof H.preload&&(H.preload=[H.preload]);for(var s=0,a=H.preload.length;a>s;s++)for(var r=$.toLanguages(H.preload[s]),o=0,l=r.length;l>o;o++)n.indexOf(r[o])<0&&n.push(r[o]);for(var c=[],u=0,h=n.length;h>u;u++){var d=!1,p=F[n[u]];if(p)for(var f=0,g=t.length;g>f;f++)p[t[f]]||(d=!0);else d=!0;d&&c.push(n[u])}c.length?N.sync._fetch(c,i,function(i,n){var s=t.length*c.length;$.each(t,function(t,i){H.ns.namespaces.indexOf(i)<0&&H.ns.namespaces.push(i),$.each(c,function(t,a){F[a]=F[a]||{},F[a][i]=n[a][i],s--,0===s&&e&&(H.useLocalStorage&&N.sync._storeLocal(F),e())})})}):e&&e()}function g(t,e,i){return"function"==typeof e?(i=e,e={}):e||(e={}),e.lng=t,a(e,i)}function m(){return P}function v(t){F={},g(P,t)}function b(){function t(t,e,i){if(0!==e.length){var n="text";if(0===e.indexOf("[")){var s=e.split("]");e=s[1],n=s[0].substr(1,s[0].length-1)}e.indexOf(";")===e.length-1&&(e=e.substr(0,e.length-2));var a;if("html"===n)a=H.defaultValueFromContent?I.extend({defaultValue:t.html()},i):i,t.html(I.t(e,a));else if("text"===n)a=H.defaultValueFromContent?I.extend({defaultValue:t.text()},i):i,t.text(I.t(e,a));else if("prepend"===n)a=H.defaultValueFromContent?I.extend({defaultValue:t.html()},i):i,t.prepend(I.t(e,a));else if("append"===n)a=H.defaultValueFromContent?I.extend({defaultValue:t.html()},i):i,t.append(I.t(e,a));else if(0===n.indexOf("data-")){var r=n.substr("data-".length);a=H.defaultValueFromContent?I.extend({defaultValue:t.data(r)},i):i;var o=I.t(e,a);t.data(r,o),t.attr(n,o)}else a=H.defaultValueFromContent?I.extend({defaultValue:t.attr(n)},i):i,t.attr(n,I.t(e,a))}}function e(e,i){var n=e.attr(H.selectorAttr);if(n||"undefined"==typeof n||n===!1||(n=e.text()||e.val()),n){var s=e,a=e.data("i18n-target");if(a&&(s=e.find(a)||e),i||H.useDataAttrOptions!==!0||(i=e.data("i18n-options")),i=i||{},n.indexOf(";")>=0){var r=n.split(";");I.each(r,function(e,n){""!==n&&t(s,n,i)})}else t(s,n,i);H.useDataAttrOptions===!0&&e.data("i18n-options",i)}}I.t=I.t||S,I.fn.i18n=function(t){return this.each(function(){e(I(this),t);var i=I(this).find("["+H.selectorAttr+"]");i.each(function(){e(I(this),t)})})}}function _(t,e,i,n){if(!t)return t;if(n=n||e,t.indexOf(n.interpolationPrefix||H.interpolationPrefix)<0)return t;var s=n.interpolationPrefix?$.regexEscape(n.interpolationPrefix):H.interpolationPrefixEscaped,a=n.interpolationSuffix?$.regexEscape(n.interpolationSuffix):H.interpolationSuffixEscaped,r="HTML"+a,o=e.replace&&"object"==typeof e.replace?e.replace:e;return $.each(o,function(e,o){var l=i?i+H.keyseparator+e:e;"object"==typeof o&&null!==o?t=_(t,o,l,n):n.escapeInterpolation||H.escapeInterpolation?(t=t.replace(new RegExp([s,l,r].join(""),"g"),$.regexReplacementEscape(o)),t=t.replace(new RegExp([s,l,a].join(""),"g"),$.regexReplacementEscape($.escape(o)))):t=t.replace(new RegExp([s,l,a].join(""),"g"),$.regexReplacementEscape(o))}),t}function y(t,e){var i=",",n="{",s="}",a=$.extend({},e);for(delete a.postProcess;-1!=t.indexOf(H.reusePrefix)&&(O++,!(O>H.maxRecursion));){var r=t.lastIndexOf(H.reusePrefix),o=t.indexOf(H.reuseSuffix,r)+H.reuseSuffix.length,l=t.substring(r,o),c=l.replace(H.reusePrefix,"").replace(H.reuseSuffix,"");if(r>=o)return $.error("there is an missing closing in following translation value",t),"";if(-1!=c.indexOf(i)){var u=c.indexOf(i);if(-1!=c.indexOf(n,u)&&-1!=c.indexOf(s,u)){var h=c.indexOf(n,u),d=c.indexOf(s,h)+s.length;try{a=$.extend(a,JSON.parse(c.substring(h,d))),c=c.substring(0,u)}catch(p){}}}var f=A(c,a);t=t.replace(l,$.regexReplacementEscape(f))}return t}function w(t){return t.context&&("string"==typeof t.context||"number"==typeof t.context)}function x(t,e){return void 0!==t.count&&"string"!=typeof t.count}function k(t){return void 0!==t.indefinite_article&&"string"!=typeof t.indefinite_article&&t.indefinite_article}function C(t,e){e=e||{};var i=D(t,e),n=E(t,e);return void 0!==n||n===i}function S(t,e){return e=e||{},j?(O=0,A.apply(null,arguments)):($.log("i18next not finished initialization. you might have called t function before loading resources finished."),e.defaultValue||"")}function D(t,e){return void 0!==e.defaultValue?e.defaultValue:t}function T(){for(var t=[],e=1;e1)for(var n=0;n-1&&(s=i.split(H.nsseparator),l=s[0],i=s[1]),void 0===r&&H.sendMissing&&"function"==typeof H.missingKeyHandler&&(e.lng?H.missingKeyHandler(o[0],l,i,a,o):H.missingKeyHandler(H.lng,l,i,a,o));var c=e.postProcess||H.postProcess;void 0!==r&&c&&Y[c]&&(r=Y[c](r,i,e));var u=a;if(a.indexOf(H.nsseparator)>-1&&(s=a.split(H.nsseparator),u=s[1]),u===i&&H.parseMissingKey&&(a=H.parseMissingKey(a)),void 0===r&&(a=_(a,e),a=y(a,e),c&&Y[c])){var h=D(i,e);r=Y[c](h,i,e)}return void 0!==r?r:a}function E(t,e){e=e||{};var i,n,s=D(t,e),a=R;if(!F)return s;if("cimode"===a[0].toLowerCase())return s;if(e.lngs&&(a=e.lngs),e.lng&&(a=$.toLanguages(e.lng,e.fallbackLng),!F[a[0]])){var r=H.getAsync;H.getAsync=!1,N.sync.load(a,H,function(t,e){$.extend(F,e),H.getAsync=r})}var o=e.ns||H.ns.defaultNs;if(t.indexOf(H.nsseparator)>-1){var l=t.split(H.nsseparator);o=l[0],t=l[1]}if(w(e)){i=$.extend({},e),delete i.context,i.defaultValue=H.contextNotFound;var c=o+H.nsseparator+t+"_"+e.context;if(n=S(c,i),n!=H.contextNotFound)return _(n,{context:e.context})}if(x(e,a[0])){i=$.extend({lngs:[a[0]]},e),delete i.count,delete i.lng,i.defaultValue=H.pluralNotFound;var u;if(V.needsPlural(a[0],e.count)){u=o+H.nsseparator+t+H.pluralSuffix;var h=V.get(a[0],e.count);h>=0?u=u+"_"+h:1===h&&(u=o+H.nsseparator+t)}else u=o+H.nsseparator+t;if(n=S(u,i),n!=H.pluralNotFound)return _(n,{count:e.count,interpolationPrefix:e.interpolationPrefix,interpolationSuffix:e.interpolationSuffix});if(!(a.length>1))return n;var d=a.slice();if(d.shift(),e=$.extend(e,{lngs:d}),delete e.lng,n=S(o+H.nsseparator+t,e),n!=H.pluralNotFound)return n}if(k(e)){var p=$.extend({},e);delete p.indefinite_article,p.defaultValue=H.indefiniteNotFound;var f=o+H.nsseparator+t+(e.count&&!x(e,a[0])||!e.count?H.indefiniteSuffix:"");if(n=S(f,p),n!=H.indefiniteNotFound)return n}for(var g,m=t.split(H.keyseparator),v=0,b=a.length;b>v&&void 0===g;v++){for(var C=a[v],T=0,M=F[C]&&F[C][o];m[T];)M=M&&M[m[T]],T++;if(void 0!==M){var P=Object.prototype.toString.apply(M);if("string"==typeof M)M=_(M,e),M=y(M,e);else if("[object Array]"!==P||H.returnObjectTrees||e.returnObjectTrees){if(null===M&&H.fallbackOnNull===!0)M=void 0;else if(null!==M)if(H.returnObjectTrees||e.returnObjectTrees){if("[object Number]"!==P&&"[object Function]"!==P&&"[object RegExp]"!==P){var I="[object Array]"===P?[]:{};$.each(M,function(i){I[i]=A(o+H.nsseparator+t+H.keyseparator+i,e)}),M=I}}else H.objectTreeKeyHandler&&"function"==typeof H.objectTreeKeyHandler?M=H.objectTreeKeyHandler(t,M,C,o,e):(M="key '"+o+":"+t+" ("+C+")' returned an object instead of string.",$.log(M))}else M=M.join("\n"),M=_(M,e),M=y(M,e);"string"==typeof M&&""===M.trim()&&H.fallbackOnEmpty===!0&&(M=void 0),g=M}}if(void 0===g&&!e.isFallbackLookup&&(H.fallbackToDefaultNS===!0||H.fallbackNS&&H.fallbackNS.length>0)){if(e.isFallbackLookup=!0,H.fallbackNS.length){for(var O=0,j=H.fallbackNS.length;j>O;O++)if(g=E(H.fallbackNS[O]+H.nsseparator+t,e),g||""===g&&H.fallbackOnEmpty===!1){var L=g.indexOf(H.nsseparator)>-1?g.split(H.nsseparator)[1]:g,z=s.indexOf(H.nsseparator)>-1?s.split(H.nsseparator)[1]:s;if(L!==z)break}}else g=E(t,e);e.isFallbackLookup=!1}return g}function M(){var t,e=H.lngWhitelist||[],i=[];if("undefined"!=typeof window&&!function(){for(var t=window.location.search.substring(1),e=t.split("&"),n=0;n0){var a=e[n].substring(0,s);a==H.detectLngQS&&i.push(e[n].substring(s+1))}}}(),H.useCookie&&"undefined"!=typeof document){var n=$.cookie.read(H.cookieName);n&&i.push(n)}if(H.detectLngFromLocalStorage&&"undefined"!=typeof window&&window.localStorage&&i.push(window.localStorage.getItem("i18next_lng")),"undefined"!=typeof navigator){if(navigator.languages)for(var s=0;s-1){var a=s.split("-");s=H.lowerCaseLng?a[0].toLowerCase()+"-"+a[1].toLowerCase():a[0].toLowerCase()+"-"+a[1].toUpperCase()}if(0===e.length||e.indexOf(s)>-1){t=s;break}}}(),t||(t=H.fallbackLng[0]),t}Array.prototype.indexOf||(Array.prototype.indexOf=function(t){"use strict";if(null==this)throw new TypeError;var e=Object(this),i=e.length>>>0;if(0===i)return-1;var n=0;if(arguments.length>0&&(n=Number(arguments[1]),n!=n?n=0:0!=n&&n!=1/0&&n!=-(1/0)&&(n=(n>0||-1)*Math.floor(Math.abs(n)))),n>=i)return-1;for(var s=n>=0?n:Math.max(i-Math.abs(n),0);i>s;s++)if(s in e&&e[s]===t)return s;return-1}),Array.prototype.lastIndexOf||(Array.prototype.lastIndexOf=function(t){"use strict";if(null==this)throw new TypeError;var e=Object(this),i=e.length>>>0;if(0===i)return-1;var n=i;arguments.length>1&&(n=Number(arguments[1]),n!=n?n=0:0!=n&&n!=1/0&&n!=-(1/0)&&(n=(n>0||-1)*Math.floor(Math.abs(n))));for(var s=n>=0?Math.min(n,i-1):i-Math.abs(n);s>=0;s--)if(s in e&&e[s]===t)return s;return-1}),"function"!=typeof String.prototype.trim&&(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")});var P,I=void 0,N={},F={},O=0,R=[],j=!1,L={};L={load:function(t,e,i){e.useLocalStorage?L._loadLocal(t,e,function(n,s){for(var a=[],r=0,o=t.length;o>r;r++)s[t[r]]||a.push(t[r]);a.length>0?L._fetch(a,e,function(t,e){$.extend(s,e),L._storeLocal(e),i(null,s)}):i(null,s)}):L._fetch(t,e,function(t,e){i(null,e)})},_loadLocal:function(t,e,i){var n={},s=(new Date).getTime();if(window.localStorage){var a=t.length;$.each(t,function(t,r){var o=window.localStorage.getItem("res_"+r);o&&(o=JSON.parse(o),o.i18nStamp&&o.i18nStamp+e.localStorageExpirationTime>s&&(n[r]=o)),a--,0===a&&i(null,n)})}},_storeLocal:function(t){if(window.localStorage)for(var e in t)t[e].i18nStamp=(new Date).getTime(),$.localStorage.setItem("res_"+e,JSON.stringify(t[e]))},_fetch:function(t,e,i){var n=e.ns,s={};if(e.dynamicLoad){var a=function(t,e){i(null,e)};if("function"==typeof e.customLoad)e.customLoad(t,n.namespaces,e,a);else{var r=_(e.resGetPath,{lng:t.join("+"),ns:n.namespaces.join("+")});$.ajax({url:r,success:function(t,e,i){$.log("loaded: "+r),a(null,t)},error:function(t,e,i){$.log("failed loading: "+r),a("failed loading resource.json error: "+i)},dataType:"json",async:e.getAsync})}}else{var o,l=n.namespaces.length*t.length;$.each(n.namespaces,function(n,a){$.each(t,function(t,n){var r=function(t,e){t&&(o=o||[],o.push(t)),s[n]=s[n]||{},s[n][a]=e,l--,0===l&&i(o,s)};"function"==typeof e.customLoad?e.customLoad(n,a,e,r):L._fetchOne(n,a,e,r)})})}},_fetchOne:function(t,e,i,n){var s=_(i.resGetPath,{lng:t,ns:e});$.ajax({url:s,success:function(t,e,i){$.log("loaded: "+s),n(null,t)},error:function(t,e,i){if(e&&200==e||t&&t.status&&200==t.status)$.error("There is a typo in: "+s);else if(e&&404==e||t&&t.status&&404==t.status)$.log("Does not exist: "+s);else{var a=e?e:t&&t.status?t.status:null;$.log(a+" when loading "+s)}n(i,{})},dataType:"json",async:i.getAsync})},postMissing:function(t,e,i,n,s){var a={};a[i]=n;var r=[];if("fallback"===H.sendMissingTo&&H.fallbackLng[0]!==!1)for(var o=0;oo;o++)r.push({lng:s[o],url:_(H.resPostPath,{lng:s[o],ns:e})});for(var c=0,u=r.length;u>c;c++){var h=r[c];$.ajax({url:h.url,type:H.sendType,data:a,success:function(t,s,a){$.log("posted missing key '"+i+"' to: "+h.url);for(var r=i.split("."),o=0,l=F[h.lng][e];r[o];)l=o===r.length-1?l[r[o]]=n:l[r[o]]=l[r[o]]||{},o++},error:function(t,e,n){$.log("failed posting missing key '"+i+"' to: "+h.url)},dataType:"json",async:H.postAsync})}},reload:v};var H={lng:void 0,load:"all",preload:[],lowerCaseLng:!1,returnObjectTrees:!1,fallbackLng:["dev"],fallbackNS:[],detectLngQS:"setLng",detectLngFromLocalStorage:!1,ns:"translation",fallbackOnNull:!0,fallbackOnEmpty:!1,fallbackToDefaultNS:!1,nsseparator:":",keyseparator:".",selectorAttr:"data-i18n",debug:!1,resGetPath:"locales/__lng__/__ns__.json",resPostPath:"locales/add/__lng__/__ns__",getAsync:!0,postAsync:!0,resStore:void 0,useLocalStorage:!1,localStorageExpirationTime:6048e5,dynamicLoad:!1,sendMissing:!1,sendMissingTo:"fallback",sendType:"POST",interpolationPrefix:"__",interpolationSuffix:"__",defaultVariables:!1,reusePrefix:"$t(",reuseSuffix:")",pluralSuffix:"_plural",pluralNotFound:["plural_not_found",Math.random()].join(""),contextNotFound:["context_not_found",Math.random()].join(""),escapeInterpolation:!1,indefiniteSuffix:"_indefinite",indefiniteNotFound:["indefinite_not_found",Math.random()].join(""),setJqueryExt:!0,defaultValueFromContent:!0,useDataAttrOptions:!1,cookieExpirationTime:void 0,useCookie:!0,cookieName:"i18next",cookieDomain:void 0,objectTreeKeyHandler:void 0,postProcess:void 0,parseMissingKey:void 0,missingKeyHandler:L.postMissing,shortcutFunction:"sprintf"},z={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},B={create:function(t,e,i,n){var s;if(i){var a=new Date;a.setTime(a.getTime()+60*i*1e3),s="; expires="+a.toGMTString()}else s="";n=n?"domain="+n+";":"",document.cookie=t+"="+e+s+";"+n+"path=/"},read:function(t){for(var e=t+"=",i=document.cookie.split(";"),n=0;n-1){var i=t.split("-");e=H.lowerCaseLng?i[0].toLowerCase()+"-"+i[1].toLowerCase():i[0].toLowerCase()+"-"+i[1].toUpperCase()}else e=H.lowerCaseLng?t.toLowerCase():t;return e}var i=this.log,n=[],s=H.lngWhitelist||!1,a=function(t){!s||s.indexOf(t)>-1?n.push(t):i("rejecting non-whitelisted language: "+t)};if("string"==typeof t&&t.indexOf("-")>-1){var r=t.split("-");"unspecific"!==H.load&&a(e(t)),"current"!==H.load&&a(e(r[this.getCountyIndexOfLng(t)]))}else a(e(t));for(var o=0;o1)},2:function(t){return Number(1!=t)},3:function(t){return 0},4:function(t){return Number(t%10==1&&t%100!=11?0:t%10>=2&&4>=t%10&&(10>t%100||t%100>=20)?1:2)},5:function(t){return Number(0===t?0:1==t?1:2==t?2:t%100>=3&&10>=t%100?3:t%100>=11?4:5)},6:function(t){return Number(1==t?0:t>=2&&4>=t?1:2)},7:function(t){return Number(1==t?0:t%10>=2&&4>=t%10&&(10>t%100||t%100>=20)?1:2)},8:function(t){return Number(1==t?0:2==t?1:8!=t&&11!=t?2:3)},9:function(t){return Number(t>=2)},10:function(t){return Number(1==t?0:2==t?1:7>t?2:11>t?3:4)},11:function(t){return Number(1==t||11==t?0:2==t||12==t?1:t>2&&20>t?2:3)},12:function(t){return Number(t%10!=1||t%100==11)},13:function(t){return Number(0!==t)},14:function(t){return Number(1==t?0:2==t?1:3==t?2:3)},15:function(t){return Number(t%10==1&&t%100!=11?0:t%10>=2&&(10>t%100||t%100>=20)?1:2)},16:function(t){return Number(t%10==1&&t%100!=11?0:0!==t?1:2)},17:function(t){return Number(1==t||t%10==1?0:1)},18:function(t){return Number(1==t?1:2)},19:function(t){return Number(1==t?0:0===t||t%100>1&&11>t%100?1:t%100>10&&20>t%100?2:3)},20:function(t){return Number(1==t?0:0===t||t%100>0&&20>t%100?1:2)},21:function(t){return Number(t%100==1?1:t%100==2?2:t%100==3||t%100==4?3:0)}},V={rules:function(){var t,e={};for(t=W.length;t--;)e[W[t][0]]={name:W[t][1],numbers:W[t][2],plurals:U[W[t][3]] +};return e}(),addRule:function(t,e){V.rules[t]=e},setCurrentLng:function(t){if(!V.currentRule||V.currentRule.lng!==t){var e=t.split("-");V.currentRule={lng:t,rule:V.rules[e[0]]}}},needsPlural:function(t,e){var i,n=t.split("-");return i=V.currentRule&&V.currentRule.lng===t?V.currentRule.rule:V.rules[n[$.getCountyIndexOfLng(t)]],i&&i.numbers.length<=1?!1:1!==this.get(t,e)},get:function(t,e){function i(e,i){var n;if(n=V.currentRule&&V.currentRule.lng===t?V.currentRule.rule:V.rules[e]){var s;s=n.noAbs?n.plurals(i):n.plurals(Math.abs(i));var a=n.numbers[s];return 2===n.numbers.length&&1===n.numbers[0]&&(2===a?a=-1:1===a&&(a=1)),a}return 1===i?"1":"-1"}var n=t.split("-");return i(n[$.getCountyIndexOfLng(t)],e)}},Y={},K=function(t,e){Y[t]=e},G=function(){function t(t){return Object.prototype.toString.call(t).slice(8,-1).toLowerCase()}function e(t,e){for(var i=[];e>0;i[--e]=t);return i.join("")}var i=function(){return i.cache.hasOwnProperty(arguments[0])||(i.cache[arguments[0]]=i.parse(arguments[0])),i.format.call(null,i.cache[arguments[0]],arguments)};return i.format=function(i,n){var s,a,r,o,l,c,u,h=1,d=i.length,p="",f=[];for(a=0;d>a;a++)if(p=t(i[a]),"string"===p)f.push(i[a]);else if("array"===p){if(o=i[a],o[2])for(s=n[h],r=0;r=0?"+"+s:s,c=o[4]?"0"==o[4]?"0":o[4].charAt(1):" ",u=o[6]-String(s).length,l=o[6]?e(c,u):"",f.push(o[5]?s+l:l+s)}return f.join("")},i.cache={},i.parse=function(t){for(var e=t,i=[],n=[],s=0;e;){if(null!==(i=/^[^\x25]+/.exec(e)))n.push(i[0]);else if(null!==(i=/^\x25{2}/.exec(e)))n.push("%");else{if(null===(i=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(e)))throw"[sprintf] huh?";if(i[2]){s|=1;var a=[],r=i[2],o=[];if(null===(o=/^([a-z_][a-z_\d]*)/i.exec(r)))throw"[sprintf] huh?";for(a.push(o[1]);""!==(r=r.substring(o[0].length));)if(null!==(o=/^\.([a-z_][a-z_\d]*)/i.exec(r)))a.push(o[1]);else{if(null===(o=/^\[(\d+)\]/.exec(r)))throw"[sprintf] huh?";a.push(o[1])}i[2]=a}else s|=2;if(3===s)throw"[sprintf] mixing positional and named placeholders is not (yet) supported";n.push(i)}e=e.substring(i[0].length)}return n},i}(),X=function(t,e){return e.unshift(t),G.apply(null,e)};return K("sprintf",function(t,e,i){return i.sprintf?"[object Array]"===Object.prototype.toString.apply(i.sprintf)?X(t,i.sprintf):"object"==typeof i.sprintf?G(t,i.sprintf):t:t}),N.init=a,N.setLng=g,N.preload=r,N.addResourceBundle=o,N.hasResourceBundle=l,N.addResource=u,N.addResources=h,N.removeResourceBundle=c,N.loadNamespace=p,N.loadNamespaces=f,N.setDefaultNamespace=d,N.t=S,N.translate=S,N.exists=C,N.detectLanguage=$.detectLanguage,N.pluralExtensions=V,N.sync=L,N.functions=$,N.lng=m,N.addPostProcessor=K,N.options=H,N}),i("views/i18n",["i18next"],function(t){"use strict";var e=t.t;return e.init=function(i){t.init({detectLngQS:"lang",fallbackLng:"en",lowerCaseLng:!0,getAsync:!1,resGetPath:i+"locales/__lng__/__ns__.json"}),Handlebars.registerHelper("t",e.bind(e))},e}),function(t){var e="object"==typeof exports&&exports,n="object"==typeof module&&module&&module.exports==e&&module,s="object"==typeof global&&global;s.global!==s&&s.window!==s||(t=s);var a=String.fromCharCode,r=function(t){return t.replace(/[\t\x20]$/gm,"").replace(/=?(?:\r\n?|\n)/g,"").replace(/=([a-fA-F0-9]{2})/g,function(t,e){var i=parseInt(e,16);return a(i)})},o=function(t){return t.replace(/\x20$/,"=20").replace(/\t$/,"=09")},l=/[\0-\b\n-\x1F=\x7F-\uD7FF\uDC00-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF]/g,c=function(t){for(var e=t.replace(l,function(t){if(t>"ÿ")throw RangeError("`quotedPrintable.encode()` expects extended ASCII input only. Don’t forget to encode the input first using a character encoding like UTF-8.");var e=t.charCodeAt(0),i=e.toString(16).toUpperCase();return"="+("0"+i).slice(-2)}),i=e.split(/\r\n?|\n/g),n=-1,s=i.length,a=[];++nu;){var d=e.slice(u,u+c);/=$/.test(d)?(d=d.slice(0,c-1),u+=c-1):/=[A-F0-9]$/.test(d)?(d=d.slice(0,c-2),u+=c-2):u+=c,a.push(d)}var p=d.length;return/[\t\x20]$/.test(d)&&(a.pop(),c+1>=p+2?a.push(o(d)):a.push(d.slice(0,p-1),o(d.slice(p-1,p)))),a.join("=\r\n")},u={encode:c,decode:r,version:"0.2.1"};if("function"==typeof i&&"object"==typeof i.amd&&i.amd)i("quoted-printable/quoted-printable",[],function(){return u});else if(e&&!e.nodeType)if(n)n.exports=u;else for(var h in u)u.hasOwnProperty(h)&&(e[h]=u[h]);else t.quotedPrintable=u}(this),function(t){function e(t){for(var e,i,n=[],s=0,a=t.length;a>s;)e=t.charCodeAt(s++),e>=55296&&56319>=e&&a>s?(i=t.charCodeAt(s++),56320==(64512&i)?n.push(((1023&e)<<10)+(1023&i)+65536):(n.push(e),s--)):n.push(e);return n}function n(t){for(var e,i=t.length,n=-1,s="";++n65535&&(e-=65536,s+=v(e>>>10&1023|55296),e=56320|1023&e),s+=v(e);return s}function s(t){if(t>=55296&&57343>=t)throw Error("Lone surrogate U+"+t.toString(16).toUpperCase()+" is not a scalar value")}function a(t,e){return v(t>>e&63|128)}function r(t){if(0==(4294967168&t))return v(t);var e="";return 0==(4294965248&t)?e=v(t>>6&31|192):0==(4294901760&t)?(s(t),e=v(t>>12&15|224),e+=a(t,6)):0==(4292870144&t)&&(e=v(t>>18&7|240),e+=a(t,12),e+=a(t,6)),e+=v(63&t|128)}function o(t){for(var i,n=e(t),s=n.length,a=-1,o="";++a=g)throw Error("Invalid byte index");var t=255&f[m];if(m++,128==(192&t))return 63&t;throw Error("Invalid continuation byte")}function c(){var t,e,i,n,a;if(m>g)throw Error("Invalid byte index");if(m==g)return!1;if(t=255&f[m],m++,0==(128&t))return t;if(192==(224&t)){var e=l();if(a=(31&t)<<6|e,a>=128)return a;throw Error("Invalid continuation byte")}if(224==(240&t)){if(e=l(),i=l(),a=(15&t)<<12|e<<6|i,a>=2048)return s(a),a;throw Error("Invalid continuation byte")}if(240==(248&t)&&(e=l(),i=l(),n=l(),a=(15&t)<<18|e<<12|i<<6|n,a>=65536&&1114111>=a))return a;throw Error("Invalid UTF-8 detected")}function u(t){f=e(t),g=f.length,m=0;for(var i,s=[];(i=c())!==!1;)s.push(i);return n(s)}var h="object"==typeof exports&&exports,d="object"==typeof module&&module&&module.exports==h&&module,p="object"==typeof global&&global;p.global!==p&&p.window!==p||(t=p);var f,g,m,v=String.fromCharCode,b={version:"2.0.0",encode:o,decode:u};if("function"==typeof i&&"object"==typeof i.amd&&i.amd)i("utf8/utf8",[],function(){return b});else if(h&&!h.nodeType)if(d)d.exports=b;else{var _={},y=_.hasOwnProperty;for(var w in b)y.call(b,w)&&(h[w]=b[w])}else t.utf8=b}(this),function(t){"use strict";var e="undefined"==typeof window?null:window;"function"==typeof i&&i.amd?i("DOMPurify",[],function(){return t(e)}):"undefined"!=typeof module?module.exports=t(e):e.DOMPurify=t(e)}(function n(t){"use strict";var e=function(t){return n(t)};if(e.version="0.7.4",!t||!t.document||9!==t.document.nodeType)return e.isSupported=!1,e;var i=t.document,s=i,a=t.DocumentFragment,r=t.HTMLTemplateElement,o=t.NodeFilter,l=t.NamedNodeMap||t.MozNamedAttrMap,c=t.Text,u=t.Comment,h=t.DOMParser;"function"==typeof r&&(i=i.createElement("template").content.ownerDocument);var d=i.implementation,p=i.createNodeIterator,f=i.getElementsByTagName,g=i.createDocumentFragment,m=s.importNode,v={};e.isSupported="undefined"!=typeof d.createHTMLDocument&&9!==i.documentMode;var b=function(t,e){for(var i=e.length;i--;)t[e[i]]=!0;return t},_=function(t){var e,i={};for(e in t)t.hasOwnProperty(e)&&(i[e]=t[e]);return i},y=null,w=b({},["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","pre","progress","q","rp","rt","ruby","s","samp","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr","svg","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","circle","clippath","defs","desc","ellipse","font","g","glyph","glyphref","hkern","image","line","lineargradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialgradient","rect","stop","switch","symbol","text","textpath","title","tref","tspan","view","vkern","feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","feSpecularLighting","feTile","feTurbulence","math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmuliscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mpspace","msqrt","mystyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover","#text"]),x=null,k=b({},["accept","action","align","alt","autocomplete","background","bgcolor","border","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","coords","datetime","default","dir","disabled","download","enctype","face","for","headers","height","hidden","high","href","hreflang","id","ismap","label","lang","list","loop","low","max","maxlength","media","method","min","multiple","name","noshade","novalidate","nowrap","open","optimum","pattern","placeholder","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","rows","rowspan","spellcheck","scope","selected","shape","size","span","srclang","start","src","step","style","summary","tabindex","title","type","usemap","valign","value","width","xmlns","accent-height","accumulate","additivive","alignment-baseline","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","clip","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dur","edgemode","elevation","end","fill","fill-opacity","fill-rule","filter","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttransform","image-rendering","in","in2","k","k1","k2","k3","k4","kerning","keypoints","keysplines","keytimes","lengthadjust","letter-spacing","kernelmatrix","kernelunitlength","lighting-color","local","marker-end","marker-mid","marker-start","markerheight","markerunits","markerwidth","maskcontentunits","maskunits","max","mask","mode","min","numoctaves","offset","operator","opacity","order","orient","orientation","origin","overflow","paint-order","path","pathlength","patterncontentunits","patterntransform","patternunits","points","preservealpha","r","rx","ry","radius","refx","refy","repeatcount","repeatdur","restart","rotate","scale","seed","shape-rendering","specularconstant","specularexponent","spreadmethod","stddeviation","stitchtiles","stop-color","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke","stroke-width","surfacescale","targetx","targety","transform","text-anchor","text-decoration","text-rendering","textlength","u1","u2","unicode","values","viewbox","visibility","vert-adv-y","vert-origin-x","vert-origin-y","word-spacing","wrap","writing-mode","xchannelselector","ychannelselector","x","x1","x2","y","y1","y2","z","zoomandpan","accent","accentunder","bevelled","close","columnsalign","columnlines","columnspan","denomalign","depth","display","displaystyle","fence","frame","largeop","length","linethickness","lspace","lquote","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","rquote","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","voffset","xlink:href","xml:id","xlink:title","xml:space","xmlns:xlink"]),C=null,S=null,D=!0,T=!1,A=!1,E=/\{\{[\s\S]*|[\s\S]*\}\}/gm,M=/<%[\s\S]*|[\s\S]*%>/gm,P=!1,I=!1,N=!1,F=!1,O=!0,R=!0,j=b({},["audio","head","math","script","style","svg","video"]),L=b({},["audio","video","img","source"]),H=b({},["alt","class","for","id","label","name","pattern","placeholder","summary","title","value","style","xmlns"]),z=null,B=i.createElement("form"),q=function(t){"object"!=typeof t&&(t={}),y="ALLOWED_TAGS"in t?b({},t.ALLOWED_TAGS):w,x="ALLOWED_ATTR"in t?b({},t.ALLOWED_ATTR):k,C="FORBID_TAGS"in t?b({},t.FORBID_TAGS):{},S="FORBID_ATTR"in t?b({},t.FORBID_ATTR):{},D=t.ALLOW_DATA_ATTR!==!1,T=t.SAFE_FOR_JQUERY||!1,A=t.SAFE_FOR_TEMPLATES||!1,P=t.WHOLE_DOCUMENT||!1,I=t.RETURN_DOM||!1,N=t.RETURN_DOM_FRAGMENT||!1,F=t.RETURN_DOM_IMPORT||!1,O=t.SANITIZE_DOM!==!1,R=t.KEEP_CONTENT!==!1,N&&(I=!0),t.ADD_TAGS&&(y===w&&(y=_(y)),b(y,t.ADD_TAGS)),t.ADD_ATTR&&(x===k&&(x=_(x)),b(x,t.ADD_ATTR)),R&&(y["#text"]=!0),Object&&"freeze"in Object&&Object.freeze(t),z=t},$=function(t){try{t.parentNode.removeChild(t)}catch(e){t.outerHTML=""}},W=function(t){var e,i;try{e=(new h).parseFromString(t,"text/html")}catch(n){}return e||(e=d.createHTMLDocument(""),i=e.body,i.parentNode.removeChild(i.parentNode.firstElementChild),i.outerHTML=t),"function"==typeof e.getElementsByTagName?e.getElementsByTagName(P?"html":"body")[0]:f.call(e,P?"html":"body")[0]},U=function(t){return p.call(t.ownerDocument||t,t,o.SHOW_ELEMENT|o.SHOW_COMMENT|o.SHOW_TEXT,function(){return o.FILTER_ACCEPT},!1)},V=function(t){return t instanceof c||t instanceof u?!1:!("string"==typeof t.nodeName&&"string"==typeof t.textContent&&"function"==typeof t.removeChild&&t.attributes instanceof l&&"function"==typeof t.removeAttribute&&"function"==typeof t.setAttribute)},Y=function(t){var e,i;if(Z("beforeSanitizeElements",t,null),V(t))return $(t),!0;if(e=t.nodeName.toLowerCase(),Z("uponSanitizeElement",t,{tagName:e}),!y[e]||C[e]){if(R&&!j[e]&&"function"==typeof t.insertAdjacentHTML)try{t.insertAdjacentHTML("AfterEnd",t.innerHTML)}catch(n){}return $(t),!0}return!T||t.firstElementChild||t.content&&t.content.firstElementChild||(t.innerHTML=t.textContent.replace(/u&&e.setAttribute("id",o.value)):("id"===s&&e.setAttribute(s,""),e.removeAttribute(s)),c.keepAttr&&(!O||"id"!==r&&"name"!==r||!(a in t||a in i||a in B))&&(A&&(a=a.replace(E," "),a=a.replace(M," ")),(x[r]&&!S[r]||!A&&D&&K.test(r))&&(G.test(a.replace(X,""))||"src"===r&&0===a.indexOf("data:")&&L[e.nodeName.toLowerCase()]||H[r])))try{e.setAttribute(s,a)}catch(h){}Z("afterSanitizeAttributes",e,null)}},J=function(t){var e,i=U(t);for(Z("beforeSanitizeShadowDOM",t,null);e=i.nextNode();)Z("uponSanitizeShadowNode",e,null),Y(e)||(e.content instanceof a&&J(e.content),Q(e));Z("afterSanitizeShadowDOM",t,null)},Z=function(t,i,n){v[t]&&v[t].forEach(function(t){t.call(e,i,n,z)})};return e.sanitize=function(i,n){var r,o,l,c,u;if(i||(i=""),"string"!=typeof i){if("function"!=typeof i.toString)throw new TypeError("toString is not a function");i=i.toString()}if(!e.isSupported)return"object"==typeof t.toStaticHTML||"function"==typeof t.toStaticHTML?t.toStaticHTML(i):i;if(q(n),!I&&!P&&-1===i.indexOf("<"))return i;if(r=W(i),!r)return I?null:"";for(c=U(r);o=c.nextNode();)3===o.nodeType&&o===l||Y(o)||(o.content instanceof a&&J(o.content),Q(o),l=o);if(I){if(N)for(u=g.call(r.ownerDocument);r.firstChild;)u.appendChild(r.firstChild);else u=r;return F&&(u=m.call(s,u,!0)),u}return P?r.outerHTML:r.innerHTML},e.addHook=function(t,e){"function"==typeof e&&(v[t]=v[t]||[],v[t].push(e))},e.removeHook=function(t){v[t]&&v[t].pop()},e.removeHooks=function(t){v[t]&&(v[t]=[])},e.removeAllHooks=function(){v=[]},e}),function(t){var e="object"==typeof exports&&exports,n="object"==typeof module&&module&&module.exports==e&&module,s="object"==typeof global&&global;s.global!==s&&s.window!==s||(t=s);var a=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,r=/[\x01-\x7F]/g,o=/[\x01-\t\x0B\f\x0E-\x1F\x7F\x81\x8D\x8F\x90\x9D\xA0-\uFFFF]/g,l=/<\u20D2|=\u20E5|>\u20D2|\u205F\u200A|\u219D\u0338|\u2202\u0338|\u2220\u20D2|\u2229\uFE00|\u222A\uFE00|\u223C\u20D2|\u223D\u0331|\u223E\u0333|\u2242\u0338|\u224B\u0338|\u224D\u20D2|\u224E\u0338|\u224F\u0338|\u2250\u0338|\u2261\u20E5|\u2264\u20D2|\u2265\u20D2|\u2266\u0338|\u2267\u0338|\u2268\uFE00|\u2269\uFE00|\u226A\u0338|\u226A\u20D2|\u226B\u0338|\u226B\u20D2|\u227F\u0338|\u2282\u20D2|\u2283\u20D2|\u228A\uFE00|\u228B\uFE00|\u228F\u0338|\u2290\u0338|\u2293\uFE00|\u2294\uFE00|\u22B4\u20D2|\u22B5\u20D2|\u22D8\u0338|\u22D9\u0338|\u22DA\uFE00|\u22DB\uFE00|\u22F5\u0338|\u22F9\u0338|\u2933\u0338|\u29CF\u0338|\u29D0\u0338|\u2A6D\u0338|\u2A70\u0338|\u2A7D\u0338|\u2A7E\u0338|\u2AA1\u0338|\u2AA2\u0338|\u2AAC\uFE00|\u2AAD\uFE00|\u2AAF\u0338|\u2AB0\u0338|\u2AC5\u0338|\u2AC6\u0338|\u2ACB\uFE00|\u2ACC\uFE00|\u2AFD\u20E5|[\xA0-\u0113\u0116-\u0122\u0124-\u012B\u012E-\u014D\u0150-\u017E\u0192\u01B5\u01F5\u0237\u02C6\u02C7\u02D8-\u02DD\u0311\u0391-\u03A1\u03A3-\u03A9\u03B1-\u03C9\u03D1\u03D2\u03D5\u03D6\u03DC\u03DD\u03F0\u03F1\u03F5\u03F6\u0401-\u040C\u040E-\u044F\u0451-\u045C\u045E\u045F\u2002-\u2005\u2007-\u2010\u2013-\u2016\u2018-\u201A\u201C-\u201E\u2020-\u2022\u2025\u2026\u2030-\u2035\u2039\u203A\u203E\u2041\u2043\u2044\u204F\u2057\u205F-\u2063\u20AC\u20DB\u20DC\u2102\u2105\u210A-\u2113\u2115-\u211E\u2122\u2124\u2127-\u2129\u212C\u212D\u212F-\u2131\u2133-\u2138\u2145-\u2148\u2153-\u215E\u2190-\u219B\u219D-\u21A7\u21A9-\u21AE\u21B0-\u21B3\u21B5-\u21B7\u21BA-\u21DB\u21DD\u21E4\u21E5\u21F5\u21FD-\u2205\u2207-\u2209\u220B\u220C\u220F-\u2214\u2216-\u2218\u221A\u221D-\u2238\u223A-\u2257\u2259\u225A\u225C\u225F-\u2262\u2264-\u228B\u228D-\u229B\u229D-\u22A5\u22A7-\u22B0\u22B2-\u22BB\u22BD-\u22DB\u22DE-\u22E3\u22E6-\u22F7\u22F9-\u22FE\u2305\u2306\u2308-\u2310\u2312\u2313\u2315\u2316\u231C-\u231F\u2322\u2323\u232D\u232E\u2336\u233D\u233F\u237C\u23B0\u23B1\u23B4-\u23B6\u23DC-\u23DF\u23E2\u23E7\u2423\u24C8\u2500\u2502\u250C\u2510\u2514\u2518\u251C\u2524\u252C\u2534\u253C\u2550-\u256C\u2580\u2584\u2588\u2591-\u2593\u25A1\u25AA\u25AB\u25AD\u25AE\u25B1\u25B3-\u25B5\u25B8\u25B9\u25BD-\u25BF\u25C2\u25C3\u25CA\u25CB\u25EC\u25EF\u25F8-\u25FC\u2605\u2606\u260E\u2640\u2642\u2660\u2663\u2665\u2666\u266A\u266D-\u266F\u2713\u2717\u2720\u2736\u2758\u2772\u2773\u27C8\u27C9\u27E6-\u27ED\u27F5-\u27FA\u27FC\u27FF\u2902-\u2905\u290C-\u2913\u2916\u2919-\u2920\u2923-\u292A\u2933\u2935-\u2939\u293C\u293D\u2945\u2948-\u294B\u294E-\u2976\u2978\u2979\u297B-\u297F\u2985\u2986\u298B-\u2996\u299A\u299C\u299D\u29A4-\u29B7\u29B9\u29BB\u29BC\u29BE-\u29C5\u29C9\u29CD-\u29D0\u29DC-\u29DE\u29E3-\u29E5\u29EB\u29F4\u29F6\u2A00-\u2A02\u2A04\u2A06\u2A0C\u2A0D\u2A10-\u2A17\u2A22-\u2A27\u2A29\u2A2A\u2A2D-\u2A31\u2A33-\u2A3C\u2A3F\u2A40\u2A42-\u2A4D\u2A50\u2A53-\u2A58\u2A5A-\u2A5D\u2A5F\u2A66\u2A6A\u2A6D-\u2A75\u2A77-\u2A9A\u2A9D-\u2AA2\u2AA4-\u2AB0\u2AB3-\u2AC8\u2ACB\u2ACC\u2ACF-\u2ADB\u2AE4\u2AE6-\u2AE9\u2AEB-\u2AF3\u2AFD\uFB00-\uFB04]|\uD835[\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDCCF\uDD04\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDD6B]/g,c={"Á":"Aacute","á":"aacute","Ă":"Abreve","ă":"abreve","∾":"ac","∿":"acd","∾̳":"acE","Â":"Acirc","â":"acirc","´":"acute","А":"Acy","а":"acy","Æ":"AElig","æ":"aelig","⁡":"af","𝔄":"Afr","𝔞":"afr","À":"Agrave","à":"agrave","ℵ":"aleph","Α":"Alpha","α":"alpha","Ā":"Amacr","ā":"amacr","⨿":"amalg","&":"amp","⩕":"andand","⩓":"And","∧":"and","⩜":"andd","⩘":"andslope","⩚":"andv","∠":"ang","⦤":"ange","⦨":"angmsdaa","⦩":"angmsdab","⦪":"angmsdac","⦫":"angmsdad","⦬":"angmsdae","⦭":"angmsdaf","⦮":"angmsdag","⦯":"angmsdah","∡":"angmsd","∟":"angrt","⊾":"angrtvb","⦝":"angrtvbd","∢":"angsph","Å":"angst","⍼":"angzarr","Ą":"Aogon","ą":"aogon","𝔸":"Aopf","𝕒":"aopf","⩯":"apacir","≈":"ap","⩰":"apE","≊":"ape","≋":"apid","'":"apos","å":"aring","𝒜":"Ascr","𝒶":"ascr","≔":"colone","*":"ast","≍":"CupCap","Ã":"Atilde","ã":"atilde","Ä":"Auml","ä":"auml","∳":"awconint","⨑":"awint","≌":"bcong","϶":"bepsi","‵":"bprime","∽":"bsim","⋍":"bsime","∖":"setmn","⫧":"Barv","⊽":"barvee","⌅":"barwed","⌆":"Barwed","⎵":"bbrk","⎶":"bbrktbrk","Б":"Bcy","б":"bcy","„":"bdquo","∵":"becaus","⦰":"bemptyv","ℬ":"Bscr","Β":"Beta","β":"beta","ℶ":"beth","≬":"twixt","𝔅":"Bfr","𝔟":"bfr","⋂":"xcap","◯":"xcirc","⋃":"xcup","⨀":"xodot","⨁":"xoplus","⨂":"xotime","⨆":"xsqcup","★":"starf","▽":"xdtri","△":"xutri","⨄":"xuplus","⋁":"Vee","⋀":"Wedge","⤍":"rbarr","⧫":"lozf","▪":"squf","▴":"utrif","▾":"dtrif","◂":"ltrif","▸":"rtrif","␣":"blank","▒":"blk12","░":"blk14","▓":"blk34","█":"block","=⃥":"bne","≡⃥":"bnequiv","⫭":"bNot","⌐":"bnot","𝔹":"Bopf","𝕓":"bopf","⊥":"bot","⋈":"bowtie","⧉":"boxbox","┐":"boxdl","╕":"boxdL","╖":"boxDl","╗":"boxDL","┌":"boxdr","╒":"boxdR","╓":"boxDr","╔":"boxDR","─":"boxh","═":"boxH","┬":"boxhd","╤":"boxHd","╥":"boxhD","╦":"boxHD","┴":"boxhu","╧":"boxHu","╨":"boxhU","╩":"boxHU","⊟":"minusb","⊞":"plusb","⊠":"timesb","┘":"boxul","╛":"boxuL","╜":"boxUl","╝":"boxUL","└":"boxur","╘":"boxuR","╙":"boxUr","╚":"boxUR","│":"boxv","║":"boxV","┼":"boxvh","╪":"boxvH","╫":"boxVh","╬":"boxVH","┤":"boxvl","╡":"boxvL","╢":"boxVl","╣":"boxVL","├":"boxvr","╞":"boxvR","╟":"boxVr","╠":"boxVR","˘":"breve","¦":"brvbar","𝒷":"bscr","⁏":"bsemi","⧅":"bsolb","\\":"bsol","⟈":"bsolhsub","•":"bull","≎":"bump","⪮":"bumpE","≏":"bumpe","Ć":"Cacute","ć":"cacute","⩄":"capand","⩉":"capbrcup","⩋":"capcap","∩":"cap","⋒":"Cap","⩇":"capcup","⩀":"capdot","ⅅ":"DD","∩︀":"caps","⁁":"caret","ˇ":"caron","ℭ":"Cfr","⩍":"ccaps","Č":"Ccaron","č":"ccaron","Ç":"Ccedil","ç":"ccedil","Ĉ":"Ccirc","ĉ":"ccirc","∰":"Cconint","⩌":"ccups","⩐":"ccupssm","Ċ":"Cdot","ċ":"cdot","¸":"cedil","⦲":"cemptyv","¢":"cent","·":"middot","𝔠":"cfr","Ч":"CHcy","ч":"chcy","✓":"check","Χ":"Chi","χ":"chi","ˆ":"circ","≗":"cire","↺":"olarr","↻":"orarr","⊛":"oast","⊚":"ocir","⊝":"odash","⊙":"odot","®":"reg","Ⓢ":"oS","⊖":"ominus","⊕":"oplus","⊗":"otimes","○":"cir","⧃":"cirE","⨐":"cirfnint","⫯":"cirmid","⧂":"cirscir","∲":"cwconint","”":"rdquo","’":"rsquo","♣":"clubs",":":"colon","∷":"Colon","⩴":"Colone",",":"comma","@":"commat","∁":"comp","∘":"compfn","ℂ":"Copf","≅":"cong","⩭":"congdot","≡":"equiv","∮":"oint","∯":"Conint","𝕔":"copf","∐":"coprod","©":"copy","℗":"copysr","↵":"crarr","✗":"cross","⨯":"Cross","𝒞":"Cscr","𝒸":"cscr","⫏":"csub","⫑":"csube","⫐":"csup","⫒":"csupe","⋯":"ctdot","⤸":"cudarrl","⤵":"cudarrr","⋞":"cuepr","⋟":"cuesc","↶":"cularr","⤽":"cularrp","⩈":"cupbrcap","⩆":"cupcap","∪":"cup","⋓":"Cup","⩊":"cupcup","⊍":"cupdot","⩅":"cupor","∪︀":"cups","↷":"curarr","⤼":"curarrm","⋎":"cuvee","⋏":"cuwed","¤":"curren","∱":"cwint","⌭":"cylcty","†":"dagger","‡":"Dagger","ℸ":"daleth","↓":"darr","↡":"Darr","⇓":"dArr","‐":"dash","⫤":"Dashv","⊣":"dashv","⤏":"rBarr","˝":"dblac","Ď":"Dcaron","ď":"dcaron","Д":"Dcy","д":"dcy","⇊":"ddarr","ⅆ":"dd","⤑":"DDotrahd","⩷":"eDDot","°":"deg","∇":"Del","Δ":"Delta","δ":"delta","⦱":"demptyv","⥿":"dfisht","𝔇":"Dfr","𝔡":"dfr","⥥":"dHar","⇃":"dharl","⇂":"dharr","˙":"dot","`":"grave","˜":"tilde","⋄":"diam","♦":"diams","¨":"die","ϝ":"gammad","⋲":"disin","÷":"div","⋇":"divonx","Ђ":"DJcy","ђ":"djcy","⌞":"dlcorn","⌍":"dlcrop",$:"dollar","𝔻":"Dopf","𝕕":"dopf","⃜":"DotDot","≐":"doteq","≑":"eDot","∸":"minusd","∔":"plusdo","⊡":"sdotb","⇐":"lArr","⇔":"iff","⟸":"xlArr","⟺":"xhArr","⟹":"xrArr","⇒":"rArr","⊨":"vDash","⇑":"uArr","⇕":"vArr","∥":"par","⤓":"DownArrowBar","⇵":"duarr","̑":"DownBreve","⥐":"DownLeftRightVector","⥞":"DownLeftTeeVector","⥖":"DownLeftVectorBar","↽":"lhard","⥟":"DownRightTeeVector","⥗":"DownRightVectorBar","⇁":"rhard","↧":"mapstodown","⊤":"top","⤐":"RBarr","⌟":"drcorn","⌌":"drcrop","𝒟":"Dscr","𝒹":"dscr","Ѕ":"DScy","ѕ":"dscy","⧶":"dsol","Đ":"Dstrok","đ":"dstrok","⋱":"dtdot","▿":"dtri","⥯":"duhar","⦦":"dwangle","Џ":"DZcy","џ":"dzcy","⟿":"dzigrarr","É":"Eacute","é":"eacute","⩮":"easter","Ě":"Ecaron","ě":"ecaron","Ê":"Ecirc","ê":"ecirc","≖":"ecir","≕":"ecolon","Э":"Ecy","э":"ecy","Ė":"Edot","ė":"edot","ⅇ":"ee","≒":"efDot","𝔈":"Efr","𝔢":"efr","⪚":"eg","È":"Egrave","è":"egrave","⪖":"egs","⪘":"egsdot","⪙":"el","∈":"in","⏧":"elinters","ℓ":"ell","⪕":"els","⪗":"elsdot","Ē":"Emacr","ē":"emacr","∅":"empty","◻":"EmptySmallSquare","▫":"EmptyVerySmallSquare"," ":"emsp13"," ":"emsp14"," ":"emsp","Ŋ":"ENG","ŋ":"eng"," ":"ensp","Ę":"Eogon","ę":"eogon","𝔼":"Eopf","𝕖":"eopf","⋕":"epar","⧣":"eparsl","⩱":"eplus","ε":"epsi","Ε":"Epsilon","ϵ":"epsiv","≂":"esim","⩵":"Equal","=":"equals","≟":"equest","⇌":"rlhar","⩸":"equivDD","⧥":"eqvparsl","⥱":"erarr","≓":"erDot","ℯ":"escr","ℰ":"Escr","⩳":"Esim","Η":"Eta","η":"eta","Ð":"ETH","ð":"eth","Ë":"Euml","ë":"euml","€":"euro","!":"excl","∃":"exist","Ф":"Fcy","ф":"fcy","♀":"female","ffi":"ffilig","ff":"fflig","ffl":"ffllig","𝔉":"Ffr","𝔣":"ffr","fi":"filig","◼":"FilledSmallSquare",fj:"fjlig","♭":"flat","fl":"fllig","▱":"fltns","ƒ":"fnof","𝔽":"Fopf","𝕗":"fopf","∀":"forall","⋔":"fork","⫙":"forkv","ℱ":"Fscr","⨍":"fpartint","½":"half","⅓":"frac13","¼":"frac14","⅕":"frac15","⅙":"frac16","⅛":"frac18","⅔":"frac23","⅖":"frac25","¾":"frac34","⅗":"frac35","⅜":"frac38","⅘":"frac45","⅚":"frac56","⅝":"frac58","⅞":"frac78","⁄":"frasl","⌢":"frown","𝒻":"fscr","ǵ":"gacute","Γ":"Gamma","γ":"gamma","Ϝ":"Gammad","⪆":"gap","Ğ":"Gbreve","ğ":"gbreve","Ģ":"Gcedil","Ĝ":"Gcirc","ĝ":"gcirc","Г":"Gcy","г":"gcy","Ġ":"Gdot","ġ":"gdot","≥":"ge","≧":"gE","⪌":"gEl","⋛":"gel","⩾":"ges","⪩":"gescc","⪀":"gesdot","⪂":"gesdoto","⪄":"gesdotol","⋛︀":"gesl","⪔":"gesles","𝔊":"Gfr","𝔤":"gfr","≫":"gg","⋙":"Gg","ℷ":"gimel","Ѓ":"GJcy","ѓ":"gjcy","⪥":"gla","≷":"gl","⪒":"glE","⪤":"glj","⪊":"gnap","⪈":"gne","≩":"gnE","⋧":"gnsim","𝔾":"Gopf","𝕘":"gopf","⪢":"GreaterGreater","≳":"gsim","𝒢":"Gscr","ℊ":"gscr","⪎":"gsime","⪐":"gsiml","⪧":"gtcc","⩺":"gtcir",">":"gt","⋗":"gtdot","⦕":"gtlPar","⩼":"gtquest","⥸":"gtrarr","≩︀":"gvnE"," ":"hairsp","ℋ":"Hscr","Ъ":"HARDcy","ъ":"hardcy","⥈":"harrcir","↔":"harr","↭":"harrw","^":"Hat","ℏ":"hbar","Ĥ":"Hcirc","ĥ":"hcirc","♥":"hearts","…":"mldr","⊹":"hercon","𝔥":"hfr","ℌ":"Hfr","⤥":"searhk","⤦":"swarhk","⇿":"hoarr","∻":"homtht","↩":"larrhk","↪":"rarrhk","𝕙":"hopf","ℍ":"Hopf","―":"horbar","𝒽":"hscr","Ħ":"Hstrok","ħ":"hstrok","⁃":"hybull","Í":"Iacute","í":"iacute","⁣":"ic","Î":"Icirc","î":"icirc","И":"Icy","и":"icy","İ":"Idot","Е":"IEcy","е":"iecy","¡":"iexcl","𝔦":"ifr","ℑ":"Im","Ì":"Igrave","ì":"igrave","ⅈ":"ii","⨌":"qint","∭":"tint","⧜":"iinfin","℩":"iiota","IJ":"IJlig","ij":"ijlig","Ī":"Imacr","ī":"imacr","ℐ":"Iscr","ı":"imath","⊷":"imof","Ƶ":"imped","℅":"incare","∞":"infin","⧝":"infintie","⊺":"intcal","∫":"int","∬":"Int","ℤ":"Zopf","⨗":"intlarhk","⨼":"iprod","⁢":"it","Ё":"IOcy","ё":"iocy","Į":"Iogon","į":"iogon","𝕀":"Iopf","𝕚":"iopf","Ι":"Iota","ι":"iota","¿":"iquest","𝒾":"iscr","⋵":"isindot","⋹":"isinE","⋴":"isins","⋳":"isinsv","Ĩ":"Itilde","ĩ":"itilde","І":"Iukcy","і":"iukcy","Ï":"Iuml","ï":"iuml","Ĵ":"Jcirc","ĵ":"jcirc","Й":"Jcy","й":"jcy","𝔍":"Jfr","𝔧":"jfr","ȷ":"jmath","𝕁":"Jopf","𝕛":"jopf","𝒥":"Jscr","𝒿":"jscr","Ј":"Jsercy","ј":"jsercy","Є":"Jukcy","є":"jukcy","Κ":"Kappa","κ":"kappa","ϰ":"kappav","Ķ":"Kcedil","ķ":"kcedil","К":"Kcy","к":"kcy","𝔎":"Kfr","𝔨":"kfr","ĸ":"kgreen","Х":"KHcy","х":"khcy","Ќ":"KJcy","ќ":"kjcy","𝕂":"Kopf","𝕜":"kopf","𝒦":"Kscr","𝓀":"kscr","⇚":"lAarr","Ĺ":"Lacute","ĺ":"lacute","⦴":"laemptyv","ℒ":"Lscr","Λ":"Lambda","λ":"lambda","⟨":"lang","⟪":"Lang","⦑":"langd","⪅":"lap","«":"laquo","⇤":"larrb","⤟":"larrbfs","←":"larr","↞":"Larr","⤝":"larrfs","↫":"larrlp","⤹":"larrpl","⥳":"larrsim","↢":"larrtl","⤙":"latail","⤛":"lAtail","⪫":"lat","⪭":"late","⪭︀":"lates","⤌":"lbarr","⤎":"lBarr","❲":"lbbrk","{":"lcub","[":"lsqb","⦋":"lbrke","⦏":"lbrksld","⦍":"lbrkslu","Ľ":"Lcaron","ľ":"lcaron","Ļ":"Lcedil","ļ":"lcedil","⌈":"lceil","Л":"Lcy","л":"lcy","⤶":"ldca","“":"ldquo","⥧":"ldrdhar","⥋":"ldrushar","↲":"ldsh","≤":"le","≦":"lE","⇆":"lrarr","⟦":"lobrk","⥡":"LeftDownTeeVector","⥙":"LeftDownVectorBar","⌊":"lfloor","↼":"lharu","⇇":"llarr","⇋":"lrhar","⥎":"LeftRightVector","↤":"mapstoleft","⥚":"LeftTeeVector","⋋":"lthree","⧏":"LeftTriangleBar","⊲":"vltri","⊴":"ltrie","⥑":"LeftUpDownVector","⥠":"LeftUpTeeVector","⥘":"LeftUpVectorBar","↿":"uharl","⥒":"LeftVectorBar","⪋":"lEg","⋚":"leg","⩽":"les","⪨":"lescc","⩿":"lesdot","⪁":"lesdoto","⪃":"lesdotor","⋚︀":"lesg","⪓":"lesges","⋖":"ltdot","≶":"lg","⪡":"LessLess","≲":"lsim","⥼":"lfisht","𝔏":"Lfr","𝔩":"lfr","⪑":"lgE","⥢":"lHar","⥪":"lharul","▄":"lhblk","Љ":"LJcy","љ":"ljcy","≪":"ll","⋘":"Ll","⥫":"llhard","◺":"lltri","Ŀ":"Lmidot","ŀ":"lmidot","⎰":"lmoust","⪉":"lnap","⪇":"lne","≨":"lnE","⋦":"lnsim","⟬":"loang","⇽":"loarr","⟵":"xlarr","⟷":"xharr","⟼":"xmap","⟶":"xrarr","↬":"rarrlp","⦅":"lopar","𝕃":"Lopf","𝕝":"lopf","⨭":"loplus","⨴":"lotimes","∗":"lowast",_:"lowbar","↙":"swarr","↘":"searr","◊":"loz","(":"lpar","⦓":"lparlt","⥭":"lrhard","‎":"lrm","⊿":"lrtri","‹":"lsaquo","𝓁":"lscr","↰":"lsh","⪍":"lsime","⪏":"lsimg","‘":"lsquo","‚":"sbquo","Ł":"Lstrok","ł":"lstrok","⪦":"ltcc","⩹":"ltcir","<":"lt","⋉":"ltimes","⥶":"ltlarr","⩻":"ltquest","◃":"ltri","⦖":"ltrPar","⥊":"lurdshar","⥦":"luruhar","≨︀":"lvnE","¯":"macr","♂":"male","✠":"malt","⤅":"Map","↦":"map","↥":"mapstoup","▮":"marker","⨩":"mcomma","М":"Mcy","м":"mcy","—":"mdash","∺":"mDDot"," ":"MediumSpace","ℳ":"Mscr","𝔐":"Mfr","𝔪":"mfr","℧":"mho","µ":"micro","⫰":"midcir","∣":"mid","−":"minus","⨪":"minusdu","∓":"mp","⫛":"mlcp","⊧":"models","𝕄":"Mopf","𝕞":"mopf","𝓂":"mscr","Μ":"Mu","μ":"mu","⊸":"mumap","Ń":"Nacute","ń":"nacute","∠⃒":"nang","≉":"nap","⩰̸":"napE","≋̸":"napid","ʼn":"napos","♮":"natur","ℕ":"Nopf"," ":"nbsp","≎̸":"nbump","≏̸":"nbumpe","⩃":"ncap","Ň":"Ncaron","ň":"ncaron","Ņ":"Ncedil","ņ":"ncedil","≇":"ncong","⩭̸":"ncongdot","⩂":"ncup","Н":"Ncy","н":"ncy","–":"ndash","⤤":"nearhk","↗":"nearr","⇗":"neArr","≠":"ne","≐̸":"nedot","​":"ZeroWidthSpace","≢":"nequiv","⤨":"toea","≂̸":"nesim","\n":"NewLine","∄":"nexist","𝔑":"Nfr","𝔫":"nfr","≧̸":"ngE","≱":"nge","⩾̸":"nges","⋙̸":"nGg","≵":"ngsim","≫⃒":"nGt","≯":"ngt","≫̸":"nGtv","↮":"nharr","⇎":"nhArr","⫲":"nhpar","∋":"ni","⋼":"nis","⋺":"nisd","Њ":"NJcy","њ":"njcy","↚":"nlarr","⇍":"nlArr","‥":"nldr","≦̸":"nlE","≰":"nle","⩽̸":"nles","≮":"nlt","⋘̸":"nLl","≴":"nlsim","≪⃒":"nLt","⋪":"nltri","⋬":"nltrie","≪̸":"nLtv","∤":"nmid","⁠":"NoBreak","𝕟":"nopf","⫬":"Not","¬":"not","≭":"NotCupCap","∦":"npar","∉":"notin","≹":"ntgl","⋵̸":"notindot","⋹̸":"notinE", +"⋷":"notinvb","⋶":"notinvc","⧏̸":"NotLeftTriangleBar","≸":"ntlg","⪢̸":"NotNestedGreaterGreater","⪡̸":"NotNestedLessLess","∌":"notni","⋾":"notnivb","⋽":"notnivc","⊀":"npr","⪯̸":"npre","⋠":"nprcue","⧐̸":"NotRightTriangleBar","⋫":"nrtri","⋭":"nrtrie","⊏̸":"NotSquareSubset","⋢":"nsqsube","⊐̸":"NotSquareSuperset","⋣":"nsqsupe","⊂⃒":"vnsub","⊈":"nsube","⊁":"nsc","⪰̸":"nsce","⋡":"nsccue","≿̸":"NotSucceedsTilde","⊃⃒":"vnsup","⊉":"nsupe","≁":"nsim","≄":"nsime","⫽⃥":"nparsl","∂̸":"npart","⨔":"npolint","⤳̸":"nrarrc","↛":"nrarr","⇏":"nrArr","↝̸":"nrarrw","𝒩":"Nscr","𝓃":"nscr","⊄":"nsub","⫅̸":"nsubE","⊅":"nsup","⫆̸":"nsupE","Ñ":"Ntilde","ñ":"ntilde","Ν":"Nu","ν":"nu","#":"num","№":"numero"," ":"numsp","≍⃒":"nvap","⊬":"nvdash","⊭":"nvDash","⊮":"nVdash","⊯":"nVDash","≥⃒":"nvge",">⃒":"nvgt","⤄":"nvHarr","⧞":"nvinfin","⤂":"nvlArr","≤⃒":"nvle","<⃒":"nvlt","⊴⃒":"nvltrie","⤃":"nvrArr","⊵⃒":"nvrtrie","∼⃒":"nvsim","⤣":"nwarhk","↖":"nwarr","⇖":"nwArr","⤧":"nwnear","Ó":"Oacute","ó":"oacute","Ô":"Ocirc","ô":"ocirc","О":"Ocy","о":"ocy","Ő":"Odblac","ő":"odblac","⨸":"odiv","⦼":"odsold","Œ":"OElig","œ":"oelig","⦿":"ofcir","𝔒":"Ofr","𝔬":"ofr","˛":"ogon","Ò":"Ograve","ò":"ograve","⧁":"ogt","⦵":"ohbar","Ω":"ohm","⦾":"olcir","⦻":"olcross","‾":"oline","⧀":"olt","Ō":"Omacr","ō":"omacr","ω":"omega","Ο":"Omicron","ο":"omicron","⦶":"omid","𝕆":"Oopf","𝕠":"oopf","⦷":"opar","⦹":"operp","⩔":"Or","∨":"or","⩝":"ord","ℴ":"oscr","ª":"ordf","º":"ordm","⊶":"origof","⩖":"oror","⩗":"orslope","⩛":"orv","𝒪":"Oscr","Ø":"Oslash","ø":"oslash","⊘":"osol","Õ":"Otilde","õ":"otilde","⨶":"otimesas","⨷":"Otimes","Ö":"Ouml","ö":"ouml","⌽":"ovbar","⏞":"OverBrace","⎴":"tbrk","⏜":"OverParenthesis","¶":"para","⫳":"parsim","⫽":"parsl","∂":"part","П":"Pcy","п":"pcy","%":"percnt",".":"period","‰":"permil","‱":"pertenk","𝔓":"Pfr","𝔭":"pfr","Φ":"Phi","φ":"phi","ϕ":"phiv","☎":"phone","Π":"Pi","π":"pi","ϖ":"piv","ℎ":"planckh","⨣":"plusacir","⨢":"pluscir","+":"plus","⨥":"plusdu","⩲":"pluse","±":"pm","⨦":"plussim","⨧":"plustwo","⨕":"pointint","𝕡":"popf","ℙ":"Popf","£":"pound","⪷":"prap","⪻":"Pr","≺":"pr","≼":"prcue","⪯":"pre","≾":"prsim","⪹":"prnap","⪵":"prnE","⋨":"prnsim","⪳":"prE","′":"prime","″":"Prime","∏":"prod","⌮":"profalar","⌒":"profline","⌓":"profsurf","∝":"prop","⊰":"prurel","𝒫":"Pscr","𝓅":"pscr","Ψ":"Psi","ψ":"psi"," ":"puncsp","𝔔":"Qfr","𝔮":"qfr","𝕢":"qopf","ℚ":"Qopf","⁗":"qprime","𝒬":"Qscr","𝓆":"qscr","⨖":"quatint","?":"quest",'"':"quot","⇛":"rAarr","∽̱":"race","Ŕ":"Racute","ŕ":"racute","√":"Sqrt","⦳":"raemptyv","⟩":"rang","⟫":"Rang","⦒":"rangd","⦥":"range","»":"raquo","⥵":"rarrap","⇥":"rarrb","⤠":"rarrbfs","⤳":"rarrc","→":"rarr","↠":"Rarr","⤞":"rarrfs","⥅":"rarrpl","⥴":"rarrsim","⤖":"Rarrtl","↣":"rarrtl","↝":"rarrw","⤚":"ratail","⤜":"rAtail","∶":"ratio","❳":"rbbrk","}":"rcub","]":"rsqb","⦌":"rbrke","⦎":"rbrksld","⦐":"rbrkslu","Ř":"Rcaron","ř":"rcaron","Ŗ":"Rcedil","ŗ":"rcedil","⌉":"rceil","Р":"Rcy","р":"rcy","⤷":"rdca","⥩":"rdldhar","↳":"rdsh","ℜ":"Re","ℛ":"Rscr","ℝ":"Ropf","▭":"rect","⥽":"rfisht","⌋":"rfloor","𝔯":"rfr","⥤":"rHar","⇀":"rharu","⥬":"rharul","Ρ":"Rho","ρ":"rho","ϱ":"rhov","⇄":"rlarr","⟧":"robrk","⥝":"RightDownTeeVector","⥕":"RightDownVectorBar","⇉":"rrarr","⊢":"vdash","⥛":"RightTeeVector","⋌":"rthree","⧐":"RightTriangleBar","⊳":"vrtri","⊵":"rtrie","⥏":"RightUpDownVector","⥜":"RightUpTeeVector","⥔":"RightUpVectorBar","↾":"uharr","⥓":"RightVectorBar","˚":"ring","‏":"rlm","⎱":"rmoust","⫮":"rnmid","⟭":"roang","⇾":"roarr","⦆":"ropar","𝕣":"ropf","⨮":"roplus","⨵":"rotimes","⥰":"RoundImplies",")":"rpar","⦔":"rpargt","⨒":"rppolint","›":"rsaquo","𝓇":"rscr","↱":"rsh","⋊":"rtimes","▹":"rtri","⧎":"rtriltri","⧴":"RuleDelayed","⥨":"ruluhar","℞":"rx","Ś":"Sacute","ś":"sacute","⪸":"scap","Š":"Scaron","š":"scaron","⪼":"Sc","≻":"sc","≽":"sccue","⪰":"sce","⪴":"scE","Ş":"Scedil","ş":"scedil","Ŝ":"Scirc","ŝ":"scirc","⪺":"scnap","⪶":"scnE","⋩":"scnsim","⨓":"scpolint","≿":"scsim","С":"Scy","с":"scy","⋅":"sdot","⩦":"sdote","⇘":"seArr","§":"sect",";":"semi","⤩":"tosa","✶":"sext","𝔖":"Sfr","𝔰":"sfr","♯":"sharp","Щ":"SHCHcy","щ":"shchcy","Ш":"SHcy","ш":"shcy","↑":"uarr","­":"shy","Σ":"Sigma","σ":"sigma","ς":"sigmaf","∼":"sim","⩪":"simdot","≃":"sime","⪞":"simg","⪠":"simgE","⪝":"siml","⪟":"simlE","≆":"simne","⨤":"simplus","⥲":"simrarr","⨳":"smashp","⧤":"smeparsl","⌣":"smile","⪪":"smt","⪬":"smte","⪬︀":"smtes","Ь":"SOFTcy","ь":"softcy","⌿":"solbar","⧄":"solb","/":"sol","𝕊":"Sopf","𝕤":"sopf","♠":"spades","⊓":"sqcap","⊓︀":"sqcaps","⊔":"sqcup","⊔︀":"sqcups","⊏":"sqsub","⊑":"sqsube","⊐":"sqsup","⊒":"sqsupe","□":"squ","𝒮":"Sscr","𝓈":"sscr","⋆":"Star","☆":"star","⊂":"sub","⋐":"Sub","⪽":"subdot","⫅":"subE","⊆":"sube","⫃":"subedot","⫁":"submult","⫋":"subnE","⊊":"subne","⪿":"subplus","⥹":"subrarr","⫇":"subsim","⫕":"subsub","⫓":"subsup","∑":"sum","♪":"sung","¹":"sup1","²":"sup2","³":"sup3","⊃":"sup","⋑":"Sup","⪾":"supdot","⫘":"supdsub","⫆":"supE","⊇":"supe","⫄":"supedot","⟉":"suphsol","⫗":"suphsub","⥻":"suplarr","⫂":"supmult","⫌":"supnE","⊋":"supne","⫀":"supplus","⫈":"supsim","⫔":"supsub","⫖":"supsup","⇙":"swArr","⤪":"swnwar","ß":"szlig"," ":"Tab","⌖":"target","Τ":"Tau","τ":"tau","Ť":"Tcaron","ť":"tcaron","Ţ":"Tcedil","ţ":"tcedil","Т":"Tcy","т":"tcy","⃛":"tdot","⌕":"telrec","𝔗":"Tfr","𝔱":"tfr","∴":"there4","Θ":"Theta","θ":"theta","ϑ":"thetav","  ":"ThickSpace"," ":"thinsp","Þ":"THORN","þ":"thorn","⨱":"timesbar","×":"times","⨰":"timesd","⌶":"topbot","⫱":"topcir","𝕋":"Topf","𝕥":"topf","⫚":"topfork","‴":"tprime","™":"trade","▵":"utri","≜":"trie","◬":"tridot","⨺":"triminus","⨹":"triplus","⧍":"trisb","⨻":"tritime","⏢":"trpezium","𝒯":"Tscr","𝓉":"tscr","Ц":"TScy","ц":"tscy","Ћ":"TSHcy","ћ":"tshcy","Ŧ":"Tstrok","ŧ":"tstrok","Ú":"Uacute","ú":"uacute","↟":"Uarr","⥉":"Uarrocir","Ў":"Ubrcy","ў":"ubrcy","Ŭ":"Ubreve","ŭ":"ubreve","Û":"Ucirc","û":"ucirc","У":"Ucy","у":"ucy","⇅":"udarr","Ű":"Udblac","ű":"udblac","⥮":"udhar","⥾":"ufisht","𝔘":"Ufr","𝔲":"ufr","Ù":"Ugrave","ù":"ugrave","⥣":"uHar","▀":"uhblk","⌜":"ulcorn","⌏":"ulcrop","◸":"ultri","Ū":"Umacr","ū":"umacr","⏟":"UnderBrace","⏝":"UnderParenthesis","⊎":"uplus","Ų":"Uogon","ų":"uogon","𝕌":"Uopf","𝕦":"uopf","⤒":"UpArrowBar","↕":"varr","υ":"upsi","ϒ":"Upsi","Υ":"Upsilon","⇈":"uuarr","⌝":"urcorn","⌎":"urcrop","Ů":"Uring","ů":"uring","◹":"urtri","𝒰":"Uscr","𝓊":"uscr","⋰":"utdot","Ũ":"Utilde","ũ":"utilde","Ü":"Uuml","ü":"uuml","⦧":"uwangle","⦜":"vangrt","⊊︀":"vsubne","⫋︀":"vsubnE","⊋︀":"vsupne","⫌︀":"vsupnE","⫨":"vBar","⫫":"Vbar","⫩":"vBarv","В":"Vcy","в":"vcy","⊩":"Vdash","⊫":"VDash","⫦":"Vdashl","⊻":"veebar","≚":"veeeq","⋮":"vellip","|":"vert","‖":"Vert","❘":"VerticalSeparator","≀":"wr","𝔙":"Vfr","𝔳":"vfr","𝕍":"Vopf","𝕧":"vopf","𝒱":"Vscr","𝓋":"vscr","⊪":"Vvdash","⦚":"vzigzag","Ŵ":"Wcirc","ŵ":"wcirc","⩟":"wedbar","≙":"wedgeq","℘":"wp","𝔚":"Wfr","𝔴":"wfr","𝕎":"Wopf","𝕨":"wopf","𝒲":"Wscr","𝓌":"wscr","𝔛":"Xfr","𝔵":"xfr","Ξ":"Xi","ξ":"xi","⋻":"xnis","𝕏":"Xopf","𝕩":"xopf","𝒳":"Xscr","𝓍":"xscr","Ý":"Yacute","ý":"yacute","Я":"YAcy","я":"yacy","Ŷ":"Ycirc","ŷ":"ycirc","Ы":"Ycy","ы":"ycy","¥":"yen","𝔜":"Yfr","𝔶":"yfr","Ї":"YIcy","ї":"yicy","𝕐":"Yopf","𝕪":"yopf","𝒴":"Yscr","𝓎":"yscr","Ю":"YUcy","ю":"yucy","ÿ":"yuml","Ÿ":"Yuml","Ź":"Zacute","ź":"zacute","Ž":"Zcaron","ž":"zcaron","З":"Zcy","з":"zcy","Ż":"Zdot","ż":"zdot","ℨ":"Zfr","Ζ":"Zeta","ζ":"zeta","𝔷":"zfr","Ж":"ZHcy","ж":"zhcy","⇝":"zigrarr","𝕫":"zopf","𝒵":"Zscr","𝓏":"zscr","‍":"zwj","‌":"zwnj"},u=/["&'<>`]/g,h={'"':""","&":"&","'":"'","<":"<",">":">","`":"`"},d=/&#(?:[xX][^a-fA-F0-9]|[^0-9xX])/,p=/[\0-\x08\x0B\x0E-\x1F\x7F-\x9F\uFDD0-\uFDEF\uFFFE\uFFFF]|[\uD83F\uD87F\uD8BF\uD8FF\uD93F\uD97F\uD9BF\uD9FF\uDA3F\uDA7F\uDABF\uDAFF\uDB3F\uDB7F\uDBBF\uDBFF][\uDFFE\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,f=/&#([0-9]+)(;?)|&#[xX]([a-fA-F0-9]+)(;?)|&([0-9a-zA-Z]+);|&(Aacute|iacute|Uacute|plusmn|otilde|Otilde|Agrave|agrave|yacute|Yacute|oslash|Oslash|Atilde|atilde|brvbar|Ccedil|ccedil|ograve|curren|divide|Eacute|eacute|Ograve|oacute|Egrave|egrave|ugrave|frac12|frac14|frac34|Ugrave|Oacute|Iacute|ntilde|Ntilde|uacute|middot|Igrave|igrave|iquest|aacute|laquo|THORN|micro|iexcl|icirc|Icirc|Acirc|ucirc|ecirc|Ocirc|ocirc|Ecirc|Ucirc|aring|Aring|aelig|AElig|acute|pound|raquo|acirc|times|thorn|szlig|cedil|COPY|Auml|ordf|ordm|uuml|macr|Uuml|auml|Ouml|ouml|para|nbsp|Euml|quot|QUOT|euml|yuml|cent|sect|copy|sup1|sup2|sup3|Iuml|iuml|shy|eth|reg|not|yen|amp|AMP|REG|uml|ETH|deg|gt|GT|LT|lt)([=a-zA-Z0-9])?/g,g={Aacute:"Á",aacute:"á",Abreve:"Ă",abreve:"ă",ac:"∾",acd:"∿",acE:"∾̳",Acirc:"Â",acirc:"â",acute:"´",Acy:"А",acy:"а",AElig:"Æ",aelig:"æ",af:"⁡",Afr:"𝔄",afr:"𝔞",Agrave:"À",agrave:"à",alefsym:"ℵ",aleph:"ℵ",Alpha:"Α",alpha:"α",Amacr:"Ā",amacr:"ā",amalg:"⨿",amp:"&",AMP:"&",andand:"⩕",And:"⩓",and:"∧",andd:"⩜",andslope:"⩘",andv:"⩚",ang:"∠",ange:"⦤",angle:"∠",angmsdaa:"⦨",angmsdab:"⦩",angmsdac:"⦪",angmsdad:"⦫",angmsdae:"⦬",angmsdaf:"⦭",angmsdag:"⦮",angmsdah:"⦯",angmsd:"∡",angrt:"∟",angrtvb:"⊾",angrtvbd:"⦝",angsph:"∢",angst:"Å",angzarr:"⍼",Aogon:"Ą",aogon:"ą",Aopf:"𝔸",aopf:"𝕒",apacir:"⩯",ap:"≈",apE:"⩰",ape:"≊",apid:"≋",apos:"'",ApplyFunction:"⁡",approx:"≈",approxeq:"≊",Aring:"Å",aring:"å",Ascr:"𝒜",ascr:"𝒶",Assign:"≔",ast:"*",asymp:"≈",asympeq:"≍",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",awconint:"∳",awint:"⨑",backcong:"≌",backepsilon:"϶",backprime:"‵",backsim:"∽",backsimeq:"⋍",Backslash:"∖",Barv:"⫧",barvee:"⊽",barwed:"⌅",Barwed:"⌆",barwedge:"⌅",bbrk:"⎵",bbrktbrk:"⎶",bcong:"≌",Bcy:"Б",bcy:"б",bdquo:"„",becaus:"∵",because:"∵",Because:"∵",bemptyv:"⦰",bepsi:"϶",bernou:"ℬ",Bernoullis:"ℬ",Beta:"Β",beta:"β",beth:"ℶ",between:"≬",Bfr:"𝔅",bfr:"𝔟",bigcap:"⋂",bigcirc:"◯",bigcup:"⋃",bigodot:"⨀",bigoplus:"⨁",bigotimes:"⨂",bigsqcup:"⨆",bigstar:"★",bigtriangledown:"▽",bigtriangleup:"△",biguplus:"⨄",bigvee:"⋁",bigwedge:"⋀",bkarow:"⤍",blacklozenge:"⧫",blacksquare:"▪",blacktriangle:"▴",blacktriangledown:"▾",blacktriangleleft:"◂",blacktriangleright:"▸",blank:"␣",blk12:"▒",blk14:"░",blk34:"▓",block:"█",bne:"=⃥",bnequiv:"≡⃥",bNot:"⫭",bnot:"⌐",Bopf:"𝔹",bopf:"𝕓",bot:"⊥",bottom:"⊥",bowtie:"⋈",boxbox:"⧉",boxdl:"┐",boxdL:"╕",boxDl:"╖",boxDL:"╗",boxdr:"┌",boxdR:"╒",boxDr:"╓",boxDR:"╔",boxh:"─",boxH:"═",boxhd:"┬",boxHd:"╤",boxhD:"╥",boxHD:"╦",boxhu:"┴",boxHu:"╧",boxhU:"╨",boxHU:"╩",boxminus:"⊟",boxplus:"⊞",boxtimes:"⊠",boxul:"┘",boxuL:"╛",boxUl:"╜",boxUL:"╝",boxur:"└",boxuR:"╘",boxUr:"╙",boxUR:"╚",boxv:"│",boxV:"║",boxvh:"┼",boxvH:"╪",boxVh:"╫",boxVH:"╬",boxvl:"┤",boxvL:"╡",boxVl:"╢",boxVL:"╣",boxvr:"├",boxvR:"╞",boxVr:"╟",boxVR:"╠",bprime:"‵",breve:"˘",Breve:"˘",brvbar:"¦",bscr:"𝒷",Bscr:"ℬ",bsemi:"⁏",bsim:"∽",bsime:"⋍",bsolb:"⧅",bsol:"\\",bsolhsub:"⟈",bull:"•",bullet:"•",bump:"≎",bumpE:"⪮",bumpe:"≏",Bumpeq:"≎",bumpeq:"≏",Cacute:"Ć",cacute:"ć",capand:"⩄",capbrcup:"⩉",capcap:"⩋",cap:"∩",Cap:"⋒",capcup:"⩇",capdot:"⩀",CapitalDifferentialD:"ⅅ",caps:"∩︀",caret:"⁁",caron:"ˇ",Cayleys:"ℭ",ccaps:"⩍",Ccaron:"Č",ccaron:"č",Ccedil:"Ç",ccedil:"ç",Ccirc:"Ĉ",ccirc:"ĉ",Cconint:"∰",ccups:"⩌",ccupssm:"⩐",Cdot:"Ċ",cdot:"ċ",cedil:"¸",Cedilla:"¸",cemptyv:"⦲",cent:"¢",centerdot:"·",CenterDot:"·",cfr:"𝔠",Cfr:"ℭ",CHcy:"Ч",chcy:"ч",check:"✓",checkmark:"✓",Chi:"Χ",chi:"χ",circ:"ˆ",circeq:"≗",circlearrowleft:"↺",circlearrowright:"↻",circledast:"⊛",circledcirc:"⊚",circleddash:"⊝",CircleDot:"⊙",circledR:"®",circledS:"Ⓢ",CircleMinus:"⊖",CirclePlus:"⊕",CircleTimes:"⊗",cir:"○",cirE:"⧃",cire:"≗",cirfnint:"⨐",cirmid:"⫯",cirscir:"⧂",ClockwiseContourIntegral:"∲",CloseCurlyDoubleQuote:"”",CloseCurlyQuote:"’",clubs:"♣",clubsuit:"♣",colon:":",Colon:"∷",Colone:"⩴",colone:"≔",coloneq:"≔",comma:",",commat:"@",comp:"∁",compfn:"∘",complement:"∁",complexes:"ℂ",cong:"≅",congdot:"⩭",Congruent:"≡",conint:"∮",Conint:"∯",ContourIntegral:"∮",copf:"𝕔",Copf:"ℂ",coprod:"∐",Coproduct:"∐",copy:"©",COPY:"©",copysr:"℗",CounterClockwiseContourIntegral:"∳",crarr:"↵",cross:"✗",Cross:"⨯",Cscr:"𝒞",cscr:"𝒸",csub:"⫏",csube:"⫑",csup:"⫐",csupe:"⫒",ctdot:"⋯",cudarrl:"⤸",cudarrr:"⤵",cuepr:"⋞",cuesc:"⋟",cularr:"↶",cularrp:"⤽",cupbrcap:"⩈",cupcap:"⩆",CupCap:"≍",cup:"∪",Cup:"⋓",cupcup:"⩊",cupdot:"⊍",cupor:"⩅",cups:"∪︀",curarr:"↷",curarrm:"⤼",curlyeqprec:"⋞",curlyeqsucc:"⋟",curlyvee:"⋎",curlywedge:"⋏",curren:"¤",curvearrowleft:"↶",curvearrowright:"↷",cuvee:"⋎",cuwed:"⋏",cwconint:"∲",cwint:"∱",cylcty:"⌭",dagger:"†",Dagger:"‡",daleth:"ℸ",darr:"↓",Darr:"↡",dArr:"⇓",dash:"‐",Dashv:"⫤",dashv:"⊣",dbkarow:"⤏",dblac:"˝",Dcaron:"Ď",dcaron:"ď",Dcy:"Д",dcy:"д",ddagger:"‡",ddarr:"⇊",DD:"ⅅ",dd:"ⅆ",DDotrahd:"⤑",ddotseq:"⩷",deg:"°",Del:"∇",Delta:"Δ",delta:"δ",demptyv:"⦱",dfisht:"⥿",Dfr:"𝔇",dfr:"𝔡",dHar:"⥥",dharl:"⇃",dharr:"⇂",DiacriticalAcute:"´",DiacriticalDot:"˙",DiacriticalDoubleAcute:"˝",DiacriticalGrave:"`",DiacriticalTilde:"˜",diam:"⋄",diamond:"⋄",Diamond:"⋄",diamondsuit:"♦",diams:"♦",die:"¨",DifferentialD:"ⅆ",digamma:"ϝ",disin:"⋲",div:"÷",divide:"÷",divideontimes:"⋇",divonx:"⋇",DJcy:"Ђ",djcy:"ђ",dlcorn:"⌞",dlcrop:"⌍",dollar:"$",Dopf:"𝔻",dopf:"𝕕",Dot:"¨",dot:"˙",DotDot:"⃜",doteq:"≐",doteqdot:"≑",DotEqual:"≐",dotminus:"∸",dotplus:"∔",dotsquare:"⊡",doublebarwedge:"⌆",DoubleContourIntegral:"∯",DoubleDot:"¨",DoubleDownArrow:"⇓",DoubleLeftArrow:"⇐",DoubleLeftRightArrow:"⇔",DoubleLeftTee:"⫤",DoubleLongLeftArrow:"⟸",DoubleLongLeftRightArrow:"⟺",DoubleLongRightArrow:"⟹",DoubleRightArrow:"⇒",DoubleRightTee:"⊨",DoubleUpArrow:"⇑",DoubleUpDownArrow:"⇕",DoubleVerticalBar:"∥",DownArrowBar:"⤓",downarrow:"↓",DownArrow:"↓",Downarrow:"⇓",DownArrowUpArrow:"⇵",DownBreve:"̑",downdownarrows:"⇊",downharpoonleft:"⇃",downharpoonright:"⇂",DownLeftRightVector:"⥐",DownLeftTeeVector:"⥞",DownLeftVectorBar:"⥖",DownLeftVector:"↽",DownRightTeeVector:"⥟",DownRightVectorBar:"⥗",DownRightVector:"⇁",DownTeeArrow:"↧",DownTee:"⊤",drbkarow:"⤐",drcorn:"⌟",drcrop:"⌌",Dscr:"𝒟",dscr:"𝒹",DScy:"Ѕ",dscy:"ѕ",dsol:"⧶",Dstrok:"Đ",dstrok:"đ",dtdot:"⋱",dtri:"▿",dtrif:"▾",duarr:"⇵",duhar:"⥯",dwangle:"⦦",DZcy:"Џ",dzcy:"џ",dzigrarr:"⟿",Eacute:"É",eacute:"é",easter:"⩮",Ecaron:"Ě",ecaron:"ě",Ecirc:"Ê",ecirc:"ê",ecir:"≖",ecolon:"≕",Ecy:"Э",ecy:"э",eDDot:"⩷",Edot:"Ė",edot:"ė",eDot:"≑",ee:"ⅇ",efDot:"≒",Efr:"𝔈",efr:"𝔢",eg:"⪚",Egrave:"È",egrave:"è",egs:"⪖",egsdot:"⪘",el:"⪙",Element:"∈",elinters:"⏧",ell:"ℓ",els:"⪕",elsdot:"⪗",Emacr:"Ē",emacr:"ē",empty:"∅",emptyset:"∅",EmptySmallSquare:"◻",emptyv:"∅",EmptyVerySmallSquare:"▫",emsp13:" ",emsp14:" ",emsp:" ",ENG:"Ŋ",eng:"ŋ",ensp:" ",Eogon:"Ę",eogon:"ę",Eopf:"𝔼",eopf:"𝕖",epar:"⋕",eparsl:"⧣",eplus:"⩱",epsi:"ε",Epsilon:"Ε",epsilon:"ε",epsiv:"ϵ",eqcirc:"≖",eqcolon:"≕",eqsim:"≂",eqslantgtr:"⪖",eqslantless:"⪕",Equal:"⩵",equals:"=",EqualTilde:"≂",equest:"≟",Equilibrium:"⇌",equiv:"≡",equivDD:"⩸",eqvparsl:"⧥",erarr:"⥱",erDot:"≓",escr:"ℯ",Escr:"ℰ",esdot:"≐",Esim:"⩳",esim:"≂",Eta:"Η",eta:"η",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",euro:"€",excl:"!",exist:"∃",Exists:"∃",expectation:"ℰ",exponentiale:"ⅇ",ExponentialE:"ⅇ",fallingdotseq:"≒",Fcy:"Ф",fcy:"ф",female:"♀",ffilig:"ffi",fflig:"ff",ffllig:"ffl",Ffr:"𝔉",ffr:"𝔣",filig:"fi",FilledSmallSquare:"◼",FilledVerySmallSquare:"▪",fjlig:"fj",flat:"♭",fllig:"fl",fltns:"▱",fnof:"ƒ",Fopf:"𝔽",fopf:"𝕗",forall:"∀",ForAll:"∀",fork:"⋔",forkv:"⫙",Fouriertrf:"ℱ",fpartint:"⨍",frac12:"½",frac13:"⅓",frac14:"¼",frac15:"⅕",frac16:"⅙",frac18:"⅛",frac23:"⅔",frac25:"⅖",frac34:"¾",frac35:"⅗",frac38:"⅜",frac45:"⅘",frac56:"⅚",frac58:"⅝",frac78:"⅞",frasl:"⁄",frown:"⌢",fscr:"𝒻",Fscr:"ℱ",gacute:"ǵ",Gamma:"Γ",gamma:"γ",Gammad:"Ϝ",gammad:"ϝ",gap:"⪆",Gbreve:"Ğ",gbreve:"ğ",Gcedil:"Ģ",Gcirc:"Ĝ",gcirc:"ĝ",Gcy:"Г",gcy:"г",Gdot:"Ġ",gdot:"ġ",ge:"≥",gE:"≧",gEl:"⪌",gel:"⋛",geq:"≥",geqq:"≧",geqslant:"⩾",gescc:"⪩",ges:"⩾",gesdot:"⪀",gesdoto:"⪂",gesdotol:"⪄",gesl:"⋛︀",gesles:"⪔",Gfr:"𝔊",gfr:"𝔤",gg:"≫",Gg:"⋙",ggg:"⋙",gimel:"ℷ",GJcy:"Ѓ",gjcy:"ѓ",gla:"⪥",gl:"≷",glE:"⪒",glj:"⪤",gnap:"⪊",gnapprox:"⪊",gne:"⪈",gnE:"≩",gneq:"⪈",gneqq:"≩",gnsim:"⋧",Gopf:"𝔾",gopf:"𝕘",grave:"`",GreaterEqual:"≥",GreaterEqualLess:"⋛",GreaterFullEqual:"≧",GreaterGreater:"⪢",GreaterLess:"≷",GreaterSlantEqual:"⩾",GreaterTilde:"≳",Gscr:"𝒢",gscr:"ℊ",gsim:"≳",gsime:"⪎",gsiml:"⪐",gtcc:"⪧",gtcir:"⩺",gt:">",GT:">",Gt:"≫",gtdot:"⋗",gtlPar:"⦕",gtquest:"⩼",gtrapprox:"⪆",gtrarr:"⥸",gtrdot:"⋗",gtreqless:"⋛",gtreqqless:"⪌",gtrless:"≷",gtrsim:"≳",gvertneqq:"≩︀",gvnE:"≩︀",Hacek:"ˇ",hairsp:" ",half:"½",hamilt:"ℋ",HARDcy:"Ъ",hardcy:"ъ",harrcir:"⥈",harr:"↔",hArr:"⇔",harrw:"↭",Hat:"^",hbar:"ℏ",Hcirc:"Ĥ",hcirc:"ĥ",hearts:"♥",heartsuit:"♥",hellip:"…",hercon:"⊹",hfr:"𝔥",Hfr:"ℌ",HilbertSpace:"ℋ",hksearow:"⤥",hkswarow:"⤦",hoarr:"⇿",homtht:"∻",hookleftarrow:"↩",hookrightarrow:"↪",hopf:"𝕙",Hopf:"ℍ",horbar:"―",HorizontalLine:"─",hscr:"𝒽",Hscr:"ℋ",hslash:"ℏ",Hstrok:"Ħ",hstrok:"ħ",HumpDownHump:"≎",HumpEqual:"≏",hybull:"⁃",hyphen:"‐",Iacute:"Í",iacute:"í",ic:"⁣",Icirc:"Î",icirc:"î",Icy:"И",icy:"и",Idot:"İ",IEcy:"Е",iecy:"е",iexcl:"¡",iff:"⇔",ifr:"𝔦",Ifr:"ℑ",Igrave:"Ì",igrave:"ì",ii:"ⅈ",iiiint:"⨌",iiint:"∭",iinfin:"⧜",iiota:"℩",IJlig:"IJ",ijlig:"ij",Imacr:"Ī",imacr:"ī",image:"ℑ",ImaginaryI:"ⅈ",imagline:"ℐ",imagpart:"ℑ",imath:"ı",Im:"ℑ",imof:"⊷",imped:"Ƶ",Implies:"⇒",incare:"℅","in":"∈",infin:"∞",infintie:"⧝",inodot:"ı",intcal:"⊺","int":"∫",Int:"∬",integers:"ℤ",Integral:"∫",intercal:"⊺",Intersection:"⋂",intlarhk:"⨗",intprod:"⨼",InvisibleComma:"⁣",InvisibleTimes:"⁢",IOcy:"Ё",iocy:"ё",Iogon:"Į",iogon:"į",Iopf:"𝕀",iopf:"𝕚",Iota:"Ι",iota:"ι",iprod:"⨼",iquest:"¿",iscr:"𝒾",Iscr:"ℐ",isin:"∈",isindot:"⋵",isinE:"⋹",isins:"⋴",isinsv:"⋳",isinv:"∈",it:"⁢",Itilde:"Ĩ",itilde:"ĩ",Iukcy:"І",iukcy:"і",Iuml:"Ï",iuml:"ï",Jcirc:"Ĵ",jcirc:"ĵ",Jcy:"Й",jcy:"й",Jfr:"𝔍",jfr:"𝔧",jmath:"ȷ",Jopf:"𝕁",jopf:"𝕛",Jscr:"𝒥",jscr:"𝒿",Jsercy:"Ј",jsercy:"ј",Jukcy:"Є",jukcy:"є",Kappa:"Κ",kappa:"κ",kappav:"ϰ",Kcedil:"Ķ",kcedil:"ķ",Kcy:"К",kcy:"к",Kfr:"𝔎",kfr:"𝔨",kgreen:"ĸ",KHcy:"Х",khcy:"х",KJcy:"Ќ",kjcy:"ќ",Kopf:"𝕂",kopf:"𝕜",Kscr:"𝒦",kscr:"𝓀",lAarr:"⇚",Lacute:"Ĺ",lacute:"ĺ",laemptyv:"⦴",lagran:"ℒ",Lambda:"Λ",lambda:"λ",lang:"⟨",Lang:"⟪",langd:"⦑",langle:"⟨",lap:"⪅",Laplacetrf:"ℒ",laquo:"«",larrb:"⇤",larrbfs:"⤟",larr:"←",Larr:"↞",lArr:"⇐",larrfs:"⤝",larrhk:"↩",larrlp:"↫",larrpl:"⤹",larrsim:"⥳",larrtl:"↢",latail:"⤙",lAtail:"⤛",lat:"⪫",late:"⪭",lates:"⪭︀",lbarr:"⤌",lBarr:"⤎",lbbrk:"❲",lbrace:"{",lbrack:"[",lbrke:"⦋",lbrksld:"⦏",lbrkslu:"⦍",Lcaron:"Ľ",lcaron:"ľ",Lcedil:"Ļ",lcedil:"ļ",lceil:"⌈",lcub:"{",Lcy:"Л",lcy:"л",ldca:"⤶",ldquo:"“",ldquor:"„",ldrdhar:"⥧",ldrushar:"⥋",ldsh:"↲",le:"≤",lE:"≦",LeftAngleBracket:"⟨",LeftArrowBar:"⇤",leftarrow:"←",LeftArrow:"←",Leftarrow:"⇐",LeftArrowRightArrow:"⇆",leftarrowtail:"↢",LeftCeiling:"⌈",LeftDoubleBracket:"⟦",LeftDownTeeVector:"⥡",LeftDownVectorBar:"⥙",LeftDownVector:"⇃",LeftFloor:"⌊",leftharpoondown:"↽",leftharpoonup:"↼",leftleftarrows:"⇇",leftrightarrow:"↔",LeftRightArrow:"↔",Leftrightarrow:"⇔",leftrightarrows:"⇆",leftrightharpoons:"⇋",leftrightsquigarrow:"↭",LeftRightVector:"⥎",LeftTeeArrow:"↤",LeftTee:"⊣",LeftTeeVector:"⥚",leftthreetimes:"⋋",LeftTriangleBar:"⧏",LeftTriangle:"⊲",LeftTriangleEqual:"⊴",LeftUpDownVector:"⥑",LeftUpTeeVector:"⥠",LeftUpVectorBar:"⥘",LeftUpVector:"↿",LeftVectorBar:"⥒",LeftVector:"↼",lEg:"⪋",leg:"⋚",leq:"≤",leqq:"≦",leqslant:"⩽",lescc:"⪨",les:"⩽",lesdot:"⩿",lesdoto:"⪁",lesdotor:"⪃",lesg:"⋚︀",lesges:"⪓",lessapprox:"⪅",lessdot:"⋖",lesseqgtr:"⋚",lesseqqgtr:"⪋",LessEqualGreater:"⋚",LessFullEqual:"≦",LessGreater:"≶",lessgtr:"≶",LessLess:"⪡",lesssim:"≲",LessSlantEqual:"⩽",LessTilde:"≲",lfisht:"⥼",lfloor:"⌊",Lfr:"𝔏",lfr:"𝔩",lg:"≶",lgE:"⪑",lHar:"⥢",lhard:"↽",lharu:"↼",lharul:"⥪",lhblk:"▄",LJcy:"Љ",ljcy:"љ",llarr:"⇇",ll:"≪",Ll:"⋘",llcorner:"⌞",Lleftarrow:"⇚",llhard:"⥫",lltri:"◺",Lmidot:"Ŀ",lmidot:"ŀ",lmoustache:"⎰",lmoust:"⎰",lnap:"⪉",lnapprox:"⪉",lne:"⪇",lnE:"≨",lneq:"⪇",lneqq:"≨",lnsim:"⋦",loang:"⟬",loarr:"⇽",lobrk:"⟦",longleftarrow:"⟵",LongLeftArrow:"⟵",Longleftarrow:"⟸",longleftrightarrow:"⟷",LongLeftRightArrow:"⟷",Longleftrightarrow:"⟺",longmapsto:"⟼",longrightarrow:"⟶",LongRightArrow:"⟶",Longrightarrow:"⟹",looparrowleft:"↫",looparrowright:"↬",lopar:"⦅",Lopf:"𝕃",lopf:"𝕝",loplus:"⨭",lotimes:"⨴",lowast:"∗",lowbar:"_",LowerLeftArrow:"↙",LowerRightArrow:"↘",loz:"◊",lozenge:"◊",lozf:"⧫",lpar:"(",lparlt:"⦓",lrarr:"⇆",lrcorner:"⌟",lrhar:"⇋",lrhard:"⥭",lrm:"‎",lrtri:"⊿",lsaquo:"‹",lscr:"𝓁",Lscr:"ℒ",lsh:"↰",Lsh:"↰",lsim:"≲",lsime:"⪍",lsimg:"⪏",lsqb:"[",lsquo:"‘",lsquor:"‚",Lstrok:"Ł",lstrok:"ł",ltcc:"⪦",ltcir:"⩹",lt:"<",LT:"<",Lt:"≪",ltdot:"⋖",lthree:"⋋",ltimes:"⋉",ltlarr:"⥶",ltquest:"⩻",ltri:"◃",ltrie:"⊴",ltrif:"◂",ltrPar:"⦖",lurdshar:"⥊",luruhar:"⥦",lvertneqq:"≨︀",lvnE:"≨︀",macr:"¯",male:"♂",malt:"✠",maltese:"✠",Map:"⤅",map:"↦",mapsto:"↦",mapstodown:"↧",mapstoleft:"↤",mapstoup:"↥",marker:"▮",mcomma:"⨩",Mcy:"М",mcy:"м",mdash:"—",mDDot:"∺",measuredangle:"∡",MediumSpace:" ",Mellintrf:"ℳ",Mfr:"𝔐",mfr:"𝔪",mho:"℧",micro:"µ",midast:"*",midcir:"⫰",mid:"∣",middot:"·",minusb:"⊟",minus:"−",minusd:"∸",minusdu:"⨪",MinusPlus:"∓",mlcp:"⫛",mldr:"…",mnplus:"∓",models:"⊧",Mopf:"𝕄",mopf:"𝕞",mp:"∓",mscr:"𝓂",Mscr:"ℳ",mstpos:"∾",Mu:"Μ",mu:"μ",multimap:"⊸",mumap:"⊸",nabla:"∇",Nacute:"Ń",nacute:"ń",nang:"∠⃒",nap:"≉",napE:"⩰̸",napid:"≋̸",napos:"ʼn",napprox:"≉",natural:"♮",naturals:"ℕ",natur:"♮",nbsp:" ",nbump:"≎̸",nbumpe:"≏̸",ncap:"⩃",Ncaron:"Ň",ncaron:"ň",Ncedil:"Ņ",ncedil:"ņ",ncong:"≇",ncongdot:"⩭̸",ncup:"⩂",Ncy:"Н",ncy:"н",ndash:"–",nearhk:"⤤",nearr:"↗",neArr:"⇗",nearrow:"↗",ne:"≠",nedot:"≐̸",NegativeMediumSpace:"​",NegativeThickSpace:"​",NegativeThinSpace:"​",NegativeVeryThinSpace:"​",nequiv:"≢",nesear:"⤨",nesim:"≂̸",NestedGreaterGreater:"≫",NestedLessLess:"≪",NewLine:"\n",nexist:"∄",nexists:"∄",Nfr:"𝔑",nfr:"𝔫",ngE:"≧̸",nge:"≱",ngeq:"≱",ngeqq:"≧̸",ngeqslant:"⩾̸",nges:"⩾̸",nGg:"⋙̸",ngsim:"≵",nGt:"≫⃒",ngt:"≯",ngtr:"≯",nGtv:"≫̸",nharr:"↮",nhArr:"⇎",nhpar:"⫲",ni:"∋",nis:"⋼",nisd:"⋺",niv:"∋",NJcy:"Њ",njcy:"њ",nlarr:"↚",nlArr:"⇍",nldr:"‥",nlE:"≦̸",nle:"≰",nleftarrow:"↚",nLeftarrow:"⇍",nleftrightarrow:"↮",nLeftrightarrow:"⇎",nleq:"≰",nleqq:"≦̸",nleqslant:"⩽̸",nles:"⩽̸",nless:"≮",nLl:"⋘̸",nlsim:"≴",nLt:"≪⃒",nlt:"≮",nltri:"⋪",nltrie:"⋬",nLtv:"≪̸",nmid:"∤",NoBreak:"⁠",NonBreakingSpace:" ",nopf:"𝕟",Nopf:"ℕ",Not:"⫬",not:"¬",NotCongruent:"≢",NotCupCap:"≭",NotDoubleVerticalBar:"∦",NotElement:"∉",NotEqual:"≠",NotEqualTilde:"≂̸",NotExists:"∄",NotGreater:"≯",NotGreaterEqual:"≱",NotGreaterFullEqual:"≧̸",NotGreaterGreater:"≫̸",NotGreaterLess:"≹",NotGreaterSlantEqual:"⩾̸",NotGreaterTilde:"≵",NotHumpDownHump:"≎̸",NotHumpEqual:"≏̸",notin:"∉",notindot:"⋵̸",notinE:"⋹̸",notinva:"∉",notinvb:"⋷",notinvc:"⋶",NotLeftTriangleBar:"⧏̸",NotLeftTriangle:"⋪",NotLeftTriangleEqual:"⋬",NotLess:"≮",NotLessEqual:"≰",NotLessGreater:"≸",NotLessLess:"≪̸",NotLessSlantEqual:"⩽̸",NotLessTilde:"≴",NotNestedGreaterGreater:"⪢̸",NotNestedLessLess:"⪡̸",notni:"∌",notniva:"∌",notnivb:"⋾",notnivc:"⋽",NotPrecedes:"⊀",NotPrecedesEqual:"⪯̸",NotPrecedesSlantEqual:"⋠",NotReverseElement:"∌",NotRightTriangleBar:"⧐̸",NotRightTriangle:"⋫",NotRightTriangleEqual:"⋭",NotSquareSubset:"⊏̸",NotSquareSubsetEqual:"⋢",NotSquareSuperset:"⊐̸",NotSquareSupersetEqual:"⋣",NotSubset:"⊂⃒",NotSubsetEqual:"⊈",NotSucceeds:"⊁",NotSucceedsEqual:"⪰̸",NotSucceedsSlantEqual:"⋡",NotSucceedsTilde:"≿̸",NotSuperset:"⊃⃒",NotSupersetEqual:"⊉",NotTilde:"≁",NotTildeEqual:"≄",NotTildeFullEqual:"≇",NotTildeTilde:"≉",NotVerticalBar:"∤",nparallel:"∦",npar:"∦",nparsl:"⫽⃥",npart:"∂̸",npolint:"⨔",npr:"⊀",nprcue:"⋠",nprec:"⊀",npreceq:"⪯̸",npre:"⪯̸",nrarrc:"⤳̸",nrarr:"↛",nrArr:"⇏",nrarrw:"↝̸",nrightarrow:"↛",nRightarrow:"⇏",nrtri:"⋫",nrtrie:"⋭",nsc:"⊁",nsccue:"⋡",nsce:"⪰̸",Nscr:"𝒩",nscr:"𝓃",nshortmid:"∤",nshortparallel:"∦",nsim:"≁",nsime:"≄",nsimeq:"≄",nsmid:"∤",nspar:"∦",nsqsube:"⋢",nsqsupe:"⋣",nsub:"⊄",nsubE:"⫅̸",nsube:"⊈",nsubset:"⊂⃒",nsubseteq:"⊈",nsubseteqq:"⫅̸",nsucc:"⊁",nsucceq:"⪰̸",nsup:"⊅",nsupE:"⫆̸",nsupe:"⊉",nsupset:"⊃⃒",nsupseteq:"⊉",nsupseteqq:"⫆̸",ntgl:"≹",Ntilde:"Ñ",ntilde:"ñ",ntlg:"≸",ntriangleleft:"⋪",ntrianglelefteq:"⋬",ntriangleright:"⋫",ntrianglerighteq:"⋭",Nu:"Ν",nu:"ν",num:"#",numero:"№",numsp:" ",nvap:"≍⃒",nvdash:"⊬",nvDash:"⊭",nVdash:"⊮",nVDash:"⊯",nvge:"≥⃒",nvgt:">⃒",nvHarr:"⤄",nvinfin:"⧞",nvlArr:"⤂",nvle:"≤⃒",nvlt:"<⃒",nvltrie:"⊴⃒",nvrArr:"⤃",nvrtrie:"⊵⃒",nvsim:"∼⃒",nwarhk:"⤣",nwarr:"↖",nwArr:"⇖",nwarrow:"↖",nwnear:"⤧",Oacute:"Ó",oacute:"ó",oast:"⊛",Ocirc:"Ô",ocirc:"ô",ocir:"⊚",Ocy:"О",ocy:"о",odash:"⊝",Odblac:"Ő",odblac:"ő",odiv:"⨸",odot:"⊙",odsold:"⦼",OElig:"Œ",oelig:"œ",ofcir:"⦿",Ofr:"𝔒",ofr:"𝔬",ogon:"˛",Ograve:"Ò",ograve:"ò",ogt:"⧁",ohbar:"⦵",ohm:"Ω",oint:"∮",olarr:"↺",olcir:"⦾",olcross:"⦻",oline:"‾",olt:"⧀",Omacr:"Ō",omacr:"ō",Omega:"Ω",omega:"ω",Omicron:"Ο",omicron:"ο",omid:"⦶",ominus:"⊖",Oopf:"𝕆",oopf:"𝕠",opar:"⦷",OpenCurlyDoubleQuote:"“",OpenCurlyQuote:"‘",operp:"⦹",oplus:"⊕",orarr:"↻",Or:"⩔",or:"∨",ord:"⩝",order:"ℴ",orderof:"ℴ",ordf:"ª",ordm:"º",origof:"⊶",oror:"⩖",orslope:"⩗",orv:"⩛",oS:"Ⓢ",Oscr:"𝒪",oscr:"ℴ",Oslash:"Ø",oslash:"ø",osol:"⊘",Otilde:"Õ",otilde:"õ",otimesas:"⨶",Otimes:"⨷",otimes:"⊗",Ouml:"Ö",ouml:"ö",ovbar:"⌽",OverBar:"‾",OverBrace:"⏞",OverBracket:"⎴",OverParenthesis:"⏜",para:"¶",parallel:"∥",par:"∥",parsim:"⫳",parsl:"⫽",part:"∂",PartialD:"∂",Pcy:"П",pcy:"п",percnt:"%",period:".",permil:"‰",perp:"⊥",pertenk:"‱",Pfr:"𝔓",pfr:"𝔭",Phi:"Φ",phi:"φ",phiv:"ϕ",phmmat:"ℳ",phone:"☎",Pi:"Π",pi:"π",pitchfork:"⋔",piv:"ϖ",planck:"ℏ",planckh:"ℎ",plankv:"ℏ",plusacir:"⨣",plusb:"⊞",pluscir:"⨢",plus:"+",plusdo:"∔",plusdu:"⨥",pluse:"⩲",PlusMinus:"±",plusmn:"±",plussim:"⨦",plustwo:"⨧",pm:"±",Poincareplane:"ℌ",pointint:"⨕",popf:"𝕡",Popf:"ℙ",pound:"£",prap:"⪷",Pr:"⪻",pr:"≺",prcue:"≼",precapprox:"⪷",prec:"≺",preccurlyeq:"≼",Precedes:"≺",PrecedesEqual:"⪯",PrecedesSlantEqual:"≼",PrecedesTilde:"≾",preceq:"⪯",precnapprox:"⪹",precneqq:"⪵",precnsim:"⋨",pre:"⪯",prE:"⪳",precsim:"≾",prime:"′",Prime:"″",primes:"ℙ",prnap:"⪹",prnE:"⪵",prnsim:"⋨",prod:"∏",Product:"∏",profalar:"⌮",profline:"⌒",profsurf:"⌓",prop:"∝",Proportional:"∝",Proportion:"∷",propto:"∝",prsim:"≾",prurel:"⊰",Pscr:"𝒫",pscr:"𝓅",Psi:"Ψ",psi:"ψ",puncsp:" ",Qfr:"𝔔",qfr:"𝔮",qint:"⨌",qopf:"𝕢",Qopf:"ℚ",qprime:"⁗",Qscr:"𝒬",qscr:"𝓆",quaternions:"ℍ",quatint:"⨖",quest:"?",questeq:"≟",quot:'"',QUOT:'"',rAarr:"⇛",race:"∽̱",Racute:"Ŕ",racute:"ŕ",radic:"√",raemptyv:"⦳",rang:"⟩",Rang:"⟫",rangd:"⦒",range:"⦥",rangle:"⟩",raquo:"»",rarrap:"⥵",rarrb:"⇥",rarrbfs:"⤠",rarrc:"⤳",rarr:"→",Rarr:"↠",rArr:"⇒",rarrfs:"⤞",rarrhk:"↪",rarrlp:"↬",rarrpl:"⥅",rarrsim:"⥴",Rarrtl:"⤖",rarrtl:"↣",rarrw:"↝",ratail:"⤚",rAtail:"⤜",ratio:"∶",rationals:"ℚ",rbarr:"⤍",rBarr:"⤏",RBarr:"⤐",rbbrk:"❳",rbrace:"}",rbrack:"]",rbrke:"⦌",rbrksld:"⦎",rbrkslu:"⦐",Rcaron:"Ř",rcaron:"ř",Rcedil:"Ŗ",rcedil:"ŗ",rceil:"⌉",rcub:"}",Rcy:"Р",rcy:"р",rdca:"⤷",rdldhar:"⥩",rdquo:"”",rdquor:"”",rdsh:"↳",real:"ℜ",realine:"ℛ",realpart:"ℜ",reals:"ℝ",Re:"ℜ",rect:"▭",reg:"®",REG:"®",ReverseElement:"∋",ReverseEquilibrium:"⇋",ReverseUpEquilibrium:"⥯",rfisht:"⥽",rfloor:"⌋",rfr:"𝔯",Rfr:"ℜ",rHar:"⥤",rhard:"⇁",rharu:"⇀",rharul:"⥬",Rho:"Ρ",rho:"ρ",rhov:"ϱ",RightAngleBracket:"⟩",RightArrowBar:"⇥",rightarrow:"→",RightArrow:"→",Rightarrow:"⇒",RightArrowLeftArrow:"⇄",rightarrowtail:"↣",RightCeiling:"⌉",RightDoubleBracket:"⟧",RightDownTeeVector:"⥝",RightDownVectorBar:"⥕",RightDownVector:"⇂",RightFloor:"⌋",rightharpoondown:"⇁",rightharpoonup:"⇀",rightleftarrows:"⇄",rightleftharpoons:"⇌",rightrightarrows:"⇉",rightsquigarrow:"↝",RightTeeArrow:"↦",RightTee:"⊢",RightTeeVector:"⥛",rightthreetimes:"⋌",RightTriangleBar:"⧐",RightTriangle:"⊳",RightTriangleEqual:"⊵",RightUpDownVector:"⥏",RightUpTeeVector:"⥜",RightUpVectorBar:"⥔",RightUpVector:"↾",RightVectorBar:"⥓",RightVector:"⇀",ring:"˚",risingdotseq:"≓",rlarr:"⇄",rlhar:"⇌",rlm:"‏",rmoustache:"⎱",rmoust:"⎱",rnmid:"⫮",roang:"⟭",roarr:"⇾",robrk:"⟧",ropar:"⦆",ropf:"𝕣",Ropf:"ℝ",roplus:"⨮",rotimes:"⨵",RoundImplies:"⥰",rpar:")",rpargt:"⦔",rppolint:"⨒",rrarr:"⇉",Rrightarrow:"⇛",rsaquo:"›",rscr:"𝓇",Rscr:"ℛ",rsh:"↱",Rsh:"↱",rsqb:"]",rsquo:"’",rsquor:"’",rthree:"⋌",rtimes:"⋊",rtri:"▹",rtrie:"⊵",rtrif:"▸",rtriltri:"⧎",RuleDelayed:"⧴",ruluhar:"⥨",rx:"℞",Sacute:"Ś",sacute:"ś",sbquo:"‚",scap:"⪸",Scaron:"Š",scaron:"š",Sc:"⪼",sc:"≻",sccue:"≽",sce:"⪰",scE:"⪴",Scedil:"Ş",scedil:"ş",Scirc:"Ŝ",scirc:"ŝ",scnap:"⪺",scnE:"⪶",scnsim:"⋩",scpolint:"⨓",scsim:"≿",Scy:"С",scy:"с",sdotb:"⊡",sdot:"⋅",sdote:"⩦",searhk:"⤥",searr:"↘",seArr:"⇘",searrow:"↘",sect:"§",semi:";",seswar:"⤩",setminus:"∖",setmn:"∖",sext:"✶",Sfr:"𝔖",sfr:"𝔰",sfrown:"⌢",sharp:"♯",SHCHcy:"Щ",shchcy:"щ",SHcy:"Ш",shcy:"ш",ShortDownArrow:"↓",ShortLeftArrow:"←",shortmid:"∣",shortparallel:"∥",ShortRightArrow:"→",ShortUpArrow:"↑",shy:"­",Sigma:"Σ",sigma:"σ",sigmaf:"ς",sigmav:"ς",sim:"∼",simdot:"⩪",sime:"≃",simeq:"≃",simg:"⪞",simgE:"⪠",siml:"⪝",simlE:"⪟",simne:"≆",simplus:"⨤",simrarr:"⥲",slarr:"←",SmallCircle:"∘",smallsetminus:"∖",smashp:"⨳",smeparsl:"⧤",smid:"∣",smile:"⌣",smt:"⪪",smte:"⪬",smtes:"⪬︀",SOFTcy:"Ь",softcy:"ь",solbar:"⌿",solb:"⧄",sol:"/",Sopf:"𝕊",sopf:"𝕤",spades:"♠",spadesuit:"♠",spar:"∥",sqcap:"⊓",sqcaps:"⊓︀",sqcup:"⊔",sqcups:"⊔︀",Sqrt:"√",sqsub:"⊏",sqsube:"⊑",sqsubset:"⊏",sqsubseteq:"⊑",sqsup:"⊐",sqsupe:"⊒",sqsupset:"⊐",sqsupseteq:"⊒",square:"□",Square:"□",SquareIntersection:"⊓",SquareSubset:"⊏",SquareSubsetEqual:"⊑",SquareSuperset:"⊐",SquareSupersetEqual:"⊒",SquareUnion:"⊔",squarf:"▪",squ:"□",squf:"▪",srarr:"→",Sscr:"𝒮",sscr:"𝓈",ssetmn:"∖",ssmile:"⌣",sstarf:"⋆",Star:"⋆",star:"☆",starf:"★",straightepsilon:"ϵ",straightphi:"ϕ",strns:"¯",sub:"⊂",Sub:"⋐",subdot:"⪽",subE:"⫅",sube:"⊆",subedot:"⫃",submult:"⫁",subnE:"⫋",subne:"⊊",subplus:"⪿",subrarr:"⥹",subset:"⊂",Subset:"⋐",subseteq:"⊆",subseteqq:"⫅",SubsetEqual:"⊆",subsetneq:"⊊",subsetneqq:"⫋",subsim:"⫇",subsub:"⫕",subsup:"⫓",succapprox:"⪸",succ:"≻",succcurlyeq:"≽",Succeeds:"≻",SucceedsEqual:"⪰",SucceedsSlantEqual:"≽",SucceedsTilde:"≿",succeq:"⪰",succnapprox:"⪺",succneqq:"⪶",succnsim:"⋩",succsim:"≿",SuchThat:"∋",sum:"∑",Sum:"∑",sung:"♪",sup1:"¹",sup2:"²",sup3:"³",sup:"⊃",Sup:"⋑",supdot:"⪾",supdsub:"⫘",supE:"⫆",supe:"⊇",supedot:"⫄",Superset:"⊃",SupersetEqual:"⊇",suphsol:"⟉",suphsub:"⫗",suplarr:"⥻",supmult:"⫂",supnE:"⫌",supne:"⊋",supplus:"⫀",supset:"⊃",Supset:"⋑",supseteq:"⊇",supseteqq:"⫆",supsetneq:"⊋",supsetneqq:"⫌",supsim:"⫈",supsub:"⫔",supsup:"⫖",swarhk:"⤦",swarr:"↙",swArr:"⇙",swarrow:"↙",swnwar:"⤪",szlig:"ß",Tab:" ",target:"⌖",Tau:"Τ",tau:"τ",tbrk:"⎴",Tcaron:"Ť",tcaron:"ť",Tcedil:"Ţ",tcedil:"ţ",Tcy:"Т",tcy:"т",tdot:"⃛",telrec:"⌕",Tfr:"𝔗",tfr:"𝔱",there4:"∴",therefore:"∴",Therefore:"∴",Theta:"Θ",theta:"θ",thetasym:"ϑ",thetav:"ϑ",thickapprox:"≈",thicksim:"∼",ThickSpace:"  ",ThinSpace:" ",thinsp:" ",thkap:"≈",thksim:"∼",THORN:"Þ",thorn:"þ",tilde:"˜",Tilde:"∼",TildeEqual:"≃",TildeFullEqual:"≅",TildeTilde:"≈",timesbar:"⨱",timesb:"⊠",times:"×",timesd:"⨰",tint:"∭",toea:"⤨",topbot:"⌶",topcir:"⫱",top:"⊤",Topf:"𝕋",topf:"𝕥",topfork:"⫚",tosa:"⤩",tprime:"‴",trade:"™",TRADE:"™",triangle:"▵",triangledown:"▿",triangleleft:"◃",trianglelefteq:"⊴",triangleq:"≜",triangleright:"▹",trianglerighteq:"⊵",tridot:"◬",trie:"≜",triminus:"⨺",TripleDot:"⃛",triplus:"⨹",trisb:"⧍",tritime:"⨻",trpezium:"⏢",Tscr:"𝒯",tscr:"𝓉",TScy:"Ц",tscy:"ц",TSHcy:"Ћ",tshcy:"ћ",Tstrok:"Ŧ",tstrok:"ŧ",twixt:"≬",twoheadleftarrow:"↞",twoheadrightarrow:"↠",Uacute:"Ú",uacute:"ú",uarr:"↑",Uarr:"↟",uArr:"⇑",Uarrocir:"⥉",Ubrcy:"Ў",ubrcy:"ў",Ubreve:"Ŭ",ubreve:"ŭ",Ucirc:"Û",ucirc:"û",Ucy:"У",ucy:"у",udarr:"⇅",Udblac:"Ű",udblac:"ű",udhar:"⥮",ufisht:"⥾",Ufr:"𝔘",ufr:"𝔲",Ugrave:"Ù",ugrave:"ù",uHar:"⥣",uharl:"↿",uharr:"↾",uhblk:"▀",ulcorn:"⌜",ulcorner:"⌜",ulcrop:"⌏",ultri:"◸",Umacr:"Ū",umacr:"ū",uml:"¨",UnderBar:"_",UnderBrace:"⏟",UnderBracket:"⎵",UnderParenthesis:"⏝",Union:"⋃",UnionPlus:"⊎",Uogon:"Ų",uogon:"ų",Uopf:"𝕌",uopf:"𝕦",UpArrowBar:"⤒",uparrow:"↑",UpArrow:"↑",Uparrow:"⇑",UpArrowDownArrow:"⇅",updownarrow:"↕",UpDownArrow:"↕",Updownarrow:"⇕",UpEquilibrium:"⥮",upharpoonleft:"↿",upharpoonright:"↾",uplus:"⊎",UpperLeftArrow:"↖",UpperRightArrow:"↗",upsi:"υ",Upsi:"ϒ",upsih:"ϒ",Upsilon:"Υ",upsilon:"υ",UpTeeArrow:"↥",UpTee:"⊥",upuparrows:"⇈",urcorn:"⌝",urcorner:"⌝",urcrop:"⌎",Uring:"Ů",uring:"ů",urtri:"◹",Uscr:"𝒰",uscr:"𝓊",utdot:"⋰",Utilde:"Ũ",utilde:"ũ",utri:"▵",utrif:"▴",uuarr:"⇈",Uuml:"Ü",uuml:"ü",uwangle:"⦧",vangrt:"⦜",varepsilon:"ϵ",varkappa:"ϰ",varnothing:"∅",varphi:"ϕ",varpi:"ϖ",varpropto:"∝",varr:"↕",vArr:"⇕",varrho:"ϱ",varsigma:"ς",varsubsetneq:"⊊︀",varsubsetneqq:"⫋︀",varsupsetneq:"⊋︀",varsupsetneqq:"⫌︀",vartheta:"ϑ",vartriangleleft:"⊲",vartriangleright:"⊳", +vBar:"⫨",Vbar:"⫫",vBarv:"⫩",Vcy:"В",vcy:"в",vdash:"⊢",vDash:"⊨",Vdash:"⊩",VDash:"⊫",Vdashl:"⫦",veebar:"⊻",vee:"∨",Vee:"⋁",veeeq:"≚",vellip:"⋮",verbar:"|",Verbar:"‖",vert:"|",Vert:"‖",VerticalBar:"∣",VerticalLine:"|",VerticalSeparator:"❘",VerticalTilde:"≀",VeryThinSpace:" ",Vfr:"𝔙",vfr:"𝔳",vltri:"⊲",vnsub:"⊂⃒",vnsup:"⊃⃒",Vopf:"𝕍",vopf:"𝕧",vprop:"∝",vrtri:"⊳",Vscr:"𝒱",vscr:"𝓋",vsubnE:"⫋︀",vsubne:"⊊︀",vsupnE:"⫌︀",vsupne:"⊋︀",Vvdash:"⊪",vzigzag:"⦚",Wcirc:"Ŵ",wcirc:"ŵ",wedbar:"⩟",wedge:"∧",Wedge:"⋀",wedgeq:"≙",weierp:"℘",Wfr:"𝔚",wfr:"𝔴",Wopf:"𝕎",wopf:"𝕨",wp:"℘",wr:"≀",wreath:"≀",Wscr:"𝒲",wscr:"𝓌",xcap:"⋂",xcirc:"◯",xcup:"⋃",xdtri:"▽",Xfr:"𝔛",xfr:"𝔵",xharr:"⟷",xhArr:"⟺",Xi:"Ξ",xi:"ξ",xlarr:"⟵",xlArr:"⟸",xmap:"⟼",xnis:"⋻",xodot:"⨀",Xopf:"𝕏",xopf:"𝕩",xoplus:"⨁",xotime:"⨂",xrarr:"⟶",xrArr:"⟹",Xscr:"𝒳",xscr:"𝓍",xsqcup:"⨆",xuplus:"⨄",xutri:"△",xvee:"⋁",xwedge:"⋀",Yacute:"Ý",yacute:"ý",YAcy:"Я",yacy:"я",Ycirc:"Ŷ",ycirc:"ŷ",Ycy:"Ы",ycy:"ы",yen:"¥",Yfr:"𝔜",yfr:"𝔶",YIcy:"Ї",yicy:"ї",Yopf:"𝕐",yopf:"𝕪",Yscr:"𝒴",yscr:"𝓎",YUcy:"Ю",yucy:"ю",yuml:"ÿ",Yuml:"Ÿ",Zacute:"Ź",zacute:"ź",Zcaron:"Ž",zcaron:"ž",Zcy:"З",zcy:"з",Zdot:"Ż",zdot:"ż",zeetrf:"ℨ",ZeroWidthSpace:"​",Zeta:"Ζ",zeta:"ζ",zfr:"𝔷",Zfr:"ℨ",ZHcy:"Ж",zhcy:"ж",zigrarr:"⇝",zopf:"𝕫",Zopf:"ℤ",Zscr:"𝒵",zscr:"𝓏",zwj:"‍",zwnj:"‌"},m={Aacute:"Á",aacute:"á",Acirc:"Â",acirc:"â",acute:"´",AElig:"Æ",aelig:"æ",Agrave:"À",agrave:"à",amp:"&",AMP:"&",Aring:"Å",aring:"å",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",brvbar:"¦",Ccedil:"Ç",ccedil:"ç",cedil:"¸",cent:"¢",copy:"©",COPY:"©",curren:"¤",deg:"°",divide:"÷",Eacute:"É",eacute:"é",Ecirc:"Ê",ecirc:"ê",Egrave:"È",egrave:"è",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",frac12:"½",frac14:"¼",frac34:"¾",gt:">",GT:">",Iacute:"Í",iacute:"í",Icirc:"Î",icirc:"î",iexcl:"¡",Igrave:"Ì",igrave:"ì",iquest:"¿",Iuml:"Ï",iuml:"ï",laquo:"«",lt:"<",LT:"<",macr:"¯",micro:"µ",middot:"·",nbsp:" ",not:"¬",Ntilde:"Ñ",ntilde:"ñ",Oacute:"Ó",oacute:"ó",Ocirc:"Ô",ocirc:"ô",Ograve:"Ò",ograve:"ò",ordf:"ª",ordm:"º",Oslash:"Ø",oslash:"ø",Otilde:"Õ",otilde:"õ",Ouml:"Ö",ouml:"ö",para:"¶",plusmn:"±",pound:"£",quot:'"',QUOT:'"',raquo:"»",reg:"®",REG:"®",sect:"§",shy:"­",sup1:"¹",sup2:"²",sup3:"³",szlig:"ß",THORN:"Þ",thorn:"þ",times:"×",Uacute:"Ú",uacute:"ú",Ucirc:"Û",ucirc:"û",Ugrave:"Ù",ugrave:"ù",uml:"¨",Uuml:"Ü",uuml:"ü",Yacute:"Ý",yacute:"ý",yen:"¥",yuml:"ÿ"},v={0:"�",128:"€",130:"‚",131:"ƒ",132:"„",133:"…",134:"†",135:"‡",136:"ˆ",137:"‰",138:"Š",139:"‹",140:"Œ",142:"Ž",145:"‘",146:"’",147:"“",148:"”",149:"•",150:"–",151:"—",152:"˜",153:"™",154:"š",155:"›",156:"œ",158:"ž",159:"Ÿ"},b=[1,2,3,4,5,6,7,8,11,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,64976,64977,64978,64979,64980,64981,64982,64983,64984,64985,64986,64987,64988,64989,64990,64991,64992,64993,64994,64995,64996,64997,64998,64999,65e3,65001,65002,65003,65004,65005,65006,65007,65534,65535,131070,131071,196606,196607,262142,262143,327678,327679,393214,393215,458750,458751,524286,524287,589822,589823,655358,655359,720894,720895,786430,786431,851966,851967,917502,917503,983038,983039,1048574,1048575,1114110,1114111],_=String.fromCharCode,y={},w=y.hasOwnProperty,x=function(t,e){return w.call(t,e)},k=function(t,e){for(var i=-1,n=t.length;++i=55296&&57343>=t||t>1114111?(e&&T("character reference outside the permissible Unicode range"),"�"):x(v,t)?(e&&T("disallowed character reference"),v[t]):(e&&k(b,t)&&T("disallowed character reference"),t>65535&&(t-=65536,i+=_(t>>>10&1023|55296),t=56320|1023&t),i+=_(t))},D=function(t){return"&#x"+t.charCodeAt(0).toString(16).toUpperCase()+";"},T=function(t){throw Error("Parse error: "+t)},A=function(t,e){e=C(e,A.options);var i=e.strict;i&&p.test(t)&&T("forbidden code point");var n=e.encodeEverything,s=e.useNamedReferences,h=e.allowUnsafeSymbols;return n?(t=t.replace(r,function(t){return s&&x(c,t)?"&"+c[t]+";":D(t)}),s&&(t=t.replace(/>\u20D2/g,">⃒").replace(/<\u20D2/g,"<⃒").replace(/fj/g,"fj")),s&&(t=t.replace(l,function(t){return"&"+c[t]+";"}))):s?(h||(t=t.replace(u,function(t){return"&"+c[t]+";"})),t=t.replace(/>\u20D2/g,">⃒").replace(/<\u20D2/g,"<⃒"),t=t.replace(l,function(t){return"&"+c[t]+";"})):h||(t=t.replace(u,D)),t.replace(a,function(t){var e=t.charCodeAt(0),i=t.charCodeAt(1),n=1024*(e-55296)+i-56320+65536;return"&#x"+n.toString(16).toUpperCase()+";"}).replace(o,D)};A.options={allowUnsafeSymbols:!1,encodeEverything:!1,strict:!1,useNamedReferences:!1};var E=function(t,e){e=C(e,E.options);var i=e.strict;return i&&d.test(t)&&T("malformed character reference"),t.replace(f,function(t,n,s,a,r,o,l,c){var u,h,d,p,f;return n?(u=n,h=s,i&&!h&&T("character reference was not terminated by a semicolon"),S(u,i)):a?(d=a,h=r,i&&!h&&T("character reference was not terminated by a semicolon"),u=parseInt(d,16),S(u,i)):o?(p=o,x(g,p)?g[p]:(i&&T("named character reference was not terminated by a semicolon"),t)):(p=l,f=c,f&&e.isAttributeValue?(i&&"="==f&&T("`&` did not start a character reference"),t):(i&&T("named character reference was not terminated by a semicolon"),m[p]+(f||"")))})};E.options={isAttributeValue:!1,strict:!1};var M=function(t){return t.replace(u,function(t){return h[t]})},P={version:"0.5.0",encode:A,decode:E,escape:M,unescape:E};if("function"==typeof i&&"object"==typeof i.amd&&i.amd)i("he",[],function(){return P});else if(e&&!e.nodeType)if(n)n.exports=P;else for(var I in P)x(P,I)&&(e[I]=P[I]);else t.he=P}(this),i("helpers/sanitizer",["DOMPurify","he"],function(t,e){"use strict";var i={};return i.whitelist=[{pre:"<em class="search-highlight">",post:''},{pre:"</em>",post:""}],i.addLineBreaks=function(t){return t.replace(/(\r)?\n/g,"
        ").replace(/( )? /g,"
        ")},i.purifyHtml=function(e){return t.sanitize(e,{SAFE_FOR_JQUERY:!0,SAFE_FOR_TEMPLATES:!0})},i.purifyText=function(t){var i=e.encode(t,{encodeEverything:!0});return this.whitelist.forEach(function(t){for(;i.indexOf(t.pre)>-1;)i=i.replace(t.pre,t.post)}),i},i.sanitize=function(t){var e;return t.htmlBody?e=this.purifyHtml(t.htmlBody):(e=this.purifyText(t.textPlainBody),e=this.addLineBreaks(e)),e},t.addHook("afterSanitizeAttributes",function(t){"target"in t&&t.setAttribute("target","_blank"),t.hasAttribute("target")||!t.hasAttribute("xlink:href")&&!t.hasAttribute("href")||t.setAttribute("xlink:show","new")}),i}),i("helpers/view_helper",["helpers/contenttype","views/i18n","quoted-printable/quoted-printable","utf8/utf8","helpers/sanitizer"],function(t,e,i,n,s){"use strict";function a(t){return _.map(t,function(t){return"status-"+t}).join(" ")}function r(t){return s.sanitize(t)}function o(t){if("number"==typeof t.selectionStart)t.selectionStart=t.selectionEnd=t.value.length;else if("undefined"!=typeof t.createTextRange){t.focus();var e=t.createTextRange();e.collapse(!1),e.select()}}function l(t,e){for(var i=t.toString();i.length wrote:\n",{date:new Date(t.header.date).toString(),from:t.header.from})}function d(t){return"\n\n"+h(t)+t.textPlainBody.replace(/^/gm,"> ")}function p(t){var e=new Date(t),i=c();return e.getTime()>i.getTime()?l(e.getHours(),2)+":"+l(e.getMinutes(),2):""+e.getFullYear()+"-"+l(e.getMonth()+1,2)+"-"+l(e.getDate(),2)}function f(t){var e=Math.floor(Math.log(t)/Math.log(1024));return(t/Math.pow(1024,e)).toFixed(2)+" "+" KMGTP".charAt(e)+"b"}function g(t){return t=t||"",t.replace(/(.{4})/g,"$1 ").trim()}return Handlebars.registerHelper("formatDate",p),Handlebars.registerHelper("formatSize",f),Handlebars.registerHelper("formatStatusClasses",a),Handlebars.registerHelper("formatFingerPrint",g),{formatStatusClasses:a,formatSize:f,formatMailBody:r,formatFingerPrint:g,moveCaretToEndOfText:u,quoteMail:d,i18n:e}}),i("helpers/iterator",[],function(){"use strict";function t(t,e){this.index=e||0,this.elems=t,this.hasPrevious=function(){return 0!==this.index},this.hasNext=function(){return this.index0},this.removeCurrent=function(){var t=this.current(),e=this.index;return this.hasNext()||this.index--,this.elems.remove(e),t}}return t}),i("helpers/browser",[],function(){"use strict";function t(t){window.location.replace(t)}function e(t){var e="; "+document.cookie,i=e.split("; "+t+"=");return 2===i.length?i.pop().split(";").shift():void 0}return{redirect:t,getCookie:e}}),i("helpers/monitored_ajax",["page/events","views/i18n","helpers/browser"],function(t,e,i){"use strict";function n(n,a,r){r=r||{},r.timeout=6e4;var o=r.beforeSend;r.beforeSend=function(){o&&o()},r.headers={"X-XSRF-TOKEN":i.getCookie("XSRF-TOKEN")};var l=r.complete;return r.complete=function(){l&&l()},$.ajax(a,r).fail(function(a,o,l){if(!r.skipErrorMessage){var c=a.responseJSON&&a.responseJSON.message||s[o]||"unexpected problem while talking to server";n.trigger(document,t.ui.userAlerts.displayMessage,{message:e(c),"class":"error"})}if(302===a.status){var u=a.getResponseHeader("Location");i.redirect(u)}else 401===a.status&&i.redirect("/")}.bind(this))}var s={timeout:"a timeout occurred",error:"problems talking to server",parseerror:"got invalid response from server"};return n}),i("features",["helpers/monitored_ajax"],function(t){"use strict";function e(){return s=s||n().disabled_features}function i(){return a=a||n().dispatcher_features}function n(){var e;return t(this,"/features",{async:!1,success:function(t){e=t},error:function(){console.error("Could not load feature toggles")}}),e}var s,a;return{isEnabled:function(t){return!_.contains(e(),t)},isAutoRefreshEnabled:function(){return this.isEnabled("autoRefresh")},isLogoutEnabled:function(){return _.has(i(),"logout")},getLogoutUrl:function(){return i().logout}}}),i("mail_view/ui/recipients/recipients_input",["flight/lib/component","page/events","features"],function(t,e,i){"use strict";function n(){function t(){var t=new Bloodhound({datumTokenizer:function(t){return[t.value]},queryTokenizer:function(t){return[t.trim()]},remote:{url:"/contacts?q=%QUERY",filter:p}});return t.initialize(),t}function i(t){t.typeahead("val","")}function n(t){return 0===t.selectionStart}function s(t){return o.hasOwnProperty(t)}function a(t){return l.hasOwnProperty(t)}var r,o={8:"backspace",37:"left"},l={9:"tab",186:"semicolon",188:"comma",13:"enter",27:"esc"},c={8:e.ui.recipients.deleteLast,37:e.ui.recipients.selectLast},u=/[^<\w,;]?([^\s<;,]+@[\w-]+\.[^\s>;,]+)/,h=/([^,;\s][^,;@]+<[^\s;,]+@[\w-]+\.[^\s;,]+>)/,d=new RegExp([u.source,"|",h.source].join(""),"g"),p=function(t){return _.map(t,function(t){return{value:t}})};this.processSpecialKey=function(t){var e=t.which;return s(e)&&n(this.$node[0])?void this.trigger(c[e]):void(!t.shiftKey&&a(e)&&(this.tokenizeRecipient(t),9!==e&&t.preventDefault()))},this.tokenizeRecipient=function(t){_.isEmpty(this.$node.val().trim())||(this.recipientSelected(null,{value:this.$node.val()}),t.preventDefault())},this.recipientSelected=function(t,n){var s=n&&n.value||this.$node.val(),a=this.extractValidAddresses(s),r=this.extractInvalidAddresses(s);this.triggerEventForEach(a,e.ui.recipients.entered),this.triggerEventForEach(r,e.ui.recipients.enteredInvalid),i(this.$node)},this.triggerEventForEach=function(t,e){var i=this;_.each(t,function(t){_.isEmpty(t.trim())||i.trigger(i.$node,e,{name:i.attr.name,address:t.trim()})})},this.extractValidAddresses=function(t){return t.match(d)},this.extractInvalidAddresses=function(t){return t.replace(d,"").split(/[,;]/)},this.init=function(){this.$node.typeahead({hint:!0,highlight:!0,minLength:1},{source:t().ttAdapter(),templates:{suggestion:function(t){return _.escape(t.value)}}})},this.attachAndReturn=function(t,e){var i=new this.constructor;return i.initialize(t,{name:e}),i},this.warnSendButtonOfInputState=function(){var t=_.isEmpty(this.$node.val())?e.ui.recipients.inputFieldIsEmpty:e.ui.recipients.inputFieldHasCharacters;this.trigger(document,t,{name:this.attr.name})},this.after("initialize",function(){r=this,this.init(),this.on("typeahead:selected typeahead:autocompleted",this.recipientSelected),this.on(this.$node,"blur",this.tokenizeRecipient),this.on(this.$node,"keydown",this.processSpecialKey),this.on(this.$node,"keyup",this.warnSendButtonOfInputState),this.on(document,e.dispatchers.rightPane.clear,this.teardown)})}return t(n)}),i("mail_view/ui/recipients/recipient",["flight/lib/component","views/templates","page/events"],function(t,e,i){"use strict";function n(){this.renderAndPrepend=function(t,i){var n=$(e.compose.fixedRecipient(i));n.insertBefore(t.children().last());var s=new this.constructor;return s.initialize(n,i),s.attr.recipient=i,s},this.recipientDelActions=function(){this.on(this.$node.find(".recipient-del"),"click",function(t){this.doSelect(),this.trigger(i.ui.recipients.deleteRecipient,this),t.preventDefault()}),this.on(this.$node.find(".recipient-del"),"mouseover",function(){this.$node.find(".recipient-value").addClass("deleting"),this.$node.find(".recipient-del").addClass("deleteTooltip")}),this.on(this.$node.find(".recipient-del"),"mouseout",function(){this.$node.find(".recipient-value").removeClass("deleting"),this.$node.find(".recipient-del").removeClass("deleteTooltip")})},this.destroy=function(){this.$node.remove(),this.teardown()},this.doSelect=function(){this.$node.find(".recipient-value").addClass("selected")},this.doUnselect=function(){this.$node.find(".recipient-value").removeClass("selected")},this.isSelected=function(){return this.$node.find(".recipient-value").hasClass("selected")},this.sinalizeInvalid=function(){this.$node.find(".recipient-value>span").addClass("invalid-format")},this.discoverEncryption=function(){this.$node.addClass("discover-encryption");var t=$.getJSON("/keys?search="+this.attr.address).promise();t.done(function(){this.$node.find(".recipient-value").addClass("encrypted"),this.$node.removeClass("discover-encryption")}.bind(this)),t.fail(function(){this.$node.find(".recipient-value").addClass("not-encrypted"),this.$node.removeClass("discover-encryption")}.bind(this))},this.getMailAddress=function(){return this.$node.find("input[type=hidden]").val()},this.triggerEditRecipient=function(t,e){this.trigger(this.$node.closest(".recipients-area"),i.ui.recipients.clickToEdit,this)},this.after("initialize",function(){this.recipientDelActions(),this.on("click",this.triggerEditRecipient),this.attr.invalidAddress?this.sinalizeInvalid():this.discoverEncryption()})}return t(n)}),i("mail_view/ui/recipients/recipients_iterator",["helpers/iterator"],function(t){"use strict";function e(e){this.iterator=new t(e.elements,e.elements.length-1),this.input=e.exitInput,this.current=function(){return this.iterator.current()},this.moveLeft=function(){this.iterator.hasPrevious()&&(this.iterator.current().doUnselect(),this.iterator.previous().doSelect())},this.moveRight=function(){this.iterator.current().doUnselect(),this.iterator.hasNext()?this.iterator.next().doSelect():this.input.focus()},this.deleteCurrent=function(){this.iterator.removeCurrent().destroy(),this.iterator.hasElements()?this.iterator.current().doSelect():this.input.focus()}}return e}),i("mail_view/ui/recipients/recipients",["flight/lib/component","views/templates","page/events","helpers/iterator","mail_view/ui/recipients/recipients_input","mail_view/ui/recipients/recipient","mail_view/ui/recipients/recipients_iterator"],function(t,e,i,n,s,a,r){"use strict";function o(){function t(t){return _.flatten(_.map(t,function(t){return t.attr.address}))}function e(){this.attr.iterator.moveLeft()}function n(){this.attr.iterator.moveRight()}function o(){this.attr.iterator.deleteCurrent(),this.addressesUpdated()}function l(t,e){var i=this.attr.iterator.current().getMailAddress();this.attr.iterator.deleteCurrent(),this.attr.input.$node.val(i).focus(),this.unselectAllRecipients(),this.addressesUpdated()}this.defaultAttrs({navigationHandler:".recipients-navigation-handler",recipientsList:".recipients-list"}),this.clickToEditRecipient=function(t,e){this.attr.iterator=null;var i=e.getMailAddress(),n=this.getRecipientPosition(e);this.attr.recipients.splice(n,1),e.destroy(),this.addressesUpdated(),this.unselectAllRecipients(),this.attr.input.$node.val(i).focus()},this.getRecipientPosition=function(t){return t.$node.closest(".recipients-area").find(".fixed-recipient").index(t.$node)},this.unselectAllRecipients=function(){this.$node.find(".recipient-value.selected").removeClass("selected")};var c={8:o,46:o,32:l,13:l,37:e,39:n};this.addRecipient=function(t){var e=a.prototype.renderAndPrepend(this.$node.find(this.attr.recipientsList),t);this.attr.recipients.push(e)},this.recipientEntered=function(t,e){this.addRecipient(e),this.addressesUpdated()},this.invalidRecipientEntered=function(t,e){e.invalidAddress=!0,this.addRecipient(e)},this.deleteRecipient=function(t,e){this.attr.iterator=null;var i=this.getRecipientPosition(e);this.attr.recipients.splice(i,1),e.destroy(),this.addressesUpdated()},this.deleteLastRecipient=function(){this.attr.recipients.pop().destroy(),this.addressesUpdated()},this.enterNavigationMode=function(){this.attr.iterator=new r({elements:this.attr.recipients,exitInput:this.attr.input.$node}),this.attr.iterator.current().doSelect(),this.attr.input.$node.blur(),this.select("navigationHandler").focus()},this.leaveNavigationMode=function(){this.attr.iterator&&this.attr.iterator.current().unselect(),this.attr.iterator=null},this.selectLastRecipient=function(){0!==this.attr.recipients.length&&this.enterNavigationMode()},this.attachInput=function(){this.attr.input=s.prototype.attachAndReturn(this.$node.find("input[type=text]"),this.attr.name)},this.processSpecialKey=function(t){c.hasOwnProperty(t.which)&&c[t.which].apply(this)},this.initializeAddresses=function(){_.each(_.flatten(this.attr.addresses),function(t){this.addRecipient({address:t,name:this.attr.name})}.bind(this))},this.addressesUpdated=function(){this.trigger(document,i.ui.recipients.updated,{recipientsName:this.attr.name,newRecipients:t(this.attr.recipients)})},this.doCompleteRecipients=function(){var e=this.attr.input.$node.val();if(!_.isEmpty(e)){var n=a.prototype.renderAndPrepend(this.$node,{name:this.attr.name,address:e});this.attr.recipients.push(n),this.attr.input.$node.val("")}this.trigger(document,i.ui.recipients.updated,{recipientsName:this.attr.name,newRecipients:t(this.attr.recipients),skipSaveDraft:!0})},this.after("initialize",function(){this.attr.recipients=[],this.attachInput(),this.initializeAddresses(),this.on(i.ui.recipients.deleteRecipient,this.deleteRecipient),this.on(i.ui.recipients.deleteLast,this.deleteLastRecipient),this.on(i.ui.recipients.selectLast,this.selectLastRecipient),this.on(i.ui.recipients.entered,this.recipientEntered),this.on(i.ui.recipients.enteredInvalid,this.invalidRecipientEntered),this.on(i.ui.recipients.clickToEdit,this.clickToEditRecipient),this.on(document,i.ui.recipients.doCompleteInput,this.doCompleteRecipients),this.on(this.attr.input.$node,"focus",this.leaveNavigationMode),this.on(this.select("navigationHandler"),"keydown",this.processSpecialKey),this.on(document,i.dispatchers.rightPane.clear,this.teardown)})}return t(o)}),i("mail_view/ui/draft_save_status",["flight/lib/component","page/events"],function(t,e){"use strict";function i(){this.setMessage=function(t){var e=this.$node;return function(){e.text(t)}},this.after("initialize",function(){this.on(document,e.mail.saveDraft,this.setMessage("Saving to Drafts...")),this.on(document,e.mail.draftSaved,this.setMessage("Draft Saved.")),this.on(document,e.ui.mail.changedSinceLastSave,this.setMessage(""))})}return t(i)}),i("mail_view/ui/send_button",["flight/lib/component","flight/lib/utils","page/events","helpers/view_helper"],function(t,e,i,n){"use strict";function s(){var t=3;this.enableButton=function(){this.$node.prop("disabled",!1)},this.disableButton=function(){this.$node.prop("disabled",!0)},this.atLeastOneInputFieldHasRecipients=function(){return _.any(_.values(this.attr.recipients),function(t){return!_.isEmpty(t)})},this.atLeastOneInputFieldHasCharacters=function(){return _.any(_.values(this.attr.inputFieldHasCharacters),function(t){return t===!0})},this.updateButton=function(){this.attr.sendingInProgress===!1&&(this.attr.uploading===!1&&(this.atLeastOneInputFieldHasCharacters()||this.atLeastOneInputFieldHasRecipients())?this.enableButton():this.disableButton())},this.inputFieldIsEmpty=function(t,e){this.attr.inputFieldHasCharacters[e.name]=!1,this.updateButton()},this.inputFieldHasCharacters=function(t,e){this.attr.inputFieldHasCharacters[e.name]=!0,this.updateButton()},this.uploadInProgress=function(t,e){this.attr.uploading=!0,this.updateButton()},this.uploadFinished=function(t,e){this.attr.uploading=!1,this.updateButton()},this.updateRecipientsForField=function(t,e){this.attr.recipients[e.recipientsName]=e.newRecipients,this.attr.inputFieldHasCharacters[e.recipientsName]=!1,this.updateButton()},this.updateRecipientsAndSendMail=function(){this.on(document,i.ui.mail.recipientsUpdated,e.countThen(t,function(){this.trigger(document,i.ui.mail.send),this.off(document,i.ui.mail.recipientsUpdated)}.bind(this))),this.disableButton(),this.$node.text(n.i18n("sending-mail")),this.attr.sendingInProgress=!0,this.trigger(document,i.ui.recipients.doCompleteInput)},this.resetButton=function(){this.attr.sendingInProgress=!1,this.attr.uploading=!1,this.$node.html(n.i18n("send-button")),this.enableButton()},this.after("initialize",function(){this.attr.recipients={},this.attr.inputFieldHasCharacters={},this.resetButton(),this.on(document,i.ui.recipients.inputFieldHasCharacters,this.inputFieldHasCharacters),this.on(document,i.ui.recipients.inputFieldIsEmpty,this.inputFieldIsEmpty),this.on(document,i.ui.recipients.updated,this.updateRecipientsForField),this.on(this.$node,"click",this.updateRecipientsAndSendMail),this.on(document,i.mail.uploadingAttachment,this.uploadInProgress),this.on(document,i.mail.uploadedAttachment,this.uploadFinished),this.on(document,i.mail.failedUploadAttachment,this.uploadFinished),this.on(document,i.dispatchers.rightPane.clear,this.teardown),this.on(document,i.ui.sendbutton.enable,this.resetButton),this.on(document,i.mail.send_failed,this.resetButton),this.disableButton()})}return t(s)}),i("mail_view/ui/attachment_icon",["flight/lib/component","page/events","features"],function(t,e,i){"use strict";return t(function(){this.render=function(){this.$node.html('')},this.triggerUploadAttachment=function(){this.trigger(document,e.mail.startUploadAttachment)},this.uploadInProgress=function(t,e){this.attr.busy=!0,this.$node.addClass("busy")},this.uploadFinished=function(t,e){this.attr.busy=!1,this.$node.removeClass("busy")},this.after("initialize",function(){i.isEnabled("attachment")&&(this.render(),this.on(document,e.mail.uploadingAttachment,this.uploadInProgress),this.on(document,e.mail.uploadedAttachment,this.uploadFinished),this.on(document,e.mail.failedUploadAttachment,this.uploadFinished)),this.on(this.$node,"click",function(){this.attr.busy||this.triggerUploadAttachment()})})})}),i("mail_view/ui/attachment_list",["views/templates","page/events","helpers/view_helper","helpers/monitored_ajax"],function(t,e,i,n){"use strict";function s(){this.defaultAttrs({inputFileUpload:"#fileupload",attachmentListItem:"#attachment-list-item",attachmentUploadItem:"#attachment-upload-item",attachmentUploadItemProgress:"#attachment-upload-item-progress",attachmentUploadItemAbort:"#attachment-upload-item-abort",attachmentBaseUrl:"/attachment",attachments:[],closeIcon:".close-icon",uploadError:"#upload-error",dismissButton:"#dismiss-button",uploadFileButton:"#upload-file-button"});var i=1048576,n=i;this.showAttachment=function(t,i){this.trigger(document,e.mail.appendAttachment,i),this.renderAttachmentListView(i)},this.addAttachment=function(t,e){this.attr.attachments.push(e)},this.renderAttachmentListView=function(t){var e=(this.select("attachmentListItem").html(),this.buildAttachmentListItem(t));this.select("attachmentListItem").append(e)},this.buildAttachmentListItem=function(i){var n={ident:i.ident,encoding:i.encoding,name:i.name,size:i.size,removable:!0},s=$(t.compose.attachmentItem(n)),a=this;return s.find("i.remove-icon").bind("click",function(t){var i=$(this),n=i.closest("li").attr("data-ident");a.trigger(document,e.mail.removeAttachment,{ident:n,element:i}),t.preventDefault()}),s},this.performPreUploadCheck=function(t,e){return!(e.originalFiles[0].size>n)},this.removeUploadError=function(){var t=this.select("uploadError");t&&t.remove()},this.showUploadError=function(){function i(t){t.preventDefault(),s.select("uploadError").remove()}function n(t){t.preventDefault(),s.trigger(document,e.mail.startUploadAttachment)}var s=this,a=$(t.compose.uploadAttachmentFailed());a.insertAfter(s.select("attachmentListItem")),s.on(s.select("closeIcon"),"click",i),s.on(s.select("dismissButton"),"click",i),s.on(s.select("uploadFileButton"),"click",n)},this.showUploadProgressBar=function(e,i){var n=$(t.compose.attachmentUploadItem({name:i.originalFiles[0].name,size:i.originalFiles[0].size}));this.select("attachmentUploadItem").append(n),this.select("attachmentUploadItem").show()},this.hideUploadProgressBar=function(){this.select("attachmentUploadItem").hide(),this.select("attachmentUploadItem").empty()},this.attachUploadAbort=function(t,e){this.on(this.select("attachmentUploadItemAbort"),"click",function(t){e.abort(),t.preventDefault()})},this.detachUploadAbort=function(){this.off(this.select("attachmentUploadItemAbort"),"click")},this.addJqueryFileUploadConfig=function(){var t=this;t.removeUploadError(),this.select("inputFileUpload").fileupload({add:function(e,i){t.performPreUploadCheck(e,i)?(t.showUploadProgressBar(e,i),t.attachUploadAbort(e,i),i.submit()):t.showUploadError()},url:t.attr.attachmentBaseUrl,dataType:"json",done:function(i,n){t.detachUploadAbort(),t.hideUploadProgressBar(),t.trigger(document,e.mail.uploadedAttachment,n.result)},fail:function(i,n){t.detachUploadAbort(),t.hideUploadProgressBar(),t.trigger(document,e.mail.failedUploadAttachment)},progressall:function(e,i){var n=parseInt(i.loaded/i.total*100,10);t.select("attachmentUploadItemProgress").css("width",n+"%")}}).bind("fileuploadstart",function(i){t.trigger(document,e.mail.uploadingAttachment)}).bind("fileuploadadd",function(t){$(".attachmentsAreaWrap").show()})},this.startUpload=function(){this.addJqueryFileUploadConfig(),this.select("inputFileUpload").click()},this.removeAttachmentFromList=function(t){for(var e=0;e",{id:"mail-"+i.ident});e.append(l),i.currentTag=r;var c=n[i.mailbox]||t;c.attachTo(l,{mail:i,selected:i.ident===a,tag:r,isChecked:o,templateType:s[i.mailbox]||"single"})};return{createAndAttach:a}}),i("mail_list/ui/mail_list",["flight/lib/component","flight/lib/utils","mail_list/ui/mail_item_factory","page/router/url_params","page/events"],function(t,e,i,n,s){"use strict";function a(){var t=function(t){return"drafts"===t?s.dispatchers.rightPane.openDraft:s.ui.mail.open};this.defaultAttrs({mail:".mail",currentMailIdent:"",urlParams:n,initialized:!1,checkedMails:{}}),this.appendMail=function(t){var e=t.ident in this.attr.checkedMails;i.createAndAttach(this.$node,t,this.attr.currentMailIdent,this.attr.currentTag,e)},this.resetMailList=function(){this.trigger(document,s.mails.teardown),this.$node.empty()},this.triggerMailOpenForPopState=function(e){e.mailIdent&&this.trigger(document,t(e.tag),{ident:e.mailIdent})},this.shouldSelectEmailFromUrlMailIdent=function(){return this.attr.urlParams.hasMailIdent()},this.selectMailBasedOnUrlMailIdent=function(){var e=this.attr.urlParams.getMailIdent();this.trigger(document,t(this.attr.currentTag),{ident:e}),this.trigger(document,s.router.pushState,{tag:this.attr.currentTag,mailIdent:e})},this.updateCurrentTagAndMail=function(t){t.ident&&(this.attr.currentMailIdent=t.ident),this.attr.currentTag=t.tag||this.attr.currentTag,this.updateCheckAllCheckbox()},this.renderMails=function(t){_.each(t,this.appendMail,this),this.trigger(document,s.search.highlightResults,{where:"#mail-list"}),this.trigger(document,s.search.highlightResults,{where:".mail-read-view__header"})},this.triggerScrollReset=function(){this.trigger(document,s.dispatchers.middlePane.resetScroll)},this.showMails=function(t,e){this.updateCurrentTagAndMail(e),this.refreshMailList(null,e),this.triggerMailOpenForPopState(e),this.openMailFromUrl()},this.refreshMailList=function(t,e){t&&this.trigger(document,s.dispatchers.tags.refreshTagList,{skipMailListRefresh:!0}),this.resetMailList(),this.renderMails(e.mails)},this.updateSelected=function(t,e){e.ident!==this.attr.currentMailIdent&&(this.attr.currentMailIdent=e.ident)},this.cleanSelected=function(){this.attr.currentMailIdent="",this.triggerScrollReset()},this.respondWithCheckedMails=function(t,e){this.trigger(e,s.ui.mail.hereChecked,{checkedMails:this.attr.checkedMails})},this.updateCheckAllCheckbox=function(){this.trigger(document,s.ui.mails.hasMailsChecked,_.keys(this.attr.checkedMails).length>0)},this.addToCheckedMails=function(t,e){this.attr.checkedMails[e.mail.ident]=e.mail,this.updateCheckAllCheckbox()},this.removeFromCheckedMails=function(t,e){e.mails?_.each(e.mails,function(t){delete this.attr.checkedMails[t.ident]},this):delete this.attr.checkedMails[e.mail.ident],this.updateCheckAllCheckbox()},this.refreshWithScroll=function(){this.trigger(document,s.ui.mails.refresh),this.triggerScrollReset()},this.refreshAfterSaveDraft=function(){"drafts"===this.attr.currentTag&&this.refreshWithScroll()},this.refreshAfterMailSent=function(){"drafts"!==this.attr.currentTag&&"sent"!==this.attr.currentTag||this.refreshWithScroll()},this.after("initialize",function(){this.on(document,s.ui.mails.cleanSelected,this.cleanSelected),this.on(document,s.ui.tag.select,this.cleanSelected),this.on(document,s.mails.available,this.showMails),this.on(document,s.mails.availableForRefresh,this.refreshMailList),this.on(document,s.mail.draftSaved,this.refreshAfterSaveDraft),this.on(document,s.mail.sent,this.refreshAfterMailSent),this.on(document,s.ui.mail.updateSelected,this.updateSelected),this.on(document,s.ui.mail.wantChecked,this.respondWithCheckedMails),this.on(document,s.ui.mail.checked,this.addToCheckedMails),this.on(document,s.ui.mail.unchecked,this.removeFromCheckedMails),this.openMailFromUrl=e.once(function(){this.shouldSelectEmailFromUrlMailIdent()&&this.selectMailBasedOnUrlMailIdent()})})}return t(a)}),i("mail_view/ui/no_message_selected_pane",["flight/lib/component","views/templates","mixins/with_hide_and_show","page/events"],function(t,e,i,n){"use strict";function s(){this.render=function(){this.$node.html(e.noMessageSelected())},this.after("initialize",function(){this.render(),this.on(document,n.dispatchers.rightPane.clear,this.teardown)})}return t(s,i)}),i("mail_view/ui/no_mails_available_pane",["flight/lib/component","views/templates","mixins/with_hide_and_show","page/events"],function(t,e,i,n){"use strict";function s(){this.defaultAttrs({tag:null,forSearch:""});var t=/-?in:"?[\w]+"?|tag:"[\w]+"/g;this.render=function(){this.attr.tag=this.attr.tag.toUpperCase(),this.attr.forSearch=this.attr.forSearch.replace(t,"").trim().toUpperCase(),this.$node.html(e.noMailsAvailable(this.attr))},this.after("initialize",function(){this.render()})}return t(s)}),i("mail_view/ui/mail_actions",["flight/lib/component","views/templates","page/events"],function(t,e,i){"use strict";function n(){this.defaultAttrs({replyButtonTop:"#reply-button-top",viewMoreActions:"#view-more-actions",replyAllButtonTop:"#reply-all-button-top",deleteButtonTop:"#delete-button-top",moreActions:"#more-actions"}),this.displayMailActions=function(){this.$node.html(e.mails.mailActions()),this.select("moreActions").hide(),this.on(this.select("replyButtonTop"),"click",function(){this.trigger(document,i.ui.replyBox.showReply)}.bind(this)),this.on(this.select("replyAllButtonTop"),"click",function(){this.trigger(document,i.ui.replyBox.showReplyAll),this.select("moreActions").hide()}.bind(this)),this.on(this.select("deleteButtonTop"),"click",function(){this.trigger(document,i.ui.mail["delete"],{mail:this.attr.mail}),this.select("moreActions").hide()}.bind(this)),this.on(this.select("viewMoreActions"),"click",function(){this.select("moreActions").toggle()}.bind(this)),this.on(this.select("viewMoreActions"),"blur",function(t){var e=this.select("replyAllButtonTop").is(":hover"),i=this.select("deleteButtonTop").is(":hover");e||i?t.preventDefault():this.select("moreActions").hide()}.bind(this))},this.after("initialize",function(){this.on(document,i.dispatchers.rightPane.clear,this.teardown),this.displayMailActions()})}return t(n)}),i("mixins/with_mail_tagging",["page/events","features"],function(t,e){"use strict";function i(){this.updateTags=function(e,i){this.trigger(document,t.mail.tags.update,{ident:e.ident,tags:i})},this.attachTagCompletion=function(t){this.tagFilter=function(e){var i=_.filter(e,function(e){return!_.contains(t.tags,e.name)});return _.map(i,function(t){return{value:Handlebars.Utils.escapeExpression(t.name)}})},this.tagCompleter=new Bloodhound({datumTokenizer:function(t){return[t.value]},queryTokenizer:function(t){return[t.trim()]},remote:{url:"/tags?skipDefaultTags=true&q=%QUERY",filter:this.tagFilter}}),this.tagCompleter.initialize(),this.select("newTagInput").typeahead({hint:!0,highlight:!0,minLength:1},{source:this.tagCompleter.ttAdapter()})},this.createNewTag=function(){var t=this.attr.mail.tags.slice();t.push(this.select("newTagInput").val()),this.tagCompleter.clear(),this.tagCompleter.clearPrefetchCache(),this.tagCompleter.clearRemoteCache(),this.updateTags(this.attr.mail,_.uniq(t))},this.after("displayMail",function(){this.on(this.select("newTagInput"),"typeahead:selected typeahead:autocompleted",this.createNewTag)})}return i}),i("mixins/with_mail_sandbox",["helpers/view_helper","page/events"],function(t,e){"use strict";function i(){this.showMailOnSandbox=function(i){var n=this,s=$("#read-sandbox"),a=s[0],r=t.formatMailBody(i);window.addEventListener("message",function(t){"null"===t.origin&&t.source===a.contentWindow&&(n.trigger(document,e.ui.replyBox.showReplyContainer),n.trigger(document,e.search.highlightResults,{where:".mail-read-view__header"}))}),a.onload=function(){function t(){var t=s.parent().width(),e=s.width(),n="none";i&&i.htmlBody&&e>t&&(n=t/e,n="scale("+n+","+n+")"),s.css({"-webkit-transform-origin":"0 0","-moz-transform-origin":"0 0","-ms-transform-origin":"0 0","transform-origin":"0 0","-webkit-transform":n,"-moz-transform":n,"-ms-transform":n,transform:n})}if(s.iFrameResize){var e={resizedCallback:t,checkOrigin:!1};s.iFrameResize(e)}a.contentWindow.postMessage({html:r},"*")}}}return i}),i("mail_view/ui/mail_view",["flight/lib/component","views/templates","mail_view/ui/mail_actions","helpers/view_helper","mixins/with_hide_and_show","mixins/with_mail_tagging","mixins/with_mail_sandbox","page/events","views/i18n"],function(t,e,i,n,s,a,r,o,l){"use strict";function c(){this.defaultAttrs({tags:".mail-read-view__header-tags-tag",newTagInput:"#new-tag-input",newTagButton:"#new-tag-button",addNew:".mail-read-view__header-tags-new-button",trashButton:"#trash-button",archiveButton:"#archive-button",closeMailButton:".close-mail-button"}),this.displayMail=function(t,s){this.attr.mail=s.mail;var a,r,o;s.mail.security_casing=s.mail.security_casing||{},a=this.checkSigned(s.mail),r=this.checkEncrypted(s.mail),o=s.mail.attachments.map(function(t){return t.received=!0,t}),"sent"===s.mail.mailbox&&(r=void 0),this.$node.html(e.mails.fullView({header:s.mail.header,body:[],statuses:n.formatStatusClasses(s.mail.status),ident:s.mail.ident,tags:s.mail.tags,encryptionStatus:r,signatureStatus:a,attachments:o})),this.showMailOnSandbox(this.attr.mail),this.attachTagCompletion(this.attr.mail),this.select("tags").on("click",function(t){this.removeTag($(t.target).text())}.bind(this)),this.addTagLoseFocus(),this.on(this.select("newTagButton"),"click",this.showNewTagInput),this.on(this.select("newTagInput"),"keydown",this.handleKeyDown),this.on(this.select("newTagInput"),"blur",this.addTagLoseFocus),this.on(this.select("trashButton"),"click",this.moveToTrash),this.on(this.select("closeMailButton"),"click",this.openNoMessageSelectedPane),i.attachTo("#mail-actions",s),this.resetScroll()},this.resetScroll=function(){$("#right-pane").scrollTop(0)},this.checkEncrypted=function(t){if(_.isEmpty(t.security_casing.locks))return{cssClass:"security-status__label--not-encrypted",label:"not-encrypted"};var e=["security-status__label--encrypted"],i=["encrypted"],n=_.any(t.security_casing.locks,function(t){return"valid"===t.state});return n?i.push("encryption-valid"):(e.push("--with-error"),i.push("encryption-error")),{cssClass:e.join(""),label:i.join(" ")}},this.checkSigned=function(t){var e={cssClass:"security-status__label--not-signed",label:"not-signed"};if(_.isEmpty(t.security_casing.imprints))return e;var i=_.any(t.security_casing.imprints,function(t){return"no_signature_information"===t.state});if(i)return e;var n=["security-status__label--signed"],s=["signed"];return _.any(t.security_casing.imprints,function(t){return"from_revoked"===t.state})&&(n.push("--revoked"),s.push("signature-revoked")),_.any(t.security_casing.imprints,function(t){return"from_expired"===t.state})&&(n.push("--expired"),s.push("signature-expired")),this.isNotTrusted(t)&&(n.push("--not-trusted"),s.push("signature-not-trusted")),{cssClass:n.join(""),label:s.join(" ")}},this.isNotTrusted=function(t){return _.any(t.security_casing.imprints,function(t){if(_.isNull(t.seal))return!0;var e=_.isUndefined(t.seal.trust)?t.seal.validity:t.seal.trust;return"no_trust"===e})},this.openNoMessageSelectedPane=function(t,e){this.trigger(document,o.dispatchers.rightPane.openNoMessageSelected)},this.handleKeyDown=function(t){var e=13,i=27;t.which===e?(t.preventDefault(),""!==this.select("newTagInput").val().trim()&&this.createNewTag()):t.which===i&&(t.preventDefault(),this.addTagLoseFocus())},this.addTagLoseFocus=function(){this.select("newTagInput").hide(),this.select("newTagInput").typeahead("val",""),this.select("addNew").show()},this.showNewTagInput=function(){this.select("newTagInput").show(),this.select("newTagInput").focus(),this.select("addNew").hide()},this.removeTag=function(t){t=t.toString();var e=_.without(this.attr.mail.tags,t);this.updateTags(this.attr.mail,e),this.trigger(document,o.dispatchers.tags.refreshTagList)},this.moveToTrash=function(){this.trigger(document,o.ui.mail["delete"],{mail:this.attr.mail})},this.tagsUpdated=function(t,e){e=e||{},this.attr.mail.tags=e.tags,this.displayMail({},{mail:this.attr.mail})},this.mailDeleted=function(t,e){_.contains(_.pluck(e.mails,"ident"),this.attr.mail.ident)&&this.openNoMessageSelectedPane()},this.fetchMailToShow=function(){this.trigger(o.mail.want,{mail:this.attr.ident,caller:this})},this.highlightMailContent=function(t,e){this.trigger(document,o.mail.highlightMailContent,e)},this.after("initialize",function(){this.on(this,o.mail.notFound,this.openNoMessageSelectedPane),this.on(this,o.mail.here,this.highlightMailContent),this.on(document,o.mail.display,this.displayMail),this.on(document,o.dispatchers.rightPane.clear,this.teardown),this.on(document,o.mail.tags.updated,this.tagsUpdated),this.on(document,o.mail.deleted,this.mailDeleted),this.fetchMailToShow()})}return t(c,i,s,a,r)}),i("mixins/with_compose_inline",["page/events","views/templates","mail_view/data/mail_builder","mixins/with_mail_edit_base"],function(t,e,i,n){"use strict";function s(){this.defaultAttrs({subjectDisplay:"#reply-subject",subjectInput:"#subject-container input", +forwardBox:"#forward-box",recipientsDisplay:"#all-recipients"}),this.openMail=function(e,i){this.trigger(document,t.ui.mail.open,{ident:this.attr.mail.ident})},this.trashReply=function(){this.trigger(document,t.ui.composeBox.trashReply),this.teardown()},this.builtMail=function(t){return i.newMail(this.attr.ident).subject(this.select("subjectBox").val()).to(this.attr.recipientValues.to).cc(this.attr.recipientValues.cc).bcc(this.attr.recipientValues.bcc).body(this.select("bodyBox").val()).attachment(this.attr.attachments).tag(t)},this.renderInlineCompose=function(t,i){this.show(),this.render(e.compose.inlineBox,i),this.$node.addClass(t),this.select("bodyBox").focus(),this.enableAutoSave()},this.updateIdent=function(t,e){this.attr.mail.ident=e.ident},this.discardDraft=function(){this.trashReply()},this.after("initialize",function(){this.on(document,t.mail.sent,this.openMail),this.on(document,t.mail.deleted,this.trashReply),this.on(document,t.mail.draftSaved,this.updateIdent)}),n.call(this)}return s}),i("mail_view/ui/reply_box",["flight/lib/component","helpers/view_helper","mixins/with_hide_and_show","mixins/with_compose_inline","page/events","views/i18n"],function(t,e,i,n,s,a){"use strict";function r(){this.defaultAttrs({replyType:"reply",draftReply:!1,mail:null,mailBeingRepliedIdent:void 0}),this.getRecipients=function(){return"replyall"===this.attr.replyType?this.attr.mail.replyToAllAddress():this.attr.mail.replyToAddress()};var t=function(t){return a("re")+t};this.setupReplyBox=function(){var i,n;this.attr.draftReply?(this.attr.ident=this.attr.mail.ident,this.attr.mailBeingRepliedIdent=this.attr.mail.draft_reply_for,i=this.attr.mail.recipients(),n=this.attr.mail.body,this.attr.subject=this.attr.mail.header.subject):(this.attr.mailBeingRepliedIdent=this.attr.mail.ident,i=this.getRecipients(),n=e.quoteMail(this.attr.mail),this.attr.subject=t(this.attr.mail.header.subject)),this.attr.recipientValues.to=i.to,this.attr.recipientValues.cc=i.cc,this.renderInlineCompose("reply-box",{recipients:i,subject:this.attr.subject,body:n}),this.on(this.select("recipientsDisplay"),"click keydown",this.showRecipientFields),this.on(this.select("subjectDisplay"),"click",this.showSubjectInput)},this.showRecipientFields=function(t,e){t.keyCode&&13!==t.keyCode||(this.select("recipientsDisplay").hide(),this.select("recipientsFields").show(),$("#recipients-to-area .tt-input").focus())},this.showSubjectInput=function(){this.select("subjectDisplay").hide(),this.select("subjectInput").show(),this.select("subjectInput").focus()},this.buildMail=function(t){var e=this.builtMail(t).subject(this.select("subjectInput").val());_.isUndefined(this.attr.mail.header.message_id)||e.header("in_reply_to",this.attr.mail.header.message_id),_.isUndefined(this.attr.mail.header.list_id)||e.header("list_id",this.attr.mail.header.list_id);var i=e.build();return i.setDraftReplyFor(this.attr.mailBeingRepliedIdent),i},this.after("initialize",function(){this.setupReplyBox()})}return t(r,i,n)}),i("mail_view/ui/forward_box",["flight/lib/component","helpers/view_helper","mixins/with_hide_and_show","mixins/with_compose_inline","page/events","views/i18n"],function(t,e,i,n,s,a){"use strict";function r(){var t=function(t){return a("Fwd: ")+t};this.fetchTargetMail=function(t){this.trigger(document,s.mail.want,{mail:this.attr.ident,caller:this})},this.setupForwardBox=function(){var i=this.attr.mail;this.attr.subject=t(i.header.subject),this.attr.attachments=i.attachments,this.renderInlineCompose("forward-box",{subject:this.attr.subject,recipients:{to:[],cc:[]},body:e.quoteMail(i),attachments:this.convertToRemovableAttachments(i.attachments)});var n=this;this.$node.find("i.remove-icon").bind("click",function(t){var e=$(this),i=e.closest("li").attr("data-ident");n.trigger(document,s.mail.removeAttachment,{ident:i}),t.preventDefault()}),this.on(this.select("subjectDisplay"),"click",this.showSubjectInput),this.select("recipientsDisplay").hide(),this.select("recipientsFields").show()},this.convertToRemovableAttachments=function(t){return t.map(function(t){return t.removable=!0,t})},this.showSubjectInput=function(){this.select("subjectDisplay").hide(),this.select("subjectInput").show(),this.select("subjectInput").focus()},this.buildMail=function(t){var e=this.builtMail(t).subject(this.select("subjectInput").val()),i=["bcc","cc","date","from","message_id","reply_to","sender","to"],n=this.attr.mail.header;return _.each(i,function(t){_.isUndefined(n[t])||e.header("resent_"+t,n[t])}),e.build()},this.after("initialize",function(){this.setupForwardBox()})}return t(r,i,n)}),i("mixins/with_feature_toggle",["features"],function(t){"use strict";function e(e,i){return function(){this.around("initialize",_.bind(function(n,s,a){return t.isEnabled(e)?n(s,a):i?(i.call(this),this):void 0},this))}}return e}),i("mail_view/ui/reply_section",["flight/lib/component","views/templates","mail_view/ui/reply_box","mail_view/ui/forward_box","mixins/with_hide_and_show","mixins/with_feature_toggle","page/events"],function(t,e,i,n,s,a,r){"use strict";function o(){this.defaultAttrs({replyButton:"#reply-button",replyAllButton:"#reply-all-button",forwardButton:"#forward-button",replyBox:"#reply-box",replyType:"reply",replyContainer:".reply-container"}),this.showReply=function(){this.attr.replyType="reply",this.fetchEmailToReplyTo()},this.showReplyAll=function(){this.attr.replyType="replyall",this.fetchEmailToReplyTo()},this.showForward=function(){this.attr.replyType="forward",this.fetchEmailToReplyTo()},this.render=function(){this.$node.html(e.compose.replySection),this.on(this.select("replyButton"),"click",this.showReply),this.on(this.select("replyAllButton"),"click",this.showReplyAll),this.on(this.select("forwardButton"),"click",this.showForward)},this.checkForDraftReply=function(){this.render(),this.hideContainer(),this.trigger(document,r.mail.draftReply.want,{ident:this.attr.ident})},this.fetchEmailToReplyTo=function(t){this.trigger(document,r.mail.want,{mail:this.attr.ident,caller:this})},this.showDraftReply=function(t,e){this.showContainer(),this.hideButtons(),i.attachTo(this.select("replyBox"),{mail:e.mail,draftReply:!0})},this.showReplyComposeBox=function(t,e){this.showContainer(),this.hideButtons(),"forward"===this.attr.replyType?n.attachTo(this.select("replyBox"),{mail:e.mail}):i.attachTo(this.select("replyBox"),{mail:e.mail,replyType:this.attr.replyType})},this.hideContainer=function(){this.select("replyContainer").hide()},this.showContainer=function(){this.select("replyContainer").show()},this.hideButtons=function(){this.select("replyButton").hide(),this.select("replyAllButton").hide(),this.select("forwardButton").hide()},this.showButtons=function(){this.showContainer(),this.select("replyBox").empty(),this.select("replyButton").show(),this.select("replyAllButton").show(),this.select("forwardButton").show()},this.after("initialize",function(){this.on(document,r.ui.replyBox.showReply,this.showReply),this.on(document,r.ui.replyBox.showReplyAll,this.showReplyAll),this.on(document,r.ui.composeBox.trashReply,this.showButtons),this.on(this,r.mail.here,this.showReplyComposeBox),this.on(document,r.dispatchers.rightPane.clear,this.teardown),this.on(document,r.ui.replyBox.showReplyContainer,this.showContainer),this.on(document,r.mail.draftReply.here,this.showDraftReply),this.checkForDraftReply()})}return t(o,s,a("replySection"))}),i("mail_view/data/mail_sender",["flight/lib/component","mail_view/data/mail_builder","page/events","helpers/monitored_ajax","features"],function(t,e,i,n,s){"use strict";function a(){function t(t){return function(e){t.trigger(document,i.mail.sent,e)}}function e(t){return function(e){t.trigger(document,i.mail.send_failed,e)}}function a(t){return function(e){t.trigger(document,i.mail.draftSaved,e)}}this.defaultAttrs({mailsResource:"/mails"}),this.sendMail=function(s,a){this.trigger(i.dispatchers.rightPane.openNoMessageSelected),n.call(_,this,this.attr.mailsResource,{type:"POST",dataType:"json",contentType:"application/json; charset=utf-8",data:JSON.stringify(a)}).done(t(this)).fail(e(this))},this.saveMail=function(t){return n.call(_,this,this.attr.mailsResource,{type:"PUT",dataType:"json",contentType:"application/json; charset=utf-8",data:JSON.stringify(t),skipErrorMessage:!0})},this.saveDraft=function(t,e){this.saveMail(e).done(a(this))},this.saveMailWithCallback=function(t,e){this.saveMail(e.mail).done(function(t){return e.callback(t)}).fail(function(t){return e.callback(t)})},this.after("initialize",function(){this.on(i.mail.send,this.sendMail),s.isEnabled("saveDraft")&&this.on(i.mail.saveDraft,this.saveDraft),this.on(document,i.mail.save,this.saveMailWithCallback)})}return t(a)}),i("mixins/with_auto_refresh",["features"],function(t){"use strict";function e(e){return function(){this.defaultAttrs({refreshInterval:15e3}),this.setupRefresher=function(){clearTimeout(this.attr.refreshTimer),this.attr.refreshTimer=setTimeout(function(){this[e](),this.setupRefresher()}.bind(this),this.attr.refreshInterval)},this.after("initialize",function(){t.isAutoRefreshEnabled()&&this.setupRefresher()})}}return e}),i("services/mail_service",["flight/lib/component","views/i18n","services/model/mail","helpers/monitored_ajax","page/events","features","mixins/with_auto_refresh","page/router/url_params"],function(t,e,i,n,s,a,r,o){"use strict";function l(){function t(t){var e='tag:"'+c.attr.currentTag+'"';return"all"===t.tag&&(e="in:all"),e}function r(t){return encodeURIComponent(t)}function l(t,e){return t+"/"+e}var c;this.defaultAttrs({mailsResource:"/mails",singleMailResource:"/mail",currentTag:"",lastQuery:"",currentPage:1,numPages:1,pageSize:25}),this.errorMessage=function(t){return function(){c.trigger(document,s.ui.userAlerts.displayMessage,{message:t})}},this.updateTags=function(t,i){var a=i.ident,r=function(t){this.refreshMails(),$(document).trigger(s.mail.tags.updated,{ident:a,tags:t.tags}),$(document).trigger(s.dispatchers.tags.refreshTagList,{skipMailListRefresh:!0})},o=function(t){var i=e("Could not update mail tags");403===t.status&&(i=e("Invalid tag name")),this.trigger(document,s.ui.userAlerts.displayMessage,{message:i})};n(this,"/mail/"+a+"/tags",{type:"POST",contentType:"application/json; charset=utf-8",data:JSON.stringify({newtags:i.tags})}).done(r.bind(this)).fail(o.bind(this))},this.readMail=function(t,e){var i;i=e.checkedMails?_.map(e.checkedMails,function(t){return t.ident}):[e.ident],n(this,"/mails/read",{type:"POST",data:JSON.stringify({idents:i})}).done(this.triggerMailsRead(e.checkedMails))},this.unreadMail=function(t,e){var i;i=e.checkedMails?_.map(e.checkedMails,function(t){return t.ident}):[e.ident],n(this,"/mails/unread",{type:"POST",data:JSON.stringify({idents:i})}).done(this.triggerMailsRead(e.checkedMails))},this.triggerMailsRead=function(t){return _.bind(function(){this.refreshMails(),this.trigger(document,s.ui.mails.uncheckAll)},this)},this.triggerDeleted=function(t){return _.bind(function(){var e=t.mails||[t.mail];this.refreshMails(),this.trigger(document,s.ui.userAlerts.displayMessage,{message:t.successMessage}),this.trigger(document,s.ui.mails.uncheckAll),this.trigger(document,s.mail.deleted,{mails:e})},this)},this.triggerRecovered=function(t){return _.bind(function(){t.mails||[t.mail];this.refreshMails(),this.trigger(document,s.ui.userAlerts.displayMessage,{message:e(t.successMessage)}),this.trigger(document,s.ui.mails.uncheckAll)},this)},this.triggerArchived=function(t){return _.bind(function(t){this.refreshMails(),this.trigger(document,s.ui.userAlerts.displayMessage,{message:e(t.successMessage)}),this.trigger(document,s.ui.mails.uncheckAll)},this)},this.archiveManyMails=function(t,i){var s=_.map(i.checkedMails,function(t){return t.ident});n(this,"/mails/archive",{type:"POST",dataType:"json",contentType:"application/json; charset=utf-8",data:JSON.stringify({idents:s})}).done(this.triggerArchived(i)).fail(this.errorMessage(e("Could not archive emails")))},this.deleteMail=function(t,i){n(this,"/mail/"+i.mail.ident,{type:"DELETE"}).done(this.triggerDeleted(i)).fail(this.errorMessage(e("Could not delete email")))},this.deleteManyMails=function(t,i){var s=i,a=_.map(i.mails,function(t){return t.ident});n(this,"/mails/delete",{type:"POST",dataType:"json",contentType:"application/json; charset=utf-8",data:JSON.stringify({idents:a})}).done(this.triggerDeleted(s)).fail(this.errorMessage(e("Could not delete emails")))},this.recoverManyMails=function(t,i){var s=i,a=_.map(i.mails,function(t){return t.ident});n(this,"/mails/recover",{type:"POST",dataType:"json",contentType:"application/json; charset=utf-8",data:JSON.stringify({idents:a})}).done(this.triggerRecovered(s)).fail(this.errorMessage(e("Could not move emails to inbox")))},this.fetchByTag=function(e,i){this.attr.currentTag=i.tag,this.attr.lastQuery=t(i),this.updateCurrentPageNumber(1),this.refreshMails()},this.newSearch=function(t,e){this.attr.lastQuery=e.query,this.attr.currentTag="all",this.refreshMails()},this.mailFromJSON=function(t){return i.create(t)},this.parseMails=function(t){return t.mails=_.map(t.mails,this.mailFromJSON,this),t},this.excludeTrashedEmailsForDraftsAndSent=function(t){return'tag:"drafts"'===t||'tag:"sent"'===t?t+' -in:"trash"':t},this.refreshMails=function(){var t=this.attr.mailsResource+"?q="+r(this.attr.lastQuery)+"&p="+this.attr.currentPage+"&w="+this.attr.pageSize;this.attr.lastQuery=this.excludeTrashedEmailsForDraftsAndSent(this.attr.lastQuery),n(this,t,{dataType:"json"}).done(function(t){this.attr.numPages=Math.ceil(t.stats.total/this.attr.pageSize),this.trigger(document,s.mails.available,_.merge({tag:this.attr.currentTag,forSearch:this.attr.lastQuery},this.parseMails(t)))}.bind(this)).fail(function(){this.trigger(document,s.ui.userAlerts.displayMessage,{message:e("Could not fetch messages"),"class":"error"})}.bind(this))},this.fetchSingle=function(t,e){var i=l(this.attr.singleMailResource,e.mail);n(this,i,{dataType:"json"}).done(function(t){return _.isNull(t)?void this.trigger(e.caller,s.mail.notFound):void this.trigger(e.caller,s.mail.here,{mail:this.mailFromJSON(t)})}.bind(this))},this.previousPage=function(){this.attr.currentPage>1&&(this.updateCurrentPageNumber(this.attr.currentPage-1),this.refreshMails())},this.nextPage=function(){this.attr.currentPage0:e.counts.total-e.counts.read>0},this.badgeType=function(t){return _.include(s,t.name)?"total":"unread"},this.doUnselect=function(){this.$node.removeClass("selected")},this.doSelect=function(){this.$node.addClass("selected")},this.selectTag=function(t,e){this.attr.currentTag=e.tag,e.tag===this.attr.tag.name?this.doSelect():this.doUnselect()},this.selectTagAll=function(){this.selectTag(null,{tag:"all"})},this.viewFor=function(t,e,i){return e({tagName:t["default"]?n("tags."+t.name):t.name,ident:this.hashIdent(t.ident),count:"total"===this.badgeType(t)?t.counts.total:t.counts.total-t.counts.read,displayBadge:this.displayBadge(t),badgeType:this.badgeType(t),icon:t.icon,selected:t.name===i?"selected":""})},this.decreaseReadCountIfMatchingTag=function(t,i){var n=_.flatten([i.tags,i.mailbox]);_.contains(n,this.attr.tag.name)&&(this.attr.tag.counts.read++,this.$node.html(this.viewFor(this.attr.tag,e.tags.tagInner,this.attr.currentTag)),_.isUndefined(this.attr.shortcut)||this.attr.shortcut.reRender())},this.triggerSelect=function(){this.trigger(document,i.ui.tag.select,{tag:this.attr.tag.name}),this.removeSearchingClass()},this.addSearchingClass=function(){"all"===this.attr.tag.name&&this.$node.addClass("searching")},this.hashIdent=function(t){return"undefined"==typeof t?"":"number"==typeof t?t:t.match(/^[a-zA-Z0-9]+$/)?t:Math.abs(String(t).split("").reduce(function(t,e){return t=(t<<5)-t+e.charCodeAt(0),t&t},0))},this.removeSearchingClass=function(){"all"===this.attr.tag.name&&this.$node.removeClass("searching")},this.after("initialize",function(){this.on("click",this.triggerSelect),this.on(document,i.mail.read,this.decreaseReadCountIfMatchingTag),this.on(document,i.search.perform,this.addSearchingClass),this.on(document,i.search.empty,this.removeSearchingClass),this.on(document,i.ui.tag.select,this.selectTag),this.on(document,i.search.perform,this.selectTagAll),this.on(document,i.search.empty,this.selectTagAll)}),this.renderAndAttach=function(t,n){var s=this.viewFor(n.tag,e.tags.tag,n.currentTag);t.append(s),this.initialize("#tag-"+this.hashIdent(n.tag.ident),n),this.on(t,i.tags.teardown,this.teardown)}}var a=t(s);return a.appendedTo=function(t,e){var i=new this;return i.renderAndAttach(t,e),i},a}),i("tags/ui/tag_list",["flight/lib/component","tags/ui/tag","views/templates","page/events","page/router/url_params"],function(t,e,i,n,s){"use strict";function a(t){return o[t.name]||"999"+t.name}function r(){function t(t,i,n){var s=t["default"]?i:n;e.appendedTo(s,{tag:t,currentTag:this.getCurrentTag()})}function r(t){_.each(t,function(t){this.trigger(t,n.tags.teardown),t.empty()}.bind(this))}this.defaultAttrs({defaultTagList:"#default-tag-list",customTagList:"#custom-tag-list"}),this.renderTagList=function(e){var i=this.select("defaultTagList"),n=this.select("customTagList");r.call(this,[i,n]),e.forEach(function(e){t.call(this,e,i,n)}.bind(this))},this.displayTags=function(t,e){this.renderTagList(_.sortBy(e.tags,a))},this.getCurrentTag=function(){return this.attr.currentTag||s.getTag()},this.updateCurrentTag=function(t,e){this.attr.currentTag=e.tag},this.renderTagListTemplate=function(){this.$node.html(i.tags.tagList())},this.after("initialize",function(){this.on(document,n.tags.received,this.displayTags),this.on(document,n.ui.tag.select,this.updateCurrentTag),this.renderTagListTemplate()})}var o={inbox:"0",sent:"1",drafts:"2",trash:"3",all:"4"};return t(r)}),i("tags/data/tags",["flight/lib/component","page/events","helpers/monitored_ajax","mixins/with_feature_toggle","mixins/with_auto_refresh"],function(t,e,i,n,s){"use strict";function a(){function t(t){return function(i){i.push(r.all),t.trigger(document,e.tags.received,{tags:i})}}this.defaultAttrs({tagsResource:"/tags"}),this.fetchTags=function(e,n){i(this,this.attr.tagsResource).done(t(this))},this.refreshTags=function(){var t=null;this.fetchTags(t)},this.after("initialize",function(){this.on(document,e.tags.want,this.fetchTags),this.on(document,e.mail.sent,this.fetchTags)})}var r=t(a,n("tags",function(){$(document).trigger(e.ui.mails.refresh)}),s("refreshTags"));return r.all={name:"all",ident:"8752888923742657436",query:"in:all","default":!0,counts:{total:0,read:0,starred:0,replied:0}},r}),i("page/router",["flight/lib/component","page/events","page/router/url_params"],function(t,e,i){"use strict";return t(function(){function t(t){var e="/#/"+t.tag;return _.isUndefined(t.mailIdent)||(e+="/mail/"+t.mailIdent),e}function n(t,e){return{tag:t.tag||e&&e.tag||i.defaultTag(),mailIdent:t.mailIdent,query:t.query,isDisplayNoMessageSelected:!!t.isDisplayNoMessageSelected}}this.defaultAttrs({history:window.history}),this.pushState=function(e,i){if(!i.fromPopState){var s=n(i,this.attr.history.state);this.attr.history.pushState(s,"",t(s))}},this.popState=function(t){var n=t.state||{};this.trigger(document,e.ui.tag.select,{tag:n.tag||i.getTag(),mailIdent:n.mailIdent,fromPopState:!0}),t.state.isDisplayNoMessageSelected&&this.trigger(document,e.dispatchers.rightPane.openNoMessageSelectedWithoutPushState)},this.after("initialize",function(){this.on(document,e.router.pushState,this.pushState),this.on(document,e.ui.tag.select,this.pushState),this.on(document,e.search.perform,this.pushState),this.on(document,e.search.empty,this.pushState),window.onpopstate=this.popState.bind(this)})})}),i("mail_view/ui/draft_box",["flight/lib/component","views/templates","mixins/with_mail_edit_base","page/events","mail_view/data/mail_builder"],function(t,e,i,n,s){"use strict";function a(){this.defaultAttrs({closeMailButton:".close-mail-button"}),this.showNoMessageSelected=function(){this.trigger(n.dispatchers.rightPane.openNoMessageSelected)},this.buildMail=function(t){return this.builtMail(t).build()},this.builtMail=function(t){return s.newMail(this.attr.ident).subject(this.select("subjectBox").val()).to(this.attr.recipientValues.to).cc(this.attr.recipientValues.cc).bcc(this.attr.recipientValues.bcc).body(this.select("bodyBox").val()).attachment(this.attr.attachments).tag(t)},this.renderDraftBox=function(t,i){var s=i.mail,a=s.textPlainBody;this.attr.ident=s.ident,this.render(e.compose.box,{recipients:{to:s.header.to,cc:s.header.cc,bcc:s.header.bcc},subject:s.header.subject,body:a,attachments:this.convertToRemovableAttachments(s.attachments)});var r=this;this.$node.find("i.remove-icon").bind("click",function(t){var e=$(this),i=e.closest("li").attr("data-ident");r.trigger(document,n.mail.removeAttachment,{ident:i,element:e}),t.preventDefault()}),this.enableFloatlabel("input.floatlabel"),this.enableFloatlabel("textarea.floatlabel"),this.select("recipientsFields").show(),this.select("bodyBox").focus(),this.select("tipMsg").hide(),this.enableAutoSave(),this.bindCollapse(),this.on(this.select("closeMailButton"),"click",this.showNoMessageSelected)},this.convertToRemovableAttachments=function(t){return t.map(function(t){return t.removable=!0,t})},this.mailDeleted=function(t,e){_.contains(_.pluck(e.mails,"ident"),this.attr.ident)&&this.trigger(n.dispatchers.rightPane.openNoMessageSelected)},this.after("initialize",function(){this.on(this,n.mail.here,this.renderDraftBox),this.on(document,n.mail.sent,this.showNoMessageSelected),this.on(document,n.mail.deleted,this.mailDeleted),this.trigger(document,n.mail.want,{mail:this.attr.mailIdent,caller:this})})}return t(a,i)}),i("mail_view/ui/feedback_box",["flight/lib/component","views/templates","page/events","features"],function(t,e,i,n){"use strict";return t(function(){this.defaultAttrs({closeButton:".close-mail-button",submitButton:"#send-button",textBox:"#text-box"}),this.render=function(){this.$node.html(e.compose.feedback())},this.openFeedbackBox=function(){var t=this.reset("feedback-box");this.attachTo(t),this.enableFloatlabel("input.floatlabel"),this.enableFloatlabel("textarea.floatlabel")},this.showNoMessageSelected=function(){this.trigger(document,i.dispatchers.rightPane.openNoMessageSelected)},this.submitFeedback=function(){var t=this.select("textBox").val();this.trigger(document,i.feedback.submit,{feedback:t})},this.showSuccessMessage=function(){this.trigger(document,i.ui.userAlerts.displayMessage,{message:"Thanks for your feedback!"})},this.after("initialize",function(){n.isEnabled("feedback")&&(this.render(),this.on(document,i.dispatchers.rightPane.openFeedbackBox,this.openFeedbackBox),this.on(document,i.feedback.submitted,this.showNoMessageSelected),this.on(document,i.feedback.submitted,this.showSuccessMessage),this.on(this.select("closeButton"),"click",this.showNoMessageSelected),this.on(this.select("submitButton"),"click",this.submitFeedback))})})}),i("dispatchers/right_pane_dispatcher",["flight/lib/component","mail_view/ui/compose_box","mail_view/ui/mail_view","mail_view/ui/reply_section","mail_view/ui/draft_box","mail_view/ui/no_message_selected_pane","mail_view/ui/feedback_box","page/events"],function(t,e,i,n,s,a,r,o){"use strict";function l(){this.defaultAttrs({rightPane:"#right-pane",composeBox:"compose-box",feedbackBox:"feedback-box",mailView:"mail-view",noMessageSelectedPane:"no-message-selected-pane",replySection:"reply-section",draftBox:"draft-box",currentTag:""}),this.createAndAttach=function(t){var e=$("
        ",{id:t});return this.select("rightPane").append(e),e},this.reset=function(t){this.trigger(document,o.dispatchers.rightPane.clear),this.select("rightPane").empty();var e=this.createAndAttach(t);return e},this.openComposeBox=function(){var t=this.reset(this.attr.composeBox);e.attachTo(t,{currentTag:this.attr.currentTag})},this.openFeedbackBox=function(){var t=this.reset(this.attr.feedbackBox);r.attachTo(t)},this.openMail=function(t,e){var s=this.reset(this.attr.mailView);i.attachTo(s,e);var a=this.createAndAttach(this.attr.replySection);n.attachTo(a,{ident:e.ident})},this.initializeNoMessageSelectedPane=function(){var t=this.reset(this.attr.noMessageSelectedPane);a.attachTo(t),this.trigger(document,o.dispatchers.middlePane.cleanSelected)},this.openNoMessageSelectedPane=function(t,e){this.initializeNoMessageSelectedPane(),this.trigger(document,o.router.pushState,{tag:this.attr.currentTag,isDisplayNoMessageSelected:!0})},this.openDraft=function(t,e){var i=this.reset(this.attr.draftBox);s.attachTo(i,{mailIdent:e.ident,currentTag:this.attr.currentTag})},this.selectTag=function(t,e){this.trigger(document,o.ui.tags.loaded,{tag:e.tag})},this.saveTag=function(t,e){this.attr.currentTag=e.tag},this.after("initialize",function(){this.on(document,o.dispatchers.rightPane.openComposeBox,this.openComposeBox),this.on(document,o.dispatchers.rightPane.openDraft,this.openDraft),this.on(document,o.ui.mail.open,this.openMail),this.on(document,o.dispatchers.rightPane.openFeedbackBox,this.openFeedbackBox),this.on(document,o.dispatchers.rightPane.openNoMessageSelected,this.openNoMessageSelectedPane),this.on(document,o.dispatchers.rightPane.selectTag,this.selectTag),this.on(document,o.ui.tag.selected,this.saveTag),this.on(document,o.ui.tag.select,this.saveTag),this.on(document,o.dispatchers.rightPane.openNoMessageSelectedWithoutPushState,this.initializeNoMessageSelectedPane),this.initializeNoMessageSelectedPane()})}return t(l)}),i("helpers/triggering",[],function(){"use strict";return function(t,e,i,n){return function(){n?t.trigger(n,e,i||{}):t.trigger(e,i||{})}}}),i("dispatchers/middle_pane_dispatcher",["flight/lib/component","page/events","helpers/triggering","mail_view/ui/no_mails_available_pane"],function(t,e,i,n){"use strict";return t(function(){this.defaultAttrs({middlePane:"#middle-pane",noMailsAvailablePane:"no-mails-available-pane"}),this.createChildDiv=function(t){var e=$("
        ",{id:t});return this.select("middlePane").append(e),e},this.resetChildDiv=function(t){$("#"+t).remove()},this.refreshMailList=function(t,i){this.trigger(document,e.ui.mails.fetchByTag,i)},this.cleanSelected=function(t,i){this.trigger(document,e.ui.mails.cleanSelected)},this.resetScroll=function(){this.select("middlePane").scrollTop(0)},this.updateMiddlePaneHeight=function(){var t=$(window).height(),e=$("#main").outerHeight()+$("#top-pane").outerHeight();this.select("middlePane").css({height:t-e+"px"})},this.onMailsChange=function(t,e){if(this.resetChildDiv(this.attr.noMailsAvailablePane),e.mails.length>0)n.teardownAll();else{var i=this.createChildDiv(this.attr.noMailsAvailablePane);n.attachTo(i,{tag:e.tag,forSearch:e.forSearch})}},this.after("initialize",function(){this.on(document,e.dispatchers.middlePane.refreshMailList,this.refreshMailList),this.on(document,e.dispatchers.middlePane.cleanSelected,this.cleanSelected),this.on(document,e.dispatchers.middlePane.resetScroll,this.resetScroll),this.on(document,e.mails.available,this.onMailsChange),this.updateMiddlePaneHeight(),$(window).on("resize",this.updateMiddlePaneHeight.bind(this))})})}),i("dispatchers/left_pane_dispatcher",["flight/lib/component","page/router/url_params","page/events"],function(t,e,i){"use strict";function n(){var t=!1;this.refreshTagList=function(t,e){this.trigger(document,i.tags.want,{caller:this.$node,skipMailListRefresh:e.skipMailListRefresh})},this.loadTags=function(t,e){this.trigger(document,i.ui.tagList.load,e)},this.selectTag=function(t,n){var s=n&&n.tag||e.getTag();this.trigger(document,i.ui.tag.select,{tag:s,skipMailListRefresh:n.skipMailListRefresh})},this.pushUrlState=function(e,n){t&&this.trigger(document,i.router.pushState,n),t=!0},this.after("initialize",function(){this.on(document,i.dispatchers.tags.refreshTagList,this.refreshTagList),this.on(document,i.ui.tags.loaded,this.selectTag),this.on(document,i.ui.tag.selected,this.pushUrlState),this.on(document,i.ui.tag.select,this.pushUrlState),this.trigger(document,i.tags.want,{caller:this.$node})})}return t(n)}),i("search/search_trigger",["flight/lib/component","views/templates","page/events"],function(t,e,i){"use strict";function n(){var t="Search results for: ";this.defaultAttrs({input:"input[type=search]",form:"form"}),this.render=function(){this.$node.html(e.search.trigger())},this.search=function(t,e){this.trigger(document,i.search.resetHighlight),t.preventDefault();var n=this.select("input"),s=n.val();n.blur(),_.isEmpty(s)?this.trigger(document,i.search.empty):this.trigger(document,i.search.perform,{query:s})},this.clearInput=function(){this.select("input").val("")},this.showOnlySearchTerms=function(e){var i=this.select("input").val(),n=i.slice(t.length);this.select("input").val(n)},this.showSearchTermsAndPlaceHolder=function(e){var i=this.select("input").val();i.length>0&&this.select("input").val(t+i)},this.after("initialize",function(){this.render(),this.on(this.select("form"),"submit",this.search),this.on(this.select("input"),"focus",this.showOnlySearchTerms), +this.on(this.select("input"),"blur",this.showSearchTermsAndPlaceHolder),this.on(document,i.ui.tag.selected,this.clearInput),this.on(document,i.ui.tag.select,this.clearInput)})}return t(n)}),i("search/results_highlighter",["flight/lib/component","page/events"],function(t,e){"use strict";function i(){function t(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}this.defaultAttrs({keywords:[]}),this.getKeywordsSearch=function(t,e){this.attr.keywords=e.query.split(" ").map(function(t){return t.toLowerCase()})},this.highlightResults=function(e,i){var n=i.where;this.attr.keywords&&_.each(this.attr.keywords,function(e){e=t(e),$(n).highlightRegex(new RegExp(e,"i"),{tagType:"em",className:"search-highlight"})})},this.clearHighlights=function(t,e){this.attr.keywords=[],_.each($("em.search-highlight"),function(t){var e=$(t),i=e.text();e.replaceWith(i)})},this.highlightString=function(e){return _.each(this.attr.keywords,function(i){i=t(i);var n=new RegExp("("+i+")","ig");e=e.replace(n,'$1')}),e},this.highlightMailContent=function(t,i){var n=i.mail;n.textPlainBody=this.highlightString(n.textPlainBody),this.trigger(document,e.mail.display,i)},this.after("initialize",function(){this.on(document,e.search.perform,this.getKeywordsSearch),this.on(document,e.ui.tag.select,this.clearHighlights),this.on(document,e.search.resetHighlight,this.clearHighlights),this.on(document,e.search.highlightResults,this.highlightResults),this.on(document,e.mail.highlightMailContent,this.highlightMailContent)})}return t(i)}),i("foundation/off_canvas",["flight/lib/component","page/events"],function(t,e){"use strict";return t(function(){this.closeSlider=function(t){$(".off-canvas-wrap.content").removeClass("move-right"),this.toggleTagsVisibility()},this.toggleSlideContent=function(t){t.preventDefault(),$(".left-off-canvas-toggle").click(),this.toggleTagsVisibility()},this.toggleTagsVisibility=function(){$(".off-canvas-wrap.content").hasClass("move-right")?$("#custom-tag-list").addClass("expanded"):$("#custom-tag-list").removeClass("expanded")},this.after("initialize",function(){this.on($("#middle-pane-container"),"click",this.closeSlider),this.on($("#right-pane"),"click",this.closeSlider),this.on($(".side-nav-toggle"),"click",this.toggleSlideContent)})})}),i("page/pane_contract_expand",["flight/lib/component","page/events"],function(t,e){"use strict";function i(){this.defaultAttrs({RIGHT_PANE_EXPAND_CLASSES:"small-7 medium-7 large-7 columns",RIGHT_PANE_CONTRACT_CLASSES:"small-7 medium-4 large-4 columns",MIDDLE_PANE_EXPAND_CLASSES:"small-5 medium-8 large-8 columns no-padding",MIDDLE_PANE_CONTRACT_CLASSES:"small-5 medium-5 large-5 columns no-padding"}),this.expandMiddlePaneContractRightPane=function(){$("#middle-pane-container").attr("class",this.attr.MIDDLE_PANE_EXPAND_CLASSES),$("#right-pane").attr("class",this.attr.RIGHT_PANE_CONTRACT_CLASSES)},this.contractMiddlePaneExpandRightPane=function(){$("#middle-pane-container").attr("class",this.attr.MIDDLE_PANE_CONTRACT_CLASSES),$("#right-pane").attr("class",this.attr.RIGHT_PANE_EXPAND_CLASSES)},this.after("initialize",function(){this.on(document,e.ui.mail.open,this.contractMiddlePaneExpandRightPane),this.on(document,e.dispatchers.rightPane.openComposeBox,this.contractMiddlePaneExpandRightPane),this.on(document,e.dispatchers.rightPane.openDraft,this.contractMiddlePaneExpandRightPane),this.on(document,e.dispatchers.rightPane.openFeedbackBox,this.contractMiddlePaneExpandRightPane),this.on(document,e.dispatchers.rightPane.openNoMessageSelected,this.expandMiddlePaneContractRightPane),this.expandMiddlePaneContractRightPane()})}return t(i)}),i("views/recipientListFormatter",[],function(){"use strict";Handlebars.registerHelper("formatRecipients",function(t){function e(t,e){return function(i){return t+Handlebars.Utils.escapeExpression(i)+e}}var i=_.map(t.to,e('',"")),n=_.map(t.cc,e('cc: ',"")),s=_.map(t.bcc,e('bcc: ',""));return new Handlebars.SafeString(i.concat(n,s).join(", "))})}),i("user_settings/data/user_settings",["flight/lib/component","helpers/monitored_ajax","page/events"],function(t,e,i){"use strict";return t(function(){this.defaultAttrs({userSettingsResource:"/user-settings",userSettings:{}}),this.sendInfo=function(){this.trigger(document,i.userSettings.here,this.attr.userSettings)},this.getUserSettings=function(){var t=function(t){this.attr.userSettings=t};e(this,this.attr.userSettingsResource,{type:"GET",contentType:"application/json; charset=utf-8"}).done(t.bind(this))},this.after("initialize",function(){this.getUserSettings(),this.on(document,i.userSettings.getInfo,this.sendInfo)})})}),i("user_settings/ui/user_settings_box",["flight/lib/component","features","views/templates","page/events","helpers/monitored_ajax"],function(t,e,i,n,s){"use strict";return t(function(){this.defaultAttrs({close:"#user-settings-close",userSettingsBoxContainer:"#user-settings-box"}),this.render=function(t,s){function a(t,e){return t.parentNode===e?!0:null===t.parentNode?!1:a(t.parentNode,e)}e.isLogoutEnabled()&&this.$node.addClass("extra-bottom-space"),this.$node.addClass("arrow-box"),this.$node.html(i.page.userSettingsBox(s)),this.on(this.attr.close,"click",function(){this.trigger(document,n.userSettings.destroyPopup)}),this.on(document,"click",function(t){var e=$(this.attr.userSettingsBoxContainer).get(0),i=t.target||t.srcElement;i===e||a(i,e)||this.destroy()})},this.destroy=function(){this.$node.remove(),this.teardown()},this.after("initialize",function(){this.on(document,n.userSettings.here,this.render),this.on(document,n.userSettings.destroyPopup,this.destroy),this.trigger(document,n.userSettings.getInfo)})})}),i("user_settings/ui/user_settings_icon",["flight/lib/component","views/templates","page/events","user_settings/ui/user_settings_box"],function(t,e,i,n){"use strict";return t(function(){this.defaultAttrs({userSettingsBox:$("#user-settings-box")}),this.render=function(){this.$node.html(e.page.userSettingsIcon())},this.toggleUserSettingsBox=function(){if(0===this.attr.userSettingsBox.children().length){var t=$("
        ");$(this.attr.userSettingsBox).append(t),n.attachTo(t),this.attr.userSettingsInfo=n}else this.trigger(document,i.userSettings.destroyPopup)},this.triggerToggleUserSettingsBox=function(t){this.trigger(document,i.ui.userSettingsBox.toggle),t.stopPropagation()},this.after("initialize",function(){this.render(),this.on("click",this.triggerToggleUserSettingsBox),this.on(document,i.ui.userSettingsBox.toggle,this.toggleUserSettingsBox)})})}),i("page/logout",["flight/lib/component","features","views/templates","helpers/browser"],function(t,e,i,n){"use strict";return t(function(){this.defaultAttrs({form:"#logout-form"}),this.render=function(){var t=i.page.logout({logout_url:e.getLogoutUrl(),csrf_token:n.getCookie("XSRF-TOKEN")});this.$node.html(t)},this.logout=function(){this.select("form").submit()},this.after("initialize",function(){e.isLogoutEnabled()&&(this.render(),this.on(this.$node,"click",this.logout))})})}),i("page/logout_shortcut",["flight/lib/component","features","views/templates"],function(t,e,i){"use strict";return t(function(){this.render=function(){if(e.isLogoutEnabled()){var t=i.page.logoutShortcut();this.$node.html(t)}},this.after("initialize",function(){this.render()})})}),i("feedback/feedback_trigger",["flight/lib/component","views/templates","page/events","features"],function(t,e,i,n){"use strict";return t(function(){this.render=function(){this.$node.html(e.feedback.feedback())},this.onClick=function(){this.trigger(document,i.dispatchers.rightPane.openFeedbackBox)},this.after("initialize",function(){n.isEnabled("feedback")&&(this.render(),this.on("click",this.onClick))})})}),i("mail_view/data/feedback_sender",["flight/lib/component","helpers/monitored_ajax","page/events"],function(t,e,i){"use strict";return t(function(){this.defaultAttrs({feedbackResource:"/feedback"}),this.successSubmittingFeedback=function(){this.trigger(document,i.feedback.submitted)},this.submitFeedback=function(t,i){e.call(_,this,this.attr.feedbackResource,{type:"POST",dataType:"json",contentType:"application/json; charset=utf-8",data:JSON.stringify(i)}).done(this.successSubmittingFeedback())},this.after("initialize",function(){this.on(document,i.feedback.submit,this.submitFeedback)})})}),i("page/version",["flight/lib/component","views/templates"],function(t,e){"use strict";return t(function(){this.render=function(){this.$node.html(e.page.version())},this.after("initialize",function(){this.render()})})}),i("page/unread_count_title",["flight/lib/component","page/events"],function(t,e){"use strict";return t(function(){this.getTitleText=function(){return document.title},this.updateCount=function(t,e){var i=e.mails.filter(function(t){return-1===t.status.indexOf("read")}).length,n=this.toTitleCase(e.tag),s=i>0?" ("+i+") - ":" - ";document.title=n+s+this.rawTitle},this.toTitleCase=function(t){return t.replace(/\b\w/g,function(t){return t.toUpperCase()})},this.after("initialize",function(){this.rawTitle=document.title,this.on(document,e.mails.available,this.updateCount)})})}),i("page/pix_logo",["flight/lib/component","page/events"],function(t,e){"use strict";function i(){this.turnAnimationOn=function(){$(".logo-part-animation-off").attr("class","logo-part-animation-on")},this.turnAnimationOff=function(){setTimeout(function(){$(".logo-part-animation-on").attr("class","logo-part-animation-off")},600)},this.triggerSpinLogo=function(t,i){this.trigger(document,e.ui.page.spinLogo)},this.triggerStopSpinningLogo=function(t,i){this.trigger(document,e.ui.page.stopSpinningLogo)},this.after("initialize",function(){this.on(document,e.ui.page.spinLogo,this.turnAnimationOn),this.on(document,e.ui.page.stopSpinningLogo,this.turnAnimationOff),this.on(document,e.ui.tag.select,this.triggerSpinLogo),this.on(document,e.mails.available,this.triggerStopSpinningLogo),this.on(document,e.mail.saveDraft,this.triggerSpinLogo),this.on(document,e.mail.draftSaved,this.triggerStopSpinningLogo),this.on(document,e.ui.mail.open,this.triggerSpinLogo),this.on(document,e.dispatchers.rightPane.openDraft,this.triggerSpinLogo),this.on(document,e.search.perform,this.triggerSpinLogo),this.on(document,e.mail.want,this.triggerStopSpinningLogo)})}return t(i)}),i("page/default",["mail_view/ui/compose_box","mail_list_actions/ui/mail_list_actions","user_alerts/ui/user_alerts","mail_list/ui/mail_list","mail_view/ui/no_message_selected_pane","mail_view/ui/no_mails_available_pane","mail_view/ui/mail_view","mail_view/ui/mail_actions","mail_view/ui/reply_section","mail_view/data/mail_sender","services/mail_service","services/delete_service","services/recover_service","tags/ui/tag_list","tags/data/tags","page/router","dispatchers/right_pane_dispatcher","dispatchers/middle_pane_dispatcher","dispatchers/left_pane_dispatcher","search/search_trigger","search/results_highlighter","foundation/off_canvas","page/pane_contract_expand","views/i18n","views/recipientListFormatter","flight/lib/logger","user_settings/data/user_settings","user_settings/ui/user_settings_icon","page/logout","page/logout_shortcut","feedback/feedback_trigger","mail_view/ui/feedback_box","mail_view/data/feedback_sender","page/version","page/unread_count_title","page/pix_logo","helpers/browser"],function(t,e,i,n,s,a,r,o,l,c,u,h,d,p,f,g,m,v,b,_,y,w,x,k,C,S,D,T,A,E,M,P,I,N,F,O,R){"use strict";function j(t){k.init(t+"/assets/"),x.attachTo(document),i.attachTo("#user-alerts"),n.attachTo("#mail-list"),e.attachTo("#list-actions"),_.attachTo("#search-trigger"),y.attachTo(document),c.attachTo(document),u.attachTo(document),h.attachTo(document),d.attachTo(document),f.attachTo(document),p.attachTo("#tag-list"),g.attachTo(document),m.attachTo(document),v.attachTo(document),b.attachTo(document),w.attachTo(document),D.attachTo(document),T.attachTo("#user-settings-icon"),A.attachTo("#logout"),E.attachTo("#logout-shortcut"),N.attachTo(".version"),M.attachTo("#feedback"),I.attachTo(document),F.attachTo(document),O.attachTo(document),$.ajaxSetup({headers:{"X-XSRF-TOKEN":R.getCookie("XSRF-TOKEN")}})}return j}),function(){"use strict";Array.prototype.remove=function(t,e){var i=this.slice((e||t)+1||this.length);return this.length=0>t?this.length+t:t,this.push.apply(this,i)}}(),i("js/monkey_patching/array",function(){}),function(){"use strict";var t=window.postMessage;window.postMessage=function(e,i){try{t(e,i)}catch(n){console.log(e,i)}}}(),i("js/monkey_patching/post_message",function(){}),e(["js/monkey_patching/array","js/monkey_patching/post_message"],function(){}),i("js/monkey_patching/all",function(){}),t.config({baseUrl:"../assets/",paths:{mail_list:"js/mail_list",page:"js/page",feedback:"js/feedback",flight:"bower_components/flight",DOMPurify:"bower_components/DOMPurify/dist/purify.min",he:"bower_components/he/he",hbs:"js/generated/hbs",helpers:"js/helpers",lib:"js/lib",views:"js/views",tags:"js/tags",mail_list_actions:"js/mail_list_actions",user_alerts:"js/user_alerts",mail_view:"js/mail_view",dispatchers:"js/dispatchers",services:"js/services",mixins:"js/mixins",search:"js/search",foundation:"js/foundation",features:"js/features/features",i18next:"bower_components/i18next/i18next.amd","quoted-printable":"bower_components/quoted-printable",utf8:"bower_components/utf8",user_settings:"js/user_settings"}}),e(["flight/lib/compose","flight/lib/debug"],function(t,e){"use strict";e.enable(!0),e.events.logAll()}),e(["flight/lib/compose","flight/lib/registry","flight/lib/advice","flight/lib/logger","flight/lib/debug","page/events","page/default","js/monkey_patching/all"],function(t,e,i,n,s,a,r,o){"use strict";window.Pixelated=window.Pixelated||{},window.Pixelated.events=a,t.mixin(e,[i.withAdvice,n]),s.enable(!0),s.events.logAll(),r("")}),i("js/main",function(){})}(); diff --git a/src/pixelated_www/bower_components/font-awesome/css/font-awesome.min.css b/src/pixelated_www/bower_components/font-awesome/css/font-awesome.min.css new file mode 100644 index 00000000..ec53d4d6 --- /dev/null +++ b/src/pixelated_www/bower_components/font-awesome/css/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.2.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff?v=4.2.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.2.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"} \ No newline at end of file diff --git a/src/pixelated_www/bower_components/font-awesome/fonts/FontAwesome.otf b/src/pixelated_www/bower_components/font-awesome/fonts/FontAwesome.otf new file mode 100644 index 00000000..81c9ad94 Binary files /dev/null and b/src/pixelated_www/bower_components/font-awesome/fonts/FontAwesome.otf differ diff --git a/src/pixelated_www/bower_components/font-awesome/fonts/fontawesome-webfont.eot b/src/pixelated_www/bower_components/font-awesome/fonts/fontawesome-webfont.eot new file mode 100644 index 00000000..84677bc0 Binary files /dev/null and b/src/pixelated_www/bower_components/font-awesome/fonts/fontawesome-webfont.eot differ diff --git a/src/pixelated_www/bower_components/font-awesome/fonts/fontawesome-webfont.svg b/src/pixelated_www/bower_components/font-awesome/fonts/fontawesome-webfont.svg new file mode 100644 index 00000000..d907b25a --- /dev/null +++ b/src/pixelated_www/bower_components/font-awesome/fonts/fontawesome-webfont.svg @@ -0,0 +1,520 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/pixelated_www/bower_components/font-awesome/fonts/fontawesome-webfont.ttf b/src/pixelated_www/bower_components/font-awesome/fonts/fontawesome-webfont.ttf new file mode 100644 index 00000000..96a3639c Binary files /dev/null and b/src/pixelated_www/bower_components/font-awesome/fonts/fontawesome-webfont.ttf differ diff --git a/src/pixelated_www/bower_components/font-awesome/fonts/fontawesome-webfont.woff b/src/pixelated_www/bower_components/font-awesome/fonts/fontawesome-webfont.woff new file mode 100644 index 00000000..628b6a52 Binary files /dev/null and b/src/pixelated_www/bower_components/font-awesome/fonts/fontawesome-webfont.woff differ diff --git a/src/pixelated_www/bower_components/jquery-file-upload/css/jquery.fileupload.css b/src/pixelated_www/bower_components/jquery-file-upload/css/jquery.fileupload.css new file mode 100644 index 00000000..ce7e4229 --- /dev/null +++ b/src/pixelated_www/bower_components/jquery-file-upload/css/jquery.fileupload.css @@ -0,0 +1,37 @@ +@charset "UTF-8"; +/* + * jQuery File Upload Plugin CSS + * https://github.com/blueimp/jQuery-File-Upload + * + * Copyright 2013, Sebastian Tschan + * https://blueimp.net + * + * Licensed under the MIT license: + * http://www.opensource.org/licenses/MIT + */ + +.fileinput-button { + position: relative; + overflow: hidden; + display: inline-block; +} +.fileinput-button input { + position: absolute; + top: 0; + right: 0; + margin: 0; + opacity: 0; + -ms-filter: 'alpha(opacity=0)'; + font-size: 200px; + direction: ltr; + cursor: pointer; +} + +/* Fixes for IE < 8 */ +@media screen\9 { + .fileinput-button input { + filter: alpha(opacity=0); + font-size: 100%; + height: 100%; + } +} diff --git a/src/pixelated_www/css/sandbox.css b/src/pixelated_www/css/sandbox.css new file mode 100644 index 00000000..06ee8a05 --- /dev/null +++ b/src/pixelated_www/css/sandbox.css @@ -0,0 +1 @@ +@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;src:local("Open Sans"),local("OpenSans"),url("/sandbox/fonts/OpenSans.woff") format("woff")}body{font-family:"Open Sans", "Microsoft YaHei", "Hiragino Sans GB", "Hiragino Sans GB W3", "微软雅黑", "Helvetica Neue", Arial, sans-serif;font-size:13px;line-height:1.2em;background:white;color:#333;padding:0;margin:0;font-weight:normal;-webkit-font-smoothing:antialiased;font-style:normal;box-sizing:border-box;word-wrap:break-word}.search-highlight{background-color:#FFEF29} diff --git a/src/pixelated_www/css/style.css b/src/pixelated_www/css/style.css new file mode 100644 index 00000000..1d5c2a89 --- /dev/null +++ b/src/pixelated_www/css/style.css @@ -0,0 +1 @@ +/*! normalize.css v3.0.1 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible;text-transform:none}select{text-transform:none}button,html input[type="button"]{-webkit-appearance:button;cursor:pointer}input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input::-moz-focus-inner{border:0;padding:0}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}meta.foundation-version{font-family:"/5.2.3/"}meta.foundation-mq-small{font-family:"/only screen/";width:0em}meta.foundation-mq-medium{font-family:"/only screen and (min-width:40.063em)/";width:40.063em}meta.foundation-mq-large{font-family:"/only screen and (min-width:64.063em)/";width:64.063em}meta.foundation-mq-xlarge{font-family:"/only screen and (min-width:90.063em)/";width:90.063em}meta.foundation-mq-xxlarge{font-family:"/only screen and (min-width:120.063em)/";width:120.063em}meta.foundation-data-attribute-namespace{font-family:false}html,body{height:100%}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%}body{font-family:"Open Sans", "Microsoft YaHei", "Hiragino Sans GB", "Hiragino Sans GB W3", "微软雅黑", "Helvetica Neue", Arial, sans-serif;font-size:13px;line-height:1.2em;background:white;color:#333;padding:0;margin:0;font-weight:normal;-webkit-font-smoothing:antialiased;font-style:normal;position:relative;cursor:default}a:hover{cursor:pointer}img{max-width:100%;height:auto;-ms-interpolation-mode:bicubic}#map_canvas img,#map_canvas embed,#map_canvas object{max-width:none !important}.map_canvas img,.map_canvas embed,.map_canvas object{max-width:none !important}.left{float:left !important}.right{float:right !important}.clearfix:before{content:" ";display:table}.clearfix:after{content:" ";display:table;clear:both}.hide{display:none}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}img{display:inline-block;vertical-align:middle}textarea{height:auto;min-height:50px}textarea:focus{outline:none}select{width:100%}.row{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0}.row:before{content:" ";display:table}.row:after{content:" ";display:table;clear:both}.row.collapse>.column,.row.collapse>.columns{padding-left:0;padding-right:0}.row.collapse .row{margin-left:0;margin-right:0}.row .row{width:auto;margin-left:-0.9375em;margin-right:-0.9375em;margin-top:0;margin-bottom:0;max-width:none}.row .row:before{content:" ";display:table}.row .row:after{content:" ";display:table;clear:both}.row .row.collapse{width:auto;margin:0;max-width:none}.row .row.collapse:before{content:" ";display:table}.row .row.collapse:after{content:" ";display:table;clear:both}.column,.columns{padding-left:0.9375em;padding-right:0.9375em;width:100%;float:left}@media only screen{.small-push-0{position:relative;left:0%;right:auto}.small-pull-0{position:relative;right:0%;left:auto}.small-push-1{position:relative;left:8.33333%;right:auto}.small-pull-1{position:relative;right:8.33333%;left:auto}.small-push-2{position:relative;left:16.66667%;right:auto}.small-pull-2{position:relative;right:16.66667%;left:auto}.small-push-3{position:relative;left:25%;right:auto}.small-pull-3{position:relative;right:25%;left:auto}.small-push-4{position:relative;left:33.33333%;right:auto}.small-pull-4{position:relative;right:33.33333%;left:auto}.small-push-5{position:relative;left:41.66667%;right:auto}.small-pull-5{position:relative;right:41.66667%;left:auto}.small-push-6{position:relative;left:50%;right:auto}.small-pull-6{position:relative;right:50%;left:auto}.small-push-7{position:relative;left:58.33333%;right:auto}.small-pull-7{position:relative;right:58.33333%;left:auto}.small-push-8{position:relative;left:66.66667%;right:auto}.small-pull-8{position:relative;right:66.66667%;left:auto}.small-push-9{position:relative;left:75%;right:auto}.small-pull-9{position:relative;right:75%;left:auto}.small-push-10{position:relative;left:83.33333%;right:auto}.small-pull-10{position:relative;right:83.33333%;left:auto}.small-push-11{position:relative;left:91.66667%;right:auto}.small-pull-11{position:relative;right:91.66667%;left:auto}.column,.columns{position:relative;padding-left:0.9375em;padding-right:0.9375em;float:left}.small-1{width:8.33333%}.small-2{width:16.66667%}.small-3{width:25%}.small-4{width:33.33333%}.small-5{width:41.66667%}.small-6{width:50%}.small-7{width:58.33333%}.small-8{width:66.66667%}.small-9{width:75%}.small-10{width:83.33333%}.small-11{width:91.66667%}.small-12{width:100%}[class*="column"]+[class*="column"]:last-child{float:right}[class*="column"]+[class*="column"].end{float:left}.small-offset-0{margin-left:0% !important}.small-offset-1{margin-left:8.33333% !important}.small-offset-2{margin-left:16.66667% !important}.small-offset-3{margin-left:25% !important}.small-offset-4{margin-left:33.33333% !important}.small-offset-5{margin-left:41.66667% !important}.small-offset-6{margin-left:50% !important}.small-offset-7{margin-left:58.33333% !important}.small-offset-8{margin-left:66.66667% !important}.small-offset-9{margin-left:75% !important}.small-offset-10{margin-left:83.33333% !important}.small-offset-11{margin-left:91.66667% !important}.small-reset-order{margin-left:0;margin-right:0;left:auto;right:auto;float:left}.column.small-centered,.columns.small-centered{margin-left:auto;margin-right:auto;float:none !important}.column.small-uncentered,.columns.small-uncentered{margin-left:0;margin-right:0;float:left !important}.column.small-uncentered.opposite,.columns.small-uncentered.opposite{float:right}}@media only screen and (min-width: 40.063em){.medium-push-0{position:relative;left:0%;right:auto}.medium-pull-0{position:relative;right:0%;left:auto}.medium-push-1{position:relative;left:8.33333%;right:auto}.medium-pull-1{position:relative;right:8.33333%;left:auto}.medium-push-2{position:relative;left:16.66667%;right:auto}.medium-pull-2{position:relative;right:16.66667%;left:auto}.medium-push-3{position:relative;left:25%;right:auto}.medium-pull-3{position:relative;right:25%;left:auto}.medium-push-4{position:relative;left:33.33333%;right:auto}.medium-pull-4{position:relative;right:33.33333%;left:auto}.medium-push-5{position:relative;left:41.66667%;right:auto}.medium-pull-5{position:relative;right:41.66667%;left:auto}.medium-push-6{position:relative;left:50%;right:auto}.medium-pull-6{position:relative;right:50%;left:auto}.medium-push-7{position:relative;left:58.33333%;right:auto}.medium-pull-7{position:relative;right:58.33333%;left:auto}.medium-push-8{position:relative;left:66.66667%;right:auto}.medium-pull-8{position:relative;right:66.66667%;left:auto}.medium-push-9{position:relative;left:75%;right:auto}.medium-pull-9{position:relative;right:75%;left:auto}.medium-push-10{position:relative;left:83.33333%;right:auto}.medium-pull-10{position:relative;right:83.33333%;left:auto}.medium-push-11{position:relative;left:91.66667%;right:auto}.medium-pull-11{position:relative;right:91.66667%;left:auto}.column,.columns{position:relative;padding-left:0.9375em;padding-right:0.9375em;float:left}.medium-1{width:8.33333%}.medium-2{width:16.66667%}.medium-3{width:25%}.medium-4{width:33.33333%}.medium-5{width:41.66667%}.medium-6{width:50%}.medium-7{width:58.33333%}.medium-8{width:66.66667%}.medium-9{width:75%}.medium-10{width:83.33333%}.medium-11{width:91.66667%}.medium-12{width:100%}[class*="column"]+[class*="column"]:last-child{float:right}[class*="column"]+[class*="column"].end{float:left}.medium-offset-0{margin-left:0% !important}.medium-offset-1{margin-left:8.33333% !important}.medium-offset-2{margin-left:16.66667% !important}.medium-offset-3{margin-left:25% !important}.medium-offset-4{margin-left:33.33333% !important}.medium-offset-5{margin-left:41.66667% !important}.medium-offset-6{margin-left:50% !important}.medium-offset-7{margin-left:58.33333% !important}.medium-offset-8{margin-left:66.66667% !important}.medium-offset-9{margin-left:75% !important}.medium-offset-10{margin-left:83.33333% !important}.medium-offset-11{margin-left:91.66667% !important}.medium-reset-order{margin-left:0;margin-right:0;left:auto;right:auto;float:left}.column.medium-centered,.columns.medium-centered{margin-left:auto;margin-right:auto;float:none !important}.column.medium-uncentered,.columns.medium-uncentered{margin-left:0;margin-right:0;float:left !important}.column.medium-uncentered.opposite,.columns.medium-uncentered.opposite{float:right}.push-0{position:relative;left:0%;right:auto}.pull-0{position:relative;right:0%;left:auto}.push-1{position:relative;left:8.33333%;right:auto}.pull-1{position:relative;right:8.33333%;left:auto}.push-2{position:relative;left:16.66667%;right:auto}.pull-2{position:relative;right:16.66667%;left:auto}.push-3{position:relative;left:25%;right:auto}.pull-3{position:relative;right:25%;left:auto}.push-4{position:relative;left:33.33333%;right:auto}.pull-4{position:relative;right:33.33333%;left:auto}.push-5{position:relative;left:41.66667%;right:auto}.pull-5{position:relative;right:41.66667%;left:auto}.push-6{position:relative;left:50%;right:auto}.pull-6{position:relative;right:50%;left:auto}.push-7{position:relative;left:58.33333%;right:auto}.pull-7{position:relative;right:58.33333%;left:auto}.push-8{position:relative;left:66.66667%;right:auto}.pull-8{position:relative;right:66.66667%;left:auto}.push-9{position:relative;left:75%;right:auto}.pull-9{position:relative;right:75%;left:auto}.push-10{position:relative;left:83.33333%;right:auto}.pull-10{position:relative;right:83.33333%;left:auto}.push-11{position:relative;left:91.66667%;right:auto}.pull-11{position:relative;right:91.66667%;left:auto}}@media only screen and (min-width: 64.063em){.large-push-0{position:relative;left:0%;right:auto}.large-pull-0{position:relative;right:0%;left:auto}.large-push-1{position:relative;left:8.33333%;right:auto}.large-pull-1{position:relative;right:8.33333%;left:auto}.large-push-2{position:relative;left:16.66667%;right:auto}.large-pull-2{position:relative;right:16.66667%;left:auto}.large-push-3{position:relative;left:25%;right:auto}.large-pull-3{position:relative;right:25%;left:auto}.large-push-4{position:relative;left:33.33333%;right:auto}.large-pull-4{position:relative;right:33.33333%;left:auto}.large-push-5{position:relative;left:41.66667%;right:auto}.large-pull-5{position:relative;right:41.66667%;left:auto}.large-push-6{position:relative;left:50%;right:auto}.large-pull-6{position:relative;right:50%;left:auto}.large-push-7{position:relative;left:58.33333%;right:auto}.large-pull-7{position:relative;right:58.33333%;left:auto}.large-push-8{position:relative;left:66.66667%;right:auto}.large-pull-8{position:relative;right:66.66667%;left:auto}.large-push-9{position:relative;left:75%;right:auto}.large-pull-9{position:relative;right:75%;left:auto}.large-push-10{position:relative;left:83.33333%;right:auto}.large-pull-10{position:relative;right:83.33333%;left:auto}.large-push-11{position:relative;left:91.66667%;right:auto}.large-pull-11{position:relative;right:91.66667%;left:auto}.column,.columns{position:relative;padding-left:0.9375em;padding-right:0.9375em;float:left}.large-1{width:8.33333%}.large-2{width:16.66667%}.large-3{width:25%}.large-4{width:33.33333%}.large-5{width:41.66667%}.large-6{width:50%}.large-7{width:58.33333%}.large-8{width:66.66667%}.large-9{width:75%}.large-10{width:83.33333%}.large-11{width:91.66667%}.large-12{width:100%}[class*="column"]+[class*="column"]:last-child{float:right}[class*="column"]+[class*="column"].end{float:left}.large-offset-0{margin-left:0% !important}.large-offset-1{margin-left:8.33333% !important}.large-offset-2{margin-left:16.66667% !important}.large-offset-3{margin-left:25% !important}.large-offset-4{margin-left:33.33333% !important}.large-offset-5{margin-left:41.66667% !important}.large-offset-6{margin-left:50% !important}.large-offset-7{margin-left:58.33333% !important}.large-offset-8{margin-left:66.66667% !important}.large-offset-9{margin-left:75% !important}.large-offset-10{margin-left:83.33333% !important}.large-offset-11{margin-left:91.66667% !important}.large-reset-order{margin-left:0;margin-right:0;left:auto;right:auto;float:left}.column.large-centered,.columns.large-centered{margin-left:auto;margin-right:auto;float:none !important}.column.large-uncentered,.columns.large-uncentered{margin-left:0;margin-right:0;float:left !important}.column.large-uncentered.opposite,.columns.large-uncentered.opposite{float:right}.push-0{position:relative;left:0%;right:auto}.pull-0{position:relative;right:0%;left:auto}.push-1{position:relative;left:8.33333%;right:auto}.pull-1{position:relative;right:8.33333%;left:auto}.push-2{position:relative;left:16.66667%;right:auto}.pull-2{position:relative;right:16.66667%;left:auto}.push-3{position:relative;left:25%;right:auto}.pull-3{position:relative;right:25%;left:auto}.push-4{position:relative;left:33.33333%;right:auto}.pull-4{position:relative;right:33.33333%;left:auto}.push-5{position:relative;left:41.66667%;right:auto}.pull-5{position:relative;right:41.66667%;left:auto}.push-6{position:relative;left:50%;right:auto}.pull-6{position:relative;right:50%;left:auto}.push-7{position:relative;left:58.33333%;right:auto}.pull-7{position:relative;right:58.33333%;left:auto}.push-8{position:relative;left:66.66667%;right:auto}.pull-8{position:relative;right:66.66667%;left:auto}.push-9{position:relative;left:75%;right:auto}.pull-9{position:relative;right:75%;left:auto}.push-10{position:relative;left:83.33333%;right:auto}.pull-10{position:relative;right:83.33333%;left:auto}.push-11{position:relative;left:91.66667%;right:auto}.pull-11{position:relative;right:91.66667%;left:auto}}.inline-list{margin:0 auto 1.0625rem auto;margin-left:-1.375rem;margin-right:0;padding:0;list-style:none;overflow:hidden}.inline-list>li{list-style:none;float:left;margin-left:1.375rem;display:block}.inline-list>li>*{display:block}.text-left{text-align:left !important}.text-right{text-align:right !important}.text-center{text-align:center !important}.text-justify{text-align:justify !important}@media only screen and (max-width: 40em){.small-only-text-left{text-align:left !important}.small-only-text-right{text-align:right !important}.small-only-text-center{text-align:center !important}.small-only-text-justify{text-align:justify !important}}@media only screen{.small-text-left{text-align:left !important}.small-text-right{text-align:right !important}.small-text-center{text-align:center !important}.small-text-justify{text-align:justify !important}}@media only screen and (min-width: 40.063em) and (max-width: 64em){.medium-only-text-left{text-align:left !important}.medium-only-text-right{text-align:right !important}.medium-only-text-center{text-align:center !important}.medium-only-text-justify{text-align:justify !important}}@media only screen and (min-width: 40.063em){.medium-text-left{text-align:left !important}.medium-text-right{text-align:right !important}.medium-text-center{text-align:center !important}.medium-text-justify{text-align:justify !important}}@media only screen and (min-width: 64.063em) and (max-width: 90em){.large-only-text-left{text-align:left !important}.large-only-text-right{text-align:right !important}.large-only-text-center{text-align:center !important}.large-only-text-justify{text-align:justify !important}}@media only screen and (min-width: 64.063em){.large-text-left{text-align:left !important}.large-text-right{text-align:right !important}.large-text-center{text-align:center !important}.large-text-justify{text-align:justify !important}}@media only screen and (min-width: 90.063em) and (max-width: 120em){.xlarge-only-text-left{text-align:left !important}.xlarge-only-text-right{text-align:right !important}.xlarge-only-text-center{text-align:center !important}.xlarge-only-text-justify{text-align:justify !important}}@media only screen and (min-width: 90.063em){.xlarge-text-left{text-align:left !important}.xlarge-text-right{text-align:right !important}.xlarge-text-center{text-align:center !important}.xlarge-text-justify{text-align:justify !important}}@media only screen and (min-width: 120.063em) and (max-width: 99999999em){.xxlarge-only-text-left{text-align:left !important}.xxlarge-only-text-right{text-align:right !important}.xxlarge-only-text-center{text-align:center !important}.xxlarge-only-text-justify{text-align:justify !important}}@media only screen and (min-width: 120.063em){.xxlarge-text-left{text-align:left !important}.xxlarge-text-right{text-align:right !important}.xxlarge-text-center{text-align:center !important}.xxlarge-text-justify{text-align:justify !important}}div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0}a{color:#2ba6cb;text-decoration:none;line-height:inherit}a:hover,a:focus{color:#258faf;outline:none}a img{border:none}p{font-family:inherit;font-weight:normal;font-size:0.9rem;line-height:1.4;margin-bottom:1.25rem;text-rendering:optimizeLegibility}p.lead{font-size:1.21875rem;line-height:1.4}p aside{font-size:0.875rem;line-height:1.35;font-style:italic}h1,h2,h3,h4,h5,h6{font-weight:normal;font-style:normal;color:#222;text-rendering:optimizeLegibility;margin-top:0.2rem;margin-bottom:0.5rem;line-height:1.2}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-size:60%;color:#6f6f6f;line-height:0}h1{font-size:2.125rem}h2{font-size:1.6875rem}h3{font-size:1.375rem}h4,h5{font-size:1.125rem}h6{font-size:1rem}.subheader{line-height:1.4;color:#6f6f6f;font-weight:normal;margin-top:0.2rem;margin-bottom:0.5rem}hr{border:solid #dddddd;border-width:1px 0 0;clear:both;margin:1.25rem 0 1.1875rem;height:0}em,i{font-style:italic;line-height:inherit}strong,b{font-weight:bold;line-height:inherit}small{font-size:60%;line-height:inherit}code{font-family:Consolas, "Liberation Mono", Courier, monospace;font-weight:bold;color:#910b0e}ul,ol,dl{font-size:0.9rem;line-height:1.6;margin-bottom:1.25rem;list-style-position:outside;font-family:inherit}ul{margin-left:0}ul.bullets{margin-left:1.1rem}ul.bullets li{margin-left:1.25rem;margin-bottom:0;list-style:circle}ul li{margin-bottom:0;list-style:none}abbr,acronym{text-transform:uppercase;font-size:90%;color:#222222;border-bottom:1px dotted #dddddd;cursor:help}abbr{text-transform:none}blockquote{margin:0 0 1.25rem;padding:0.5625rem 1.25rem 0 1.1875rem;border-left:1px solid #dddddd;line-height:1.6;color:#6f6f6f}blockquote cite{display:block;font-size:0.8125rem;color:#555555}blockquote cite:before{content:"\2014 \0020"}blockquote cite a{color:#555555}blockquote cite a:visited{color:#555555}blockquote p{line-height:1.6;color:#6f6f6f}.vcard{display:inline-block;margin:0 0 1.25rem 0;border:1px solid #dddddd;padding:0.625rem 0.75rem}.vcard li{margin:0;display:block}.vcard .fn{font-weight:bold;font-size:0.9375rem}.vevent .summary{font-weight:bold}.vevent abbr{cursor:default;text-decoration:none;font-weight:bold;border:none;padding:0 0.0625rem}@media only screen and (min-width: 40.063em){h1,h2,h3,h4,h5,h6{line-height:1.2}h1{font-size:2.55rem}h2{font-size:2.3125rem}h3{font-size:1.4875rem}h4{font-size:1.1375rem}}.print-only{display:none !important}@media print{*{background:transparent !important;color:black !important;box-shadow:none !important;text-shadow:none !important}a{text-decoration:underline}a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after{content:""}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999999;page-break-inside:avoid}thead{display:table-header-group}tr{page-break-inside:avoid}img{page-break-inside:avoid;max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.hide-on-print{display:none !important}.print-only{display:block !important}.hide-for-print{display:none !important}.show-for-print{display:inherit !important}}.reveal-modal-bg{position:fixed;height:100%;width:100%;background:black;background:rgba(0,0,0,0.45);z-index:99;display:none;top:0;left:0}dialog,.reveal-modal{visibility:hidden;display:none;position:absolute;z-index:100;width:100vw;top:0;left:0;background-color:white;padding:1.25rem;border:solid 1px #666666;box-shadow:0 0 10px rgba(0,0,0,0.4)}@media only screen and (max-width: 40em){dialog,.reveal-modal{min-height:100vh}}@media only screen and (min-width: 40.063em){dialog,.reveal-modal{left:50%}}dialog .column,dialog .columns{min-width:0}.reveal-modal .column,.reveal-modal .columns{min-width:0}dialog>:first-child,.reveal-modal>:first-child{margin-top:0}dialog>:last-child,.reveal-modal>:last-child{margin-bottom:0}@media only screen and (min-width: 40.063em){dialog,.reveal-modal{margin-left:-26%;width:50%}}@media only screen and (min-width: 40.063em){dialog,.reveal-modal{top:6.25rem}}dialog .close-reveal-modal,.reveal-modal .close-reveal-modal{font-size:2.5rem;line-height:1;position:absolute;top:0.5rem;right:0.6875rem;color:#aaaaaa;font-weight:bold;cursor:pointer}dialog[open]{display:block;visibility:visible}@media only screen and (min-width: 40.063em){dialog,.reveal-modal{padding:1.875rem}dialog.radius,.reveal-modal.radius{border-radius:3px}dialog.round,.reveal-modal.round{border-radius:1000px}dialog.collapse,.reveal-modal.collapse{padding:0}dialog.full,.reveal-modal.full{top:0;left:0;height:100vh;min-height:100vh;margin-left:0 !important}}@media only screen and (min-width: 40.063em) and (min-width: 40.063em){dialog.tiny,.reveal-modal.tiny{margin-left:-15%;width:30%}}@media only screen and (min-width: 40.063em) and (min-width: 40.063em){dialog.small,.reveal-modal.small{margin-left:-20%;width:40%}}@media only screen and (min-width: 40.063em) and (min-width: 40.063em){dialog.medium,.reveal-modal.medium{margin-left:-30%;width:60%}}@media only screen and (min-width: 40.063em) and (min-width: 40.063em){dialog.large,.reveal-modal.large{margin-left:-35%;width:70%}}@media only screen and (min-width: 40.063em) and (min-width: 40.063em){dialog.xlarge,.reveal-modal.xlarge{margin-left:-47.5%;width:95%}}@media only screen and (min-width: 40.063em) and (min-width: 40.063em){dialog.full,.reveal-modal.full{margin-left:-50vw;width:100vw}}@media print{dialog,.reveal-modal{background:white !important}}.label{font-weight:normal;text-align:center;text-decoration:none;line-height:1;white-space:nowrap;display:inline-block;position:relative;margin-bottom:inherit;padding:0.25rem 0.5rem 0.375rem;font-size:0.6875rem;background-color:#2ba6cb;color:white}.label.radius{border-radius:3px}.label.round{border-radius:1000px}.label.alert{background-color:#c60f13;color:white}.label.success{background-color:#5da423;color:white}.label.secondary{background-color:#e9e9e9;color:#333333}button,.button,input[type=button]{cursor:pointer;margin:0 0 1.25rem;border:none;position:relative;text-decoration:none;text-align:center;-webkit-appearance:none;display:inline-block;padding:0.4rem 1.1rem;font-size:0.9rem;background-color:#2ba6cb;border-color:#2285a2;color:white;transition:background-color 150ms ease-out;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px}button:hover,button:focus,.button:hover,.button:focus,input[type=button]:hover,input[type=button]:focus{background-color:#2285a2;outline:none;color:white}button.large,.button.large,input[type=button].large{padding-top:1.125rem;padding-right:2.25rem;padding-bottom:1.1875rem;padding-left:2.25rem;font-size:1.25rem}button.small,.button.small,input[type=button].small{padding-top:0.875rem;padding-right:1.75rem;padding-bottom:0.9375rem;padding-left:1.75rem;font-size:0.8125rem}button.tiny,.button.tiny,input[type=button].tiny{padding-top:0.625rem;padding-right:1.25rem;padding-bottom:0.6875rem;padding-left:1.25rem;font-size:0.6875rem}button.expand,.button.expand,input[type=button].expand{padding-right:0;padding-left:0;width:100%}button.left-align,.button.left-align,input[type=button].left-align{text-align:left;text-indent:0.75rem}button.right-align,.button.right-align,input[type=button].right-align{text-align:right;padding-right:0.75rem}button.round,.button.round,input[type=button].round{border-radius:1000px}button.disabled,button[disabled],.button.disabled,.button[disabled],input[type=button].disabled,input[type=button][disabled]{background-color:#2285a2;border-color:#2285a2;color:white;cursor:default;opacity:0.5;box-shadow:none}button.disabled:hover,button.disabled:focus,button[disabled]:hover,button[disabled]:focus,.button.disabled:hover,.button.disabled:focus,.button[disabled]:hover,.button[disabled]:focus,input[type=button].disabled:hover,input[type=button].disabled:focus,input[type=button][disabled]:hover,input[type=button][disabled]:focus{background-color:#2285a2;opacity:0.5}@media only screen and (min-width: 40.063em){button,.button{display:inline-block}}.keystroke,kbd{background-color:#ededed;border-color:#dddddd;color:#222222;border-style:solid;border-width:1px;margin:0;font-family:"Consolas", "Menlo", "Courier", monospace;font-size:inherit;padding:0.125rem 0.25rem 0;border-radius:3px}input[type="text"],input[type="password"],input[type="date"],input[type="datetime"],input[type="datetime-local"],input[type="month"],input[type="week"],input[type="email"],input[type="number"],input[type="search"],input[type="tel"],input[type="time"],input[type="url"],textarea{-webkit-appearance:none;background-color:white;font-family:inherit;border:1px solid #cccccc;color:rgba(0,0,0,0.75);display:block;font-size:0.875rem;margin:0 0 1rem 0;padding:0.4rem;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="text"]:focus,input[type="password"]:focus,input[type="date"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="month"]:focus,input[type="week"]:focus,input[type="email"]:focus,input[type="number"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="time"]:focus,input[type="url"]:focus,textarea:focus{background:#fafafa;border-color:#999999;outline:none}input[type="text"][disabled],fieldset[disabled] input[type="text"],input[type="password"][disabled],fieldset[disabled] input[type="password"],input[type="date"][disabled],fieldset[disabled] input[type="date"],input[type="datetime"][disabled],fieldset[disabled] input[type="datetime"],input[type="datetime-local"][disabled],fieldset[disabled] input[type="datetime-local"],input[type="month"][disabled],fieldset[disabled] input[type="month"],input[type="week"][disabled],fieldset[disabled] input[type="week"],input[type="email"][disabled],fieldset[disabled] input[type="email"],input[type="number"][disabled],fieldset[disabled] input[type="number"],input[type="search"][disabled],fieldset[disabled] input[type="search"],input[type="tel"][disabled],fieldset[disabled] input[type="tel"],input[type="time"][disabled],fieldset[disabled] input[type="time"],input[type="url"][disabled],fieldset[disabled] input[type="url"],textarea[disabled],fieldset[disabled] textarea{background-color:#dddddd}input[type="text"].radius,input[type="password"].radius,input[type="date"].radius,input[type="datetime"].radius,input[type="datetime-local"].radius,input[type="month"].radius,input[type="week"].radius,input[type="email"].radius,input[type="number"].radius,input[type="search"].radius,input[type="tel"].radius,input[type="time"].radius,input[type="url"].radius,textarea.radius{border-radius:3px}input[type="submit"]{-webkit-appearance:none}textarea[rows]{height:auto}select{-webkit-appearance:none !important;background-color:#fafafa;background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgeD0iMHB4IiB5PSIwcHgiIHdpZHRoPSI2cHgiIGhlaWdodD0iM3B4IiB2aWV3Qm94PSIwIDAgNiAzIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA2IDMiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwb2x5Z29uIHBvaW50cz0iNS45OTIsMCAyLjk5MiwzIC0wLjAwOCwwICIvPjwvc3ZnPg==");background-repeat:no-repeat;background-position:97% center;border:1px solid #cccccc;padding:0.5rem;font-size:0.875rem;color:rgba(0,0,0,0.75);line-height:normal;border-radius:0}select.radius{border-radius:3px}select:hover{background-color:#f3f3f3;border-color:#999999}input[type="file"],input[type="checkbox"],input[type="radio"],select{margin:0 0 1rem 0}input[type="checkbox"]+label,input[type="radio"]+label{display:inline-block;margin-left:0.5rem;margin-right:1rem;margin-bottom:0;vertical-align:baseline}input[type="file"]{width:100%}@font-face{font-family:'Open Sans';font-style:normal;font-weight:300;src:local("Open Sans Light"),local("OpenSans-Light"),url("/assets/fonts/OpenSans-Light.woff") format("woff")}@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;src:local("Open Sans"),local("OpenSans"),url("/assets/fonts/OpenSans.woff") format("woff")}@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;src:local("Open Sans Semibold"),local("OpenSans-Semibold"),url("/assets/fonts/OpenSans-Semibold.woff") format("woff")}@font-face{font-family:'Open Sans';font-style:normal;font-weight:700;src:local("Open Sans Bold"),local("OpenSans-Bold"),url("/assets/fonts/OpenSans-Bold.woff") format("woff")}@font-face{font-family:'Open Sans';font-style:normal;font-weight:800;src:local("Open Sans Extrabold"),local("OpenSans-Extrabold"),url("/assets/fonts/OpenSans-Extrabold.woff") format("woff")}@font-face{font-family:'Open Sans';font-style:italic;font-weight:300;src:local("Open Sans Light Italic"),local("OpenSansLight-Italic"),url("/assets/fonts/OpenSansLight-Italic.woff") format("woff")}@font-face{font-family:'Open Sans';font-style:italic;font-weight:400;src:local("Open Sans Italic"),local("OpenSans-Italic"),url("/assets/fonts/OpenSans-Italic.woff") format("woff")}@font-face{font-family:'Open Sans';font-style:italic;font-weight:600;src:local("Open Sans Semibold Italic"),local("OpenSans-SemiboldItalic"),url("/assets/fonts/OpenSans-SemiboldItalic.woff") format("woff")}@font-face{font-family:'Open Sans';font-style:italic;font-weight:700;src:local("Open Sans Bold Italic"),local("OpenSans-BoldItalic"),url("/assets/fonts/OpenSans-BoldItalic.woff") format("woff")}@font-face{font-family:'Open Sans';font-style:italic;font-weight:800;src:local("Open Sans Extrabold Italic"),local("OpenSans-ExtraboldItalic"),url("/assets/fonts/OpenSans-ExtraboldItalic.woff") format("woff")}html{height:100%}body{min-height:100%;overflow:hidden;background:#FFF}@keyframes hideshow{0%{fill:#ffd799}25%{opacity:1}100%{opacity:0}}.logo-part-animation-off{animation:none}.logo-part-animation-on{animation:hideshow 0.6s ease infinite;opacity:1}.logo-part-animation-on:nth-child(2){opacity:0;animation-delay:0.1s}.logo-part-animation-on:nth-child(3){animation-delay:0.2s}.logo-part-animation-on:nth-child(4){animation-delay:0.3s}.logo-part-animation-on:nth-child(5){animation-delay:0.4s}.logo-part-animation-on:nth-child(6){animation-delay:0.5s}.no-content-placeholder,.no-message-selected-pane__text,.no-mails-available-pane{margin:auto;position:absolute;left:50%;top:50%;-ms-transform:translate(-50%, -50%);-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);color:#666}.message-panel{width:100%;margin:10px auto;position:fixed;z-index:10000;text-align:center}.message-panel__growl{padding:5px 60px}.message-panel__growl--success{background:#F7E8AF;color:#987b0f;border:1px solid #f2db81;-moz-box-shadow:1px 1px 3px #69560b;-webkit-box-shadow:1px 1px 3px #69560b;box-shadow:1px 1px 3px #69560b}.message-panel__growl--error{font-weight:bold;color:white;background:#D93C38;border:1px solid #ba2724;-moz-box-shadow:1px 1px 3px #000;-webkit-box-shadow:1px 1px 3px #000;box-shadow:1px 1px 3px #000}.close-mail-button{margin-right:3px;float:left;background:#DDD;color:#999;width:27px;height:27px;padding:0;border-radius:0}.close-mail-button:hover,.close-mail-button:focus,.close-mail-button:active{background-color:#d8d8d8;color:gray}.close-mail-button i{padding:0;margin:0}.no-message-selected-pane{background:#EEE;position:absolute;top:0;left:0;width:100%;height:100%}.no-message-selected-pane__text{margin-bottom:40px}.mail-read-view{overflow:hidden}.mail-read-view hr{margin:0}.mail-read-view__header{font-size:0.9em;margin:0;margin:3px 0 10px 0}.mail-read-view__header:after{content:"";display:table;clear:both}.mail-read-view__header-recipients{display:inline;margin-bottom:5px;line-height:1.5em}.mail-read-view__header-recipients-separator{margin:0 10px}.mail-read-view__header-recipients--highlight-sender{font-weight:bold}.mail-read-view__header-date{display:inline;float:right}.mail-read-view__header-subject{display:inline;float:left;max-width:80%}.mail-read-view__header-actions{display:inline;float:right;max-width:20%;background:#FFF;white-space:nowrap;margin-top:10px}.mail-read-view__header-actions-button{color:#999;background-color:inherit;display:inline;border:1px solid #DDD;line-height:2em;margin-bottom:0}.mail-read-view__header-actions-button i{margin:0;padding:0}.mail-read-view__header-actions-button:hover,.mail-read-view__header-actions-button:active,.mail-read-view__header-actions-button:focus{-moz-transition-property:background-color;-o-transition-property:background-color;-webkit-transition-property:background-color;transition-property:background-color;-moz-transition-duration:300ms;-o-transition-duration:300ms;-webkit-transition-duration:300ms;transition-duration:300ms;-moz-transition-timing-function:ease-out;-o-transition-timing-function:ease-out;-webkit-transition-timing-function:ease-out;transition-timing-function:ease-out;background:#e1e1e1;color:inherit}.mail-read-view__header-actions-button--reply{padding:0 20px;margin-right:-4px}.mail-read-view__header-actions-button--more{padding:0 5px}.mail-read-view__header-actions-dropdown{background:inherit;position:absolute;border:1px solid #DDD;right:10px}.mail-read-view__header-actions-dropdown-entry{box-sizing:border-box;background:inherit;padding:5px 10px;display:block;border-bottom:1px solid #DDD}.mail-read-view__header-actions-dropdown-entry:last-child{border-bottom:none}.mail-read-view__header-actions-dropdown-entry:hover{cursor:pointer;background:#EEE}.mail-read-view__header-tags{clear:both;margin:0 0 10px}.mail-read-view__header-tags>*{display:inline}.mail-read-view__header-tags-tag{font-size:.6rem;font-weight:normal;background-color:#6cbfd2;color:white;padding:2px 3px;margin:0 1px;border-radius:2px}.mail-read-view__header-tags-tag:hover{text-decoration:line-through;cursor:pointer;position:relative}.mail-read-view__header-tags-tag:hover:before{background:rgba(0,0,0,0.7);color:#FFF;position:absolute;z-index:2;left:25%;top:130%;font-size:0.8rem;padding:2px 10px;white-space:nowrap;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;content:"click to remove";text-transform:lowercase}.mail-read-view__header-tags-label{vertical-align:bottom;color:#C2C2C2}.mail-read-view__header-tags-new-button{font-size:.6rem;padding:0;background:transparent;border-radius:2px;padding:2px}.mail-read-view__header-tags-new-button:hover{opacity:1;background:#DDD}.mail-read-view__header-tags-name-input{opacity:0.6;transition:background-color 150ms ease-out}.mail-read-view__header-tags-name-input:hover{opacity:1}.mail-read-view__header-tags-name-input * .tt-input{border-radius:2px;padding:1px 5px;margin-top:2px;font-size:.6rem}.mail-read-view__header-tags-name-input * .tt-hint{color:#999;padding:1px 5px;margin-top:2px;font-size:.6rem;background:transparent}.mail-read-view__header-tags-name-input * .tt-dropdown-menu{min-width:250px;padding:0;font-size:.6rem;background-color:#EEE;border:1px solid #e1e1e1}.mail-read-view__header-tags-name-input * .tt-suggestion{padding:5px 10px;font-size:.6rem;border-bottom:1px solid #e1e1e1}.mail-read-view__header-tags-name-input * .tt-suggestion:last-child{border-bottom:none}.mail-read-view__header-tags-name-input * .tt-suggestion p{margin:0}.mail-read-view__header-tags-name-input * .tt-cursor{background-color:#FFF}.mail-read-view__body{margin:10px 0;width:100%;border:none}.mail-read-view__attachments{margin:10px 0}.mail-read-view__attachments-header{font-weight:bold}.mail-read-view__attachments-item{display:block;margin-bottom:8px;padding:5px;border:1px solid #D9D9D9;border-radius:2px;background-color:#F5F5F5}.mail-read-view__attachments-item:after{content:"";display:table;clear:both}.mail-read-view__attachments-item-label{color:#555;text-decoration:none}.mail-read-view__attachments-item-label:hover,.mail-read-view__attachments-item-label:focus{color:#a2a2a2;outline:none}.mail-read-view__attachments-item-label:hover i.download-icon,.mail-read-view__attachments-item-label:focus i.download-icon{color:#c8c8c8}.mail-read-view__attachments-item-download{color:#a2a2a2;float:right;margin-top:5px}.security-status{margin:0 0 5px}.security-status__label{display:inline-block;padding:2px 6px;white-space:nowrap;background:#50BA5B;color:#FFF;border-radius:12px}.security-status__label:before{font-family:FontAwesome}.security-status__label--encrypted:before{content:"\f023"}.security-status__label--encrypted--with-error{background:#F6A41C}.security-status__label--encrypted--with-error:before{content:"\f023 \f057"}.security-status__label--not-encrypted{background:#F6A41C}.security-status__label--not-encrypted:before{content:"\f13e "}.security-status__label--signed:before{content:"\f00c"}.security-status__label--signed--revoked,.security-status__label--signed--expired{background:#F6A41C}.security-status__label--signed--revoked:before,.security-status__label--signed--expired:before{content:"\f05e"}.security-status__label--signed--not-trusted{background:#D93C38}.security-status__label--signed--not-trusted:before{content:"\f05e"}.security-status__label--not-signed{background:#F6A41C}.security-status__label--not-signed:before{content:"\f05e"}.compose-view{overflow:auto}#compose-box div.floatlabel,#draft-box div.floatlabel,#reply-box div.floatlabel,#feedback-box div.floatlabel{position:relative}#compose-box .input-container,#draft-box .input-container,#reply-box .input-container,#feedback-box .input-container{padding:1px}#compose-box label,#compose-box span,#draft-box label,#draft-box span,#reply-box label,#reply-box span,#feedback-box label,#feedback-box span{color:#AAA;padding:0.5rem;cursor:text;display:inline-block}#compose-box label,#draft-box label,#reply-box label,#feedback-box label{padding:13px 10px}#compose-box span,#draft-box span,#reply-box span,#feedback-box span{padding:3px}#compose-box span.attachment-size,#draft-box span.attachment-size,#reply-box span.attachment-size,#feedback-box span.attachment-size{color:#a2a2a2;cursor:pointer}#compose-box label.floatlabel,#draft-box label.floatlabel,#reply-box label.floatlabel,#feedback-box label.floatlabel{padding:0.4rem !important;position:absolute;font-size:0.6rem;transition:all 0.1s linear;opacity:0;font-weight:bold}#compose-box label.showfloatlabel,#draft-box label.showfloatlabel,#reply-box label.showfloatlabel,#feedback-box label.showfloatlabel{color:#3DABC4 !important;top:-0.3rem;opacity:1}#compose-box input,#compose-box textarea,#draft-box input,#draft-box textarea,#reply-box input,#reply-box textarea,#feedback-box input,#feedback-box textarea{margin:0;border:none;transition:all 0.1s linear}#compose-box input.showfloatlabel,#compose-box textarea.showfloatlabel,#draft-box input.showfloatlabel,#draft-box textarea.showfloatlabel,#reply-box input.showfloatlabel,#reply-box textarea.showfloatlabel,#feedback-box input.showfloatlabel,#feedback-box textarea.showfloatlabel{padding-top:1rem !important}#compose-box input#subject,#compose-box #feedback-subject,#draft-box input#subject,#draft-box #feedback-subject,#reply-box input#subject,#reply-box #feedback-subject,#feedback-box input#subject,#feedback-box #feedback-subject{font-size:1.6875rem;line-height:1.4;border-top:1px solid #DDD}#compose-box #feedback-subject,#draft-box #feedback-subject,#reply-box #feedback-subject,#feedback-box #feedback-subject{color:#333}#compose-box textarea,#draft-box textarea,#reply-box textarea,#feedback-box textarea{border-bottom:2px solid #DDD;min-height:400px;font-family:inherit;font-weight:normal;font-size:1rem;line-height:1.6;text-rendering:optimizeLegibility}#compose-box.reply-box,#compose-box.forward-box,#draft-box.reply-box,#draft-box.forward-box,#reply-box.reply-box,#reply-box.forward-box,#feedback-box.reply-box,#feedback-box.forward-box{margin:0}#compose-box.reply-box h4,#compose-box.forward-box h4,#draft-box.reply-box h4,#draft-box.forward-box h4,#reply-box.reply-box h4,#reply-box.forward-box h4,#feedback-box.reply-box h4,#feedback-box.forward-box h4{font-size:0.9em;font-style:italic;color:#777;margin:2px 0;clear:both;cursor:pointer}#compose-box.reply-box h4:hover,#compose-box.forward-box h4:hover,#draft-box.reply-box h4:hover,#draft-box.forward-box h4:hover,#reply-box.reply-box h4:hover,#reply-box.forward-box h4:hover,#feedback-box.reply-box h4:hover,#feedback-box.forward-box h4:hover{background:#EEE}#compose-box.reply-box textarea,#compose-box.forward-box textarea,#draft-box.reply-box textarea,#draft-box.forward-box textarea,#reply-box.reply-box textarea,#reply-box.forward-box textarea,#feedback-box.reply-box textarea,#feedback-box.forward-box textarea{min-height:200px;margin:10px 0}#compose-box.reply-box p,#compose-box.forward-box p,#draft-box.reply-box p,#draft-box.forward-box p,#reply-box.reply-box p,#reply-box.forward-box p,#feedback-box.reply-box p,#feedback-box.forward-box p{padding:5px;margin:10px 0;font-style:italic;cursor:pointer}#compose-box.reply-box p:hover,#compose-box.forward-box p:hover,#draft-box.reply-box p:hover,#draft-box.forward-box p:hover,#reply-box.reply-box p:hover,#reply-box.forward-box p:hover,#feedback-box.reply-box p:hover,#feedback-box.forward-box p:hover{background:#EEE}#compose-box button.close-mail-button,#draft-box button.close-mail-button,#reply-box button.close-mail-button,#feedback-box button.close-mail-button{margin:1px}#compose-box .buttons-group,#draft-box .buttons-group,#reply-box .buttons-group,#feedback-box .buttons-group{margin-top:0px}#compose-box #attachment-upload-item,#draft-box #attachment-upload-item,#reply-box #attachment-upload-item,#feedback-box #attachment-upload-item{display:none}#compose-box #attachment-upload-item .progress,#draft-box #attachment-upload-item .progress,#reply-box #attachment-upload-item .progress,#feedback-box #attachment-upload-item .progress{width:0%;position:absolute;right:0;left:0;top:0;bottom:0;min-height:100%}#compose-box #attachment-upload-item .progress .progress-bar,#draft-box #attachment-upload-item .progress .progress-bar,#reply-box #attachment-upload-item .progress .progress-bar,#feedback-box #attachment-upload-item .progress .progress-bar{height:100%;background-color:rgba(61,171,196,0.3)}#compose-box .attachmentsAreaWrap,#draft-box .attachmentsAreaWrap,#reply-box .attachmentsAreaWrap,#feedback-box .attachmentsAreaWrap{padding:0}#compose-box .attachmentsAreaWrap .attachmentsArea,#draft-box .attachmentsAreaWrap .attachmentsArea,#reply-box .attachmentsAreaWrap .attachmentsArea,#feedback-box .attachmentsAreaWrap .attachmentsArea{padding:0;border-top:0}#compose-box .attachmentsAreaWrap .attachmentsArea #upload-error,#draft-box .attachmentsAreaWrap .attachmentsArea #upload-error,#reply-box .attachmentsAreaWrap .attachmentsArea #upload-error,#feedback-box .attachmentsAreaWrap .attachmentsArea #upload-error{color:#D93C38;margin-bottom:20px}#compose-box .attachmentsAreaWrap .attachmentsArea #upload-error .close-icon,#draft-box .attachmentsAreaWrap .attachmentsArea #upload-error .close-icon,#reply-box .attachmentsAreaWrap .attachmentsArea #upload-error .close-icon,#feedback-box .attachmentsAreaWrap .attachmentsArea #upload-error .close-icon{font-size:1.0rem;cursor:pointer}#compose-box .attachmentsAreaWrap .attachmentsArea #upload-error span,#compose-box .attachmentsAreaWrap .attachmentsArea #upload-error a,#draft-box .attachmentsAreaWrap .attachmentsArea #upload-error span,#draft-box .attachmentsAreaWrap .attachmentsArea #upload-error a,#reply-box .attachmentsAreaWrap .attachmentsArea #upload-error span,#reply-box .attachmentsAreaWrap .attachmentsArea #upload-error a,#feedback-box .attachmentsAreaWrap .attachmentsArea #upload-error span,#feedback-box .attachmentsAreaWrap .attachmentsArea #upload-error a{color:#D93C38;font-size:0.9rem}#compose-box .attachmentsAreaWrap .attachmentsArea #upload-error a,#draft-box .attachmentsAreaWrap .attachmentsArea #upload-error a,#reply-box .attachmentsAreaWrap .attachmentsArea #upload-error a,#feedback-box .attachmentsAreaWrap .attachmentsArea #upload-error a{text-decoration:underline;padding:5px}#compose-box .recipients-area,#draft-box .recipients-area,#reply-box .recipients-area,#feedback-box .recipients-area{-webkit-appearance:none;background-color:white;font-family:inherit;display:flex;flex-wrap:wrap;font-size:0.898em;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:relative}#compose-box .recipients-area .compose-column-label,#draft-box .recipients-area .compose-column-label,#reply-box .recipients-area .compose-column-label,#feedback-box .recipients-area .compose-column-label{width:5%;display:inline-block}#compose-box .recipients-area .compose-column-recipients,#draft-box .recipients-area .compose-column-recipients,#reply-box .recipients-area .compose-column-recipients,#feedback-box .recipients-area .compose-column-recipients{width:95%;display:inline-block}#compose-box .recipients-area .recipients-label,#draft-box .recipients-area .recipients-label,#reply-box .recipients-area .recipients-label,#feedback-box .recipients-area .recipients-label{width:100%;height:100%}#compose-box .recipients-area .recipients-navigation-handler,#draft-box .recipients-area .recipients-navigation-handler,#reply-box .recipients-area .recipients-navigation-handler,#feedback-box .recipients-area .recipients-navigation-handler{z-index:-1;position:absolute;top:-200px}#compose-box .recipients-area .twitter-typeahead,#draft-box .recipients-area .twitter-typeahead,#reply-box .recipients-area .twitter-typeahead,#feedback-box .recipients-area .twitter-typeahead{flex:1 1 50px}#compose-box .recipients-area .invalid-format,#draft-box .recipients-area .invalid-format,#reply-box .recipients-area .invalid-format,#feedback-box .recipients-area .invalid-format{border-bottom:1px dotted #D93C38}#compose-box .recipients-area input[type=text],#draft-box .recipients-area input[type=text],#reply-box .recipients-area input[type=text],#feedback-box .recipients-area input[type=text]{vertical-align:top;height:35px;margin-left:1px;font-size:0.9em;width:100%}#compose-box .recipients-area .fixed-recipient,#draft-box .recipients-area .fixed-recipient,#reply-box .recipients-area .fixed-recipient,#feedback-box .recipients-area .fixed-recipient{display:inline-block;margin-right:-3px;flex:none;position:relative}#compose-box .recipients-area .fixed-recipient .recipient-value,#draft-box .recipients-area .fixed-recipient .recipient-value,#reply-box .recipients-area .fixed-recipient .recipient-value,#feedback-box .recipients-area .fixed-recipient .recipient-value{margin:3px;padding:5px;background-color:#F5F5F5;border:1px solid #D9D9D9;border-radius:2px}#compose-box .recipients-area .fixed-recipient .recipient-value.selected,#draft-box .recipients-area .fixed-recipient .recipient-value.selected,#reply-box .recipients-area .fixed-recipient .recipient-value.selected,#feedback-box .recipients-area .fixed-recipient .recipient-value.selected{border:1px solid #666}#compose-box .recipients-area .fixed-recipient .recipient-value:before,#draft-box .recipients-area .fixed-recipient .recipient-value:before,#reply-box .recipients-area .fixed-recipient .recipient-value:before,#feedback-box .recipients-area .fixed-recipient .recipient-value:before{font-family:FontAwesome;padding-right:4px}#compose-box .recipients-area .fixed-recipient .recipient-value.encrypted,#draft-box .recipients-area .fixed-recipient .recipient-value.encrypted,#reply-box .recipients-area .fixed-recipient .recipient-value.encrypted,#feedback-box .recipients-area .fixed-recipient .recipient-value.encrypted{border-bottom-color:#50BA5B}#compose-box .recipients-area .fixed-recipient .recipient-value.encrypted:before,#draft-box .recipients-area .fixed-recipient .recipient-value.encrypted:before,#reply-box .recipients-area .fixed-recipient .recipient-value.encrypted:before,#feedback-box .recipients-area .fixed-recipient .recipient-value.encrypted:before{color:#50BA5B;content:"\f023 "}#compose-box .recipients-area .fixed-recipient .recipient-value.not-encrypted,#draft-box .recipients-area .fixed-recipient .recipient-value.not-encrypted,#reply-box .recipients-area .fixed-recipient .recipient-value.not-encrypted,#feedback-box .recipients-area .fixed-recipient .recipient-value.not-encrypted{border-bottom-color:#F6A41C}#compose-box .recipients-area .fixed-recipient .recipient-value.not-encrypted:before,#draft-box .recipients-area .fixed-recipient .recipient-value.not-encrypted:before,#reply-box .recipients-area .fixed-recipient .recipient-value.not-encrypted:before,#feedback-box .recipients-area .fixed-recipient .recipient-value.not-encrypted:before{color:#F6A41C;content:"\f13e "}#compose-box .recipients-area .fixed-recipient .recipient-value.deleting span,#draft-box .recipients-area .fixed-recipient .recipient-value.deleting span,#reply-box .recipients-area .fixed-recipient .recipient-value.deleting span,#feedback-box .recipients-area .fixed-recipient .recipient-value.deleting span{text-decoration:line-through}#compose-box .recipients-area .fixed-recipient .recipient-value span,#draft-box .recipients-area .fixed-recipient .recipient-value span,#reply-box .recipients-area .fixed-recipient .recipient-value span,#feedback-box .recipients-area .fixed-recipient .recipient-value span{margin:0px;padding:0px;cursor:pointer}#compose-box .recipients-area .fixed-recipient .recipient-del,#draft-box .recipients-area .fixed-recipient .recipient-del,#reply-box .recipients-area .fixed-recipient .recipient-del,#feedback-box .recipients-area .fixed-recipient .recipient-del{position:relative;color:#AAA}#compose-box .recipients-area .fixed-recipient .recipient-del:hover,#compose-box .recipients-area .fixed-recipient .recipient-del:focus,#draft-box .recipients-area .fixed-recipient .recipient-del:hover,#draft-box .recipients-area .fixed-recipient .recipient-del:focus,#reply-box .recipients-area .fixed-recipient .recipient-del:hover,#reply-box .recipients-area .fixed-recipient .recipient-del:focus,#feedback-box .recipients-area .fixed-recipient .recipient-del:hover,#feedback-box .recipients-area .fixed-recipient .recipient-del:focus{color:#AAA}#compose-box .recipients-area .fixed-recipient .recipient-del:before,#draft-box .recipients-area .fixed-recipient .recipient-del:before,#reply-box .recipients-area .fixed-recipient .recipient-del:before,#feedback-box .recipients-area .fixed-recipient .recipient-del:before{margin-left:0.4em;font-weight:bold;content:"x"}#compose-box .recipients-area .fixed-recipient .recipient-del.deleteTooltip:hover:after,#draft-box .recipients-area .fixed-recipient .recipient-del.deleteTooltip:hover:after,#reply-box .recipients-area .fixed-recipient .recipient-del.deleteTooltip:hover:after,#feedback-box .recipients-area .fixed-recipient .recipient-del.deleteTooltip:hover:after{position:absolute;content:"Click to remove";font-size:0.5rem;background:rgba(0,0,0,0.7);color:#FFF;position:absolute;z-index:2;left:0px;top:25px;font-size:0.8rem;padding:2px 10px;white-space:nowrap;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px}#compose-box .recipients-area input.recipients-input:focus,#draft-box .recipients-area input.recipients-input:focus,#reply-box .recipients-area input.recipients-input:focus,#feedback-box .recipients-area input.recipients-input:focus{background-color:#FAFAFA !important;border-color:#999;outline:none;width:270px}#compose-box .collapse,#draft-box .collapse,#reply-box .collapse,#feedback-box .collapse{display:block;position:absolute;right:10px;padding-right:15px;padding-left:15px;font-family:'FontAwesome';font-weight:bolder;font-size:larger;cursor:pointer}#compose-box .collapse+input,#compose-box .collapse+input+*,#draft-box .collapse+input,#draft-box .collapse+input+*,#reply-box .collapse+input,#reply-box .collapse+input+*,#feedback-box .collapse+input,#feedback-box .collapse+input+*{display:none}#compose-box .collapse+input:checked+*,#draft-box .collapse+input:checked+*,#reply-box .collapse+input:checked+*,#feedback-box .collapse+input:checked+*{display:block}#compose{margin-bottom:5px;padding-right:4px}#compose #compose-trigger{width:100%;display:inline-block;padding:5px}#compose #compose-trigger #compose-mails-trigger{background:#3DABC4;color:#FFF;padding:10px 30px;text-align:center;font-weight:400;font-size:1.2em;-moz-transition-property:background-color;-o-transition-property:background-color;-webkit-transition-property:background-color;transition-property:background-color;-moz-transition-duration:300ms;-o-transition-duration:300ms;-webkit-transition-duration:300ms;transition-duration:300ms;-moz-transition-timing-function:ease-out;-o-transition-timing-function:ease-out;-webkit-transition-timing-function:ease-out;transition-timing-function:ease-out}#compose #compose-trigger #compose-mails-trigger:hover{background:#64bcd0;cursor:pointer}.mail-list-entry{padding:8px 10px 10px 10px;border-bottom:1px solid white;transition:background-color 150ms ease-out;cursor:pointer;font-weight:bold;height:80px;position:relative;line-height:normal}.mail-list-entry:after{content:"";display:table;clear:both}.mail-list-entry.status-read{font-weight:normal;color:#555}.mail-list-entry.selected{background:#FFF;z-index:10}.mail-list-entry:hover{background:#e1e1e1}.mail-list-entry__checkbox{margin-right:5px;display:block;float:left;min-height:100%}.mail-list-entry__checkbox>input[type=checkbox]{background-color:#FFF;border:1px solid #C2C2C2;padding:7px;margin:3px 0;cursor:pointer;display:inline-block;position:relative;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-moz-appearance:none;-webkit-appearance:none}.mail-list-entry__checkbox>input[type=checkbox]:focus{outline:none;border-color:#666}.mail-list-entry__checkbox>input[type=checkbox]:checked{background-color:#EEE;border:1px solid #c4c4c4;color:#333}.mail-list-entry__checkbox>input[type=checkbox]:checked:after{content:'\2714';font-size:1em;position:absolute;bottom:-2px;left:1px;color:#3E3A37}.mail-list-entry__item{display:block;color:#333;padding-left:24px}.mail-list-entry__item-from{white-space:nowrap;font-size:0.8em;overflow:hidden;text-overflow:ellipsis;display:inline-block}.mail-list-entry__item-date{font-size:0.7em;float:right;display:inline-block}.mail-list-entry__item-subject{display:inline-block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:85%}.mail-list-entry__item-subject-icon{color:#C2C2C2}.mail-list-entry__item-attachment{width:14px;text-align:right;display:inline-block;float:right;color:#C2C2C2}.mail-list-entry__item-tags{line-height:normal;margin-bottom:0}.mail-list-entry__item-tags>*{display:inline}.mail-list-entry__item-tags-tag{font-size:.6rem;font-weight:normal;background-color:#6cbfd2;color:white;padding:2px 3px;margin:0 1px;border-radius:2px}.mail-list-entry__item:hover,.mail-list-entry__item:focus,.mail-list-entry__item:active{color:#333}.no-padding{padding:0}.text-right{text-align:right}#reply-section{padding-left:30px}#reply-section .reply-container{margin:10px 0;padding:10px;border:1px dashed #d5d5d5;-moz-transition-property:background-color;-o-transition-property:background-color;-webkit-transition-property:background-color;transition-property:background-color;-moz-transition-duration:300ms;-o-transition-duration:300ms;-webkit-transition-duration:300ms;transition-duration:300ms;-moz-transition-timing-function:ease-out;-o-transition-timing-function:ease-out;-webkit-transition-timing-function:ease-out;transition-timing-function:ease-out}#reply-section button{margin:0}#reply-section #all-recipients{color:#000}#reply-section #all-recipients:focus{background-color:#d5d5d5}#reply-section #reply-button,#reply-section #reply-all-button,#reply-section #forward-button{text-align:center;font-weight:100;font-size:1.1em;background:#FFF;color:#999;padding:25px;margin:0;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}#reply-section #reply-button:hover,#reply-section #reply-all-button:hover,#reply-section #forward-button:hover{background:#e1e1e1;cursor:pointer}#logo{color:#FFF}#logout{color:#FFF;cursor:pointer}.search-highlight{background-color:#FFEF29}#user-settings-box{position:fixed;z-index:10}#user-settings-box>div{position:fixed;left:70px;bottom:0px;z-index:1;padding:10px 16px 10px 18px;background-color:rgba(62,58,55,0.9);min-width:230px}#user-settings-box>div.extra-bottom-space{bottom:33px}#user-settings-box>div header{border-bottom:1px solid white;margin-bottom:10px}#user-settings-box>div #user-settings-close{float:right}#user-settings-box>div h1,#user-settings-box>div i{font-size:1.2em;color:white;line-height:1.2em}#user-settings-box>div h2{font-size:1.1em;color:white;line-height:1.1em;display:inline;margin-left:5px}#user-settings-box>div i.fa-user{margin-right:10px;float:left}#user-settings-box>div i.fa-close{margin-left:10px;float:right;cursor:pointer}#user-settings-box>div p{font-size:1.1em;color:#FF9C00}.arrow-box:before{right:100%;top:65%;border:20px solid transparent;content:" ";height:0;width:0;position:absolute;pointer-events:none;border-right-color:rgba(62,58,55,0.9);margin-top:-20px}section{display:inline-block;vertical-align:top;height:100vh;overflow-y:scroll}section#top-pane{height:auto;overflow:hidden;background:#EEE;border-top:1px solid #EEE}section#top-pane #list-actions{width:100%;height:34px;margin:0;border-top:1px solid #FFF;border-bottom:2px solid #fff;background:#EEE;clear:both;overflow:hidden}section#top-pane #list-actions li{display:inline-block;margin:1px -3px;vertical-align:top}section#top-pane #list-actions li input[type=checkbox]{background-color:#FFF;border:1px solid #C2C2C2;padding:7px;margin:3px 0;cursor:pointer;display:inline-block;position:relative;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-moz-appearance:none;-webkit-appearance:none;margin:7px 13px 7px}section#top-pane #list-actions li input[type=checkbox]:focus{outline:none;border-color:#666}section#top-pane #list-actions li input[type=checkbox]:checked{background-color:#EEE;border:1px solid #c4c4c4;color:#333}section#top-pane #list-actions li input[type=checkbox]:checked:after{content:'\2714';font-size:1em;position:absolute;bottom:-2px;left:1px;color:#3E3A37}section#top-pane #list-actions li select{padding:1px 3px;margin:0}section#top-pane #list-actions li input[type=button]{margin:2px;padding:4px 10px;background:#fff;color:#333;text-transform:uppercase;font-weight:400;font-size:0.8em;opacity:0.7;border:1px solid #d5d5d5;-moz-border-radius:1px;-webkit-border-radius:1px;border-radius:1px;-moz-transition-property:background-color;-o-transition-property:background-color;-webkit-transition-property:background-color;transition-property:background-color;-moz-transition-duration:300ms;-o-transition-duration:300ms;-webkit-transition-duration:300ms;transition-duration:300ms;-moz-transition-timing-function:ease-out;-o-transition-timing-function:ease-out;-webkit-transition-timing-function:ease-out;transition-timing-function:ease-out}section#top-pane #list-actions li input[type=button]:hover{opacity:1}section#top-pane #list-actions li input[type=button][disabled=disabled]{opacity:0.5;cursor:default}section#top-pane #list-actions #pagination-trigger{cursor:pointer;margin:4px 12px 0 5px}section#top-pane #list-actions #pagination-trigger span{padding-left:5px}section#top-pane #compose-search-trigger{padding:4px}section#top-pane #actions ul{margin:0}section#top-pane #actions ul li{display:inline-block;margin-right:-5px}section#top-pane #actions ul li a{transition:background-color 150ms ease-out;background:#EEE;color:#FFF;font-size:1.5em;display:block;padding:14px 20px;margin:0 1px 0px;opacity:0.35}section#top-pane #actions ul li a.selected{background:#EEE;opacity:1;cursor:default}section#top-pane #actions ul li a:hover{opacity:1}section#top-pane #search-trigger{padding:5px;padding-left:0}section#top-pane #search-trigger input{margin:0;padding:8px 30px;color:#3E3A37;background:white;border:none;transition:background-color 150ms ease-out}section#top-pane #search-trigger input:hover{background:#fafafa}section#top-pane #search-trigger input:focus{background:#f2f2f2}section#top-pane #search-trigger form:before{font-family:"FontAwesome";content:"\f002";position:absolute;padding:0 10px;top:15px;color:#999}section#left-pane{background-color:#3E3A37;color:white}section#left-pane nav{border-right:1px solid #59534f}section#left-pane nav ul#default-tag-list li,section#left-pane nav #custom-tag-list li{transition:background-color 150ms ease-out;padding:2px 10px;cursor:pointer}section#left-pane nav ul#default-tag-list li:hover,section#left-pane nav #custom-tag-list li:hover{background:#C2C2C2;color:#3E3A37}section#left-pane nav ul#default-tag-list li.selected,section#left-pane nav #custom-tag-list li.selected{font-weight:bold;background:#EEE;color:#3E3A37}section#left-pane nav ul#default-tag-list .unread-count,section#left-pane nav ul#default-tag-list .total-count{font-size:0.7em;padding:0px 5px 0;top:1px;left:0;border:1px solid #FFF;border-bottom:1px solid white;position:absolute;opacity:0.95}section#left-pane nav ul#default-tag-list .total-count{background:#999}section#left-pane nav ul#default-tag-list span.tag-label{padding-left:2px}section#left-pane nav ul#default-tag-list li{padding:5px 10px 5px 18px;position:relative}section#left-pane nav ul#default-tag-list li.searching:after{font-family:FontAwesome;content:"\f002";font-size:.7em;top:4px;left:19px;position:absolute;color:#333;text-shadow:-1px 0 #EEE,0 1px #EEE,1px 0 #EEE,0 -1px #EEE}section#left-pane nav ul#default-tag-list li:before{font-size:1.5em;font-family:"FontAwesome";margin-right:16px;font-weight:normal;position:relative;top:2px;margin-left:-3px}section#left-pane nav ul#default-tag-list li:after{padding-left:10px}section#left-pane nav ul#default-tag-list li:nth-child(1):before{content:"\f01c"}section#left-pane nav ul#default-tag-list li:nth-child(2):before{content:"\f1d8";margin-left:-5px}section#left-pane nav ul#default-tag-list li:nth-child(3):before{content:"\f040"}section#left-pane nav ul#default-tag-list li:nth-child(4):before{content:"\f014"}section#left-pane nav ul#default-tag-list li:nth-child(5):before{content:"\f187";margin-left:-5px}section#left-pane nav ul#custom-tag-list{visibility:hidden;opacity:0;transition-duration:500ms;height:100%;max-height:220px;overflow:auto;background-color:#413d39}section#left-pane nav ul#custom-tag-list li{white-space:nowrap;overflow:hidden;font-size:0.8em;padding:5px 10px 5px 15px}section#left-pane nav ul#custom-tag-list li.custom-tag{text-overflow:ellipsis}section#left-pane nav ul#custom-tag-list li span.tag-label{padding:5px 20px 5px 38px}section#left-pane nav ul#custom-tag-list.expanded{visibility:visible;opacity:1}section#left-pane nav div.tags-icon{border-top:1px solid white;padding-top:25px;margin-bottom:20px}section#left-pane nav div.tags-icon i{font-size:1.5em;font-family:"FontAwesome";margin-right:13px;font-weight:normal;position:relative;top:2px;left:16px}section#left-pane nav div.tags-icon span.tag-label{font-size:0.9rem;padding-left:16px;margin-bottom:10px}section#left-pane nav ul#logout,section#left-pane nav ul#feedback,section#left-pane nav ul#user-settings-icon{margin-bottom:0}section#left-pane nav ul#logout li,section#left-pane nav ul#feedback li,section#left-pane nav ul#user-settings-icon li{background-color:#3E3A37;padding:5px 10px;position:relative}section#left-pane nav ul#logout li.searching:after,section#left-pane nav ul#feedback li.searching:after,section#left-pane nav ul#user-settings-icon li.searching:after{font-family:FontAwesome;content:"\f002";font-size:.7em;top:4px;left:19px;position:absolute;color:#333;text-shadow:-1px 0 #EEE,0 1px #EEE,1px 0 #EEE,0 -1px #EEE}section#left-pane nav ul#logout li:hover,section#left-pane nav ul#feedback li:hover,section#left-pane nav ul#user-settings-icon li:hover{color:#3E3A37}section#left-pane nav ul#logout li div,section#left-pane nav ul#feedback li div,section#left-pane nav ul#user-settings-icon li div{padding-left:7px}section#left-pane nav ul#logout li div:before,section#left-pane nav ul#feedback li div:before,section#left-pane nav ul#user-settings-icon li div:before{font-size:1.5em;font-family:"FontAwesome";margin-right:13px;font-weight:normal;position:relative;top:2px}section#left-pane nav ul#logout li{color:#3DABC4}section#left-pane nav ul#logout li:hover{background-color:#3DABC4}section#left-pane nav ul#user-settings-icon li{color:white}section#left-pane nav ul#user-settings-icon li:hover{background-color:white}section#left-pane nav ul#feedback{margin-bottom:0}section#left-pane nav ul#feedback li{color:#FF9C00}section#left-pane nav ul#feedback li:hover{background-color:#FF9C00}section#left-pane nav h3{color:white;text-transform:uppercase;font-size:0.6em;padding:5px;font-weight:600;margin:0 10px;border-bottom:1px dotted #59534f}section#middle-pane{background:#EEE}section#right-pane{padding:0 10px 60px 0px;background:#FFF;box-shadow:-2px -2px 5px rgba(0,0,0,0.12);z-index:2;overflow-y:auto}.unread-count{background:#e68c00;color:#FFF;padding:2px 5px;font-size:0.7em;margin-left:5px;font-weight:700;position:relative;-moz-border-radius:100px;-webkit-border-radius:100px;border-radius:100px}.total-count{background:#999;color:#FFF;padding:2px 5px;font-size:0.7em;margin-left:5px;font-weight:700;position:relative;-moz-border-radius:100px;-webkit-border-radius:100px;border-radius:100px}#refresh-mails-trigger i{margin-top:3px;cursor:pointer;opacity:0.9;padding:4px}#refresh-mails-trigger i:hover{opacity:1}#refresh-mails-trigger i:hover:after{content:"\f021"}#refresh-mails-trigger i:hover:before{content:"refresh";font-size:0.8em;padding-right:5px}.buttons-group{clear:both;margin:20px 0 0;padding:0}#draft-save-status{float:right;padding:0.4rem 1.1rem;color:#91C2D1}button{border:1px solid transparent}button i{margin-left:5px}button#trash-button{background:#FFF;border:1px solid #999;color:#999;float:right;margin-left:5px}button#trash-button:hover,button#trash-button:focus{background:#EEE}button.no-style{background:transparent;color:#999;padding:0;margin:0}button.no-style i{margin:0;padding:0;vertical-align:middle}.side-nav-toggle,.side-nav-toggle-icon{color:white;cursor:pointer;background:#3E3A37}.side-nav-toggle:hover,.side-nav-toggle:focus,.side-nav-toggle-icon:hover,.side-nav-toggle-icon:focus{color:white}.side-nav-toggle.logout,.side-nav-toggle-icon.logout{color:#3DABC4}.side-nav-toggle-icon{padding:6px 0px 8px 19px;display:block;left:0;top:0;position:relative}.left-off-canvas-logo svg{width:162px;height:56px;padding-left:6px;padding-top:2px}.left-off-canvas-logo svg path,.left-off-canvas-logo svg polygon,.left-off-canvas-logo svg rect{fill:#FF9C00}.collapsed-nav{width:50px;position:absolute;height:100vh;background:#3E3A37}.collapsed-nav ul.shortcuts li{position:relative;margin-bottom:5px;opacity:0.8}.collapsed-nav ul.shortcuts li.selected{background:#EEE;opacity:1;cursor:default}.collapsed-nav ul.shortcuts li.selected a{color:#3E3A37}.collapsed-nav ul.shortcuts li.searching:after{font-family:FontAwesome;content:"\f002";font-size:.9em;top:6px;left:26px;position:absolute;color:#666;text-shadow:-1px 0 #EEE,0 1px #EEE,1px 0 #EEE,0 -1px #EEE}.collapsed-nav ul.shortcuts li a{display:block;position:relative;font-size:1.4em;padding:5px;color:white;text-align:center}.collapsed-nav ul.shortcuts li a:hover{background:#d5d5d5;color:#3E3A37;-moz-transition-property:background-color;-o-transition-property:background-color;-webkit-transition-property:background-color;transition-property:background-color;-moz-transition-duration:300ms;-o-transition-duration:300ms;-webkit-transition-duration:300ms;transition-duration:300ms;-moz-transition-timing-function:ease-out;-o-transition-timing-function:ease-out;-webkit-transition-timing-function:ease-out;transition-timing-function:ease-out}.collapsed-nav ul.shortcuts li a:hover.logout{color:#000;background:#3DABC4}.collapsed-nav ul.shortcuts li a[title]:hover:after{content:attr(title);background:rgba(0,0,0,0.7);color:#FFF;position:absolute;z-index:2;left:40px;top:8px;font-size:0.8rem;padding:2px 10px;white-space:nowrap;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px}.collapsed-nav ul.shortcuts li .unread-count,.collapsed-nav ul.shortcuts li .total-count{font-size:0.5em;padding:1px 5px 0;top:1px;left:0;border:1px solid #FFF;position:absolute;opacity:0.95}.collapsed-nav ul.shortcuts li .total-count{background:#999}.collapsed-nav #custom-tags-shortcuts li{border-top:1px solid #DDD}.collapsed-nav div.shortcut-label{font-size:xx-small;text-transform:uppercase;text-align:center}.move-right ul.shortcuts li{display:none}.hidden{display:none}.left-off-canvas-menu{width:222px;-webkit-backface-visibility:hidden;box-sizing:content-box;left:0;top:0;bottom:0;position:absolute;overflow-y:auto}.left-off-canvas-menu *{-webkit-backface-visibility:hidden}.off-canvas-wrap{-webkit-backface-visibility:hidden;position:relative;width:100%;overflow:hidden}.off-canvas-wrap.move-right,.off-canvas-wrap.move-left{min-height:100%;-webkit-overflow-scrolling:touch}.inner-wrap{-webkit-backface-visibility:hidden;width:100%}.inner-wrap:before,.inner-wrap:after{content:" ";display:table}.inner-wrap:after{clear:both}.off-canvas-wrap.content{-webkit-transition:-webkit-transform 500ms ease;-moz-transition:-moz-transform 500ms ease;-ms-transition:-ms-transform 500ms ease;-o-transition:-o-transform 500ms ease;transition:transform 500ms ease}.off-canvas-wrap.content.move-right{-webkit-transform:translate3d(10rem, 0, 0);-moz-transform:translate3d(10rem, 0, 0);-ms-transform:translate3d(10rem, 0, 0);-o-transform:translate3d(10rem, 0, 0);transform:translate3d(10rem, 0, 0)}.off-canvas-wrap.content.move-right #user-settings-box>div{left:20px}.move-right .exit-off-canvas{-webkit-backface-visibility:hidden;transition:background 300ms ease;cursor:pointer;display:block;position:absolute;background:rgba(255,255,255,0.2);top:0;bottom:0;left:0;right:0;-webkit-tap-highlight-color:transparent}@media only screen and (min-width: 40.063em){.move-right .exit-off-canvas:hover{background:rgba(255,255,255,0.05)}}.off-canvas-wrap.move-right.menu{position:absolute}.off-canvas-wrap.content{left:50px;padding-right:50px}.offcanvas-overlap .left-off-canvas-menu,.offcanvas-overlap .right-off-canvas-menu{-ms-transform:none;-webkit-transform:none;-moz-transform:none;-o-transform:none;transform:none}.offcanvas-overlap .exit-offcanvas-menu{-webkit-backface-visibility:hidden;transition:background 300ms ease;cursor:pointer;display:block;position:absolute;background:rgba(255,255,255,0.2);top:0;bottom:0;left:0;right:0;-webkit-tap-highlight-color:transparent}#delete-modal button#trash-button,#delete-modal button#archive-button{width:40%;margin:0 22px 30px;height:80px}#delete-modal small{font-size:80%;display:block}div.side-nav-bottom{width:100%;position:fixed;bottom:20px;background-color:#3E3A37}div.side-nav-bottom .version{padding-left:55px;padding-bottom:3px}.buttons-group span#attachment-button{cursor:pointer;outline:0;margin-left:18px;padding-top:0px;-ms-transform:rotate(224deg);-webkit-transform:rotate(224deg);transform:rotate(224deg)}.buttons-group span#attachment-button i.fa-paperclip{font-size:1.7em}.buttons-group span#attachment-button.busy{color:#c4c4c4;cursor:progress} diff --git a/src/pixelated_www/fonts/OpenSans-Bold.woff b/src/pixelated_www/fonts/OpenSans-Bold.woff new file mode 100644 index 00000000..dacf3c9c Binary files /dev/null and b/src/pixelated_www/fonts/OpenSans-Bold.woff differ diff --git a/src/pixelated_www/fonts/OpenSans-BoldItalic.woff b/src/pixelated_www/fonts/OpenSans-BoldItalic.woff new file mode 100644 index 00000000..a4e29c0f Binary files /dev/null and b/src/pixelated_www/fonts/OpenSans-BoldItalic.woff differ diff --git a/src/pixelated_www/fonts/OpenSans-Extrabold.woff b/src/pixelated_www/fonts/OpenSans-Extrabold.woff new file mode 100644 index 00000000..7a2e352b Binary files /dev/null and b/src/pixelated_www/fonts/OpenSans-Extrabold.woff differ diff --git a/src/pixelated_www/fonts/OpenSans-ExtraboldItalic.woff b/src/pixelated_www/fonts/OpenSans-ExtraboldItalic.woff new file mode 100644 index 00000000..ce3ab2e7 Binary files /dev/null and b/src/pixelated_www/fonts/OpenSans-ExtraboldItalic.woff differ diff --git a/src/pixelated_www/fonts/OpenSans-Italic.woff b/src/pixelated_www/fonts/OpenSans-Italic.woff new file mode 100644 index 00000000..c5f6bac1 Binary files /dev/null and b/src/pixelated_www/fonts/OpenSans-Italic.woff differ diff --git a/src/pixelated_www/fonts/OpenSans-Light.woff b/src/pixelated_www/fonts/OpenSans-Light.woff new file mode 100644 index 00000000..eb601d70 Binary files /dev/null and b/src/pixelated_www/fonts/OpenSans-Light.woff differ diff --git a/src/pixelated_www/fonts/OpenSans-Semibold.woff b/src/pixelated_www/fonts/OpenSans-Semibold.woff new file mode 100644 index 00000000..56c44944 Binary files /dev/null and b/src/pixelated_www/fonts/OpenSans-Semibold.woff differ diff --git a/src/pixelated_www/fonts/OpenSans-SemiboldItalic.woff b/src/pixelated_www/fonts/OpenSans-SemiboldItalic.woff new file mode 100644 index 00000000..3a439fc3 Binary files /dev/null and b/src/pixelated_www/fonts/OpenSans-SemiboldItalic.woff differ diff --git a/src/pixelated_www/fonts/OpenSans.woff b/src/pixelated_www/fonts/OpenSans.woff new file mode 100644 index 00000000..77706fa6 Binary files /dev/null and b/src/pixelated_www/fonts/OpenSans.woff differ diff --git a/src/pixelated_www/fonts/OpenSansLight-Italic.woff b/src/pixelated_www/fonts/OpenSansLight-Italic.woff new file mode 100644 index 00000000..3f9f088f Binary files /dev/null and b/src/pixelated_www/fonts/OpenSansLight-Italic.woff differ diff --git a/src/pixelated_www/index.html b/src/pixelated_www/index.html new file mode 100644 index 00000000..1e6acc46 --- /dev/null +++ b/src/pixelated_www/index.html @@ -0,0 +1,18 @@ +$account_email - Pixelated Mail
            \ No newline at end of file diff --git a/src/pixelated_www/locales/en-us/translation.json b/src/pixelated_www/locales/en-us/translation.json new file mode 100644 index 00000000..357187b0 --- /dev/null +++ b/src/pixelated_www/locales/en-us/translation.json @@ -0,0 +1,71 @@ +{ + "compose": "Compose", + "re": "Re: ", + "Fwd: ": "Fwd: ", + "Your message was moved to trash!": "Your message was moved to trash!", + "Your message was archived": "Your message was archived", + "Your message was permanently deleted!": "Your message was permanently deleted!", + "Saved as draft.": "Saved as draft.", + "One or more of the recipients are not valid emails": "One or more of the recipients are not valid emails", + "Could not update mail tags": "Could not update mail tags", + "Invalid tag name": "Invalid tag name", + "Could not delete email": "Could not delete email", + "Could not fetch messages": "Could not fetch messages", + "TO": "TO", + "To": "To", + "CC": "CC", + "BCC": "BCC", + "Body": "Body", + "Subject": "Subject", + "Don't worry about recipients right now, you'll be able to add them just before sending.": "Don't worry about recipients right now, you'll be able to add them just before sending.", + "Send": "Send", + "Cancel": "Cancel", + "Reply": "Reply", + "Reply to All": "Reply to All", + "Mark as read": "Mark as read", + "mark-as-unread": "Mark as unread", + "Delete": "Delete", + "Archive": "Archive", + "Close": "Close", + "Trash this message": "Trash this message", + "NOTHING SELECTED": "NOTHING SELECTED", + "Press Enter to add tag": "Press Enter to add tag", + "You are trying to delete the last tag on this message.": "You are trying to delete the last tag on this message.", + "What would you like to do?": "What would you like to do?", + "Trash message": "Trash message", + "Archive it": "Archive it", + "Trash:": "Trash:", + "Archive:": "Archive:", + "we will keep this message for 30 days, then delete it forever.": "we will keep this message for 30 days, then delete it forever.", + "we will remove all the tags, but keep it in your account in case you need it.": "we will remove all the tags, but keep it in your account in case you need it.", + "to:": "to:", + "no_subject": "", + "no_recipient": "", + "you": "you", + "encrypted": "Encrypted", + "encrypted encryption-error": "Unable to decrypt", + "encrypted encryption-valid": "Encrypted", + "not-encrypted": "Not Encrypted", + "signed": "Verified sender", + "signed signature-revoked": "Unreliable signature", + "signed signature-expired": "Unreliable signature", + "signed signature-not-trusted": "Unreliable signature", + "signed signature-unknown": "Unreliable signature", + "not-signed": "Not signed", + "send-button": "Send", + "sending-mail": "Sending...", + "trash-button": "Delete it", + "search-placeholder" : "Search...", + "Search results for:": "Search results for:", + "Tags": "Tags", + "Forward": "Forward", + "feedback-placeholder": "Tell us what you liked, didn't like, what is missing and generally what you think about Pixelated.", + + "tags": { + "inbox": "Inbox", + "sent": "Sent", + "drafts": "Drafts", + "trash": "Trash", + "all": "All" + } +} diff --git a/src/pixelated_www/locales/pt/translation.json b/src/pixelated_www/locales/pt/translation.json new file mode 100644 index 00000000..77525342 --- /dev/null +++ b/src/pixelated_www/locales/pt/translation.json @@ -0,0 +1,71 @@ +{ + "compose": "Escrever", + "re": "Res: ", + "Fwd: ": "Enc: ", + "Your message was moved to trash!": "Sua mensagem foi movida para a lixeira!", + "Your message was archived": "Sua mensagem foi arquivada!", + "Your message was permanently deleted!": "Sua mensagem foi permanentemente deletada!", + "Saved as draft.": "Mensagem salva como rascunho.", + "One or more of the recipients are not valid emails": "Email de um ou mais destinatários é inválido", + "Could not update mail tags": "Não foi possível atualizar as etiquetas do email", + "Invalid tag name": "Nome de etiqueta inválido", + "Could not delete email": "Não foi possível deletar o email", + "Could not fetch messages": "Não foi possível buscar as mensagens", + "TO": "PARA", + "To": "Para", + "CC": "CC", + "BCC": "BCC", + "Body": "Corpo", + "Subject": "Assunto", + "Don't worry about recipients right now, you'll be able to add them just before sending.": "Não se preocupe com os destinatários agora, você poderá adicioná-los antes de enviar.", + "Send": "Enviar", + "Cancel": "Cancelar", + "Reply": "Responder", + "Reply to All": "Responder a todos", + "Mark as read": "Marcar como lida", + "mark-as-unread": "Marcar como não lida", + "Delete": "Descartar", + "Archive": "Arquivar", + "Close": "Fechar", + "Trash this message": "Descartar essa mensagem", + "NOTHING SELECTED": "NADA SELECIONADO", + "Press Enter to add tag": "Precione Enter para adicionar a tag", + "You are trying to delete the last tag on this message.": "Você está tentando excluir a última tag dessa mensagem.", + "What would you like to do?": "O que você gostaria de fazer?", + "Trash message": "Descartar mensagem", + "Archive it": "Arquivar", + "Trash:": "Lixeira:", + "Archive:": "Arquivo:", + "we will keep this message for 30 days, then delete it forever.": "manteremos essa mensagem por 30 dias, após isso ela será excluída definitivamente.", + "we will remove all the tags, but keep it in your account in case you need it.": "iremos remover todas as tags, mas manteremos em sua conta caso necessite.", + "to:": "para:", + "no_subject": "", + "no_recipient": "", + "you": "você", + "encrypted": "Criptografado", + "encrypted encryption-error": "Não é possível descriptografar", + "encrypted encryption-valid": "Criptografado", + "not-encrypted": "Não Criptografado", + "signed": "Remetente verificado", + "signed signature-revoked": "Assinatura não confiável", + "signed signature-expired": "Assinatura não confiável", + "signed signature-not-trusted": "Assinatura não confiável", + "signed signature-unknown": "Assinatura não confiável", + "not-signed": "Não assinado", + "send-button": "Enviar", + "sending-mail": "Enviando...", + "trash-button": "Descartar", + "search-placeholder" : "Pesquisar...", + "Search results for:": "Resultados da pesquisa:", + "Tags": "Tags", + "Forward": "Encaminhar", + "feedback-placeholder": "Nos diga o que gosta, não gosta, o que está faltando e o que pensa sobre o Pixelated.", + + "tags": { + "inbox": "Caixa de Entrada", + "sent": "Enviadas", + "drafts": "Rascunhos", + "trash": "Lixeira", + "all": "Todas" + } +} diff --git a/src/pixelated_www/locales/sv/translation.json b/src/pixelated_www/locales/sv/translation.json new file mode 100644 index 00000000..0c64d6d7 --- /dev/null +++ b/src/pixelated_www/locales/sv/translation.json @@ -0,0 +1,66 @@ +{ + "compose": "Skriv nytt", + "re": "Sv: ", + "Fwd: ": "VB: ", + "Your message was moved to trash!": "Ditt meddelande har flyttats till papperskorgen!", + "Your message was archived": "Ditt meddelande har arkiverats!", + "Your message was permanently deleted!": "Ditt meddelande har tagits bort permanent!", + "Saved as draft.": "Sparat som utkast.", + "One or more of the recipients are not valid emails": "En eller flera mottagare är inte giltiga epost-adresser", + "Could not update mail tags": "Kan inte ändra taggar", + "Invalid tag name": "Ogiltigt taggnamn", + "Could not delete email": "Kan inte ta bort meddelande", + "Could not fetch messages": "Kan inte hämta meddelanden", + "TO": "TILL", + "To": "Till", + "CC": "CC", + "BCC": "BCC", + "Body": "Innehåll", + "Subject": "Titel", + "Don't worry about recipients right now, you'll be able to add them just before sending.": "Oroa dig inte över mottagare just nu, du kan lägga till dem senare.", + "Send": "Skicka", + "Cancel": "Avbryt", + "Reply": "Svara", + "Reply to All": "Svara Alla", + "Mark as read": "Markera som läst", + "Delete": "Ta bort", + "Archive": "Arkivera", + "Close": "Stäng", + "Trash this message": "Kasta detta meddelande", + "NOTHING SELECTED": "INGET VALT", + "Press Enter to add tag": "Tryck retur för att skapa", + "You are trying to delete the last tag on this message.": "Du försöker ta bort den sista taggen på detta meddelande.", + "What would you like to do?": "Vad vill du göra?", + "Trash message": "Ta bort", + "Archive it": "Arkivera", + "Trash:": "Ta bort:", + "Archive:": "Arkivera:", + "we will keep this message for 30 days, then delete it forever.": "vi kommer spara meddelandet i 30 dagar och sedan ta bort det för alltid.", + "we will remove all the tags, but keep it in your account in case you need it.": "vi kommer ta bort alla taggar men spara meddelandet i ditt konto ifall du behöver det.", + "to:": "till:", + "no_subject": "", + "no_recipient": "", + "you": "du", + "encrypted": "krypterad", + "encrypted encryption-error": "Du har inte tillstånd att see det här meddelandet.", + "encrypted encryption-valid": "Meddelandet skickades säkert.", + "not-encrypted": "Meddelandet var läsbart medans det var på väg.", + "signed": "Certifierad avsändare.", + "signed signature-revoked": "Avsändaren kunde inte säkert identifieras.", + "signed signature-expired": "Avsändaren kunde inte säkert identifieras.", + "signed signature-not-trusted": "Avsändaren och/eller meddelandet är inte pålitligt.", + "signed signature-unknown": "Avsändaren och/eller meddelandet är inte pålitligt.", + "not-signed": "Avsändaren kunde inte säkert identifieras.", + "search-placeholder" : "Sök...", + "Search results for:": "Sökresultat för:", + "Tags": "Taggar", + "Forward": "Vidarebefodra", + + "tags": { + "inbox": "Inlåda", + "sent": "Skickat", + "drafts": "Utkast", + "trash": "Skräp", + "all": "Alla" + } +} diff --git a/src/pixelated_www/sandbox.html b/src/pixelated_www/sandbox.html new file mode 100644 index 00000000..ea372e65 --- /dev/null +++ b/src/pixelated_www/sandbox.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/pixelated_www/sandbox.min.js b/src/pixelated_www/sandbox.min.js new file mode 100644 index 00000000..b9f6bd6b --- /dev/null +++ b/src/pixelated_www/sandbox.min.js @@ -0,0 +1 @@ +!function(){"use strict";window.onmessage=function(e){if(e.data.html){document.body.innerHTML=e.data.html;var t=e.source;t.postMessage("data ok",e.origin)}}}(),function(e){"use strict";function t(t,n,o){"addEventListener"in e?t.addEventListener(n,o,!1):"attachEvent"in e&&t.attachEvent("on"+n,o)}function n(t,n,o){"removeEventListener"in e?t.removeEventListener(n,o,!1):"detachEvent"in e&&t.detachEvent("on"+n,o)}function o(e){return e.charAt(0).toUpperCase()+e.slice(1)}function i(e){var t,n,o,i=null,r=0,a=function(){r=xe(),i=null,o=e.apply(t,n),i||(t=n=null)};return function(){var u=xe();r||(r=u);var c=Oe-(u-r);return t=this,n=arguments,0>=c||c>Oe?(i&&(clearTimeout(i),i=null),r=u,o=e.apply(t,n),i||(t=n=null)):i||(i=setTimeout(a,c)),o}}function r(e){return fe+"["+ge+"] "+e}function a(t){de&&"object"==typeof e.console&&console.log(r(t))}function u(t){"object"==typeof e.console&&console.warn(r(t))}function c(){s(),a("Initialising iFrame ("+location.href+")"),l(),m(),f("background",Y),f("padding",Z),N(),y(),b(),g(),w(),T(),ce=k(),q("init","Init message from host page"),Ce()}function s(){function e(e){return"true"===e}var t=ue.substr(me).split(":");ge=t[0],$=void 0!==t[1]?Number(t[1]):$,_=void 0!==t[2]?e(t[2]):_,de=void 0!==t[3]?e(t[3]):de,se=void 0!==t[4]?Number(t[4]):se,K=void 0!==t[6]?e(t[6]):K,G=t[7],re=void 0!==t[8]?t[8]:re,Y=t[9],Z=t[10],Te=void 0!==t[11]?Number(t[11]):Te,ce.enable=void 0!==t[12]?e(t[12]):!1,he=void 0!==t[13]?t[13]:he,Ne=void 0!==t[14]?t[14]:Ne}function l(){function t(){var t=e.iFrameResizer;a("Reading data from page: "+JSON.stringify(t)),we="messageCallback"in t?t.messageCallback:we,Ce="readyCallback"in t?t.readyCallback:Ce,be="targetOrigin"in t?t.targetOrigin:be,re="heightCalculationMethod"in t?t.heightCalculationMethod:re,Ne="widthCalculationMethod"in t?t.widthCalculationMethod:Ne}"iFrameResizer"in e&&Object===e.iFrameResizer.constructor&&t(),a("TargetOrigin for parent set to: "+be)}function d(e,t){return-1!==t.indexOf("-")&&(u("Negative CSS value ignored for "+e),t=""),t}function f(e,t){void 0!==t&&""!==t&&"null"!==t&&(document.body.style[e]=t,a("Body "+e+' set to "'+t+'"'))}function m(){void 0===G&&(G=$+"px"),f("margin",d("margin",G))}function g(){document.documentElement.style.height="",document.body.style.height="",a('HTML & body height set to "auto"')}function v(i){function r(){q(i.eventName,i.eventType)}var u={add:function(n){t(e,n,r)},remove:function(t){n(e,t,r)}};i.eventNames&&Array.prototype.map?(i.eventName=i.eventNames[0],i.eventNames.map(u[i.method])):u[i.method](i.eventName),a(o(i.method)+" event listener: "+i.eventType)}function h(e){v({method:e,eventType:"Animation Start",eventNames:["animationstart","webkitAnimationStart"]}),v({method:e,eventType:"Animation Iteration",eventNames:["animationiteration","webkitAnimationIteration"]}),v({method:e,eventType:"Animation End",eventNames:["animationend","webkitAnimationEnd"]}),v({method:e,eventType:"Input",eventName:"input"}),v({method:e,eventType:"Mouse Up",eventName:"mouseup"}),v({method:e,eventType:"Mouse Down",eventName:"mousedown"}),v({method:e,eventType:"Orientation Change",eventName:"orientationchange"}),v({method:e,eventType:"Print",eventName:["afterprint","beforeprint"]}),v({method:e,eventType:"Ready State Change",eventName:"readystatechange"}),v({method:e,eventType:"Touch Start",eventName:"touchstart"}),v({method:e,eventType:"Touch End",eventName:"touchend"}),v({method:e,eventType:"Touch Cancel",eventName:"touchcancel"}),v({method:e,eventType:"Transition Start",eventNames:["transitionstart","webkitTransitionStart","MSTransitionStart","oTransitionStart","otransitionstart"]}),v({method:e,eventType:"Transition Iteration",eventNames:["transitioniteration","webkitTransitionIteration","MSTransitionIteration","oTransitionIteration","otransitioniteration"]}),v({method:e,eventType:"Transition End",eventNames:["transitionend","webkitTransitionEnd","MSTransitionEnd","oTransitionEnd","otransitionend"]}),"child"===he&&v({method:e,eventType:"IFrame Resized",eventName:"resize"})}function p(e,t,n,o){return t!==e&&(e in n||(u(e+" is not a valid option for "+o+"CalculationMethod."),e=t),a(o+' calculation method set to "'+e+'"')),e}function y(){re=p(re,ie,ze,"height")}function b(){Ne=p(Ne,Ie,Re,"width")}function T(){!0===K?(h("add"),x()):a("Auto Resize disabled")}function E(){a("Disable outgoing messages"),pe=!1}function S(){a("Remove event listener: Message"),n(e,"message",U)}function O(){null!==Q&&Q.disconnect()}function M(){h("remove"),O(),clearInterval(le)}function I(){E(),S(),!0===K&&M()}function N(){var e=document.createElement("div");e.style.clear="both",e.style.display="block",document.body.appendChild(e)}function k(){function n(){return{x:void 0!==e.pageXOffset?e.pageXOffset:document.documentElement.scrollLeft,y:void 0!==e.pageYOffset?e.pageYOffset:document.documentElement.scrollTop}}function o(e){var t=e.getBoundingClientRect(),o=n();return{x:parseInt(t.left,10)+parseInt(o.x,10),y:parseInt(t.top,10)+parseInt(o.y,10)}}function i(e){function t(e){var t=o(e);a("Moving to in page link (#"+n+") at x: "+t.x+" y: "+t.y),J(t.y,t.x,"scrollToOffset")}var n=e.split("#")[1]||e,i=decodeURIComponent(n),r=document.getElementById(i)||document.getElementsByName(i)[0];void 0!==r?t(r):(a("In page link (#"+n+") not found in iFrame, so sending to parent"),J(0,0,"inPageLink","#"+n))}function r(){""!==location.hash&&"#"!==location.hash&&i(location.href)}function c(){function e(e){function n(e){e.preventDefault(),i(this.getAttribute("href"))}"#"!==e.getAttribute("href")&&t(e,"click",n)}Array.prototype.forEach.call(document.querySelectorAll('a[href^="#"]'),e)}function s(){t(e,"hashchange",r)}function l(){setTimeout(r,te)}function d(){Array.prototype.forEach&&document.querySelectorAll?(a("Setting up location.hash handlers"),c(),s(),l()):u("In page linking not fully supported in this browser! (See README.md for IE8 workaround)")}return ce.enable?d():a("In page linking not enabled"),{findTarget:i}}function w(){a("Enable public methods"),ke.parentIFrame={autoResize:function(e){return!0===e&&!1===K?(K=!0,T()):!1===e&&!0===K&&(K=!1,M()),K},close:function(){J(0,0,"close"),I()},getId:function(){return ge},getPageInfo:function(e){"function"==typeof e?(Ae=e,J(0,0,"pageInfo")):(Ae=function(){},J(0,0,"pageInfoStop"))},moveToAnchor:function(e){ce.findTarget(e)},reset:function(){V("parentIFrame.reset")},scrollTo:function(e,t){J(t,e,"scrollTo")},scrollToOffset:function(e,t){J(t,e,"scrollToOffset")},sendMessage:function(e,t){J(0,0,"message",JSON.stringify(e),t)},setHeightCalculationMethod:function(e){re=e,y()},setWidthCalculationMethod:function(e){Ne=e,b()},setTargetOrigin:function(e){a("Set targetOrigin: "+e),be=e},size:function(e,t){var n=""+(e?e:"")+(t?","+t:"");q("size","parentIFrame.size("+n+")",e,t)}}}function C(){0!==se&&(a("setInterval: "+se+"ms"),le=setInterval(function(){q("interval","setInterval: "+se)},Math.abs(se)))}function A(){function t(e){function t(e){!1===e.complete&&(a("Attach listeners to "+e.src),e.addEventListener("load",r,!1),e.addEventListener("error",u,!1),l.push(e))}"attributes"===e.type&&"src"===e.attributeName?t(e.target):"childList"===e.type&&Array.prototype.forEach.call(e.target.querySelectorAll("img"),t)}function n(e){l.splice(l.indexOf(e),1)}function o(e){a("Remove listeners from "+e.src),e.removeEventListener("load",r,!1),e.removeEventListener("error",u,!1),n(e)}function i(e,t,n){o(e.target),q(t,n+": "+e.target.src,void 0,void 0)}function r(e){i(e,"imageLoad","Image loaded")}function u(e){i(e,"imageLoadFailed","Image load failed")}function c(e){q("mutationObserver","mutationObserver: "+e[0].target+" "+e[0].type),e.forEach(t)}function s(){var e=document.querySelector("body"),t={attributes:!0,attributeOldValue:!1,characterData:!0,characterDataOldValue:!1,childList:!0,subtree:!0};return f=new d(c),a("Create body MutationObserver"),f.observe(e,t),f}var l=[],d=e.MutationObserver||e.WebKitMutationObserver,f=s();return{disconnect:function(){"disconnect"in f&&(a("Disconnect body MutationObserver"),f.disconnect(),l.forEach(o))}}}function x(){var t=0>se;e.MutationObserver||e.WebKitMutationObserver?t?C():Q=A():(a("MutationObserver not supported in this browser!"),C())}function z(e,t){function n(e){var n=/^\d+(px)?$/i;if(n.test(e))return parseInt(e,X);var o=t.style.left,i=t.runtimeStyle.left;return t.runtimeStyle.left=t.currentStyle.left,t.style.left=e||0,e=t.style.pixelLeft,t.style.left=o,t.runtimeStyle.left=i,e}var o=0;return t=t||document.body,"defaultView"in document&&"getComputedStyle"in document.defaultView?(o=document.defaultView.getComputedStyle(t,null),o=null!==o?o[e]:0):o=n(t.currentStyle[e]),parseInt(o,X)}function R(e){e>Oe/2&&(Oe=2*e,a("Event throttle increased to "+Oe+"ms"))}function L(e,t){for(var n=t.length,i=0,r=0,u=o(e),c=xe(),s=0;n>s;s++)i=t[s].getBoundingClientRect()[e]+z("margin"+u,t[s]),i>r&&(r=i);return c=xe()-c,a("Parsed "+n+" HTML elements"),a("Element position calculated in "+c+"ms"),R(c),r}function F(e){return[e.bodyOffset(),e.bodyScroll(),e.documentElementOffset(),e.documentElementScroll()]}function P(e,t){function n(){return u("No tagged elements ("+t+") found on page"),oe}var o=document.querySelectorAll("["+t+"]");return 0===o.length?n():L(e,o)}function D(){return document.querySelectorAll("body *")}function H(e,t,n,o){function i(){oe=d,Me=f,J(oe,Me,e)}function r(){function e(e,t){var n=Math.abs(e-t)<=Te;return!n}return d=void 0!==n?n:ze[re](),f=void 0!==o?o:Re[Ne](),e(oe,d)||_&&e(Me,f)}function u(){return!(e in{init:1,interval:1,size:1})}function c(){return re in ve||_&&Ne in ve}function s(){a("No change in size detected")}function l(){u()&&c()?V(t):e in{interval:1}||s()}var d,f;r()||"init"===e?(W(),i()):l()}function q(e,t,n,o){function i(){e in{reset:1,resetPage:1,init:1}||a("Trigger event: "+t)}function r(){return Ee&&e in ee}r()?a("Trigger event cancelled: "+e):(i(),Le(e,t,n,o))}function W(){Ee||(Ee=!0,a("Trigger event lock on")),clearTimeout(Se),Se=setTimeout(function(){Ee=!1,a("Trigger event lock off"),a("--")},te)}function B(e){oe=ze[re](),Me=Re[Ne](),J(oe,Me,e)}function V(e){var t=re;re=ie,a("Reset trigger event: "+e),W(),B("reset"),re=t}function J(e,t,n,o,i){function r(){void 0===i?i=be:a("Message targetOrigin: "+i)}function u(){var r=e+":"+t,u=ge+":"+r+":"+n+(void 0!==o?":"+o:"");a("Sending message to host page ("+u+")"),ye.postMessage(fe+u,i)}!0===pe&&(r(),u())}function U(t){function n(){return fe===(""+t.data).substr(0,me)}function o(){ue=t.data,ye=t.source,c(),ne=!1,setTimeout(function(){ae=!1},te)}function i(){ae?a("Page reset ignored by init"):(a("Page size reset by host page"),B("resetPage"))}function r(){q("resizeParent","Parent window requested size check")}function s(){var e=d();ce.findTarget(e)}function l(){return t.data.split("]")[1].split(":")[0]}function d(){return t.data.substr(t.data.indexOf(":")+1)}function f(){return"iFrameResize"in e}function m(){var e=d();a("MessageCallback called from parent: "+e),we(JSON.parse(e)),a(" --")}function g(){var e=d();a("PageInfoFromParent called from parent: "+e),Ae(JSON.parse(e)),a(" --")}function v(){return t.data.split(":")[2]in{"true":1,"false":1}}function h(){switch(l()){case"reset":i();break;case"resize":r();break;case"moveToAnchor":s();break;case"message":m();break;case"pageInfo":g();break;default:f()||v()||u("Unexpected message ("+t.data+")")}}function p(){!1===ne?h():v()?o():a('Ignored message of type "'+l()+'". Received before initialization.')}n()&&p()}function j(){"loading"!==document.readyState&&e.parent.postMessage("[iFrameResizerChild]Ready","*")}var K=!0,X=10,Y="",$=0,G="",Q=null,Z="",_=!1,ee={resize:1,click:1},te=128,ne=!0,oe=1,ie="bodyOffset",re=ie,ae=!0,ue="",ce={},se=32,le=null,de=!1,fe="[iFrameSizer]",me=fe.length,ge="",ve={max:1,min:1,bodyScroll:1,documentElementScroll:1},he="child",pe=!0,ye=e.parent,be="*",Te=0,Ee=!1,Se=null,Oe=16,Me=1,Ie="scroll",Ne=Ie,ke=e,we=function(){u("MessageCallback function not defined")},Ce=function(){},Ae=function(){},xe=Date.now||function(){return(new Date).getTime()},ze={bodyOffset:function(){return document.body.offsetHeight+z("marginTop")+z("marginBottom")},offset:function(){return ze.bodyOffset()},bodyScroll:function(){return document.body.scrollHeight},documentElementOffset:function(){return document.documentElement.offsetHeight},documentElementScroll:function(){return document.documentElement.scrollHeight},max:function(){return Math.max.apply(null,F(ze))},min:function(){return Math.min.apply(null,F(ze))},grow:function(){return ze.max()},lowestElement:function(){return Math.max(ze.bodyOffset(),L("bottom",D()))},taggedElement:function(){return P("bottom","data-iframe-height")}},Re={bodyScroll:function(){return document.body.scrollWidth},bodyOffset:function(){return document.body.offsetWidth},documentElementScroll:function(){return document.documentElement.scrollWidth},documentElementOffset:function(){return document.documentElement.offsetWidth},scroll:function(){return Math.max(Re.bodyScroll(),Re.documentElementScroll())},max:function(){return Math.max.apply(null,F(Re))},min:function(){return Math.min.apply(null,F(Re))},rightMostElement:function(){return L("right",D())},taggedElement:function(){return P("right","data-iframe-width")}},Le=i(H);t(e,"message",U),j()}(window||{}); -- cgit v1.2.3